From 21fe34d4a532eea7e8516299bd538cece6ed4b10 Mon Sep 17 00:00:00 2001 From: guinux <nuxgui@gmail.com> Date: Sat, 8 Jun 2019 18:42:58 +0200 Subject: [PATCH] new gtk ui --- resources/aur_row.ui | 134 ++ resources/choose_ignorepkgs_dialog.ui | 119 -- resources/choose_pkgs_dialog.ui | 13 +- resources/choose_provider_dialog.ui | 9 +- resources/history_dialog.ui | 7 +- resources/manager_window.ui | 967 ++++++------- resources/package_row.ui | 169 +++ resources/pamac.manager.gresource.xml | 2 + resources/preferences_dialog.ui | 18 +- resources/progress_box.ui | 2 +- resources/progress_dialog.ui | 3 +- resources/transaction_sum_dialog.ui | 10 +- src/aur_row.vala | 47 + src/choose_ignorepkgs_dialog.vala | 49 - src/choose_pkgs_dialog.vala | 2 + src/database.vala | 301 ++-- src/manager.vala | 2 +- src/manager_window.vala | 1905 ++++++++++++------------- src/meson.build | 2 +- src/package.vala | 4 +- src/package_row.vala | 51 + src/preferences_dialog.vala | 4 +- src/transaction-cli.vala | 3 + src/transaction-gtk.vala | 40 +- src/transaction_sum_dialog.vala | 2 + 25 files changed, 1993 insertions(+), 1872 deletions(-) create mode 100644 resources/aur_row.ui delete mode 100644 resources/choose_ignorepkgs_dialog.ui create mode 100644 resources/package_row.ui create mode 100644 src/aur_row.vala delete mode 100644 src/choose_ignorepkgs_dialog.vala create mode 100644 src/package_row.vala diff --git a/resources/aur_row.ui b/resources/aur_row.ui new file mode 100644 index 00000000..04529eee --- /dev/null +++ b/resources/aur_row.ui @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface> + <requires lib="gtk+" version="3.20"/> + <template class="PamacAURRow" parent="GtkListBoxRow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkBox" id="main_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkImage" id="app_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="icon_size">5</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="name_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <property name="homogeneous">True</property> + <child> + <object class="GtkLabel" id="name_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">end</property> + <property name="width_chars">60</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">60</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="desc_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">end</property> + <property name="width_chars">60</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">60</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="version_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">end</property> + <property name="width_chars">10</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">10</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkToggleButton" id="action_togglebutton"> + <property name="label" translatable="yes">Build</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + <child> + <object class="GtkButton" id="details_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="relief">none</property> + <child> + <object class="GtkImage" id="details_image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">go-next-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + </object> + </child> + </template> +</interface> diff --git a/resources/choose_ignorepkgs_dialog.ui b/resources/choose_ignorepkgs_dialog.ui deleted file mode 100644 index 22c87615..00000000 --- a/resources/choose_ignorepkgs_dialog.ui +++ /dev/null @@ -1,119 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface> - <requires lib="gtk+" version="3.20"/> - <template class="PamacChooseIgnorepkgsDialog" parent="GtkDialog"> - <property name="can_focus">False</property> - <property name="border_width">3</property> - <property name="title" translatable="yes">Choose Ignored Upgrades</property> - <property name="modal">True</property> - <property name="window_position">center-on-parent</property> - <property name="default_width">600</property> - <property name="icon_name">system-software-install</property> - <property name="type_hint">dialog</property> - <property name="urgency_hint">True</property> - <property name="deletable">False</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox1"> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area1"> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancel_button"> - <property name="label" translatable="yes">_Cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="valid_button"> - <property name="label" translatable="yes">Choose</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">False</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> - <property name="min_content_width">300</property> - <property name="min_content_height">250</property> - <child> - <object class="GtkTreeView" id="treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="search_column">1</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection"> - <property name="mode">none</property> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn1"> - <property name="sizing">autosize</property> - <child> - <object class="GtkCellRendererToggle" id="renderertoggle"> - <signal name="toggled" handler="on_renderertoggle_toggled" swapped="no"/> - </object> - <attributes> - <attribute name="active">0</attribute> - </attributes> - </child> - <child> - <object class="GtkCellRendererText" id="renderertext1"/> - <attributes> - <attribute name="text">1</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancel_button</action-widget> - <action-widget response="-5">valid_button</action-widget> - </action-widgets> - </template> -</interface> diff --git a/resources/choose_pkgs_dialog.ui b/resources/choose_pkgs_dialog.ui index 6503abfa..60c73843 100644 --- a/resources/choose_pkgs_dialog.ui +++ b/resources/choose_pkgs_dialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> +<!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.20"/> <template class="PamacChoosePkgsDialog" parent="GtkDialog"> @@ -12,11 +12,14 @@ <property name="type_hint">dialog</property> <property name="urgency_hint">True</property> <property name="deletable">False</property> + <child> + <placeholder/> + </child> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> <property name="can_focus">False</property> <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="spacing">6</property> <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> <property name="can_focus">False</property> @@ -26,7 +29,7 @@ <property name="label" translatable="yes">_Cancel</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="receives_default">False</property> <property name="use_underline">True</property> </object> <packing> @@ -40,7 +43,6 @@ <property name="label" translatable="yes">Choose</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="has_focus">True</property> <property name="can_default">True</property> <property name="has_default">True</property> <property name="receives_default">False</property> @@ -63,6 +65,7 @@ <object class="GtkScrolledWindow" id="scrolledwindow"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="vexpand">True</property> <property name="shadow_type">in</property> <property name="min_content_width">300</property> <property name="min_content_height">250</property> @@ -103,7 +106,7 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> diff --git a/resources/choose_provider_dialog.ui b/resources/choose_provider_dialog.ui index f12e1f44..730071f7 100644 --- a/resources/choose_provider_dialog.ui +++ b/resources/choose_provider_dialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> +<!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.20"/> <template class="PamacChooseProviderDialog" parent="GtkDialog"> @@ -13,11 +13,14 @@ <property name="type_hint">dialog</property> <property name="urgency_hint">True</property> <property name="deletable">False</property> + <child> + <placeholder/> + </child> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox2"> <property name="can_focus">False</property> <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="spacing">6</property> <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area2"> <property name="can_focus">False</property> @@ -33,7 +36,7 @@ <property name="receives_default">False</property> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> diff --git a/resources/history_dialog.ui b/resources/history_dialog.ui index 9de74f0d..e3dd48fa 100644 --- a/resources/history_dialog.ui +++ b/resources/history_dialog.ui @@ -48,10 +48,12 @@ <object class="GtkBox" id="search_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="halign">center</property> <child> <object class="GtkSearchEntry" id="search_entry"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="width_chars">50</property> <property name="caps_lock_warning">False</property> <property name="primary_icon_name">edit-find-symbolic</property> <property name="secondary_icon_name">edit-clear-symbolic</property> @@ -61,7 +63,7 @@ <signal name="search-changed" handler="on_search_entry_search_changed" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> @@ -122,6 +124,7 @@ <object class="GtkScrolledWindow" id="scrolledwindow"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="vexpand">True</property> <property name="shadow_type">in</property> <property name="min_content_width">300</property> <property name="min_content_height">400</property> @@ -136,7 +139,7 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> diff --git a/resources/manager_window.ui b/resources/manager_window.ui index 7ebf5b32..68b20838 100644 --- a/resources/manager_window.ui +++ b/resources/manager_window.ui @@ -15,6 +15,7 @@ <object class="GtkModelButton" id="refresh_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="text" translatable="yes">Refresh databases</property> <signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/> @@ -29,6 +30,7 @@ <object class="GtkModelButton" id="history_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="text" translatable="yes">View History</property> <signal name="clicked" handler="on_history_button_clicked" swapped="no"/> @@ -43,6 +45,7 @@ <object class="GtkModelButton" id="local_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="text" translatable="yes">Install Local Packages</property> <signal name="clicked" handler="on_local_button_clicked" swapped="no"/> @@ -57,6 +60,7 @@ <object class="GtkModelButton" id="preferences_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="text" translatable="yes">Preferences</property> <signal name="clicked" handler="on_preferences_button_clicked" swapped="no"/> @@ -71,6 +75,7 @@ <object class="GtkModelButton" id="about_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="text" translatable="yes">About</property> <signal name="clicked" handler="on_about_button_clicked" swapped="no"/> @@ -111,6 +116,7 @@ <object class="GtkButton" id="button_back"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="halign">start</property> <signal name="clicked" handler="on_button_back_clicked" swapped="no"/> @@ -143,21 +149,13 @@ <property name="position">1</property> </packing> </child> - <child> - <object class="GtkButton" id="select_all_button"> - <property name="label" translatable="yes">Select All</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="margin_left">18</property> - <signal name="clicked" handler="on_select_all_button_clicked" swapped="no"/> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">3</property> - </packing> - </child> + </object> + </child> + <child type="title"> + <object class="GtkStackSwitcher" id="main_stack_switcher"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stack">browse_stack</property> </object> </child> <child> @@ -169,6 +167,7 @@ <object class="GtkToggleButton" id="search_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <signal name="toggled" handler="on_search_button_toggled" swapped="no"/> <child> @@ -189,6 +188,7 @@ <object class="GtkMenuButton" id="menu_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="popover">popovermenu</property> <signal name="toggled" handler="on_menu_button_toggled" swapped="no"/> @@ -227,578 +227,548 @@ <object class="GtkStack" id="main_stack"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="vexpand">True</property> <property name="transition_type">slide-left-right</property> <child> - <object class="GtkBox" id="box3"> + <object class="GtkBox" id="box12"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="orientation">vertical</property> <child> - <object class="GtkRevealer" id="sidebar_revealer"> + <object class="GtkSearchBar" id="searchbar"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="transition_type">slide-right</property> - <property name="transition_duration">200</property> - <property name="reveal_child">True</property> <child> - <object class="GtkStack" id="filters_stack"> - <property name="width_request">175</property> + <object class="GtkComboBoxText" id="search_comboboxtext"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="transition_duration">250</property> - <property name="transition_type">slide-left-right</property> - <child> - <object class="GtkScrolledWindow" id="filters_scrolledwindow"> + <property name="focus_on_click">False</property> + <property name="has_entry">True</property> + <signal name="changed" handler="on_search_comboboxtext_changed" swapped="no"/> + <child internal-child="entry"> + <object class="GtkEntry" id="search_entry"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="width_chars">50</property> + <property name="caps_lock_warning">False</property> + <property name="primary_icon_name">edit-find-symbolic</property> + <property name="secondary_icon_name">edit-clear-symbolic</property> + <property name="placeholder_text" translatable="yes">Search</property> + <signal name="icon-press" handler="on_search_entry_icon_press" swapped="no"/> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkRevealer" id="sidebar_revealer"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="transition_type">slide-right</property> + <property name="transition_duration">200</property> + <property name="reveal_child">True</property> + <child> + <object class="GtkStack" id="browse_stack"> + <property name="width_request">175</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="transition_type">slide-left-right</property> <child> - <object class="GtkViewport" id="filters_viewport"> + <object class="GtkStack" id="filters_stack"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="transition_type">slide-left-right</property> <child> - <object class="GtkListBox" id="filters_listbox"> + <object class="GtkScrolledWindow" id="filters_scrolledwindow"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">none</property> - <signal name="row-activated" handler="on_filters_listbox_row_activated" swapped="no"/> + <property name="can_focus">True</property> + <child> + <object class="GtkViewport" id="filters_viewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkListBox" id="filters_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">none</property> + <signal name="row-activated" handler="on_filters_listbox_row_activated" swapped="no"/> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="name">filters</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="categories_scrolledwindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkViewport" id="categories_viewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkListBox" id="categories_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_categories_listbox_row_activated" swapped="no"/> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="name">categories</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="groups_scrolledwindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkViewport" id="groups_viewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkListBox" id="groups_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_groups_listbox_row_activated" swapped="no"/> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="name">groups</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="repos_scrolledwindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkViewport" id="repos_viewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkListBox" id="repos_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_repos_listbox_row_activated" swapped="no"/> + </object> + </child> + </object> + </child> </object> + <packing> + <property name="name">repos</property> + <property name="position">3</property> + </packing> </child> </object> + <packing> + <property name="name">browse</property> + <property name="title" translatable="yes">All</property> + </packing> </child> - </object> - <packing> - <property name="name">filters</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="categories_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> <child> - <object class="GtkViewport" id="categories_viewport"> + <object class="GtkScrolledWindow" id="installed_scrolledwindow"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can_focus">True</property> <child> - <object class="GtkListBox" id="categories_listbox"> + <object class="GtkViewport" id="installed_viewport"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_categories_listbox_row_activated" swapped="no"/> + <child> + <object class="GtkListBox" id="installed_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_installed_listbox_row_activated" swapped="no"/> + </object> + </child> </object> </child> </object> + <packing> + <property name="name">installed</property> + <property name="title" translatable="yes">Installed</property> + <property name="position">1</property> + </packing> </child> - </object> - <packing> - <property name="name">categories</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="groups_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> <child> - <object class="GtkViewport" id="groups_viewport"> + <object class="GtkListBox" id="pending_listbox"> <property name="visible">True</property> <property name="can_focus">False</property> - <child> - <object class="GtkListBox" id="groups_listbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_groups_listbox_row_activated" swapped="no"/> - </object> - </child> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_pending_listbox_row_activated" swapped="no"/> </object> + <packing> + <property name="name">pending</property> + <property name="title" translatable="yes">Pending</property> + <property name="position">2</property> + </packing> </child> - </object> - <packing> - <property name="name">groups</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="repos_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> <child> - <object class="GtkViewport" id="repos_viewport"> + <object class="GtkListBox" id="updates_listbox"> <property name="visible">True</property> <property name="can_focus">False</property> - <child> - <object class="GtkListBox" id="repos_listbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_repos_listbox_row_activated" swapped="no"/> - </object> - </child> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_updates_listbox_row_activated" swapped="no"/> </object> + <packing> + <property name="name">updates</property> + <property name="title" translatable="yes">Updates</property> + <property name="position">3</property> + </packing> </child> - </object> - <packing> - <property name="name">repos</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="installed_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> <child> - <object class="GtkViewport" id="installed_viewport"> + <object class="GtkListBox" id="search_listbox"> <property name="visible">True</property> <property name="can_focus">False</property> - <child> - <object class="GtkListBox" id="installed_listbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_installed_listbox_row_activated" swapped="no"/> - </object> - </child> + <property name="selection_mode">browse</property> + <signal name="row-activated" handler="on_search_listbox_row_activated" swapped="no"/> </object> + <packing> + <property name="name">search</property> + <property name="position">4</property> + </packing> </child> </object> - <packing> - <property name="name">installed</property> - <property name="position">4</property> - </packing> - </child> - <child> - <object class="GtkListBox" id="updates_listbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_updates_listbox_row_activated" swapped="no"/> - </object> - <packing> - <property name="name">updates</property> - <property name="position">5</property> - </packing> - </child> - <child> - <object class="GtkListBox" id="pending_listbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_pending_listbox_row_activated" swapped="no"/> - </object> - <packing> - <property name="name">pending</property> - <property name="position">6</property> - </packing> - </child> - <child> - <object class="GtkListBox" id="search_listbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="selection_mode">browse</property> - <signal name="row-activated" handler="on_search_listbox_row_activated" swapped="no"/> - </object> - <packing> - <property name="name">search</property> - <property name="position">7</property> - </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="box7"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> <child> - <object class="GtkSearchBar" id="searchbar"> + <object class="GtkSeparator" id="separator2"> <property name="visible">True</property> <property name="can_focus">False</property> - <child> - <object class="GtkComboBoxText" id="search_comboboxtext"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="has_entry">True</property> - <signal name="changed" handler="on_search_comboboxtext_changed" swapped="no"/> - <child internal-child="entry"> - <object class="GtkEntry" id="search_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="is_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">True</property> - <property name="width_chars">50</property> - <property name="caps_lock_warning">False</property> - <property name="primary_icon_name">edit-find-symbolic</property> - <property name="secondary_icon_name">edit-clear-symbolic</property> - <property name="placeholder_text" translatable="yes">Search</property> - <signal name="icon-press" handler="on_search_entry_icon_press" swapped="no"/> - </object> - </child> - </object> - </child> + <property name="orientation">vertical</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkStack" id="origin_stack"> + <object class="GtkBox" id="box7"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="orientation">vertical</property> <child> - <object class="GtkScrolledWindow" id="packages_scrolledwindow"> - <property name="width_request">700</property> - <property name="height_request">200</property> + <object class="GtkBox" id="box10"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="shadow_type">in</property> + <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">5</property> + <property name="spacing">6</property> <child> - <object class="GtkTreeView" id="packages_treeview"> + <object class="GtkButtonBox" id="list_button_box"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_tooltip">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="search_column">1</property> - <property name="fixed_height_mode">True</property> - <property name="show_expanders">False</property> - <property name="rubber_banding">True</property> - <signal name="button-press-event" handler="on_packages_treeview_button_press_event" swapped="no"/> - <signal name="query-tooltip" handler="on_packages_treeview_query_tooltip" swapped="no"/> - <signal name="row-activated" handler="on_packages_treeview_row_activated" swapped="no"/> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="packages_treeview_selection"> - <property name="mode">multiple</property> - </object> - </child> + <property name="spacing">6</property> + <property name="layout_style">start</property> <child> - <object class="GtkTreeViewColumn" id="packages_state_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">60</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">State</property> - <property name="clickable">True</property> - <property name="sort_column_id">0</property> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="packages_name_column"> - <property name="resizable">True</property> - <property name="spacing">12</property> - <property name="sizing">fixed</property> - <property name="fixed_width">240</property> - <property name="min_width">40</property> - <property name="title" translatable="yes">Name</property> - <property name="expand">True</property> - <property name="clickable">True</property> - <property name="sort_column_id">2</property> - <child> - <object class="GtkCellRendererPixbuf" id="packages_pixbuf"/> - <attributes> - <attribute name="pixbuf">8</attribute> - </attributes> - </child> - <child> - <object class="GtkCellRendererText" id="packages_name_renderertext"> - <property name="wrap_mode">word</property> - </object> - <attributes> - <attribute name="markup">2</attribute> - </attributes> - </child> + <object class="GtkButton" id="remove_all_button"> + <property name="label" translatable="yes">Remove all</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="on_remove_all_button_clicked" swapped="no"/> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> <child> - <object class="GtkTreeViewColumn" id="packages_version_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">90</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Version</property> - <property name="clickable">True</property> - <property name="sort_column_id">3</property> - <child> - <object class="GtkCellRendererText" id="packages_version_renderertext"/> - <attributes> - <attribute name="markup">3</attribute> - </attributes> - </child> + <object class="GtkButton" id="install_all_button"> + <property name="label" translatable="yes">Install all</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">False</property> + <signal name="clicked" handler="on_install_all_button_clicked" swapped="no"/> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="sort_order_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="spacing">6</property> <child> - <object class="GtkTreeViewColumn" id="packages_repo_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">90</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Repository</property> - <property name="clickable">True</property> - <property name="sort_column_id">4</property> - <child> - <object class="GtkCellRendererText" id="packages_repo_renderertext"/> - <attributes> - <attribute name="text">4</attribute> - </attributes> - </child> + <object class="GtkLabel" id="sort_order_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Sort by</property> + <property name="track_visited_links">False</property> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> <child> - <object class="GtkTreeViewColumn" id="packages_size_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">90</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Size</property> - <property name="clickable">True</property> - <property name="sort_column_id">5</property> - <child> - <object class="GtkCellRendererText" id="packages_size_renderertext"/> - <attributes> - <attribute name="text">6</attribute> - </attributes> - </child> + <object class="GtkComboBoxText" id="sort_comboboxtext"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="focus_on_click">False</property> + <property name="active">0</property> + <items> + <item translatable="yes">Relevance</item> + <item translatable="yes">Name</item> + <item translatable="yes">Repository</item> + <item translatable="yes">Size</item> + </items> + <signal name="changed" handler="on_sort_comboboxtext_changed" swapped="no"/> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> </child> </object> <packing> - <property name="name">repos</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="aur_scrolledwindow"> - <property name="width_request">700</property> - <property name="height_request">200</property> + <object class="GtkStack" id="origin_stack"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> + <property name="can_focus">False</property> <property name="vexpand">True</property> - <property name="shadow_type">in</property> + <property name="transition_type">crossfade</property> <child> - <object class="GtkTreeView" id="aur_treeview"> + <object class="GtkScrolledWindow" id="packages_scrolledwindow"> + <property name="width_request">700</property> + <property name="height_request">200</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="has_tooltip">True</property> <property name="hexpand">True</property> <property name="vexpand">True</property> - <property name="search_column">1</property> - <property name="fixed_height_mode">True</property> - <property name="show_expanders">False</property> - <property name="rubber_banding">True</property> - <signal name="button-press-event" handler="on_aur_treeview_button_press_event" swapped="no"/> - <signal name="query-tooltip" handler="on_aur_treeview_query_tooltip" swapped="no"/> - <signal name="row-activated" handler="on_aur_treeview_row_activated" swapped="no"/> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="aur_treeview_selection"> - <property name="mode">multiple</property> - </object> - </child> + <property name="hscrollbar_policy">never</property> <child> - <object class="GtkTreeViewColumn" id="aur_state_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">60</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">State</property> - <property name="clickable">True</property> - <property name="sort_column_id">0</property> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="aur_name_column"> - <property name="resizable">True</property> - <property name="spacing">12</property> - <property name="sizing">fixed</property> - <property name="fixed_width">240</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Name</property> - <property name="expand">True</property> - <property name="clickable">True</property> - <property name="sort_column_id">1</property> - <child> - <object class="GtkCellRendererPixbuf" id="aur_pixbuf"/> - <attributes> - <attribute name="pixbuf">6</attribute> - </attributes> - </child> + <object class="GtkViewport" id="packages_viewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <object class="GtkCellRendererText" id="aur_name_renderertext"> - <property name="wrap_mode">word</property> + <object class="GtkListBox" id="packages_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">none</property> + <property name="activate_on_single_click">False</property> + <signal name="row-activated" handler="on_packages_listbox_row_activated" swapped="no"/> </object> - <attributes> - <attribute name="markup">2</attribute> - </attributes> </child> </object> </child> - <child> - <object class="GtkTreeViewColumn" id="aur_version_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">90</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Version</property> - <property name="clickable">True</property> - <property name="sort_column_id">3</property> - <child> - <object class="GtkCellRendererText" id="aur_version_renderertext"/> - <attributes> - <attribute name="markup">3</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="aur_popularity_column"> - <property name="resizable">True</property> - <property name="sizing">fixed</property> - <property name="fixed_width">100</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Popularity</property> - <property name="clickable">True</property> - <property name="sort_column_id">4</property> - <child> - <object class="GtkCellRendererText" id="aur_popularity_renderertext"/> - <attributes> - <attribute name="text">5</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="name">aur</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkBox" id="updated_box"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkImage" id="updated_icon"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="valign">end</property> - <property name="icon_name">object-select-symbolic</property> - <property name="icon_size">6</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> + <property name="name">repos</property> </packing> </child> <child> - <object class="GtkLabel" id="updated_label"> + <object class="GtkScrolledWindow" id="aur_scrolledwindow"> + <property name="width_request">700</property> + <property name="height_request">200</property> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="valign">start</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkViewport" id="aur_viewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkListBox" id="aur_listbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">none</property> + <property name="activate_on_single_click">False</property> + <signal name="row-activated" handler="on_aur_listbox_row_activated" swapped="no"/> + </object> + </child> + </object> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> + <property name="name">aur</property> <property name="position">1</property> </packing> </child> - </object> - <packing> - <property name="name">updated</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkBox" id="no_item_box"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <property name="homogeneous">True</property> <child> - <object class="GtkImage" id="no_item_icon"> + <object class="GtkBox" id="no_item_box"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="valign">end</property> - <property name="icon_name">action-unavailable-symbolic</property> - <property name="icon_size">6</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <property name="homogeneous">True</property> + <child> + <object class="GtkImage" id="no_item_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">end</property> + <property name="icon_name">action-unavailable-symbolic</property> + <property name="icon_size">6</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="no_item_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> + <property name="name">no_item</property> + <property name="position">2</property> </packing> </child> <child> - <object class="GtkLabel" id="no_item_label"> + <object class="GtkBox" id="checking_box"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="valign">start</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <property name="homogeneous">True</property> + <child> + <object class="GtkLabel" id="checking_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> + <property name="name">checking</property> + <property name="position">3</property> </packing> </child> - </object> - <packing> - <property name="name">no_item</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkBox" id="checking_box"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <property name="homogeneous">True</property> <child> - <object class="GtkLabel" id="checking_label"> + <object class="GtkBox" id="updated_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <property name="homogeneous">True</property> + <child> + <object class="GtkImage" id="updated_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">end</property> + <property name="icon_name">object-select-symbolic</property> + <property name="icon_size">6</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="updated_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> + <property name="name">updated</property> + <property name="position">4</property> </packing> </child> </object> <packing> - <property name="name">checking</property> - <property name="position">4</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> </packing> </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> @@ -818,6 +788,7 @@ <property name="width_request">175</property> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="selection_mode">browse</property> <signal name="row-activated" handler="on_properties_listbox_row_activated" swapped="no"/> </object> <packing> @@ -826,10 +797,23 @@ <property name="position">0</property> </packing> </child> + <child> + <object class="GtkSeparator" id="separator3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> <child> <object class="GtkBox" id="box9"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="hexpand">True</property> <property name="orientation">vertical</property> <child> <object class="GtkBox" id="properties_box1"> @@ -846,6 +830,7 @@ <object class="GtkImage" id="app_image"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="valign">start</property> </object> <packing> <property name="expand">False</property> @@ -919,11 +904,12 @@ <property name="label" translatable="yes">Remove</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <signal name="toggled" handler="on_remove_togglebutton_toggled" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> @@ -933,11 +919,12 @@ <property name="label" translatable="yes">Reinstall</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <signal name="toggled" handler="on_reinstall_togglebutton_toggled" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> @@ -947,11 +934,12 @@ <property name="label" translatable="yes">Install</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <signal name="toggled" handler="on_install_togglebutton_toggled" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> @@ -961,11 +949,12 @@ <property name="label" translatable="yes">Build</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> <signal name="toggled" handler="on_build_togglebutton_toggled" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">3</property> </packing> @@ -975,11 +964,12 @@ <property name="label" translatable="yes">Reset build files</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">False</property> <signal name="clicked" handler="on_reset_files_button_clicked" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">4</property> </packing> @@ -1003,6 +993,7 @@ <object class="GtkStack" id="properties_stack"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="vexpand">True</property> <child> <object class="GtkScrolledWindow" id="details_scrolledwindow"> <property name="visible">True</property> @@ -1095,6 +1086,7 @@ <property name="can_focus">False</property> <property name="margin_left">24</property> <property name="margin_bottom">18</property> + <property name="vexpand">True</property> <property name="row_spacing">18</property> <property name="column_spacing">18</property> <child> @@ -1126,7 +1118,7 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> @@ -1217,16 +1209,16 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> @@ -1238,9 +1230,9 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> <child> @@ -1251,7 +1243,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> <child> @@ -1259,6 +1251,7 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="transition_type">slide-up</property> + <property name="transition_duration">200</property> <child> <object class="GtkBox" id="transaction_infobox"> <property name="visible">True</property> @@ -1266,7 +1259,27 @@ <property name="border_width">6</property> <property name="spacing">12</property> <child> - <placeholder/> + <object class="GtkButton" id="details_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">False</property> + <property name="relief">none</property> + <signal name="clicked" handler="on_details_button_clicked" swapped="no"/> + <child> + <object class="GtkImage" id="details_image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">go-next-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> </child> <child> <object class="GtkButtonBox" id="transaction_infos_buttonbox"> @@ -1274,17 +1287,20 @@ <property name="can_focus">False</property> <property name="valign">end</property> <property name="spacing">6</property> + <property name="homogeneous">True</property> <property name="layout_style">start</property> <child> - <object class="GtkButton" id="details_button"> - <property name="label" translatable="yes">Details</property> + <object class="GtkButton" id="cancel_button"> + <property name="label" translatable="yes">_Cancel</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">False</property> - <signal name="clicked" handler="on_details_button_clicked" swapped="no"/> + <property name="use_underline">True</property> + <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> @@ -1294,31 +1310,17 @@ <property name="label" translatable="yes">_Apply</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="focus_on_click">False</property> <property name="receives_default">True</property> <property name="use_underline">True</property> <signal name="clicked" handler="on_apply_button_clicked" swapped="no"/> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> - <child> - <object class="GtkButton" id="cancel_button"> - <property name="label" translatable="yes">_Cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> </object> <packing> <property name="expand">False</property> @@ -1327,13 +1329,16 @@ <property name="position">1</property> </packing> </child> + <child> + <placeholder/> + </child> </object> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">2</property> + <property name="position">3</property> </packing> </child> </object> diff --git a/resources/package_row.ui b/resources/package_row.ui new file mode 100644 index 00000000..49d18f12 --- /dev/null +++ b/resources/package_row.ui @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface> + <requires lib="gtk+" version="3.20"/> + <template class="PamacPackageRow" parent="GtkListBoxRow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkBox" id="main_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkImage" id="app_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="icon_size">5</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="name_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <property name="homogeneous">True</property> + <child> + <object class="GtkLabel" id="name_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">end</property> + <property name="width_chars">60</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">60</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="desc_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">3</property> + <property name="ellipsize">end</property> + <property name="width_chars">60</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">60</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkBox" id="version_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">3</property> + <property name="homogeneous">True</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="repo_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">end</property> + <property name="width_chars">10</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">10</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="size_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="ellipsize">middle</property> + <property name="width_chars">8</property> + <property name="single_line_mode">True</property> + <property name="max_width_chars">8</property> + <property name="track_visited_links">False</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + <child> + <object class="GtkToggleButton" id="action_togglebutton"> + <property name="width_request">110</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="GtkButton" id="details_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="relief">none</property> + <child> + <object class="GtkImage" id="details_image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">go-next-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">6</property> + </packing> + </child> + </object> + </child> + </template> +</interface> diff --git a/resources/pamac.manager.gresource.xml b/resources/pamac.manager.gresource.xml index deb798de..c920b548 100644 --- a/resources/pamac.manager.gresource.xml +++ b/resources/pamac.manager.gresource.xml @@ -3,6 +3,8 @@ <gresource prefix="/org/manjaro/pamac/manager"> <file preprocess="xml-stripblanks">manager_window.ui</file> <file preprocess="xml-stripblanks">history_dialog.ui</file> + <file preprocess="xml-stripblanks">package_row.ui</file> + <file preprocess="xml-stripblanks">aur_row.ui</file> </gresource> <gresource prefix="/org/manjaro/pamac/preferences"> <file preprocess="xml-stripblanks">preferences_dialog.ui</file> diff --git a/resources/preferences_dialog.ui b/resources/preferences_dialog.ui index dac5896a..d8215531 100644 --- a/resources/preferences_dialog.ui +++ b/resources/preferences_dialog.ui @@ -35,7 +35,7 @@ <object class="GtkBox" id="dialog-vbox"> <property name="can_focus">False</property> <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="spacing">6</property> <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area"> <property name="can_focus">False</property> @@ -66,6 +66,7 @@ <object class="GtkNotebook" id="notebook"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="vexpand">True</property> <child> <object class="GtkBox" id="general_config_box"> <property name="visible">True</property> @@ -376,6 +377,7 @@ <object class="GtkBox" id="ignorepkgs_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="vexpand">True</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="ignorepkgs_label"> @@ -400,13 +402,13 @@ <property name="margin_left">12</property> <property name="margin_start">12</property> <property name="hexpand">True</property> - <property name="vexpand">True</property> <property name="orientation">vertical</property> <child> <object class="GtkScrolledWindow" id="ignorepkgs_scrolledwindow"> <property name="height_request">100</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="vexpand">True</property> <property name="hscrollbar_policy">never</property> <property name="shadow_type">in</property> <child> @@ -434,7 +436,7 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> @@ -483,14 +485,14 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">8</property> </packing> @@ -613,7 +615,7 @@ </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -641,7 +643,7 @@ All AUR users should be familiar with the build process.</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -969,7 +971,7 @@ All AUR users should be familiar with the build process.</property> </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> diff --git a/resources/progress_box.ui b/resources/progress_box.ui index d72aa94e..f6bbe0ad 100644 --- a/resources/progress_box.ui +++ b/resources/progress_box.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> +<!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.20"/> <template class="PamacProgressBox" parent="GtkBox"> diff --git a/resources/progress_dialog.ui b/resources/progress_dialog.ui index 3ac3b475..894e7c0f 100644 --- a/resources/progress_dialog.ui +++ b/resources/progress_dialog.ui @@ -26,6 +26,7 @@ <object class="GtkExpander" id="expander"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="vexpand">True</property> <property name="resize_toplevel">True</property> <child> <placeholder/> @@ -39,7 +40,7 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> diff --git a/resources/transaction_sum_dialog.ui b/resources/transaction_sum_dialog.ui index 0d55a6b5..1a2c6d5c 100644 --- a/resources/transaction_sum_dialog.ui +++ b/resources/transaction_sum_dialog.ui @@ -18,7 +18,7 @@ <object class="GtkBox" id="dialog-vbox6"> <property name="can_focus">False</property> <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="spacing">6</property> <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area6"> <property name="can_focus">False</property> @@ -28,7 +28,6 @@ <property name="label" translatable="yes">_Cancel</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="has_focus">True</property> <property name="can_default">True</property> <property name="has_default">True</property> <property name="receives_default">False</property> @@ -45,7 +44,7 @@ <property name="label" translatable="yes">_Apply</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="receives_default">False</property> <property name="use_underline">True</property> </object> <packing> @@ -59,7 +58,7 @@ <property name="label" translatable="yes">Edit build files</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="receives_default">False</property> </object> <packing> <property name="expand">False</property> @@ -90,7 +89,6 @@ <object class="GtkScrolledWindow" id="scrolledwindow4"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="shadow_type">in</property> <property name="min_content_width">450</property> @@ -177,7 +175,7 @@ </child> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> diff --git a/src/aur_row.vala b/src/aur_row.vala new file mode 100644 index 00000000..fe3faffc --- /dev/null +++ b/src/aur_row.vala @@ -0,0 +1,47 @@ +/* + * pamac-vala + * + * Copyright (C) 2019 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + + [GtkTemplate (ui = "/org/manjaro/pamac/manager/aur_row.ui")] + public class AURRow : Gtk.ListBoxRow { + + [GtkChild] + public Gtk.Image app_icon; + [GtkChild] + public Gtk.Label name_label; + [GtkChild] + public Gtk.Label desc_label; + [GtkChild] + public Gtk.Label version_label; + [GtkChild] + public Gtk.ToggleButton action_togglebutton; + [GtkChild] + public Gtk.Button details_button; + + public AURPackage aur_pkg; + + public AURRow (AURPackage aur_pkg) { + Object (); + this.aur_pkg = aur_pkg; + } + + } + +} diff --git a/src/choose_ignorepkgs_dialog.vala b/src/choose_ignorepkgs_dialog.vala deleted file mode 100644 index d3954fba..00000000 --- a/src/choose_ignorepkgs_dialog.vala +++ /dev/null @@ -1,49 +0,0 @@ -/* - * pamac-vala - * - * Copyright (C) 2015-2019 Guillaume Benoit <guillaume@manjaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a get of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -namespace Pamac { - - [GtkTemplate (ui = "/org/manjaro/pamac/preferences/choose_ignorepkgs_dialog.ui")] - class ChooseIgnorepkgsDialog : Gtk.Dialog { - - [GtkChild] - public Gtk.TreeView treeview; - - public Gtk.ListStore pkgs_list; - - public ChooseIgnorepkgsDialog (Gtk.Window window) { - int use_header_bar; - Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); - Object (transient_for: window, use_header_bar: use_header_bar); - - pkgs_list = new Gtk.ListStore (2, typeof (bool), typeof (string)); - treeview.set_model (pkgs_list); - } - - [GtkCallback] - void on_renderertoggle_toggled (string path) { - Gtk.TreeIter iter; - bool selected; - if (pkgs_list.get_iter_from_string (out iter, path)) { - pkgs_list.get (iter, 0, out selected); - pkgs_list.set (iter, 0, !selected); - } - } - } -} diff --git a/src/choose_pkgs_dialog.vala b/src/choose_pkgs_dialog.vala index 18dbf293..dd79a5cc 100644 --- a/src/choose_pkgs_dialog.vala +++ b/src/choose_pkgs_dialog.vala @@ -24,6 +24,8 @@ namespace Pamac { [GtkChild] public Gtk.TreeView treeview; + [GtkChild] + public Gtk.Button valid_button; public Gtk.ListStore pkgs_list; diff --git a/src/database.vala b/src/database.vala index d98f8b22..b8034131 100644 --- a/src/database.vala +++ b/src/database.vala @@ -78,7 +78,6 @@ namespace Pamac { app_store.load (As.StoreLoadFlags.APP_INFO_SYSTEM); app_store.set_search_match (As.AppSearchMatch.PKGNAME | As.AppSearchMatch.DESCRIPTION - | As.AppSearchMatch.COMMENT | As.AppSearchMatch.NAME | As.AppSearchMatch.KEYWORD); } catch (Error e) { @@ -374,8 +373,10 @@ namespace Pamac { SList<As.App> get_pkgname_matching_apps (string pkgname) { var matching_apps = new SList<As.App> (); app_store.get_apps ().foreach ((app) => { - if (app.get_pkgname_default () == pkgname) { - matching_apps.append (app); + if (app.get_kind () == As.AppKind.DESKTOP) { + if (app.get_pkgname_default () == pkgname) { + matching_apps.append (app); + } } }); return (owned) matching_apps; @@ -445,9 +446,12 @@ namespace Pamac { } } - List<Package> initialise_pkgs (Alpm.Package? alpm_pkg) { + List<Package> initialise_pkgs (Alpm.List<unowned Alpm.Package>? alpm_pkgs) { var pkgs = new List<Package> (); - if (alpm_pkg != null) { + var data = new HashTable<string, Package> (str_hash, str_equal); + string[] foreign_pkgnames = {}; + while (alpm_pkgs != null) { + unowned Alpm.Package alpm_pkg = alpm_pkgs.data; string installed_version = ""; string repo_name = ""; if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) { @@ -456,15 +460,7 @@ namespace Pamac { if (sync_pkg != null) { repo_name = sync_pkg.db.name; } else if (config.enable_aur) { - var loop = new MainLoop (); - get_aur_pkg.begin (alpm_pkg.name, (obj, res) => { - var aur_pkg = get_aur_pkg.end (res); - if (aur_pkg.name != "") { - repo_name = dgettext (null, "AUR"); - } - loop.quit (); - }); - loop.run (); + foreign_pkgnames += alpm_pkg.name; } } else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) { unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (alpm_pkg.name); @@ -473,7 +469,33 @@ namespace Pamac { } repo_name = alpm_pkg.db.name; } - if (repo_name != "" && repo_name != dgettext (null, "AUR")) { + if (repo_name == "" ) { + if (config.enable_aur) { + data.insert (alpm_pkg.name, new Package.from_struct (PackageStruct () { + name = alpm_pkg.name, + app_name = "", + version = alpm_pkg.version, + installed_version = (owned) installed_version, + desc = alpm_pkg.desc ?? "", + repo = (owned) repo_name, + size = alpm_pkg.isize, + download_size = alpm_pkg.download_size, + icon = "" + })); + } else { + pkgs.append (new Package.from_struct (PackageStruct () { + name = alpm_pkg.name, + app_name = "", + version = alpm_pkg.version, + installed_version = (owned) installed_version, + desc = alpm_pkg.desc ?? "", + repo = (owned) repo_name, + size = alpm_pkg.isize, + download_size = alpm_pkg.download_size, + icon = "" + })); + } + } else { var apps = get_pkgname_matching_apps (alpm_pkg.name); if (apps.length () > 0) { // alpm_pkg provide some apps @@ -503,55 +525,64 @@ namespace Pamac { icon = "" })); } - } else { - pkgs.append (new Package.from_struct (PackageStruct () { - name = alpm_pkg.name, - app_name = "", - version = alpm_pkg.version, - installed_version = (owned) installed_version, - desc = alpm_pkg.desc ?? "", - repo = (owned) repo_name, - size = alpm_pkg.isize, - download_size = alpm_pkg.download_size, - icon = "" - })); + } + alpm_pkgs.next (); + } + // get aur infos + if (foreign_pkgnames.length > 0) { + var loop = new MainLoop (); + get_aur_pkgs.begin (foreign_pkgnames, (obj, res) => { + var aur_pkgs = get_aur_pkgs.end (res); + var iter = HashTableIter<string, AURPackage> (aur_pkgs); + unowned string pkgname; + unowned AURPackage aur_pkg; + while (iter.next (out pkgname, out aur_pkg)) { + if (aur_pkg.name != "") { + unowned Package pkg = data.lookup (pkgname); + if (pkg != null) { + pkg.repo = dgettext (null, "AUR"); + } + } + } + loop.quit (); + }); + loop.run (); + var iter = HashTableIter<string, Package> (data); + unowned Package pkg; + while (iter.next (null, out pkg)) { + pkgs.append (pkg); } } return pkgs; } public List<Package> get_installed_pkgs () { - var pkgs = new List<Package> (); - unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package alpm_pkg = pkgcache.data; - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } - pkgcache.next (); - } + var pkgs = initialise_pkgs (alpm_handle.localdb.pkgcache); + pkgs.sort (pkg_compare_name); return pkgs; } public List<Package> get_installed_apps () { var result = new List<Package> (); app_store.get_apps ().foreach ((app) => { - unowned string pkgname = app.get_pkgname_default (); - unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (local_pkg != null) { - unowned Alpm.Package? sync_pkg = get_syncpkg (pkgname); - if (sync_pkg != null) { - result.append (new Package.from_struct (PackageStruct () { - name = sync_pkg.name, - app_name = get_app_name (app), - version = sync_pkg.version, - installed_version = local_pkg.version, - desc = get_app_summary (app), - repo = sync_pkg.db.name, - size = sync_pkg.isize, - download_size = sync_pkg.download_size, - icon = get_app_icon (app, sync_pkg.db.name) - })); + if (app.get_kind () == As.AppKind.DESKTOP) { + unowned string pkgname = app.get_pkgname_default (); + unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (local_pkg != null) { + unowned Alpm.Package? sync_pkg = get_syncpkg (pkgname); + if (sync_pkg != null) { + result.append (new Package.from_struct (PackageStruct () { + name = sync_pkg.name, + app_name = get_app_name (app), + version = sync_pkg.version, + installed_version = local_pkg.version, + desc = get_app_summary (app), + repo = sync_pkg.db.name, + size = sync_pkg.isize, + download_size = sync_pkg.download_size, + icon = get_app_icon (app, sync_pkg.db.name) + })); + } } } }); @@ -559,22 +590,22 @@ namespace Pamac { } public List<Package> get_explicitly_installed_pkgs () { - var pkgs = new List<Package> (); + Alpm.List<unowned Alpm.Package> alpm_pkgs = null; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { unowned Alpm.Package alpm_pkg = pkgcache.data; if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } + alpm_pkgs.add (alpm_pkg); } pkgcache.next (); } + var pkgs = initialise_pkgs (alpm_pkgs); + pkgs.sort (pkg_compare_name); return pkgs; } public List<Package> get_foreign_pkgs () { - var pkgs = new List<Package> (); + Alpm.List<unowned Alpm.Package> alpm_pkgs = null; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { unowned Alpm.Package alpm_pkg = pkgcache.data; @@ -590,17 +621,17 @@ namespace Pamac { syncdbs.next (); } if (sync_found == false) { - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } + alpm_pkgs.add (alpm_pkg); } pkgcache.next (); } + var pkgs = initialise_pkgs (alpm_pkgs); + pkgs.sort (pkg_compare_name); return pkgs; } public List<Package> get_orphans () { - var pkgs = new List<Package> (); + Alpm.List<unowned Alpm.Package> alpm_pkgs = null; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { unowned Alpm.Package alpm_pkg = pkgcache.data; @@ -609,9 +640,7 @@ namespace Pamac { if (requiredby.length == 0) { Alpm.List<string> optionalfor = alpm_pkg.compute_optionalfor (); if (optionalfor.length == 0) { - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } + alpm_pkgs.add (alpm_pkg); } else { optionalfor.free_inner (GLib.free); } @@ -621,6 +650,8 @@ namespace Pamac { } pkgcache.next (); } + var pkgs = initialise_pkgs (alpm_pkgs); + pkgs.sort (pkg_compare_name); return pkgs; } @@ -731,22 +762,21 @@ namespace Pamac { if (search_terms != null) { Alpm.List<unowned Alpm.Package> appstream_result = null; app_store.get_apps ().foreach ((app) => { - uint match_score = app.search_matches_all (search_terms); - if (match_score > 0) { - unowned string pkgname = app.get_pkgname_default (); - unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (alpm_pkg != null) { - if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { - appstream_result.add (alpm_pkg); + if (app.get_kind () == As.AppKind.DESKTOP) { + uint match_score = app.search_matches_all (search_terms); + if (match_score > 0) { + unowned string pkgname = app.get_pkgname_default (); + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg != null) { + if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { + appstream_result.add (alpm_pkg); + } } } } }); result.join (appstream_result.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); } - // use custom sort function - global_search_string = search_string; - result.sort (result.length, (Alpm.List.CompareFunc) alpm_pkg_sort_search_by_relevance); return result; } @@ -775,15 +805,17 @@ namespace Pamac { if (search_terms != null) { Alpm.List<unowned Alpm.Package> appstream_result = null; app_store.get_apps ().foreach ((app) => { - uint match_score = app.search_matches_all (search_terms); - if (match_score > 0) { - unowned string pkgname = app.get_pkgname_default (); - unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (alpm_pkg == null) { - alpm_pkg = get_syncpkg (pkgname); - if (alpm_pkg != null) { - if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { - appstream_result.add (alpm_pkg); + if (app.get_kind () == As.AppKind.DESKTOP) { + uint match_score = app.search_matches_all (search_terms); + if (match_score > 0) { + unowned string pkgname = app.get_pkgname_default (); + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg == null) { + alpm_pkg = get_syncpkg (pkgname); + if (alpm_pkg != null) { + if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { + appstream_result.add (alpm_pkg); + } } } } @@ -791,23 +823,14 @@ namespace Pamac { }); result.join (appstream_result.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); } - // use custom sort function - global_search_string = search_string; - result.sort (result.length, (Alpm.List.CompareFunc) alpm_pkg_sort_search_by_relevance); return result; } public List<Package> search_installed_pkgs (string search_string) { - var pkgs = new List<Package> (); - Alpm.List<unowned Alpm.Package> alpm_pkgs = search_local_db (search_string); - unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; - while (list != null) { - unowned Alpm.Package alpm_pkg = list.data; - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } - list.next (); - } + var pkgs = initialise_pkgs (search_local_db (search_string)); + // use custom sort function + global_search_string = search_string; + pkgs.sort (pkg_sort_search_by_relevance); return pkgs; } @@ -823,16 +846,10 @@ namespace Pamac { } public List<Package> search_repos_pkgs (string search_string) { - var pkgs = new List<Package> (); - Alpm.List<unowned Alpm.Package> alpm_pkgs = search_sync_dbs (search_string); - unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; - while (list != null) { - unowned Alpm.Package alpm_pkg = list.data; - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } - list.next (); - } + var pkgs = initialise_pkgs (search_sync_dbs (search_string)); + // use custom sort function + global_search_string = search_string; + pkgs.sort (pkg_sort_search_by_relevance); return pkgs; } @@ -871,39 +888,32 @@ namespace Pamac { if (search_terms != null) { Alpm.List<unowned Alpm.Package> appstream_result = null; app_store.get_apps ().foreach ((app) => { - uint match_score = app.search_matches_all (search_terms); - if (match_score > 0) { - unowned string pkgname = app.get_pkgname_default (); - unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (alpm_pkg == null) { - alpm_pkg = get_syncpkg (pkgname); - } - if (alpm_pkg != null) { - if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { - appstream_result.add (alpm_pkg); + if (app.get_kind () == As.AppKind.DESKTOP) { + uint match_score = app.search_matches_all (search_terms); + if (match_score > 0) { + unowned string pkgname = app.get_pkgname_default (); + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg == null) { + alpm_pkg = get_syncpkg (pkgname); + } + if (alpm_pkg != null) { + if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { + appstream_result.add (alpm_pkg); + } } } } }); result.join (appstream_result.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); } - // use custom sort function - global_search_string = search_string; - result.sort (result.length, (Alpm.List.CompareFunc) alpm_pkg_sort_search_by_relevance); return result; } public List<Package> search_pkgs (string search_string) { - var pkgs = new List<Package> (); - Alpm.List<unowned Alpm.Package> alpm_pkgs = search_all_dbs (search_string); - unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; - while (list != null) { - unowned Alpm.Package alpm_pkg = list.data; - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } - list.next (); - } + var pkgs = initialise_pkgs (search_all_dbs (search_string)); + // use custom sort function + global_search_string = search_string; + pkgs.sort (pkg_sort_search_by_relevance); return pkgs; } @@ -1088,7 +1098,7 @@ namespace Pamac { } public List<Package> get_repo_pkgs (string repo) { - var pkgs = new List<Package> (); + Alpm.List<unowned Alpm.Package> alpm_pkgs = null; unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; while (syncdbs != null) { unowned Alpm.DB db = syncdbs.data; @@ -1098,13 +1108,9 @@ namespace Pamac { unowned Alpm.Package sync_pkg = pkgcache.data; unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (sync_pkg.name); if (local_pkg != null) { - foreach (unowned Package pkg in initialise_pkgs (local_pkg)) { - pkgs.append (pkg); - } + alpm_pkgs.add (local_pkg); } else { - foreach (unowned Package pkg in initialise_pkgs (sync_pkg)) { - pkgs.append (pkg); - } + alpm_pkgs.add (sync_pkg); } pkgcache.next (); } @@ -1112,6 +1118,8 @@ namespace Pamac { } syncdbs.next (); } + var pkgs = initialise_pkgs (alpm_pkgs); + pkgs.sort (pkg_compare_name); return pkgs; } @@ -1183,16 +1191,8 @@ namespace Pamac { } public List<Package> get_group_pkgs (string group_name) { - var pkgs = new List<Package> (); - Alpm.List<unowned Alpm.Package> alpm_pkgs = group_pkgs (group_name); - unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; - while (list != null) { - unowned Alpm.Package alpm_pkg = list.data; - foreach (unowned Package pkg in initialise_pkgs (alpm_pkg)) { - pkgs.append (pkg); - } - list.next (); - } + var pkgs = initialise_pkgs (group_pkgs (group_name)); + pkgs.sort (pkg_compare_name); return pkgs; } @@ -1274,7 +1274,8 @@ namespace Pamac { if (appname != "") { bool found = false; app_store.get_apps ().foreach ((app) => { - if (!found && get_app_name (app) == appname) { + if (!found && app.get_kind () == As.AppKind.DESKTOP + && get_app_name (app) == appname) { found = true; if (app.get_pkgname_default () == alpm_pkg.name) { app_name = appname; @@ -2088,9 +2089,13 @@ private int alpm_pkg_compare_name (Alpm.Package pkg_a, Alpm.Package pkg_b) { return strcmp (pkg_a.name, pkg_b.name); } +private int pkg_compare_name (Pamac.Package pkg_a, Pamac.Package pkg_b) { + return strcmp (pkg_a.name, pkg_b.name); +} + private string global_search_string; -private int alpm_pkg_sort_search_by_relevance (Alpm.Package pkg_a, Alpm.Package pkg_b) { +private int pkg_sort_search_by_relevance (Pamac.Package pkg_a, Pamac.Package pkg_b) { if (global_search_string != null) { // display exact match first if (pkg_a.name == global_search_string) { diff --git a/src/manager.vala b/src/manager.vala index 28c5298e..514db903 100644 --- a/src/manager.vala +++ b/src/manager.vala @@ -82,7 +82,7 @@ namespace Pamac { } manager_window.display_package_queue.clear (); manager_window.main_stack.visible_child_name = "browse"; - manager_window.filters_stack.visible_child_name = "updates"; + manager_window.browse_stack.visible_child_name = "updates"; manager_window.present (); }); this.add_action (action); diff --git a/src/manager_window.vala b/src/manager_window.vala index e0e47143..2093dcad 100644 --- a/src/manager_window.vala +++ b/src/manager_window.vala @@ -19,33 +19,165 @@ namespace Pamac { - class ActivableCellRendererPixbuf : Gtk.CellRendererPixbuf { - public signal void activated (Gtk.TreePath path); + string search_string; + List<string> repos_names; + GenericSet<string?> to_install; + GenericSet<string?> to_remove; + GenericSet<string?> to_load; + GenericSet<string?> to_build; + GenericSet<string?> to_update; + GenericSet<string?> temporary_ignorepkgs; + + int sort_pkgs_by_relevance (Package pkg_a, Package pkg_b) { + if (pkg_a.name in to_remove) { + if (pkg_b.name in to_remove) { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return -1; + } + } + if (pkg_b.name in to_remove) { + if (pkg_a.name in to_remove) { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return 1; + } + } + if (pkg_a.name in to_install) { + if (pkg_b.name in to_install) { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return -1; + } + } + if (pkg_b.name in to_install) { + if (pkg_a.name in to_install) { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return 1; + } + } + if (pkg_a.name in temporary_ignorepkgs) { + if (pkg_b.name in temporary_ignorepkgs) { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return -1; + } + } + if (pkg_b.name in temporary_ignorepkgs) { + if (pkg_a.name in temporary_ignorepkgs) { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return 1; + } + } + if (pkg_a.installed_version == "") { + if (pkg_b.installed_version == "") { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return 1; + } + } + if (pkg_b.installed_version == "") { + if (pkg_a.installed_version == "") { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return -1; + } + } + if (pkg_a.app_name == "") { + if (pkg_b.app_name == "") { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return 1; + } + } + if (pkg_b.app_name == "") { + if (pkg_a.app_name == "") { + return sort_pkgs_by_name (pkg_a, pkg_b); + } else { + return -1; + } + } + return sort_pkgs_by_name (pkg_a, pkg_b); + } + + int sort_pkgs_by_name (Package pkg_a, Package pkg_b) { + string str_a = "%s%s".printf (pkg_a.app_name, pkg_a.name); + string str_b = "%s%s".printf (pkg_b.app_name, pkg_b.name); + return strcmp (str_a, str_b); + } + + int sort_pkgs_by_repo (Package pkg_a, Package pkg_b) { + int index_a = -2; + if (pkg_a.repo == dgettext (null, "AUR")) { + index_a = -1; + } else if (pkg_a.repo != "") { + unowned List<string>? element = repos_names.find_custom (pkg_a.repo, strcmp); + if (element != null) { + index_a = repos_names.index (element.data); + } + } + int index_b = -2; + if (pkg_b.repo == dgettext (null, "AUR")) { + index_b = -1; + } else if (pkg_b.repo != "") { + unowned List<string>? element = repos_names.find_custom (pkg_b.repo, strcmp); + if (element != null) { + index_b = repos_names.index (element.data); + } + } + if (index_a > index_b) { + return 1; + } + if (index_b > index_a) { + return -1; + } + return sort_pkgs_by_name (pkg_a, pkg_b); + } - public ActivableCellRendererPixbuf () { - Object (); - this.mode = Gtk.CellRendererMode.ACTIVATABLE; + int sort_pkgs_by_size (Package pkg_a, Package pkg_b) { + if (pkg_a.size > pkg_b.size) { + return -1; + } + if (pkg_b.size > pkg_a.size) { + return 1; } + return sort_pkgs_by_name (pkg_a, pkg_b); + } - public override bool activate (Gdk.Event event, Gtk.Widget widget, string path, Gdk.Rectangle background_area, - Gdk.Rectangle cell_area, Gtk.CellRendererState flags) { - activated (new Gtk.TreePath.from_string (path)); - return true; + int sort_aur_by_relevance (AURPackage pkg_a, AURPackage pkg_b) { + if (pkg_a.name in to_build) { + if (pkg_b.name in to_build) { + return sort_aur_by_name (pkg_a, pkg_b); + } else { + return -1; + } + } + if (pkg_b.name in to_build) { + if (pkg_a.name in to_build) { + return sort_aur_by_name (pkg_a, pkg_b); + } else { + return 1; + } + } + if (pkg_a.popularity > pkg_b.popularity) { + return -1; + } + if (pkg_b.popularity > pkg_a.popularity) { + return 1; } + return sort_aur_by_name (pkg_a, pkg_b); + } + + int sort_aur_by_name (AURPackage pkg_a, AURPackage pkg_b) { + return strcmp (pkg_a.name, pkg_b.name); } [GtkTemplate (ui = "/org/manjaro/pamac/manager/manager_window.ui")] class ManagerWindow : Gtk.ApplicationWindow { // icons Gtk.IconTheme icon_theme; - Gdk.Pixbuf? installed_icon; - Gdk.Pixbuf? uninstalled_icon; - Gdk.Pixbuf? to_install_icon; - Gdk.Pixbuf? to_reinstall_icon; - Gdk.Pixbuf? to_remove_icon; - Gdk.Pixbuf? to_upgrade_icon; - Gdk.Pixbuf? installed_locked_icon; - Gdk.Pixbuf? available_locked_icon; Gdk.Pixbuf? package_icon; // manager objects @@ -54,25 +186,23 @@ namespace Pamac { [GtkChild] public Gtk.Stack main_stack; [GtkChild] - Gtk.Button button_back; + Gtk.StackSwitcher main_stack_switcher; [GtkChild] - Gtk.Button select_all_button; + Gtk.Button button_back; [GtkChild] Gtk.Label header_filter_label; [GtkChild] Gtk.ModelButton preferences_button; [GtkChild] - Gtk.TreeView packages_treeview; + Gtk.ListBox packages_listbox; [GtkChild] - Gtk.TreeViewColumn packages_state_column; - [GtkChild] - Gtk.TreeView aur_treeview; - [GtkChild] - Gtk.TreeViewColumn aur_state_column; + Gtk.ListBox aur_listbox; [GtkChild] Gtk.Revealer sidebar_revealer; [GtkChild] - public Gtk.Stack filters_stack; + Gtk.Stack filters_stack; + [GtkChild] + public Gtk.Stack browse_stack; [GtkChild] public Gtk.ToggleButton search_button; [GtkChild] @@ -80,7 +210,7 @@ namespace Pamac { [GtkChild] public Gtk.ComboBoxText search_comboboxtext; [GtkChild] - Gtk.Entry search_entry; + public Gtk.Entry search_entry; [GtkChild] Gtk.ListBox filters_listbox; [GtkChild] @@ -100,6 +230,14 @@ namespace Pamac { [GtkChild] Gtk.ListBox search_listbox; [GtkChild] + Gtk.Button remove_all_button; + [GtkChild] + Gtk.Button install_all_button; + [GtkChild] + Gtk.Box sort_order_box; + [GtkChild] + Gtk.ComboBoxText sort_comboboxtext; + [GtkChild] Gtk.ScrolledWindow packages_scrolledwindow; [GtkChild] Gtk.ScrolledWindow aur_scrolledwindow; @@ -154,35 +292,13 @@ namespace Pamac { [GtkChild] Gtk.Button cancel_button; - // menu - Gtk.Menu right_click_menu; - Gtk.MenuItem deselect_item; - Gtk.MenuItem upgrade_item; - Gtk.MenuItem install_item; - Gtk.MenuItem build_item; - Gtk.MenuItem remove_item; - Gtk.MenuItem details_item; - GLib.List<string> selected_pkgs; - GLib.List<string> selected_aur; - - // liststores - Gtk.ListStore packages_list; - Gtk.ListStore aur_list; - int sort_column_id; - Gtk.SortType sort_order; - bool restore_sort_order; - public Queue<string> display_package_queue; string current_package_displayed; - public GenericSet<string?> to_install; - public GenericSet<string?> to_remove; - public GenericSet<string?> to_load; - public GenericSet<string?> to_build; - public GenericSet<string?> to_update; - public GenericSet<string?> temporary_ignorepkgs; - public GenericSet<string?> previous_to_install; - public GenericSet<string?> previous_to_remove; - public GenericSet<string?> previous_to_build; + string current_files; + string current_build_files; + GenericSet<string?> previous_to_install; + GenericSet<string?> previous_to_remove; + GenericSet<string?> previous_to_build; public TransactionGtk transaction; public Database database { get; construct; } @@ -197,11 +313,12 @@ namespace Pamac { List<Package> repos_updates; List<AURPackage> aur_updates; + List<Package> current_packages_list; + unowned List<Package> current_packages_list_pos; + List<AURPackage> current_aur_list; + unowned List<AURPackage> current_aur_list_pos; uint search_entry_timeout_id; - string search_string; - Gtk.Label pending_label; - Gtk.ListBoxRow pending_row; Gtk.ListBoxRow files_row; Gtk.ListBoxRow build_files_row; bool scroll_to_top; @@ -218,7 +335,8 @@ namespace Pamac { } button_back.visible = false; - select_all_button.visible = false; + remove_all_button.visible = false; + install_all_button.visible = false; details_button.sensitive = false; scroll_to_top = true; searchbar.connect_entry (search_entry); @@ -230,130 +348,34 @@ namespace Pamac { updated_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "Your system is up-to-date"))); no_item_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "No package found"))); checking_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "Checking for Updates"))); - right_click_menu = new Gtk.Menu (); - deselect_item = new Gtk.MenuItem.with_label (dgettext (null, "Deselect")); - deselect_item.activate.connect (on_deselect_item_activate); - right_click_menu.append (deselect_item); - upgrade_item = new Gtk.MenuItem.with_label (dgettext (null, "Upgrade")); - upgrade_item.activate.connect (on_upgrade_item_activate); - right_click_menu.append (upgrade_item); - install_item = new Gtk.MenuItem.with_label (dgettext (null, "Install")); - install_item.activate.connect (on_install_item_activate); - right_click_menu.append (install_item); - build_item = new Gtk.MenuItem.with_label (dgettext (null, "Build")); - build_item.activate.connect (on_build_item_activate); - right_click_menu.append (build_item); - remove_item = new Gtk.MenuItem.with_label (dgettext (null, "Remove")); - remove_item.activate.connect (on_remove_item_activate); - right_click_menu.append (remove_item); - var separator_item = new Gtk.SeparatorMenuItem (); - right_click_menu.append (separator_item); - details_item = new Gtk.MenuItem.with_label (dgettext (null, "Details")); - details_item.activate.connect (on_details_item_activate); - right_click_menu.append (details_item); - - packages_list = new Gtk.ListStore (9, - typeof (uint), //origin - typeof (string), //pkgname - typeof (string), //name+desc - typeof (string), //version - typeof (string), //repo - typeof (uint64), //isize - typeof (string), //GLib.format (isize) - typeof (string), //app_name - typeof (Gdk.Pixbuf)); //icon - // sort packages by app_name by default - packages_list.set_sort_column_id (2, Gtk.SortType.ASCENDING); - restore_sort_order = false; - packages_treeview.set_model (packages_list); - // add custom cellrenderer to packages_treeview and aur_treewiew - var packages_state_renderer = new ActivableCellRendererPixbuf (); - packages_state_column.pack_start (packages_state_renderer, false); - packages_state_column.set_cell_data_func (packages_state_renderer, (celllayout, cellrenderer, treemodel, treeiter) => { - Gdk.Pixbuf pixbuf; - uint origin; - string pkgname; - treemodel.get (treeiter, 0, out origin, 1, out pkgname); - if (filters_stack.visible_child_name == "updates") { - if (unlikely (temporary_ignorepkgs.contains (pkgname))) { - pixbuf = uninstalled_icon; - } else if (unlikely (transaction.transaction_summary.contains (pkgname))) { - pixbuf = installed_locked_icon; - } else { - pixbuf = to_upgrade_icon; - } - } else if (origin == 0) { // installed - if (unlikely (transaction.transaction_summary.contains (pkgname))) { - pixbuf = installed_locked_icon; - } else if (unlikely (database.should_hold (pkgname))) { - pixbuf = installed_locked_icon; - } else if (unlikely (to_install.contains (pkgname))) { - pixbuf = to_reinstall_icon; - } else if (unlikely (to_remove.contains (pkgname))) { - pixbuf = to_remove_icon; - } else { - pixbuf = installed_icon; - } - } else if (unlikely (transaction.transaction_summary.contains (pkgname))) { - pixbuf = available_locked_icon; - } else if (unlikely (to_install.contains (pkgname))) { - pixbuf = to_install_icon; - } else { - pixbuf = uninstalled_icon; + + // auto complete list + packages_scrolledwindow.vadjustment.value_changed.connect (() => { + double max_value = (packages_scrolledwindow.vadjustment.upper - packages_scrolledwindow.vadjustment.page_size) * 0.8; + if (packages_scrolledwindow.vadjustment.value >= max_value) { + complete_packages_list (); } - cellrenderer.set ("pixbuf", pixbuf); }); - packages_state_renderer.activated.connect (on_packages_state_icon_activated); - - aur_list = new Gtk.ListStore (7, - typeof (uint), //origin - typeof (string), //name - typeof (string), //name+desc - typeof (string), //version - typeof (double), //popularity - typeof (string), //populariy to string - typeof (Gdk.Pixbuf)); //icon - // sort packages by popularity by default - aur_list.set_sort_column_id (4, Gtk.SortType.DESCENDING); - aur_treeview.set_model (aur_list); - // add custom cellrenderer to aur_treewiew - var aur_state_renderer = new ActivableCellRendererPixbuf (); - aur_state_column.pack_start (aur_state_renderer, false); - aur_state_column.set_cell_data_func (aur_state_renderer, (celllayout, cellrenderer, treemodel, treeiter) => { - Gdk.Pixbuf pixbuf; - uint origin; - string pkgname; - treemodel.get (treeiter, 0, out origin, 1, out pkgname); - if (filters_stack.visible_child_name == "updates") { - if (unlikely (temporary_ignorepkgs.contains (pkgname))) { - pixbuf = uninstalled_icon; - } else if (unlikely (transaction.transaction_summary.contains (pkgname))) { - pixbuf = installed_locked_icon; - } else { - pixbuf = to_upgrade_icon; - } - } else if ((uint) origin == 0) { // installed - if (unlikely (transaction.transaction_summary.contains (pkgname))) { - pixbuf = installed_locked_icon; - } else if (unlikely (database.should_hold (pkgname))) { - pixbuf = installed_locked_icon; - } else if (unlikely (to_install.contains (pkgname))) { - pixbuf = to_reinstall_icon; - } else if (unlikely (to_remove.contains (pkgname))) { - pixbuf = to_remove_icon; - } else { - pixbuf = installed_icon; - } - } else if (unlikely (transaction.transaction_summary.contains (pkgname))) { - pixbuf = available_locked_icon; - } else if (unlikely (to_build.contains (pkgname))) { - pixbuf = to_install_icon; - } else { - pixbuf = uninstalled_icon; + packages_scrolledwindow.vadjustment.changed.connect (() => { + while (need_more_packages ()) { + complete_packages_list (); + } + }); + aur_scrolledwindow.vadjustment.value_changed.connect (() => { + double max_value = (aur_scrolledwindow.vadjustment.upper - aur_scrolledwindow.vadjustment.page_size) * 0.8; + if (aur_scrolledwindow.vadjustment.value >= max_value) { + complete_aur_list (); } - cellrenderer.set ("pixbuf", pixbuf); }); - aur_state_renderer.activated.connect (on_aur_state_icon_activated); + aur_scrolledwindow.vadjustment.changed.connect (() => { + while (need_more_aur ()) { + complete_aur_list (); + } + }); + + // packages listbox functions + packages_listbox.set_header_func (set_header_func); + aur_listbox.set_header_func (set_header_func); // icons icon_theme = Gtk.IconTheme.get_default (); @@ -383,6 +405,33 @@ namespace Pamac { transaction.set_pkgreason_finished.connect (on_set_pkgreason_finished); transaction.start_generating_mirrors_list.connect (on_start_generating_mirrors_list); transaction.generate_mirrors_list_finished.connect (on_generate_mirrors_list_finished); + transaction.transaction_sum_populated.connect (() => { + // make buttons of pkgs in transaction unsensitive + packages_listbox.foreach ((row) => { + unowned PackageRow pamac_row = row as PackageRow; + if (pamac_row == null) { + return; + } + if (transaction.transaction_summary.contains (pamac_row.pkg.name)) { + pamac_row.action_togglebutton.active = false; + pamac_row.action_togglebutton.sensitive = false; + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + } + }); + aur_listbox.foreach ((row) => { + unowned AURRow pamac_row = row as AURRow; + if (pamac_row == null) { + return; + } + if (transaction.transaction_summary.contains (pamac_row.aur_pkg.name)) { + pamac_row.action_togglebutton.active = false; + pamac_row.action_togglebutton.sensitive = false; + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + } + }); + }); // integrate progress box and term widget main_stack.add_named (transaction.details_window, "term"); @@ -402,13 +451,16 @@ namespace Pamac { temporary_ignorepkgs = new GenericSet<string?> (str_hash, str_equal); main_stack.notify["visible-child"].connect (on_main_stack_visible_child_changed); + browse_stack.notify["visible-child"].connect (on_browse_stack_visible_child_changed); filters_stack.notify["visible-child"].connect (on_filters_stack_visible_child_changed); - properties_stack.notify["visible-child"].connect (on_properties_stack_visible_child_changed); + origin_stack.notify["visible-child"].connect (on_origin_stack_visible_child_changed); searchbar.notify["search-mode-enabled"].connect (on_search_mode_enabled); // enable "type to search" this.key_press_event.connect ((event) => { - if (main_stack.visible_child_name == "browse") { + if (main_stack.visible_child_name == "browse" + && (browse_stack.visible_child_name == "browse" + || browse_stack.visible_child_name == "installed")) { return searchbar.handle_event (event); } return false; @@ -427,17 +479,13 @@ namespace Pamac { } } + void set_header_func (Gtk.ListBoxRow row, Gtk.ListBoxRow? row_before) { + row.set_header (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); + } + void update_icons () { icon_theme = Gtk.IconTheme.get_default (); try { - installed_icon = icon_theme.load_icon ("package-installed-updated", 16, 0); - uninstalled_icon = icon_theme.load_icon ("package-available", 16, 0); - to_install_icon = icon_theme.load_icon ("package-install", 16, 0); - to_reinstall_icon = icon_theme.load_icon ("package-reinstall", 16, 0); - to_remove_icon = icon_theme.load_icon ("package-remove", 16, 0); - to_upgrade_icon = icon_theme.load_icon ("package-upgrade", 16, 0); - installed_locked_icon = icon_theme.load_icon ("package-installed-locked", 16, 0); - available_locked_icon = icon_theme.load_icon ("package-available-locked", 16, 0); package_icon = icon_theme.load_icon ("package-x-generic", 64, 0); } catch (GLib.Error e) { stderr.printf ("%s\n", e.message); @@ -470,7 +518,7 @@ namespace Pamac { display_aur_properties (current_package_displayed); } } - } + } void support_aur (bool enable_aur) { unowned Gtk.ListBoxRow aur_row = search_listbox.get_row_at_index (2); @@ -490,7 +538,6 @@ namespace Pamac { repos_row.selectable = true; repos_row.can_focus = true; repos_row.get_child ().sensitive = true; - origin_stack.visible_child_name = "repos"; } } @@ -536,18 +583,17 @@ namespace Pamac { } void set_pendings_operations () { - refresh_state_icons (); if (!transaction_running && !generate_mirrors_list && !sysupgrade_running) { - if (filters_stack.visible_child_name == "updates") { + if (browse_stack.visible_child_name == "updates") { uint64 total_dsize = 0; - packages_list.foreach ((model, path, iter) => { - string name; - uint64 dsize; - packages_list.get (iter, 1, out name, 5, out dsize); - if (to_update.contains (name)) { - total_dsize += dsize; + packages_listbox.foreach ((row) => { + unowned PackageRow pamac_row = row as PackageRow; + if (pamac_row == null) { + return; + } + if (to_update.contains (pamac_row.pkg.name)) { + total_dsize += pamac_row.pkg.download_size; } - return false; }); if (total_dsize > 0) { transaction.progress_box.action_label.set_markup("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size (total_dsize))); @@ -565,8 +611,8 @@ namespace Pamac { } else { uint total_pending = to_install.length + to_remove.length + to_build.length; if (total_pending == 0) { - if (filters_stack.visible_child_name != "pending") { - active_pending_row (false); + if (browse_stack.visible_child_name != "pending") { + active_pending_stack (false); } transaction.progress_box.action_label.label = ""; cancel_button.sensitive = false; @@ -575,7 +621,7 @@ namespace Pamac { show_transaction_infobox (); } } else { - active_pending_row (true); + active_pending_stack (true); string info = dngettext (null, "%u pending operation", "%u pending operations", total_pending).printf (total_pending); transaction.progress_box.action_label.label = info; cancel_button.sensitive = true; @@ -588,7 +634,6 @@ namespace Pamac { void show_default_pkgs () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; current_filter = "installed_apps"; database.get_installed_apps_async.begin ((obj, res) => { if (current_filter != "installed_apps") { @@ -598,131 +643,98 @@ namespace Pamac { }); } - Gtk.Label create_list_label (string str) { + Gtk.ListBoxRow create_list_row (string str) { var label = new Gtk.Label (str); label.visible = true; label.margin = 12; label.xalign = 0; - return label; + var row = new Gtk.ListBoxRow (); + row.visible = true; + row.add (label); + return row; } int sort_list_row (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) { - var label1 = row1.get_child () as Gtk.Label; - var label2 = row2.get_child () as Gtk.Label; + unowned Gtk.Label label1 = row1.get_child () as Gtk.Label; + unowned Gtk.Label label2 = row2.get_child () as Gtk.Label; return strcmp (label1.label, label2.label); } - void active_pending_row (bool active) { - pending_row.activatable = active; - pending_label.sensitive = active; + void active_pending_stack (bool active) { + pending_listbox.visible = active; } void create_all_listbox () { - Gtk.Label label; - label = create_list_label (dgettext (null, "Categories")); - filters_listbox.add (label); - label = create_list_label (dgettext (null, "Groups")); - filters_listbox.add (label); - label = create_list_label (dgettext (null, "Repositories")); - filters_listbox.add (label); - label = create_list_label (dgettext (null, "Installed")); - filters_listbox.add (label); - label = create_list_label (dgettext (null, "Updates")); - filters_listbox.add (label); - pending_label = create_list_label (dgettext (null, "Pending")); - pending_row = new Gtk.ListBoxRow (); - pending_row.visible = true; - pending_row.add (pending_label); - filters_listbox.add (pending_row); - active_pending_row (false); - filters_listbox.select_row (filters_listbox.get_row_at_index (0)); - - foreach (unowned string repo in database.get_repos_names ()) { - label = create_list_label (repo); - repos_listbox.add (label); + filters_listbox.add (create_list_row (dgettext (null, "Categories"))); + filters_listbox.add (create_list_row (dgettext (null, "Groups"))); + filters_listbox.add (create_list_row (dgettext (null, "Repositories"))); + + repos_names = database.get_repos_names (); + foreach (unowned string repo in repos_names) { + repos_listbox.add (create_list_row (repo)); } repos_listbox.select_row (repos_listbox.get_row_at_index (0)); foreach (unowned string group in database.get_groups_names ()) { - label = create_list_label (group); - groups_listbox.add (label); + groups_listbox.add (create_list_row (group)); } groups_listbox.set_sort_func (sort_list_row); groups_listbox.select_row (groups_listbox.get_row_at_index (0)); - label = create_list_label (dgettext (null, "Installed")); - installed_listbox.add (label); - label = create_list_label (dgettext (null, "Explicitly installed")); - installed_listbox.add (label); - label = create_list_label (dgettext (null, "Orphans")); - installed_listbox.add (label); - label = create_list_label (dgettext (null, "Foreign")); - installed_listbox.add (label); + installed_listbox.add (create_list_row (dgettext (null, "Installed"))); + installed_listbox.add (create_list_row (dgettext (null, "Explicitly installed"))); + installed_listbox.add (create_list_row (dgettext (null, "Orphans"))); + installed_listbox.add (create_list_row (dgettext (null, "Foreign"))); installed_listbox.select_row (installed_listbox.get_row_at_index (0)); - label = create_list_label (dgettext (null, "Accessories")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Audio & Video")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Development")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Education")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Games")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Graphics")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Internet")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Office")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Science")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "Settings")); - categories_listbox.add (label); - label = create_list_label (dgettext (null, "System Tools")); - categories_listbox.add (label); + categories_listbox.add (create_list_row (dgettext (null, "Accessories"))); + categories_listbox.add (create_list_row (dgettext (null, "Audio & Video"))); + categories_listbox.add (create_list_row (dgettext (null, "Development"))); + categories_listbox.add (create_list_row (dgettext (null, "Education"))); + categories_listbox.add (create_list_row (dgettext (null, "Games"))); + categories_listbox.add (create_list_row (dgettext (null, "Graphics"))); + categories_listbox.add (create_list_row (dgettext (null, "Internet"))); + categories_listbox.add (create_list_row (dgettext (null, "Office"))); + categories_listbox.add (create_list_row (dgettext (null, "Science"))); + categories_listbox.add (create_list_row (dgettext (null, "Settings"))); + categories_listbox.add (create_list_row (dgettext (null, "System Tools"))); categories_listbox.set_sort_func (sort_list_row); categories_listbox.select_row (categories_listbox.get_row_at_index (0)); - label = create_list_label (dgettext (null, "Repositories")); - updates_listbox.add (label); - label = create_list_label (dgettext (null, "AUR")); - updates_listbox.add (label); + updates_listbox.add (create_list_row (dgettext (null, "Repositories"))); + updates_listbox.add (create_list_row (dgettext (null, "AUR"))); updates_listbox.select_row (updates_listbox.get_row_at_index (0)); - label = create_list_label (dgettext (null, "Repositories")); - pending_listbox.add (label); - label = create_list_label (dgettext (null, "AUR")); - pending_listbox.add (label); + + pending_listbox.add (create_list_row (dgettext (null, "Repositories"))); + pending_listbox.add (create_list_row (dgettext (null, "AUR"))); pending_listbox.select_row (pending_listbox.get_row_at_index (0)); - label = create_list_label (dgettext (null, "Installed")); - search_listbox.add (label); - label = create_list_label (dgettext (null, "Repositories")); - search_listbox.add (label); - label = create_list_label (dgettext (null, "AUR")); - search_listbox.add (label); + active_pending_stack (false); + + search_listbox.add (create_list_row (dgettext (null, "Installed"))); + search_listbox.add (create_list_row (dgettext (null, "Repositories"))); + search_listbox.add (create_list_row (dgettext (null, "AUR"))); search_listbox.select_row (search_listbox.get_row_at_index (0)); if (database.config.enable_aur == false) { search_listbox.get_row_at_index (2).visible = false; } - label = create_list_label (dgettext (null, "Details")); - properties_listbox.add (label); - label = create_list_label (dgettext (null, "Dependencies")); - properties_listbox.add (label); - label = create_list_label (dgettext (null, "Files")); - files_row = new Gtk.ListBoxRow (); - files_row.visible = true; - files_row.add (label); + properties_listbox.add (create_list_row (dgettext (null, "Details"))); + properties_listbox.add (create_list_row (dgettext (null, "Dependencies"))); + files_row = create_list_row (dgettext (null, "Files")); properties_listbox.add (files_row); - label = create_list_label (dgettext (null, "Build files")); - build_files_row = new Gtk.ListBoxRow (); - build_files_row.visible = false; - build_files_row.add (label); + build_files_row = create_list_row (dgettext (null, "Build files")); properties_listbox.add (build_files_row); properties_listbox.select_row (properties_listbox.get_row_at_index (0)); } + void clear_packages_listbox () { + packages_listbox.foreach (transaction.destroy_widget); + } + + void clear_aur_listbox () { + aur_listbox.foreach (transaction.destroy_widget); + } + void clear_lists () { to_install.remove_all (); to_remove.remove_all (); @@ -776,7 +788,7 @@ namespace Pamac { Gtk.Container container = button.get_parent (); container.foreach ((widget) => { if (widget.name == "GtkButton") { - var dep_button = widget as Gtk.Button; + unowned Gtk.Button dep_button = widget as Gtk.Button; Package pkg = database.find_sync_satisfier (dep_button.label); if (pkg.name != "") { dep_name = pkg.name; @@ -813,6 +825,7 @@ namespace Pamac { box2.homogeneous = false; var dep_button = new Gtk.Button.with_label (dep); dep_button.relief = Gtk.ReliefStyle.NONE; + dep_button.valign = Gtk.Align.CENTER; dep_button.clicked.connect (on_dep_button_clicked); box2.pack_start (dep_button, false); if (database.find_installed_satisfier (dep).name == "") { @@ -828,6 +841,7 @@ namespace Pamac { var dep_button = new Gtk.Button.with_label (dep); dep_button.relief = Gtk.ReliefStyle.NONE; dep_button.halign = Gtk.Align.START; + dep_button.valign = Gtk.Align.CENTER; dep_button.clicked.connect (on_dep_button_clicked); box.pack_start (dep_button, false); } @@ -937,30 +951,35 @@ namespace Pamac { install_togglebutton.visible = false; build_togglebutton.visible = false; reset_files_button.visible = false; - remove_togglebutton.visible = true; - remove_togglebutton.active = to_remove.contains (details.name); reinstall_togglebutton.visible = false; - Package find_pkg = database.get_sync_pkg (details.name); - if (find_pkg.name != "") { - if (find_pkg.version == details.version) { - reinstall_togglebutton.visible = true; - reinstall_togglebutton.active = to_install.contains (details.name); - } + remove_togglebutton.visible = true; + if (database.should_hold (pkgname)) { + remove_togglebutton.sensitive = false; } else { - AURPackage aur_pkg = yield database.get_aur_pkg (details.name); - if (aur_pkg.name != "") { - // always show reinstall button for VCS package - if (aur_pkg.name.has_suffix ("-git") || - aur_pkg.name.has_suffix ("-svn") || - aur_pkg.name.has_suffix ("-bzr") || - aur_pkg.name.has_suffix ("-hg") || - aur_pkg.version == details.version) { - build_togglebutton.visible = true; - build_togglebutton.active = to_build.contains (details.name); + remove_togglebutton.sensitive = true; + remove_togglebutton.active = to_remove.contains (details.name); + Package find_pkg = database.get_sync_pkg (details.name); + if (find_pkg.name != "") { + if (find_pkg.version == details.version) { + reinstall_togglebutton.visible = true; + reinstall_togglebutton.active = to_install.contains (details.name); + } + } else { + AURPackage aur_pkg = yield database.get_aur_pkg (details.name); + if (aur_pkg.name != "") { + // always show reinstall button for VCS package + if (aur_pkg.name.has_suffix ("-git") || + aur_pkg.name.has_suffix ("-svn") || + aur_pkg.name.has_suffix ("-bzr") || + aur_pkg.name.has_suffix ("-hg") || + aur_pkg.version == details.version) { + build_togglebutton.visible = true; + build_togglebutton.active = to_build.contains (details.name); + } + build_files_row.visible = true; + string aur_url = "http://aur.archlinux.org/packages/" + details.name; + link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (escaped_url, escaped_url, aur_url, aur_url)); } - build_files_row.visible = true; - string aur_url = "http://aur.archlinux.org/packages/" + details.name; - link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (escaped_url, escaped_url, aur_url, aur_url)); } } } else { @@ -1091,35 +1110,22 @@ namespace Pamac { // files // will be populated on properties_stack switch if (properties_stack.visible_child_name == "files") { - on_properties_stack_visible_child_changed (); + properties_listbox.get_row_at_index (2).activate (); } } async void set_aur_details (string pkgname) { - app_image.pixbuf = null; + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + AURPackageDetails details = yield database.get_aur_pkg_details (pkgname); app_screenshot.pixbuf = null; - name_label.set_text (""); - desc_label.set_text (""); - link_label.set_text (""); - licenses_label.set_text (""); - long_desc_label.visible = false; - remove_togglebutton.visible = false; reinstall_togglebutton.visible = false; install_togglebutton.visible = false; - build_togglebutton.visible = false; reset_files_button.visible = false; - properties_listbox.visible = false; - details_grid.foreach (transaction.destroy_widget); - deps_grid.foreach (transaction.destroy_widget); - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - AURPackageDetails details = yield database.get_aur_pkg_details (pkgname); // infos name_label.set_markup ("<big><b>%s %s</b></big>".printf (details.name, details.version)); app_image.pixbuf = package_icon; desc_label.set_text (details.desc); + long_desc_label.visible = false; string aur_url = "http://aur.archlinux.org/packages/" + details.name; string escaped_url = Markup.escape_text (details.url); link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (escaped_url, escaped_url, aur_url, aur_url)); @@ -1197,7 +1203,7 @@ namespace Pamac { // build files // will be populated on properties_stack switch if (properties_stack.visible_child_name == "build_files") { - on_properties_stack_visible_child_changed (); + properties_listbox.get_row_at_index (3).activate (); } } @@ -1215,11 +1221,41 @@ namespace Pamac { break; case 2: // files reset_files_button.visible = false; - properties_stack.visible_child_name = "files"; + if (current_files != current_package_displayed) { + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + database.get_pkg_files_async.begin (current_package_displayed, (obj, res) => { + var files = database.get_pkg_files_async.end (res); + StringBuilder text = new StringBuilder (); + foreach (unowned string file in files) { + if (text.len > 0) { + text.append ("\n"); + } + text.append (file); + } + files_textview.buffer.set_text (text.str, (int) text.len); + properties_stack.visible_child_name = "files"; + this.get_window ().set_cursor (null); + }); + current_files = current_package_displayed; + } else { + properties_stack.visible_child_name = "files"; + } break; case 3: // build files reset_files_button.visible = true; - properties_stack.visible_child_name = "build_files"; + if (current_build_files != current_package_displayed) { + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + database.get_aur_pkg.begin (current_package_displayed, (obj, res) => { + AURPackage pkg = database.get_aur_pkg.end (res); + transaction.populate_build_files.begin (pkg.packagebase, true, false, () => { + properties_stack.visible_child_name = "build_files"; + }); + this.get_window ().set_cursor (null); + }); + current_build_files = current_package_displayed; + } else { + properties_stack.visible_child_name = "build_files"; + } break; default: break; @@ -1255,11 +1291,7 @@ namespace Pamac { [GtkCallback] void on_reset_files_button_clicked () { - transaction.build_files_notebook.foreach (transaction.destroy_widget); this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } database.get_aur_pkg.begin (current_package_displayed, (obj, res) => { AURPackage pkg = database.get_aur_pkg.end (res); transaction.populate_build_files.begin (pkg.packagebase, true, true); @@ -1303,22 +1335,46 @@ namespace Pamac { set_pendings_operations (); } - void populate_packages_list (List<Package> pkgs) { - // populate liststore - packages_list.clear (); + void sort_packages_list () { + int sort_index = sort_comboboxtext.active; + switch (sort_index) { + case 0: // relevance + if (browse_stack.visible_child_name != "search") { + current_packages_list.sort (sort_pkgs_by_relevance); + } + break; + case 1: // name + current_packages_list.sort (sort_pkgs_by_name); + break; + case 2: // repository + current_packages_list.sort (sort_pkgs_by_repo); + break; + case 3: // size + current_packages_list.sort (sort_pkgs_by_size); + break; + default: + break; + } + } + + void populate_packages_list (owned List<Package> pkgs) { + // populate listbox if (pkgs.length () == 0) { origin_stack.visible_child_name = "no_item"; - select_all_button.visible = false; this.get_window ().set_cursor (null); return; } else { - if (main_stack.visible_child_name == "browse") { - select_all_button.visible = filters_stack.visible_child_name != "filters"; - } - } - foreach (unowned Package pkg in pkgs) { - create_packagelist_row (pkg); + packages_listbox.freeze_child_notify (); + clear_packages_listbox (); + packages_listbox.thaw_child_notify (); + origin_stack.visible_child_name = "repos"; } + current_packages_list = (owned) pkgs; + sort_packages_list (); + current_packages_list_pos = current_packages_list; + do { + complete_packages_list (); + } while (need_more_packages ()); // scroll to top if (scroll_to_top) { packages_scrolledwindow.vadjustment.value = 0; @@ -1329,27 +1385,77 @@ namespace Pamac { this.get_window ().set_cursor (null); } + bool need_more_packages () { + if (current_packages_list_pos != null) { + int natural_height; + packages_listbox.get_preferred_height (null, out natural_height); + if (packages_scrolledwindow.vadjustment.page_size > natural_height) { + return true; + } + } + return false; + } + + void complete_packages_list () { + if (current_packages_list_pos != null) { + packages_listbox.freeze_child_notify (); + uint i = 0; + // display the next 20 packages + while (i < 20) { + var pkg = current_packages_list_pos.data; + create_packagelist_row (pkg); + i++; + current_packages_list_pos = current_packages_list_pos.next; + if (current_packages_list_pos == null) { + // add an empty row to have an ending separator + var row = new Gtk.ListBoxRow (); + row.visible = true; + packages_listbox.add (row); + break; + } + } + packages_listbox.thaw_child_notify (); + } + } + void create_packagelist_row (Package pkg) { - uint origin = 0; - string version; - uint64 size; - string size_str; - string summary; - Gdk.Pixbuf pixbuf = null; + bool is_update = browse_stack.visible_child_name == "updates"; + var row = new PackageRow (pkg); + //populate info if (pkg.app_name == "") { - summary = "<b>%s</b>\n%s".printf (pkg.name, Markup.escape_text (pkg.desc)); + row.name_label.set_markup ("<b>%s</b>".printf (pkg.name)); } else { - summary = "<b>%s (%s)</b>\n%s".printf (Markup.escape_text (pkg.app_name), pkg.name, Markup.escape_text (pkg.desc)); - } - if (filters_stack.visible_child_name == "updates") { - version = "<b>%s</b>\n(%s)".printf (pkg.version, pkg.installed_version); - size = pkg.download_size; - size_str = pkg.download_size == 0 ? "" : GLib.format_size (pkg.download_size); + row.name_label.set_markup ("<b>%s (%s)</b>".printf (Markup.escape_text (pkg.app_name), pkg.name)); + } + row.desc_label.label = pkg.desc; + if (is_update) { + var label = new Gtk.Label (pkg.version); + label.visible = true; + label.width_chars = 10; + label.max_width_chars = 10; + label.ellipsize = Pango.EllipsizeMode.END; + label.xalign = 0; + row.version_box.pack_start (label); + label = new Gtk.Label ("(%s)".printf (pkg.installed_version)); + label.visible = true; + label.width_chars = 10; + label.max_width_chars = 10; + label.ellipsize = Pango.EllipsizeMode.END; + label.xalign = 0; + row.version_box.pack_start (label); + row.size_label.label = pkg.download_size == 0 ? "" : GLib.format_size (pkg.download_size); } else { - version = pkg.version; - size = pkg.size; - size_str = GLib.format_size (pkg.size); - } + var label = new Gtk.Label (pkg.version); + label.visible = true; + label.width_chars = 10; + label.max_width_chars = 10; + label.ellipsize = Pango.EllipsizeMode.END; + label.xalign = 0; + row.version_box.pack_start (label); + row.size_label.label = GLib.format_size (pkg.size); + } + row.repo_label.label = pkg.repo; + Gdk.Pixbuf pixbuf; if (pkg.icon != "") { try { pixbuf = new Gdk.Pixbuf.from_file_at_scale (pkg.icon, 32, 32, true); @@ -1371,37 +1477,128 @@ namespace Pamac { } else { pixbuf = package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR); } + row.app_icon.pixbuf = pixbuf; + row.details_button.clicked.connect (() => { + on_packages_listbox_row_activated (row); + }); + if (transaction.transaction_summary.contains (pkg.name)) { + row.action_togglebutton.sensitive = false; + } if (pkg.installed_version == "") { - origin = 1; - } - packages_list.insert_with_values (null, -1, - 0, origin, - 1, pkg.name, - 2, summary, - 3, version, - 4, pkg.repo, - 5, size, - 6, size_str, - 7, pkg.app_name, - 8, pixbuf); - } - - void populate_aur_list (List<AURPackage> pkgs) { - // populate liststore - aur_list.clear (); + row.action_togglebutton.label = dgettext (null, "Install"); + if (pkg.name in to_install) { + row.action_togglebutton.active = true; + row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + } + row.action_togglebutton.toggled.connect ((button) => { + if (button.active) { + to_install.add (pkg.name); + } else { + to_install.remove (pkg.name); + } + refresh_listbox_buttons (); + set_pendings_operations (); + }); + } else if (is_update) { + row.action_togglebutton.label = dgettext (null, "Upgrade"); + row.action_togglebutton.active = true; + row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + row.action_togglebutton.toggled.connect ((button) => { + if (button.active) { + to_update.add (pkg.name); + temporary_ignorepkgs.remove (pkg.name); + } else { + to_update.remove (pkg.name); + temporary_ignorepkgs.add (pkg.name); + } + refresh_listbox_buttons (); + set_pendings_operations (); + }); + } else { + row.action_togglebutton.label = dgettext (null, "Remove"); + if (database.should_hold (pkg.name)) { + row.action_togglebutton.sensitive = false; + } else if (pkg.name in to_remove) { + row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + row.action_togglebutton.active = true; + } + row.action_togglebutton.toggled.connect ((button) => { + if (button.active) { + to_install.remove (pkg.name); + to_remove.add (pkg.name); + } else { + to_remove.remove (pkg.name); + } + refresh_listbox_buttons (); + set_pendings_operations (); + }); + } + // insert + packages_listbox.add (row); + } + + void refresh_listbox_buttons () { + packages_listbox.foreach ((row) => { + unowned PackageRow pamac_row = row as PackageRow; + if (pamac_row == null) { + return; + } + unowned string pkgname = pamac_row.pkg.name; + if (!database.should_hold (pkgname)) { + pamac_row.action_togglebutton.sensitive = true; + } + if (pkgname in to_install) { + pamac_row.action_togglebutton.active = true; + pamac_row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + } else if (pkgname in to_remove) { + pamac_row.action_togglebutton.active = true; + pamac_row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + } else if (pkgname in to_update) { + pamac_row.action_togglebutton.active = true; + pamac_row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + } else if (pkgname in temporary_ignorepkgs) { + pamac_row.action_togglebutton.active = false; + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + } else { + pamac_row.action_togglebutton.active = false; + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + pamac_row.action_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + } + }); + } + + void sort_aur_list () { + int sort_index = sort_comboboxtext.active; + switch (sort_index) { + case 0: // relevance + current_aur_list.sort (sort_aur_by_relevance); + break; + case 1: // name + current_aur_list.sort (sort_aur_by_name); + break; + default: + break; + } + } + + async void populate_aur_list (owned List<AURPackage> pkgs) { + // populate listbox if (pkgs.length () == 0) { origin_stack.visible_child_name = "no_item"; - select_all_button.visible = false; this.get_window ().set_cursor (null); return; } else { - if (main_stack.visible_child_name == "browse") { - select_all_button.visible = filters_stack.visible_child_name != "filters"; - } - } - foreach (unowned AURPackage aur_pkg in pkgs) { - create_aurlist_row (aur_pkg); - } + aur_listbox.freeze_child_notify (); + clear_aur_listbox (); + aur_listbox.thaw_child_notify (); + origin_stack.visible_child_name = "aur"; + } + current_aur_list = (owned) pkgs; + sort_aur_list (); + current_aur_list_pos = current_aur_list; + do { + complete_aur_list (); + } while (need_more_aur ()); // scroll to top if (scroll_to_top) { aur_scrolledwindow.vadjustment.value = 0; @@ -1410,179 +1607,173 @@ namespace Pamac { scroll_to_top = true; } this.get_window ().set_cursor (null); + // get aur details to save time + string[] pkgnames = {}; + foreach (unowned AURPackage pkg in current_aur_list) { + pkgnames += pkg.name; + } + yield database.get_aur_pkgs_details (pkgnames); } - void create_aurlist_row (AURPackage aur_pkg) { - string version; - if (filters_stack.visible_child_name == "updates") { - version = "<b>%s</b>\n(%s)".printf (aur_pkg.version, aur_pkg.installed_version); - } else if (aur_pkg.installed_version == "") { - version = aur_pkg.version; - } else { - version = aur_pkg.installed_version; + bool need_more_aur () { + if (current_aur_list_pos != null) { + int natural_height; + aur_listbox.get_preferred_height (null, out natural_height); + if (aur_scrolledwindow.vadjustment.page_size > natural_height) { + return true; + } } - aur_list.insert_with_values (null, -1, - 0, aur_pkg.installed_version == "" ? 1 : 0, // installed - 1, aur_pkg.name, - 2, "<b>%s</b>\n%s".printf (aur_pkg.name, Markup.escape_text (aur_pkg.desc)), - 3, version, - 4, aur_pkg.popularity, - 5, "%.2f".printf (aur_pkg.popularity), - 6, package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR)); + return false; } - void save_packages_sort_order () { - if (restore_sort_order == false) { - packages_list.get_sort_column_id (out sort_column_id, out sort_order); - restore_sort_order = true; + void complete_aur_list () { + if (current_aur_list_pos != null) { + aur_listbox.freeze_child_notify (); + uint i = 0; + // display the next 20 packages + while (i < 20) { + var pkg = current_aur_list_pos.data; + create_aurlist_row (pkg); + i++; + current_aur_list_pos = current_aur_list_pos.next; + if (current_aur_list_pos == null) { + // add an empty row to have an ending separator + var row = new Gtk.ListBoxRow (); + row.visible = true; + aur_listbox.add (row); + break; + } + } + aur_listbox.thaw_child_notify (); } } - void restore_packages_sort_order () { - if (restore_sort_order == true) { - packages_list.set_sort_column_id (sort_column_id, sort_order); - restore_sort_order = false; + void create_aurlist_row (AURPackage aur_pkg) { + var row = new AURRow (aur_pkg); + //populate info + row.name_label.set_markup ("<b>%s</b>".printf (aur_pkg.name)); + if (browse_stack.visible_child_name == "updates") { + row.version_label.set_markup ("<b>%s</b>\n(%s)".printf (aur_pkg.version, aur_pkg.installed_version)); + } else if (aur_pkg.installed_version == "") { + row.version_label.label = aur_pkg.version; + } else { + row.version_label.label = aur_pkg.installed_version; } + row.desc_label.label = aur_pkg.desc; + row.app_icon.pixbuf = package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR); + row.details_button.clicked.connect (() => { + on_aur_listbox_row_activated (row); + }); + if (aur_pkg.name in to_build) { + row.action_togglebutton.active = true; + row.action_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + } + row.action_togglebutton.toggled.connect ((button) => { + if (button.active) { + button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + to_build.add (aur_pkg.name); + } else { + button.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + to_build.remove (aur_pkg.name); + } + set_pendings_operations (); + }); + // insert + aur_listbox.add (row); } public void refresh_packages_list () { button_back.visible = (main_stack.visible_child_name != "browse" || filters_stack.visible_child_name != "filters"); - if (filters_stack.visible_child_name != "pending") { - uint total_pending = to_install.length + to_remove.length + to_build.length; - if (total_pending == 0) { - active_pending_row (false); - } - } - switch (filters_stack.visible_child_name) { - case "filters": - this.title = dgettext (null, "Package Manager"); - filters_listbox.select_row (null); - header_filter_label.set_markup (""); - search_button.active = false; - restore_packages_sort_order (); - show_sidebar (); - set_pendings_operations (); - // let time to show_sidebar - Timeout.add (200, () => { + if (browse_stack.visible_child_name == "browse") { + show_sidebar (); + search_button.visible = true; + switch (filters_stack.visible_child_name) { + case "filters": show_default_pkgs (); - return false; - }); - break; - case "categories": - header_filter_label.label = dgettext (null, "Categories"); - search_button.active = false; - restore_packages_sort_order (); - show_sidebar (); - set_pendings_operations (); - // let time to show_sidebar - Timeout.add (200, () => { + header_filter_label.label = ""; + search_button.active = false; + remove_all_button.visible = false; + install_all_button.visible = false; + set_pendings_operations (); + break; + case "categories": on_categories_listbox_row_activated (categories_listbox.get_selected_row ()); - return false; - }); - break; - case "search": - this.title = dgettext (null, "Search"); - header_filter_label.set_markup (""); - save_packages_sort_order (); - set_pendings_operations (); - // pkgs are ordered by relevance so keep this - packages_list.set_sort_column_id (Gtk.TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, 0); - if (search_string != null) { - // select last search_string - bool found = false; - search_comboboxtext.get_model ().foreach ((model, path, iter) => { - string line; - model.get (iter, 0, out line); - if (line == search_string) { - found = true; - // we select the iter in search list - // it will populate the packages list with the comboboxtext changed signal - search_comboboxtext.set_active_iter (null); - search_comboboxtext.set_active_iter (iter); - } - return found; - }); - if (!searchbar.search_mode_enabled) { - searchbar.search_mode_enabled = true; - } - } - break; - case "groups": - header_filter_label.label = dgettext (null, "Groups"); - search_button.active = false; - restore_packages_sort_order (); - show_sidebar (); - set_pendings_operations (); - // let time to show_sidebar - Timeout.add (200, () => { + header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Categories"))); + search_button.active = false; + remove_all_button.visible = false; + install_all_button.visible = false; + set_pendings_operations (); + break; + case "groups": on_groups_listbox_row_activated (groups_listbox.get_selected_row ()); - return false; - }); - break; - case "installed": - header_filter_label.label = dgettext (null, "Installed"); - search_button.active = false; - restore_packages_sort_order (); - show_sidebar (); - set_pendings_operations (); - // let time to show_sidebar - Timeout.add (200, () => { - on_installed_listbox_row_activated (installed_listbox.get_selected_row ()); - return false; - }); - break; - case "repos": - header_filter_label.label = dgettext (null, "Repositories"); - search_button.active = false; - restore_packages_sort_order (); - show_sidebar (); - set_pendings_operations (); - // let time to show_sidebar - Timeout.add (200, () => { + header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Groups"))); + search_button.active = false; + set_pendings_operations (); + break; + case "repos": on_repos_listbox_row_activated (repos_listbox.get_selected_row ()); - return false; - }); - break; - case "updates": - this.title = dgettext (null, "Updates"); - header_filter_label.set_markup (""); - search_button.active = false; - save_packages_sort_order (); - // order updates by name - packages_list.set_sort_column_id (2, Gtk.SortType.ASCENDING); + header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Repositories"))); + search_button.active = false; + remove_all_button.visible = false; + install_all_button.visible = false; + set_pendings_operations (); + break; + default: + break; + } + } else if (browse_stack.visible_child_name == "installed") { + on_installed_listbox_row_activated (installed_listbox.get_selected_row ()); + show_sidebar (); + header_filter_label.label = ""; + search_button.active = false; + search_button.visible = true; + install_all_button.visible = false; + set_pendings_operations (); + } else if (browse_stack.visible_child_name == "updates") { + database.get_updates.begin (on_get_updates_finished); + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + hide_sidebar (); + origin_stack.visible_child_name = "checking"; + header_filter_label.label = ""; + search_button.active = false; + search_button.visible = false; + remove_all_button.visible = false; + install_all_button.visible = false; + apply_button.sensitive = false;; + } else if (browse_stack.visible_child_name == "pending") { + on_pending_listbox_row_activated (pending_listbox.get_selected_row ()); + if (to_build.length == 0) { hide_sidebar (); - origin_stack.visible_child_name = "checking"; - packages_list.clear (); - aur_list.clear (); - select_all_button.visible = false; - apply_button.sensitive = false; - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - // let time to hide_sidebar - Timeout.add (200, () => { - database.get_updates.begin (on_get_updates_finished); - return false; + } + header_filter_label.label = ""; + search_button.active = false; + search_button.visible = false; + remove_all_button.visible = false; + install_all_button.visible = false; + } else if (browse_stack.visible_child_name == "search") { + if (search_string != null) { + // select last search_string + bool found = false; + search_comboboxtext.get_model ().foreach ((model, path, iter) => { + string line; + model.get (iter, 0, out line); + if (line == search_string) { + found = true; + // we select the iter in search list + // it will populate the packages list with the comboboxtext changed signal + search_comboboxtext.set_active_iter (null); + search_comboboxtext.set_active_iter (iter); + } + return found; }); - break; - case "pending": - this.title = dgettext (null, "Pending"); - header_filter_label.set_markup (""); - search_button.active = false; - save_packages_sort_order (); - // order pending by name - packages_list.set_sort_column_id (2, Gtk.SortType.ASCENDING); - if (to_build.length != 0) { - show_sidebar (); - } else { - hide_sidebar (); + if (!searchbar.search_mode_enabled) { + searchbar.search_mode_enabled = true; } - // let time to show/hide_sidebar - Timeout.add (200, () => { - on_pending_listbox_row_activated (pending_listbox.get_selected_row ()); - return false; - }); - break; - default: - break; + } + header_filter_label.label = ""; + remove_all_button.visible = false; + install_all_button.visible = false; + set_pendings_operations (); } } @@ -1609,30 +1800,18 @@ namespace Pamac { } [GtkCallback] - void on_packages_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) { - if (column.title == dgettext (null, "Name")) { - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - main_stack.visible_child_name = "details"; - Gtk.TreeIter iter; - packages_list.get_iter (out iter, path); - string pkgname; - string app_name; - packages_list.get (iter, 1, out pkgname, 7, out app_name); - bool sync_pkg = false; - if (filters_stack.visible_child_name == "updates") { - sync_pkg = true; - } - display_package_properties (pkgname, app_name, sync_pkg); - this.get_window ().set_cursor (null); - } + void on_packages_listbox_row_activated (Gtk.ListBoxRow row) { + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + main_stack.visible_child_name = "details"; + bool sync_pkg = browse_stack.visible_child_name == "updates"; + unowned PackageRow pamac_row = row as PackageRow; + display_package_properties (pamac_row.pkg.name, pamac_row.pkg.app_name, sync_pkg); + this.get_window ().set_cursor (null); } void on_dep_button_clicked (Gtk.Button button) { bool sync_pkg = false; - if (filters_stack.visible_child_name == "updates") { + if (browse_stack.visible_child_name == "updates") { sync_pkg = true; } if (display_package_queue.find_custom (current_package_displayed, strcmp) == null) { @@ -1648,9 +1827,6 @@ namespace Pamac { display_package_properties (pkg.name, "", sync_pkg); } else { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } string dep_name = database.get_alpm_dep_name (depstring); database.get_aur_pkg.begin (dep_name, (obj, res) => { this.get_window ().set_cursor (null); @@ -1662,114 +1838,17 @@ namespace Pamac { } } - void on_properties_stack_visible_child_changed () { - switch (properties_stack.visible_child_name) { - case "files": - files_textview.buffer.set_text ("", -1); - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - database.get_pkg_files_async.begin (current_package_displayed, (obj, res) => { - var files = database.get_pkg_files_async.end (res); - StringBuilder text = new StringBuilder (); - foreach (unowned string file in files) { - if (text.len > 0) { - text.append ("\n"); - } - text.append (file); - } - files_textview.buffer.set_text (text.str, (int) text.len); - this.get_window ().set_cursor (null); - }); - break; - case "build_files": - reset_files_button.visible = true; - transaction.build_files_notebook.foreach (transaction.destroy_widget); - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - database.get_aur_pkg.begin (current_package_displayed, (obj, res) => { - AURPackage pkg = database.get_aur_pkg.end (res); - transaction.populate_build_files.begin (pkg.packagebase, true, false); - this.get_window ().set_cursor (null); - }); - break; - default: - break; - } - } - - void on_packages_state_icon_activated (Gtk.TreePath path) { - Gtk.TreeIter iter; - packages_list.get_iter (out iter, path); - uint origin; - string pkgname; - packages_list.get (iter, 0, out origin, 1, out pkgname); - if (!transaction.transaction_summary.contains (pkgname)) { - if (filters_stack.visible_child_name == "updates") { - if (to_update.remove (pkgname)) { - temporary_ignorepkgs.add (pkgname); - } else if (temporary_ignorepkgs.remove (pkgname)) { - to_update.add (pkgname); - } - } else if (origin == 0) { // installed - if (to_remove.remove (pkgname)) { - } else if (!database.should_hold (pkgname)) { - to_remove.add (pkgname); - } - } else if (to_install.remove (pkgname)) { - } else { - to_install.add (pkgname); - } - set_pendings_operations (); - } - } - [GtkCallback] - void on_aur_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) { - if (column.title == dgettext (null, "Name")) { - main_stack.visible_child_name = "details"; - Gtk.TreeIter iter; - aur_list.get_iter (out iter, path); - uint origin; - string pkgname; - aur_list.get (iter, 0, out origin, 1, out pkgname); - if (filters_stack.visible_child_name == "updates") { - display_aur_properties (pkgname); - } else if (origin == 0) { // installed - display_package_properties (pkgname); - } else { - display_aur_properties (pkgname); - } - } - } - - void on_aur_state_icon_activated (Gtk.TreePath path) { - Gtk.TreeIter iter; - aur_list.get_iter (out iter, path); - uint origin; - string pkgname; - aur_list.get (iter, 0, out origin, 1, out pkgname); - if (!transaction.transaction_summary.contains (pkgname)) { - if (filters_stack.visible_child_name == "updates") { - if (to_update.remove (pkgname)) { - temporary_ignorepkgs.add (pkgname); - } else if (temporary_ignorepkgs.remove (pkgname)) { - to_update.add (pkgname); - } - } else if (origin == 0) { // installed - if (to_remove.remove (pkgname)) { - } else if (!database.should_hold (pkgname)) { - to_remove.add (pkgname); - } - } else if (to_build.remove (pkgname)) { - } else { - to_build.add (pkgname); - } - set_pendings_operations (); + void on_aur_listbox_row_activated (Gtk.ListBoxRow row) { + unowned AURRow pamac_row = row as AURRow; + if (browse_stack.visible_child_name == "updates") { + display_aur_properties (pamac_row.aur_pkg.name); + } else if (pamac_row.aur_pkg.installed_version != "") { + display_package_properties (pamac_row.aur_pkg.name); + } else { + display_aur_properties (pamac_row.aur_pkg.name); } + main_stack.visible_child_name = "details"; } [GtkCallback] @@ -1777,10 +1856,11 @@ namespace Pamac { switch (main_stack.visible_child_name) { case "browse": filters_stack.visible_child_name = "filters"; + search_entry.set_text (""); break; case "details": bool sync_pkg = false; - if (filters_stack.visible_child_name == "updates") { + if (browse_stack.visible_child_name == "updates") { sync_pkg = true; } string? pkgname = display_package_queue.pop_tail (); @@ -1814,97 +1894,29 @@ namespace Pamac { } } - void on_install_item_activate () { - foreach (unowned string pkgname in selected_pkgs) { - if (!database.is_installed_pkg (pkgname)) { - to_install.add (pkgname); - } - } - set_pendings_operations (); - } - - void on_build_item_activate () { - foreach (unowned string pkgname in selected_aur) { - to_build.add (pkgname); - } - set_pendings_operations (); - } - - void on_details_item_activate () { - // show details for the first selected package - if (selected_pkgs.length () == 1) { - bool sync_pkg = false; - if (filters_stack.visible_child_name == "updates") { - sync_pkg = true; - } - display_package_properties (selected_pkgs.data, "", sync_pkg); - main_stack.visible_child_name = "details"; - } else if (selected_aur.length () == 1) { - display_aur_properties (selected_aur.data); - main_stack.visible_child_name = "details"; - } - } - - void on_remove_item_activate () { - foreach (unowned string pkgname in selected_pkgs) { - to_install.remove (pkgname); - if (!database.should_hold (pkgname)) { - if (database.is_installed_pkg (pkgname)) { - to_remove.add (pkgname); - } - } - } - set_pendings_operations (); - } - - void on_deselect_item_activate () { - foreach (unowned string pkgname in selected_pkgs) { - if (to_install.remove (pkgname)) { - } else if (to_update.remove (pkgname)) { - temporary_ignorepkgs.add (pkgname); - } else { - to_remove.remove (pkgname); - } - } - foreach (unowned string pkgname in selected_aur) { - if (to_build.remove (pkgname)) { - } else { - to_update.remove (pkgname); - temporary_ignorepkgs.add (pkgname); - } - } - set_pendings_operations (); - } - - void on_upgrade_item_activate () { - foreach (unowned string pkgname in selected_pkgs) { - temporary_ignorepkgs.remove (pkgname); - to_update.add (pkgname); - } - foreach (unowned string pkgname in selected_aur) { - temporary_ignorepkgs.remove (pkgname); - to_update.add (pkgname); - } - set_pendings_operations (); - } - [GtkCallback] void on_updates_listbox_row_activated (Gtk.ListBoxRow row) { int index = row.get_index (); switch (index) { case 0: // repos this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; row.activatable = true; row.selectable = true; row.can_focus = true; row.get_child ().sensitive = true; - populate_packages_list (repos_updates); + var pkgs = new List<Package> (); + foreach (unowned Package pkg in repos_updates) { + pkgs.append (pkg); + } + populate_packages_list ((owned) pkgs); break; case 1: // aur - origin_stack.visible_child_name = "aur"; this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - populate_aur_list (aur_updates); + var pkgs = new List<AURPackage> (); + foreach (unowned AURPackage pkg in aur_updates) { + pkgs.append (pkg); + } + populate_aur_list.begin ((owned) pkgs); unowned Gtk.ListBoxRow repo_row = updates_listbox.get_row_at_index (0); if (repos_updates.length () > 0) { repo_row.activatable = true; @@ -1931,7 +1943,6 @@ namespace Pamac { case 0: // repos if ((to_install.length + to_remove.length) > 0) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; row.activatable = true; row.selectable = true; row.can_focus = true; @@ -1952,7 +1963,7 @@ namespace Pamac { pkgs.append (pkg); } } - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); } unowned Gtk.ListBoxRow aur_row = pending_listbox.get_row_at_index (1); if (to_build.length > 0) { @@ -2026,8 +2037,7 @@ namespace Pamac { aur_pkgs.append (aur_pkg); } } - origin_stack.visible_child_name = "aur"; - populate_aur_list (aur_pkgs); + populate_aur_list.begin ((owned) aur_pkgs); } [GtkCallback] @@ -2040,11 +2050,7 @@ namespace Pamac { if (search_string == null) { return; } - origin_stack.visible_child_name = "repos"; this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } current_filter = "search_installed_pkgs_%s".printf (search_string); database.search_installed_pkgs_async.begin (search_string, (obj, res) => { if (current_filter != "search_installed_pkgs_%s".printf (search_string)) { @@ -2088,15 +2094,15 @@ namespace Pamac { search_listbox.select_row (aur_row); on_search_listbox_row_activated (search_listbox.get_selected_row ()); } else { - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); } }); } else { - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); } }); } else { - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); database.search_repos_pkgs_async.begin (search_string, (obj, res) => { if (database.search_repos_pkgs_async.end (res).length () > 0) { unowned Gtk.ListBoxRow repos_row = search_listbox.get_row_at_index (1); @@ -2108,7 +2114,6 @@ namespace Pamac { }); } }); - aur_list.clear (); break; case 1: // repos search_entry.grab_focus_without_selecting (); @@ -2116,11 +2121,7 @@ namespace Pamac { if (search_string == null) { return; } - origin_stack.visible_child_name = "repos"; this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } current_filter = "search_repos_pkgs_%s".printf (search_string); database.search_repos_pkgs_async.begin (search_string, (obj, res) => { if (current_filter != "search_repos_pkgs_%s".printf (search_string)) { @@ -2164,15 +2165,15 @@ namespace Pamac { search_listbox.select_row (aur_row); on_search_listbox_row_activated (search_listbox.get_selected_row ()); } else { - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); } }); } else { - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); } }); } else { - populate_packages_list (pkgs); + populate_packages_list ((owned) pkgs); database.search_installed_pkgs_async.begin (search_string, (obj, res) => { if (database.search_installed_pkgs_async.end (res).length () > 0) { unowned Gtk.ListBoxRow installed_row = search_listbox.get_row_at_index (0); @@ -2184,7 +2185,6 @@ namespace Pamac { }); } }); - aur_list.clear (); break; case 2: // aur search_entry.grab_focus_without_selecting (); @@ -2193,17 +2193,13 @@ namespace Pamac { origin_stack.visible_child_name = "no_item"; return; } - origin_stack.visible_child_name = "aur"; this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } current_filter = "search_in_aur"; database.search_in_aur.begin (search_string, (obj, res) => { if (current_filter != "search_in_aur") { return; } - populate_aur_list (database.search_in_aur.end (res)); + populate_aur_list.begin (database.search_in_aur.end (res)); }); database.search_installed_pkgs_async.begin (search_string, (obj, res) => { unowned Gtk.ListBoxRow installed_row = search_listbox.get_row_at_index (0); @@ -2235,7 +2231,6 @@ namespace Pamac { repos_row.get_child ().sensitive = false; } }); - packages_list.clear (); break; default: break; @@ -2243,177 +2238,26 @@ namespace Pamac { } [GtkCallback] - void on_select_all_button_clicked () { - if (origin_stack.visible_child_name == "repos") { - packages_treeview.get_selection ().select_all (); - } else if (origin_stack.visible_child_name == "aur") { - aur_treeview.get_selection ().select_all (); - } - } - - [GtkCallback] - bool on_packages_treeview_button_press_event (Gdk.EventButton event) { - // Check if right mouse button was clicked - if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) { - Gtk.TreePath treepath; - if (packages_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null)) { - packages_treeview.grab_focus (); - Gtk.TreeSelection selection = packages_treeview.get_selection (); - if (!selection.path_is_selected (treepath)) { - selection.unselect_all (); - selection.select_path (treepath); - } - GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null); - selected_pkgs = new GLib.List<string> (); - selected_aur = new GLib.List<string> (); - deselect_item.visible = false; - upgrade_item.visible = false; - install_item.visible = false; - build_item.visible = false; - remove_item.visible = false; - if (selected_paths.length () == 1) { - Gtk.TreePath path = selected_paths.data; - Gtk.TreeIter iter; - packages_list.get_iter (out iter, path); - uint origin; - string pkgname; - string pkgversion; - packages_list.get (iter, 0, out origin, 1, out pkgname, 3, out pkgversion); - selected_pkgs.append (pkgname); - details_item.visible = true; - if (to_install.contains (pkgname) - || to_remove.contains (pkgname) - || to_update.contains (pkgname)) { - deselect_item.visible = true; - } else if (temporary_ignorepkgs.contains (pkgname)) { - upgrade_item.visible = true; - } else if (origin == 0) { // installed - remove_item.visible = true; - } else if (origin == 1) { - install_item.visible = true; - } - } else { - details_item.visible = false; - foreach (unowned Gtk.TreePath path in selected_paths) { - Gtk.TreeIter iter; - packages_list.get_iter (out iter, path); - uint origin; - string pkgname; - packages_list.get (iter, 0, out origin, 1, out pkgname); - selected_pkgs.append (pkgname); - if (!deselect_item.visible) { - if (to_install.contains (pkgname) - || to_remove.contains (pkgname) - || to_update.contains (pkgname)) { - deselect_item.visible = true; - } - } - if (temporary_ignorepkgs.contains (pkgname)) { - upgrade_item.visible = true; - } - if (origin == 1) { - install_item.visible = true; - } - if (filters_stack.visible_child_name != "updates" && origin == 0) { // installed - remove_item.visible = true; - } - } - } - right_click_menu.popup_at_pointer (event); - return true; + void on_remove_all_button_clicked () { + foreach (unowned Package pkg in current_packages_list) { + if (!transaction.transaction_summary.contains (pkg.name) && pkg.installed_version != "") { + to_install.remove (pkg.name); + to_remove.add (pkg.name); } } - return false; - } - - [GtkCallback] - bool on_packages_treeview_query_tooltip (int x, int y, bool keyboard_tooltip, Gtk.Tooltip tooltip) { - Gtk.TreePath path; - Gtk.TreeIter iter; - if (packages_treeview.get_tooltip_context (ref x, ref y, keyboard_tooltip, null, out path, out iter)) { - string desc; - packages_list.get (iter, 2, out desc); - tooltip.set_markup (desc); - packages_treeview.set_tooltip_row (tooltip, path); - return true; - } - return false; + refresh_listbox_buttons (); + set_pendings_operations (); } [GtkCallback] - bool on_aur_treeview_button_press_event (Gdk.EventButton event) { - aur_treeview.grab_focus (); - // Check if right mouse button was clicked - if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) { - Gtk.TreePath? treepath; - Gtk.TreeSelection selection = aur_treeview.get_selection (); - if (aur_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null)) { - if (!selection.path_is_selected (treepath)) { - selection.unselect_all (); - selection.select_path (treepath); - } - GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null); - selected_pkgs = new GLib.List<string> (); - selected_aur = new GLib.List<string> (); - deselect_item.visible = false; - upgrade_item.visible = false; - install_item.visible = false; - build_item.visible = false; - remove_item.visible = false; - if (selected_paths.length () == 1) { - details_item.visible = true; - } else { - details_item.visible = false; - } - foreach (unowned Gtk.TreePath path in selected_paths) { - Gtk.TreeIter iter; - aur_list.get_iter (out iter, path); - string pkgname; - aur_list.get (iter, 1, out pkgname); - if (database.is_installed_pkg (pkgname)) { - selected_pkgs.append (pkgname); - if (filters_stack.visible_child_name != "updates" && !to_remove.contains (pkgname)) { - // there is for sure a pkg to remove - remove_item.visible = true; - } - } else { - selected_aur.append (pkgname); - } - } - foreach (unowned string pkgname in selected_aur) { - if (to_build.contains (pkgname)) { - deselect_item.visible = true; - } else { - build_item.visible = true; - } - } - foreach (unowned string pkgname in selected_pkgs) { - if (to_remove.contains (pkgname) - || to_update.contains (pkgname)) { - deselect_item.visible = true; - } else if (temporary_ignorepkgs.contains (pkgname)) { - upgrade_item.visible = true; - } - } - right_click_menu.popup_at_pointer (event); - return true; + void on_install_all_button_clicked () { + foreach (unowned Package pkg in current_packages_list) { + if (!transaction.transaction_summary.contains (pkg.name) && pkg.installed_version == "") { + to_install.add (pkg.name); } } - return false; - } - - [GtkCallback] - bool on_aur_treeview_query_tooltip (int x, int y, bool keyboard_tooltip, Gtk.Tooltip tooltip) { - Gtk.TreePath path; - Gtk.TreeIter iter; - if (aur_treeview.get_tooltip_context (ref x, ref y, keyboard_tooltip, null, out path, out iter)) { - string desc; - aur_list.get (iter, 2, out desc); - tooltip.set_markup (desc); - aur_treeview.set_tooltip_row (tooltip, path); - return true; - } - return false; + refresh_listbox_buttons (); + set_pendings_operations (); } void on_search_mode_enabled () { @@ -2453,7 +2297,7 @@ namespace Pamac { }); if (!found) { Gtk.TreeIter iter; - var store = search_comboboxtext.get_model () as Gtk.ListStore; + unowned Gtk.ListStore store = search_comboboxtext.get_model () as Gtk.ListStore; store.insert_with_values (out iter, -1, 0, tmp_search_string); // we select the iter in search list // it will populate the packages list with the comboboxtext changed signal @@ -2477,9 +2321,9 @@ namespace Pamac { // a history line was choosen this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); search_string = search_comboboxtext.get_active_text ().strip (); - if (filters_stack.visible_child_name != "search") { + if (browse_stack.visible_child_name != "search") { // this function will be recalled when refresh_packages_list - filters_stack.visible_child_name = "search"; + browse_stack.visible_child_name = "search"; return; } on_search_listbox_row_activated (search_listbox.get_selected_row ()); @@ -2493,6 +2337,11 @@ namespace Pamac { } } + [GtkCallback] + void on_sort_comboboxtext_changed () { + refresh_packages_list (); + } + [GtkCallback] void on_filters_listbox_row_activated (Gtk.ListBoxRow row) { int index = row.get_index (); @@ -2506,15 +2355,6 @@ namespace Pamac { case 2: // repos filters_stack.visible_child_name = "repos"; break; - case 3: // installed - filters_stack.visible_child_name = "installed"; - break; - case 4: // updates - filters_stack.visible_child_name = "updates"; - break; - case 5: // pending - filters_stack.visible_child_name = "pending"; - break; default: break; } @@ -2523,11 +2363,9 @@ namespace Pamac { [GtkCallback] void on_categories_listbox_row_activated (Gtk.ListBoxRow row) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; - var label = row.get_child () as Gtk.Label; + unowned Gtk.Label label = row.get_child () as Gtk.Label; string matching_cat = ""; - string category = label.label; - this.title = category; + unowned string category = label.label; if (category == dgettext (null, "Accessories")) { matching_cat = "Utility"; } else if (category == dgettext (null, "Audio & Video")) { @@ -2566,17 +2404,32 @@ namespace Pamac { [GtkCallback] void on_groups_listbox_row_activated (Gtk.ListBoxRow row) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; - var label = row.get_child () as Gtk.Label; - string group_name = label.label; - this.title = group_name; + unowned Gtk.Label label = row.get_child () as Gtk.Label; + unowned string group_name = label.label; Timeout.add (200, () => { current_filter = "group_pkgs_%s".printf (group_name); database.get_group_pkgs_async.begin (group_name, (obj, res) => { if (current_filter != "group_pkgs_%s".printf (group_name)) { return; } - populate_packages_list (database.get_group_pkgs_async.end (res)); + var pkgs = database.get_group_pkgs_async.end (res); + bool found = false; + foreach (unowned Package pkg in pkgs) { + if (pkg.installed_version == "") { + found = true; + break; + } + } + install_all_button.visible = found; + found = false; + foreach (unowned Package pkg in pkgs) { + if (pkg.installed_version != "") { + found = true; + break; + } + } + remove_all_button.visible = found; + populate_packages_list ((owned) pkgs); }); return false; }); @@ -2585,9 +2438,6 @@ namespace Pamac { [GtkCallback] void on_installed_listbox_row_activated (Gtk.ListBoxRow row) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; - var label = row.get_child () as Gtk.Label; - this.title = label.label; int index = row.get_index (); switch (index) { case 0: // Installed @@ -2597,6 +2447,7 @@ namespace Pamac { if (current_filter != "installed_pkgs") { return; } + remove_all_button.visible = false; populate_packages_list (database.get_installed_pkgs_async.end (res)); }); return false; @@ -2609,6 +2460,7 @@ namespace Pamac { if (current_filter != "explicitly_installed_pkgs") { return; } + remove_all_button.visible = false; populate_packages_list (database.get_explicitly_installed_pkgs_async.end (res)); }); return false; @@ -2621,7 +2473,9 @@ namespace Pamac { if (current_filter != "orphans") { return; } - populate_packages_list (database.get_orphans_async.end (res)); + var pkgs = database.get_orphans_async.end (res); + remove_all_button.visible = pkgs.length () > 0; + populate_packages_list ((owned) pkgs); }); return false; }); @@ -2633,6 +2487,7 @@ namespace Pamac { if (current_filter != "foreign_pkgs") { return; } + remove_all_button.visible = false; populate_packages_list (database.get_foreign_pkgs_async.end (res)); }); return false; @@ -2646,10 +2501,8 @@ namespace Pamac { [GtkCallback] void on_repos_listbox_row_activated (Gtk.ListBoxRow row) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - origin_stack.visible_child_name = "repos"; - var label = row.get_child () as Gtk.Label; - string repo = label.label; - this.title = repo; + unowned Gtk.Label label = row.get_child () as Gtk.Label; + unowned string repo = label.label; Timeout.add (200, () => { current_filter = "repo_pkgs_%s".printf (repo); database.get_repo_pkgs_async.begin (repo, (obj, res) => { @@ -2665,38 +2518,40 @@ namespace Pamac { void on_main_stack_visible_child_changed () { switch (main_stack.visible_child_name) { case "browse": + main_stack_switcher.visible = true; button_back.visible = filters_stack.visible_child_name != "filters"; if (filters_stack.visible_child_name == "categories") { header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Categories"))); } else if (filters_stack.visible_child_name == "groups") { header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Groups"))); - } else if (filters_stack.visible_child_name == "installed") { - header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Installed"))); } else if (filters_stack.visible_child_name == "repos") { header_filter_label.set_markup ("<b>%s</b>".printf (dgettext (null, "Repositories"))); } else { - header_filter_label.set_markup (""); + header_filter_label.label = ""; + } + if (browse_stack.visible_child_name == "updates" + || browse_stack.visible_child_name == "pending") { + search_button.visible = false; + } else { + search_button.visible = true; } - select_all_button.visible = filters_stack.visible_child_name != "filters" - && origin_stack.visible_child_name != "updated"; - search_button.visible = true; if (transaction.details_textview.buffer.get_char_count () > 0) { details_button.sensitive = true; } break; case "details": + main_stack_switcher.visible = false; button_back.visible = true; - header_filter_label.set_markup (""); - select_all_button.visible = false; + header_filter_label.label = ""; search_button.visible = false; if (transaction.details_textview.buffer.get_char_count () > 0) { details_button.sensitive = true; } break; case "term": + main_stack_switcher.visible = false; button_back.visible = true; - header_filter_label.set_markup (""); - select_all_button.visible = false; + header_filter_label.label = ""; search_button.visible = false; details_button.sensitive = false; details_button.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); @@ -2706,10 +2561,44 @@ namespace Pamac { } } + void on_browse_stack_visible_child_changed () { + refresh_packages_list (); + } + void on_filters_stack_visible_child_changed () { refresh_packages_list (); } + void on_origin_stack_visible_child_changed () { + switch (origin_stack.visible_child_name) { + case "repos": + sort_order_box.visible = true; + // check if aur was used + Gtk.TreeIter iter; + if (!sort_comboboxtext.get_model ().get_iter (out iter, new Gtk.TreePath.from_indices (2, -1))) { + sort_comboboxtext.append_text (dgettext (null, "Repository")); + sort_comboboxtext.append_text (dgettext (null, "Size")); + } + break; + case "aur": + sort_order_box.visible = true; + Gtk.TreeIter iter; + // check if packages was used + if (sort_comboboxtext.get_model ().get_iter (out iter, new Gtk.TreePath.from_indices (2, -1))) { + if (sort_comboboxtext.active == 2 + || sort_comboboxtext.active == 3) { + sort_comboboxtext.active = 0; + } + sort_comboboxtext.remove (2); + sort_comboboxtext.remove (2); + } + break; + default: + sort_order_box.visible = false; + break; + } + } + [GtkCallback] void on_menu_button_toggled () { preferences_button.sensitive = !(transaction_running || sysupgrade_running); @@ -2718,18 +2607,12 @@ namespace Pamac { [GtkCallback] void on_history_button_clicked () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } var history_dialog = new HistoryDialog (this); this.get_window ().set_cursor (null); history_dialog.show (); history_dialog.response.connect (() => { history_dialog.destroy (); }); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } } [GtkCallback] @@ -2758,9 +2641,6 @@ namespace Pamac { } } else { chooser.destroy (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } } } @@ -2785,18 +2665,15 @@ namespace Pamac { var preferences_dialog = new PreferencesDialog (transaction); preferences_dialog.run (); preferences_dialog.destroy (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } } on_run_preferences_dialog_finished (); } void on_run_preferences_dialog_finished () { transaction.unlock (); - if (filters_stack.visible_child_name == "updates") { - origin_stack.visible_child_name = "checking"; + if (browse_stack.visible_child_name == "updates") { database.get_updates.begin (on_get_updates_finished); + origin_stack.visible_child_name = "checking"; } else { this.get_window ().set_cursor (null); } @@ -2811,7 +2688,7 @@ namespace Pamac { "icon_name", "system-software-install", "logo_icon_name", "system-software-install", "comments", dgettext (null, "A Gtk3 frontend for libalpm"), - "copyright", "Copyright © 2018 Guillaume Benoit", + "copyright", "Copyright © 2019 Guillaume Benoit", "authors", authors, "version", VERSION, "license_type", Gtk.License.GPL_3_0, @@ -2826,7 +2703,7 @@ namespace Pamac { [GtkCallback] void on_apply_button_clicked () { - if (filters_stack.visible_child_name == "updates" && + if (browse_stack.visible_child_name == "updates" && main_stack.visible_child_name == "browse") { force_refresh = false; transaction.no_confirm_upgrade = true; @@ -2842,16 +2719,6 @@ namespace Pamac { details_button.sensitive = true; } - bool refresh_row (Gtk.TreeModel model, Gtk.TreePath path, Gtk.TreeIter iter) { - model.row_changed (path, iter); - return false; - } - - void refresh_state_icons () { - packages_list.foreach (refresh_row); - aur_list.foreach (refresh_row); - } - void run_transaction () { transaction.no_confirm_upgrade = false; transaction_running = true; @@ -2879,11 +2746,6 @@ namespace Pamac { } transaction.start (to_install_, to_remove_, to_load_, to_build_, {}, {}); clear_lists (); - // let time to update packages states - Timeout.add (500, () => { - refresh_state_icons (); - return false; - }); } void run_sysupgrade () { @@ -2897,11 +2759,6 @@ namespace Pamac { } show_transaction_infobox (); transaction.start_sysupgrade (force_refresh, database.config.enable_downgrade, temp_ign_pkgs, {}); - // let time to update packages states - Timeout.add (500, () => { - refresh_state_icons (); - return false; - }); } [GtkCallback] @@ -2929,9 +2786,6 @@ namespace Pamac { display_aur_properties (current_package_displayed); } } - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } } } @@ -2944,9 +2798,6 @@ namespace Pamac { void on_get_updates_progress (uint percent) { checking_label.set_markup ("<big><b>%s %u %</b></big>".printf (dgettext (null, "Checking for Updates"), percent)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } } void on_get_updates_finished (Object? source_object, AsyncResult res) { @@ -2960,8 +2811,7 @@ namespace Pamac { foreach (unowned AURPackage pkg in updates.aur_updates) { aur_updates.append (pkg); } - origin_stack.visible_child_name = "repos"; - if (filters_stack.visible_child_name == "updates") { + if (browse_stack.visible_child_name == "updates") { populate_updates (); } else { this.get_window ().set_cursor (null); @@ -2994,14 +2844,9 @@ namespace Pamac { show_sidebar (); } if (repos_updates.length () > 0) { - updates_listbox.select_row (updates_listbox.get_row_at_index (0)); - on_updates_listbox_row_activated (updates_listbox.get_selected_row ()); + updates_listbox.get_row_at_index (0).activate (); } else { - updates_listbox.select_row (updates_listbox.get_row_at_index (1)); - on_updates_listbox_row_activated (updates_listbox.get_selected_row ()); - } - if (main_stack.visible_child_name == "browse") { - select_all_button.visible = filters_stack.visible_child_name != "filters"; + updates_listbox.get_row_at_index (1).activate (); } set_pendings_operations (); } @@ -3077,6 +2922,7 @@ namespace Pamac { } } } + transaction.transaction_summary.remove_all (); clear_previous_lists (); scroll_to_top = false; if (main_stack.visible_child_name == "details") { @@ -3095,6 +2941,7 @@ namespace Pamac { transaction_running = false; generate_mirrors_list = false; } + refresh_listbox_buttons (); set_pendings_operations (); } } diff --git a/src/meson.build b/src/meson.build index b7f8cb04..736be362 100644 --- a/src/meson.build +++ b/src/meson.build @@ -94,7 +94,7 @@ custom_target('pamac typelib', command: [g_ir_compiler, '--shared-library', 'lib libpamac_gtk_dep = declare_dependency(link_with: libpamac_gtk) executable('pamac-manager', - sources: ['version.vala', 'history_dialog.vala', preferences_sources, 'manager_window.vala', 'manager.vala', 'search-provider.vala', manager_resources], + sources: ['version.vala', 'history_dialog.vala', preferences_sources, 'package_row.vala', 'aur_row.vala', 'manager_window.vala', 'manager.vala', 'search-provider.vala', manager_resources], dependencies: [gtk3, libsoup, libpamac_dep, libpamac_gtk_dep], vala_args: common_vala_args, c_args: common_c_args, diff --git a/src/package.vala b/src/package.vala index bcd1474b..87a68f36 100644 --- a/src/package.vala +++ b/src/package.vala @@ -25,7 +25,9 @@ namespace Pamac { public string version { get {return pkg_struct.version;} } public string installed_version { get {return pkg_struct.installed_version;} } public string desc { get {return pkg_struct.desc;} } - public string repo { get {return pkg_struct.repo;} } + public string repo { get {return pkg_struct.repo;} + internal set {pkg_struct.repo = value;} + } public uint64 size { get {return pkg_struct.size;} } public uint64 download_size { get {return pkg_struct.download_size;} } public string icon { get {return pkg_struct.icon;} } diff --git a/src/package_row.vala b/src/package_row.vala new file mode 100644 index 00000000..19b13395 --- /dev/null +++ b/src/package_row.vala @@ -0,0 +1,51 @@ +/* + * pamac-vala + * + * Copyright (C) 2019 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + + [GtkTemplate (ui = "/org/manjaro/pamac/manager/package_row.ui")] + public class PackageRow : Gtk.ListBoxRow { + + [GtkChild] + public Gtk.Image app_icon; + [GtkChild] + public Gtk.Label name_label; + [GtkChild] + public Gtk.Label desc_label; + [GtkChild] + public Gtk.Box version_box; + [GtkChild] + public Gtk.Label repo_label; + [GtkChild] + public Gtk.Label size_label; + [GtkChild] + public Gtk.ToggleButton action_togglebutton; + [GtkChild] + public Gtk.Button details_button; + + public Package pkg; + + public PackageRow (Package pkg) { + Object (); + this.pkg = pkg; + } + + } + +} diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala index 04f98c63..7c3c288e 100644 --- a/src/preferences_dialog.vala +++ b/src/preferences_dialog.vala @@ -384,6 +384,7 @@ namespace Pamac { transaction.choose_pkgs_dialog.pkgs_list.insert_with_values (null, -1, 0, false, 1, pkg.name); } } + transaction.choose_pkgs_dialog.valid_button.grab_focus (); this.get_window ().set_cursor (null); if (transaction.choose_pkgs_dialog.run () == Gtk.ResponseType.OK) { var ignorepkg_string = new StringBuilder (); @@ -411,9 +412,6 @@ namespace Pamac { transaction.start_write_alpm_config (new_alpm_conf); } transaction.choose_pkgs_dialog.hide (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } }); } diff --git a/src/transaction-cli.vala b/src/transaction-cli.vala index e5b440d2..a5670a76 100644 --- a/src/transaction-cli.vala +++ b/src/transaction-cli.vala @@ -102,6 +102,9 @@ namespace Pamac { void print_download_progress (string action, string status, double progress) { if (progress == 0) { + if (action == current_action) { + return; + } current_action = action; current_line = status; stdout.printf (action); diff --git a/src/transaction-gtk.vala b/src/transaction-gtk.vala index e6c7ce2d..9854b2b2 100644 --- a/src/transaction-gtk.vala +++ b/src/transaction-gtk.vala @@ -38,6 +38,8 @@ namespace Pamac { bool summary_shown; bool commit_transaction_answer; + public signal void transaction_sum_populated (); + public TransactionGtk (Database database, Gtk.ApplicationWindow? application_window) { Object (database: database, application_window: application_window); } @@ -51,6 +53,7 @@ namespace Pamac { current_action = ""; progress_box = new ProgressBox (); progress_box.progressbar.text = ""; + progress_box.progressbar.visible = false; choose_pkgs_dialog = new ChoosePkgsDialog (application_window); // create details textview details_window = new Gtk.ScrolledWindow (null, null); @@ -75,6 +78,7 @@ namespace Pamac { // create build files notebook build_files_notebook = new Gtk.Notebook (); build_files_notebook.visible = true; + build_files_notebook.show_border = false; build_files_notebook.expand = true; build_files_notebook.scrollable = true; build_files_notebook.enable_popup = true; @@ -93,6 +97,7 @@ namespace Pamac { sysupgrade_finished.connect (on_finished); start_generating_mirrors_list.connect (start_progressbar_pulse); generate_mirrors_list_finished.connect (reset_progress_box); + start_downloading.connect (() => {progress_box.progressbar.visible = true;}); start_preparing.connect (start_progressbar_pulse); stop_preparing.connect (stop_progressbar_pulse); start_building.connect (start_progressbar_pulse); @@ -166,10 +171,12 @@ namespace Pamac { stop_progressbar_pulse (); progress_box.progressbar.fraction = 0; progress_box.progressbar.text = ""; + progress_box.progressbar.visible = false; } public void start_progressbar_pulse () { stop_progressbar_pulse (); + progress_box.progressbar.visible = true; pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_box.progressbar.pulse); } @@ -178,6 +185,7 @@ namespace Pamac { Source.remove (pulse_timeout_id); pulse_timeout_id = 0; progress_box.progressbar.fraction = 0; + progress_box.progressbar.visible = false; } } @@ -188,6 +196,7 @@ namespace Pamac { foreach (unowned string name in optdeps) { choose_pkgs_dialog.pkgs_list.insert_with_values (null, -1, 0, false, 1, name); } + choose_pkgs_dialog.valid_button.grab_focus (); if (choose_pkgs_dialog.run () == Gtk.ResponseType.OK) { choose_pkgs_dialog.pkgs_list.foreach ((model, path, iter) => { GLib.Value val; @@ -209,6 +218,7 @@ namespace Pamac { var choose_provider_dialog = new ChooseProviderDialog (application_window); choose_provider_dialog.title = dgettext (null, "Choose a provider for %s").printf (depend); unowned Gtk.Box box = choose_provider_dialog.get_content_area (); + box.vexpand = true; Gtk.RadioButton? last_radiobutton = null; Gtk.RadioButton? first_radiobutton = null; foreach (unowned string provider in providers) { @@ -248,12 +258,11 @@ namespace Pamac { var dialog = new Gtk.Dialog.with_buttons (dgettext (null, "Import PGP key"), application_window, flags); - dialog.border_width = 6; + dialog.border_width = 3; dialog.icon_name = "system-software-install"; dialog.deletable = false; - unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "Trust and Import"), Gtk.ResponseType.OK); - widget.receives_default = true; - widget = dialog.add_button (dgettext (null, "_Cancel"), Gtk.ResponseType.CANCEL); + dialog.add_button (dgettext (null, "Trust and Import"), Gtk.ResponseType.OK); + unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Cancel"), Gtk.ResponseType.CANCEL); widget.can_focus = true; widget.has_focus = true; widget.can_default = true; @@ -270,6 +279,7 @@ namespace Pamac { unowned Gtk.Box box = dialog.get_content_area (); box.add (label); box.valign = Gtk.Align.CENTER; + box.spacing = 6; dialog.default_width = 800; dialog.default_height = 150; int response = dialog.run (); @@ -461,6 +471,8 @@ namespace Pamac { } else { show_warnings (true); } + transaction_sum_populated (); + transaction_sum_dialog.cancel_button.grab_focus (); int response = transaction_sum_dialog.run (); transaction_sum_dialog.hide (); return response; @@ -491,16 +503,15 @@ namespace Pamac { application_window, flags); dialog.icon_name = "system-software-install"; - unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "Save"), Gtk.ResponseType.CLOSE); - widget.receives_default = true; - widget = dialog.add_button (dgettext (null, "_Cancel"), Gtk.ResponseType.CANCEL); + dialog.border_width = 3; + dialog.add_button (dgettext (null, "Save"), Gtk.ResponseType.CLOSE); + unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Cancel"), Gtk.ResponseType.CANCEL); widget.can_focus = true; widget.has_focus = true; widget.can_default = true; widget.has_default = true; unowned Gtk.Box box = dialog.get_content_area (); - box.margin_bottom = 6; - build_files_notebook.margin = 6; + box.spacing = 6; box.add (build_files_notebook); dialog.default_width = 700; dialog.default_height = 500; @@ -510,7 +521,6 @@ namespace Pamac { int response = dialog.run (); // re-add noteboook to manager_window properties stack box.remove (build_files_notebook); - build_files_notebook.margin = 0; if (stack != null) { stack.add_named (build_files_notebook, "build_files"); } @@ -570,16 +580,17 @@ namespace Pamac { } public async bool populate_build_files (string pkgname, bool clone, bool overwrite) { - build_files_notebook.foreach (destroy_widget); if (clone) { File? clone_dir = yield database.clone_build_files (pkgname, overwrite); if (clone_dir == null) { // error + build_files_notebook.foreach (destroy_widget); return false; } } bool success = true; string[] file_paths = yield get_build_files (pkgname); + build_files_notebook.foreach (destroy_widget); foreach (unowned string path in file_paths) { if ("PKGBUILD" in path) { success = yield create_build_files_tab (path); @@ -650,7 +661,7 @@ namespace Pamac { var dialog = new Gtk.Dialog.with_buttons (dgettext (null, "Warning"), application_window, flags); - dialog.border_width = 6; + dialog.border_width = 3; dialog.icon_name = "system-software-install"; dialog.deletable = false; unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE); @@ -668,6 +679,7 @@ namespace Pamac { scrolledwindow.expand = true; unowned Gtk.Box box = dialog.get_content_area (); box.add (scrolledwindow); + box.spacing = 6; dialog.default_width = 600; dialog.default_height = 300; if (block) { @@ -694,7 +706,7 @@ namespace Pamac { var dialog = new Gtk.Dialog.with_buttons (message, application_window, flags); - dialog.border_width = 6; + dialog.border_width = 3; dialog.icon_name = "system-software-install"; var textbuffer = new StringBuilder (); if (details.length != 0) { @@ -723,6 +735,7 @@ namespace Pamac { scrolledwindow.expand = true; unowned Gtk.Box box = dialog.get_content_area (); box.add (scrolledwindow); + box.spacing = 6; dialog.default_width = 600; dialog.default_height = 300; Timeout.add (1000, () => { @@ -754,7 +767,6 @@ namespace Pamac { } else { warning_textbuffer = new StringBuilder (); } - transaction_summary.remove_all (); reset_progress_box (); show_details (""); } diff --git a/src/transaction_sum_dialog.vala b/src/transaction_sum_dialog.vala index f2d8330e..7da292c6 100644 --- a/src/transaction_sum_dialog.vala +++ b/src/transaction_sum_dialog.vala @@ -28,6 +28,8 @@ namespace Pamac { Gtk.TreeView treeview; [GtkChild] public Gtk.Button edit_button; + [GtkChild] + public Gtk.Button cancel_button; public Gtk.ListStore sum_list; -- GitLab