diff --git a/examples/pactree.vala b/examples/pactree.vala index d738d7f28af6494fb8eaa72b4d0053fc1ebc7e2d..a76c69d6076f85cfd1a9692f46da101800540778 100644 --- a/examples/pactree.vala +++ b/examples/pactree.vala @@ -18,7 +18,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -// Compile with: valac --pkg=libalpm --vapidir=../vapi --Xcc=-I../util ../util/alpm-util.c pactree.vala -o pactree +// Compile with: valac --pkg=libalpm --vapidir=../vapi pactree.vala using Alpm; @@ -37,10 +37,10 @@ string leaf2_color; string color_off; /* globals */ -unowned Handle? handle; +Handle handle; unowned DB localdb; -Alpm.List<string?> walked = null; -Alpm.List<string?> provisions = null; +Alpm.List<string> walked; +Alpm.List<string> provisions; /* options */ bool color; @@ -127,7 +127,7 @@ static int parse_options(ref unowned string[] args) { static void local_init() { Alpm.Errno error; - handle = Handle.new ("/", dbpath, out error); + handle = new Handle ("/", dbpath, out error); assert (error == 0); localdb = handle.localdb; assert (localdb != null); @@ -187,11 +187,11 @@ static void walk_reverse_deps(Package pkg, int depth) { if((max_depth >= 0) && (depth > max_depth)) return; walked.add(pkg.name); - Alpm.List<string?> *required_by = pkg.compute_requiredby(); + Alpm.List<string> required_by = pkg.compute_requiredby(); - int i = 0; - while (i < required_by->length) { - string? pkgname = required_by->nth_data(i); + unowned Alpm.List<string> list = required_by; + while (list != null) { + unowned string pkgname = list.data; if (walked.find_str(pkgname) != null) { /* if we've already seen this package, don't print in "unique" output * and don't recurse */ @@ -202,9 +202,9 @@ static void walk_reverse_deps(Package pkg, int depth) { print(pkg.name, pkgname, null, depth); walk_reverse_deps(localdb.get_pkg(pkgname), depth + 1); } - i++; + list.next (); } - Alpm.List.free_all(required_by); + required_by.free_inner(GLib.free); } /** @@ -216,8 +216,10 @@ static void walk_deps(Package pkg, int depth) walked.add(pkg.name); - foreach (unowned Depend depend in pkg.depends) { - string depname = depend.name; + unowned Alpm.List<unowned Depend> depends = pkg.depends; + while (depends != null) { + unowned Alpm.Depend depend = depends.data; + unowned string depname = depend.name; unowned Package? provider = find_satisfier (localdb.pkgcache, depname); if (provider != null) { @@ -237,6 +239,7 @@ static void walk_deps(Package pkg, int depth) /* unresolvable package */ print(pkg.name, null, depname, depth); } + depends.next (); } } diff --git a/po/pamac.pot b/po/pamac.pot index f987d85124d879122f57d8bf18410cc3e6a4d1a5..dfe17732fd5652fb5cd92d96b08d4273af93f74f 100644 --- a/po/pamac.pot +++ b/po/pamac.pot @@ -21,7 +21,7 @@ msgstr "" msgid "Authentication is required" msgstr "" -#: ../src/daemon.vala ../src/transaction.vala +#: ../src/daemon.vala msgid "Failed to initialize alpm library" msgstr "" @@ -29,6 +29,26 @@ msgstr "" msgid "Failed to synchronize any databases" msgstr "" +#: ../src/daemon.vala +msgid "Unknown" +msgstr "" + +#: ../src/daemon.vala +msgid "Explicitly installed" +msgstr "" + +#: ../src/daemon.vala +msgid "Installed as a dependency for another package" +msgstr "" + +#: ../src/daemon.vala +msgid "Yes" +msgstr "" + +#: ../src/daemon.vala +msgid "No" +msgstr "" + #: ../src/daemon.vala msgid "Failed to init transaction" msgstr "" @@ -120,7 +140,7 @@ msgstr "" msgid "Transaction Summary" msgstr "" -#: ../src/transaction.vala ../src/manager_window.vala +#: ../src/transaction.vala msgid "To remove" msgstr "" @@ -132,7 +152,7 @@ msgstr "" msgid "To build" msgstr "" -#: ../src/transaction.vala ../src/manager_window.vala +#: ../src/transaction.vala msgid "To install" msgstr "" @@ -153,11 +173,7 @@ msgid "Building packages" msgstr "" #: ../src/transaction.vala -msgid "Running pre-transaction hooks" -msgstr "" - -#: ../src/transaction.vala -msgid "Running post-transaction hooks" +msgid "Transaction cancelled" msgstr "" #: ../src/transaction.vala @@ -183,36 +199,28 @@ msgstr "" #: ../src/transaction.vala #, c-format -msgid "Reinstalling %s" +msgid "Upgrading %s" msgstr "" #: ../src/transaction.vala #, c-format -msgid "Removing %s" +msgid "Reinstalling %s" msgstr "" #: ../src/transaction.vala #, c-format -msgid "Upgrading %s" +msgid "Downgrading %s" msgstr "" #: ../src/transaction.vala #, c-format -msgid "Downgrading %s" +msgid "Removing %s" msgstr "" #: ../src/transaction.vala msgid "Checking integrity" msgstr "" -#: ../src/transaction.vala -msgid "Checking keyring" -msgstr "" - -#: ../src/transaction.vala -msgid "Downloading required keys" -msgstr "" - #: ../src/transaction.vala msgid "Loading packages files" msgstr "" @@ -247,6 +255,11 @@ msgstr "" msgid "Downloading" msgstr "" +#: ../src/transaction.vala +#, c-format +msgid "Downloading %s" +msgstr "" + #: ../src/transaction.vala msgid "Checking available disk space" msgstr "" @@ -261,6 +274,14 @@ msgstr "" msgid "Database file for %s does not exist" msgstr "" +#: ../src/transaction.vala +msgid "Checking keyring" +msgstr "" + +#: ../src/transaction.vala +msgid "Downloading required keys" +msgstr "" + #: ../src/transaction.vala #, c-format msgid "%s installed as %s.pacnew" @@ -272,13 +293,11 @@ msgid "%s installed as %s.pacsave" msgstr "" #: ../src/transaction.vala -#, c-format -msgid "Refreshing %s" +msgid "Running pre-transaction hooks" msgstr "" #: ../src/transaction.vala -#, c-format -msgid "Downloading %s" +msgid "Running post-transaction hooks" msgstr "" #: ../src/transaction.vala @@ -294,7 +313,8 @@ msgstr[0] "" msgstr[1] "" #: ../src/transaction.vala -msgid "Warning" +#, c-format +msgid "Refreshing %s" msgstr "" #: ../src/transaction.vala @@ -302,7 +322,7 @@ msgid "Error" msgstr "" #: ../src/transaction.vala -msgid "Transaction cancelled" +msgid "Warning" msgstr "" #: ../src/transaction.vala @@ -369,8 +389,11 @@ msgid "Mark as explicitly installed" msgstr "" #: ../src/manager_window.vala -msgid "local" -msgstr "" +#, c-format +msgid "%u pending operation" +msgid_plural "%u pending operations" +msgstr[0] "" +msgstr[1] "" #: ../src/manager_window.vala msgid "Installed" @@ -381,95 +404,76 @@ msgid "Orphans" msgstr "" #: ../src/manager_window.vala -msgid "Licenses" -msgstr "" - -#: ../src/manager_window.vala -msgid "Unknown" -msgstr "" - -#: ../src/manager_window.vala -msgid "Depends On" +msgid "Foreign" msgstr "" #: ../src/manager_window.vala -msgid "Optional Dependencies" -msgstr "" - -#: ../src/manager_window.vala -msgid "Required By" +msgid "Pending" msgstr "" #: ../src/manager_window.vala -msgid "Optional For" +msgid "Licenses" msgstr "" -#: ../src/manager_window.vala -msgid "Provides" +#: ../src/manager_window.vala ../resources/manager_window.ui +#: ../resources/updater_window.ui +msgid "Repository" msgstr "" -#: ../src/manager_window.vala -msgid "Replaces" +#: ../src/manager_window.vala ../resources/manager_window.ui +msgid "Groups" msgstr "" #: ../src/manager_window.vala -msgid "Conflicts With" +msgid "Packager" msgstr "" #: ../src/manager_window.vala -msgid "Make Dependencies" +msgid "Build Date" msgstr "" #: ../src/manager_window.vala -msgid "Check Dependencies" -msgstr "" - -#: ../src/manager_window.vala ../resources/manager_window.ui -msgid "Repository" -msgstr "" - -#: ../src/manager_window.vala ../resources/manager_window.ui -msgid "Groups" +msgid "Install Date" msgstr "" #: ../src/manager_window.vala -msgid "Packager" +msgid "Install Reason" msgstr "" #: ../src/manager_window.vala -msgid "Build Date" +msgid "Signatures" msgstr "" #: ../src/manager_window.vala -msgid "Install Date" +msgid "Backup files" msgstr "" #: ../src/manager_window.vala -msgid "Explicitly installed" +msgid "Depends On" msgstr "" #: ../src/manager_window.vala -msgid "Installed as a dependency for another package" +msgid "Optional Dependencies" msgstr "" #: ../src/manager_window.vala -msgid "Install Reason" +msgid "Required By" msgstr "" #: ../src/manager_window.vala -msgid "Yes" +msgid "Optional For" msgstr "" #: ../src/manager_window.vala -msgid "No" +msgid "Provides" msgstr "" #: ../src/manager_window.vala -msgid "Signatures" +msgid "Replaces" msgstr "" #: ../src/manager_window.vala -msgid "Backup files" +msgid "Conflicts With" msgstr "" #: ../src/manager_window.vala @@ -488,7 +492,7 @@ msgstr "" msgid "Last Modified" msgstr "" -#: ../src/manager_window.vala ../resources/manager_window.ui +#: ../src/manager_window.vala msgid "Votes" msgstr "" @@ -496,6 +500,11 @@ msgstr "" msgid "Out of Date" msgstr "" +#: ../src/manager_window.vala ../resources/manager_window.ui +#: ../resources/updater_window.ui +msgid "Name" +msgstr "" + #: ../src/manager_window.vala #, c-format msgid "" @@ -507,17 +516,13 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: ../src/manager_window.vala -msgid "Uninstalled" -msgstr "" - #: ../src/manager_window.vala ../resources/manager_window.ui msgid "Install Local Packages" msgstr "" #: ../src/manager_window.vala ../resources/progress_dialog.ui #: ../resources/transaction_sum_dialog.ui ../resources/choose_dep_dialog.ui -#: ../resources/choose_ignorepkgs_dialog.ui +#: ../resources/manager_window.ui ../resources/choose_ignorepkgs_dialog.ui msgid "_Cancel" msgstr "" @@ -571,10 +576,8 @@ msgstr "" msgid "Progress" msgstr "" -#: ../resources/progress_dialog.ui ../resources/history_dialog.ui -#: ../resources/transaction_info_dialog.ui ../resources/updater_window.ui -#: ../resources/preferences_dialog.ui -msgid "_Close" +#: ../resources/progress_dialog.ui +msgid "_Hide" msgstr "" #: ../resources/progress_dialog.ui ../resources/transaction_info_dialog.ui @@ -586,6 +589,11 @@ msgstr "" msgid "Pamac History" msgstr "" +#: ../resources/history_dialog.ui ../resources/transaction_info_dialog.ui +#: ../resources/updater_window.ui ../resources/preferences_dialog.ui +msgid "_Close" +msgstr "" + #: ../resources/choose_dep_dialog.ui msgid "Choose Optional Dependencies" msgstr "" @@ -606,14 +614,6 @@ msgstr "" msgid "Refresh databases" msgstr "" -#: ../resources/manager_window.ui -msgid "Apply changes" -msgstr "" - -#: ../resources/manager_window.ui -msgid "Cancel all planned changes" -msgstr "" - #: ../resources/manager_window.ui msgid "Search in AUR" msgstr "" @@ -622,7 +622,7 @@ msgstr "" msgid "Search" msgstr "" -#: ../resources/manager_window.ui +#: ../resources/manager_window.ui ../resources/updater_window.ui msgid "State" msgstr "" @@ -630,16 +630,16 @@ msgstr "" msgid "Repositories" msgstr "" -#: ../resources/manager_window.ui -msgid "Name" +#: ../resources/manager_window.ui ../resources/updater_window.ui +msgid "Version" msgstr "" -#: ../resources/manager_window.ui -msgid "Version" +#: ../resources/manager_window.ui ../resources/updater_window.ui +msgid "Size" msgstr "" #: ../resources/manager_window.ui -msgid "Size" +msgid "Popularity" msgstr "" #: ../resources/manager_window.ui ../resources/updater_window.ui @@ -647,8 +647,12 @@ msgstr "" msgid "AUR" msgstr "" +#: ../resources/manager_window.ui ../resources/updater_window.ui +msgid "_Apply" +msgstr "" + #: ../resources/manager_window.ui -msgid "Description" +msgid "Browse" msgstr "" #: ../resources/manager_window.ui @@ -663,10 +667,6 @@ msgstr "" msgid "_Refresh" msgstr "" -#: ../resources/updater_window.ui -msgid "_Apply" -msgstr "" - #: ../resources/preferences_dialog.ui msgid "Preferences" msgstr "" @@ -689,6 +689,10 @@ msgstr "" msgid "Check for updates" msgstr "" +#: ../resources/preferences_dialog.ui +msgid "6" +msgstr "" + #: ../resources/preferences_dialog.ui msgid "Hide tray icon when no update available" msgstr "" diff --git a/resources/Makefile b/resources/Makefile index 898cd7c5da9d31f8f6aa65284d0ed91c7f5774b9..ba1e352449f6a258457347fda9479e333c0470f0 100644 --- a/resources/Makefile +++ b/resources/Makefile @@ -3,6 +3,7 @@ MANAGER_RESOURCES_FILES = manager_window.ui \ choose_dep_dialog.ui \ history_dialog.ui \ package-available.png \ + package-available-locked.png \ package-install.png \ package-installed-locked.png \ package-installed-updated.png \ diff --git a/resources/choose_dep_dialog.ui b/resources/choose_dep_dialog.ui index 5262dc0792c46578501302681ad1026dfba5c0a6..e98fb2bc76ecc23c6fb0fe50650dd964de05be96 100644 --- a/resources/choose_dep_dialog.ui +++ b/resources/choose_dep_dialog.ui @@ -1,13 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.19.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacChooseDependenciesDialog" parent="GtkDialog"> + <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Choose Optional Dependencies</property> <property name="modal">True</property> <property name="window_position">center-on-parent</property> <property name="icon_name">system-software-install</property> <property name="type_hint">dialog</property> + <property name="urgency_hint">True</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> <property name="can_focus">False</property> @@ -23,25 +26,28 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> - <property name="use_underline">True</property> <property name="receives_default">False</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">_OK</property> - <property name="use_underline">True</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> @@ -49,6 +55,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> + <property name="position">0</property> </packing> </child> <child> @@ -59,6 +66,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> @@ -112,6 +120,7 @@ <packing> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/resources/choose_ignorepkgs_dialog.ui b/resources/choose_ignorepkgs_dialog.ui index d8ce4a794dc861dc103d07aef65d65b5020aaf68..472f70098a266088dae4f4abee87a4d6e5cae8da 100644 --- a/resources/choose_ignorepkgs_dialog.ui +++ b/resources/choose_ignorepkgs_dialog.ui @@ -10,6 +10,7 @@ <property name="window_position">center-on-parent</property> <property name="icon_name">system-software-install</property> <property name="type_hint">dialog</property> + <property name="urgency_hint">True</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> <property name="can_focus">False</property> diff --git a/resources/choose_provider_dialog.ui b/resources/choose_provider_dialog.ui index 42ee77d5e9d85727a4b9ee1290ca581b88a089ca..f5caa288f4b26041db3f78fad084000d49c047f7 100644 --- a/resources/choose_provider_dialog.ui +++ b/resources/choose_provider_dialog.ui @@ -1,13 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.19.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacChooseProviderDialog" parent="GtkDialog"> + <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Choose a Provider</property> <property name="modal">True</property> <property name="window_position">center-on-parent</property> <property name="icon_name">system-software-install</property> <property name="type_hint">dialog</property> + <property name="urgency_hint">True</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox2"> <property name="can_focus">False</property> @@ -20,14 +23,16 @@ <child> <object class="GtkButton" id="valid_button"> <property name="label" translatable="yes">_OK</property> - <property name="use_underline">True</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">0</property> </packing> </child> </object> @@ -35,6 +40,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> + <property name="position">0</property> </packing> </child> <child> @@ -52,6 +58,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> @@ -62,12 +69,14 @@ <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> </object> diff --git a/resources/history_dialog.ui b/resources/history_dialog.ui index d922853d7f4d6ef3ab988c2c61dcd6c0b2079f4d..688087b51793f1068bb1ecb021199afa321f7018 100644 --- a/resources/history_dialog.ui +++ b/resources/history_dialog.ui @@ -1,9 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacHistoryDialog" parent="GtkDialog"> + <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Pamac History</property> + <property name="window_position">center-on-parent</property> <property name="default_width">600</property> <property name="default_height">500</property> <property name="icon_name">system-software-install</property> @@ -20,14 +23,16 @@ <child> <object class="GtkButton" id="close_button"> <property name="label" translatable="yes">_Close</property> - <property name="use_underline">True</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> + <property name="receives_default">False</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> </object> @@ -35,6 +40,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> + <property name="position">0</property> </packing> </child> <child> @@ -58,6 +64,7 @@ <packing> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> diff --git a/resources/manager_window.ui b/resources/manager_window.ui index d7950d86c2638e8130c9aa1d07e5abd9796c3c61..968b4331dbdb47c7f987395b6c98991ef5102c0a 100644 --- a/resources/manager_window.ui +++ b/resources/manager_window.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.19.0 --> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.12"/> <object class="GtkMenu" id="main_menu"> @@ -44,173 +44,119 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="title" translatable="yes">Package Manager</property> - <property name="window_position">center</property> <property name="default_height">600</property> <property name="icon_name">system-software-install</property> + <property name="gravity">center</property> <child> - <object class="GtkBox" id="box0"> + <object class="GtkStack" id="main_stack"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="transition_type">slide-left-right</property> <child> - <object class="GtkBox" id="box1"> + <object class="GtkBox" id="box2"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="spacing">6</property> + <property name="orientation">vertical</property> + <property name="spacing">3</property> <child> - <object class="GtkButton" id="refresh_button"> + <object class="GtkBox" id="box1"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip_text" translatable="yes">Refresh databases</property> - <signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkImage" id="refresh_icon"> + <object class="GtkButton" id="refresh_button"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="icon_name">view-refresh-symbolic</property> - <property name="icon_size">1</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Refresh databases</property> + <signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/> + <child> + <object class="GtkImage" id="refresh_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">view-refresh-symbolic</property> + <property name="icon_size">1</property> + </object> + </child> + <style> + <class name="image-button"/> + </style> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> - <style> - <class name="image-button"/> - </style> - </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="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip_text" translatable="yes">Apply changes</property> - <signal name="clicked" handler="on_valid_button_clicked" swapped="no"/> <child> - <object class="GtkImage" id="valid_icon"> + <object class="GtkMenuButton" id="menu_button"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="icon_name">emblem-ok-symbolic</property> - <property name="icon_size">1</property> - </object> - </child> - <style> - <class name="image-button"/> - </style> - </object> - <packing> - <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="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip_text" translatable="yes">Cancel all planned changes</property> - <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/> - <child> - <object class="GtkImage" id="cancel_icon"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="icon_name">edit-delete-symbolic</property> - <property name="icon_size">1</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="popup">main_menu</property> + <child> + <object class="GtkImage" id="menu_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">emblem-system-symbolic</property> + <property name="icon_size">1</property> + </object> + </child> + <style> + <class name="image-button"/> + </style> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">3</property> + </packing> </child> - <style> - <class name="image-button"/> - </style> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">2</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkMenuButton" id="menu_button"> + <object class="GtkStackSwitcher" id="filters_stackswitcher"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="popup">main_menu</property> - <child> - <object class="GtkImage" id="menu_icon"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="icon_name">emblem-system-symbolic</property> - <property name="icon_size">1</property> - </object> - </child> - <style> - <class name="image-button"/> - </style> + <property name="can_focus">False</property> + <property name="stack">filters_stack</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">3</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="GtkPaned" id="paned1"> - <property name="visible">True</property> - <property name="can_focus">True</property> <child> - <object class="GtkNotebook" id="filters_notebook"> + <object class="GtkBox" id="box3"> <property name="visible">True</property> - <property name="can_focus">True</property> - <signal name="switch-page" handler="on_filters_notebook_switch_page" after="yes" swapped="no"/> + <property name="can_focus">False</property> + <property name="spacing">3</property> <child> - <object class="GtkBox" id="box3"> + <object class="GtkStack" id="filters_stack"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkSearchEntry" id="search_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="receives_default">True</property> - <property name="caps_lock_warning">False</property> - <property name="primary_icon_name">edit-find-symbolic</property> - <signal name="activate" handler="on_search_entry_activate" swapped="no"/> - <signal name="changed" handler="on_search_entry_changed" swapped="no"/> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> <child> - <object class="GtkBox" id="search_aur_box"> + <object class="GtkBox" id="box5"> + <property name="width_request">200</property> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="spacing">12</property> - <property name="homogeneous">True</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> <child> - <object class="GtkLabel" id="search_aur_label"> + <object class="GtkSearchEntry" id="search_entry"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_start">6</property> - <property name="hexpand">True</property> - <property name="label" translatable="yes">Search in AUR</property> - <property name="xalign">0</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="caps_lock_warning">False</property> + <property name="primary_icon_name">edit-find-symbolic</property> + <signal name="activate" handler="on_search_entry_activate" swapped="no"/> + <signal name="changed" handler="on_search_entry_changed" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -219,11 +165,39 @@ </packing> </child> <child> - <object class="GtkSwitch" id="search_aur_button"> + <object class="GtkBox" id="search_aur_box"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="tooltip_text" translatable="yes">Search in AUR</property> - <property name="halign">end</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="search_aur_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_start">6</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">Search in AUR</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="GtkSwitch" id="search_aur_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">Search in AUR</property> + <property name="halign">end</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> @@ -231,20 +205,59 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="search_treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="headers_clickable">False</property> + <property name="enable_search">False</property> + <property name="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="search_treeview_selection"> + <signal name="changed" handler="on_search_treeview_selection_changed" after="yes" swapped="no"/> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="Terms"> + <child> + <object class="GtkCellRendererText" id="cellrenderertext8"/> + <attributes> + <attribute name="text">0</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> + <child> + <placeholder/> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> + <property name="name">search</property> + <property name="title" translatable="yes">Search</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="scrolledwindow3"> + <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="shadow_type">in</property> <child> - <object class="GtkTreeView" id="search_treeview"> + <object class="GtkTreeView" id="groups_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="headers_visible">False</property> @@ -252,14 +265,14 @@ <property name="enable_search">False</property> <property name="show_expanders">False</property> <child internal-child="selection"> - <object class="GtkTreeSelection" id="search_treeview_selection"> - <signal name="changed" handler="on_search_treeview_selection_changed" after="yes" swapped="no"/> + <object class="GtkTreeSelection" id="groups_treeview_selection"> + <signal name="changed" handler="on_groups_treeview_selection_changed" after="yes" swapped="no"/> </object> </child> <child> - <object class="GtkTreeViewColumn" id="Terms"> + <object class="GtkTreeViewColumn" id="Groups"> <child> - <object class="GtkCellRendererText" id="cellrenderertext8"/> + <object class="GtkCellRendererText" id="cellrenderertext2"/> <attributes> <attribute name="text">0</attribute> </attributes> @@ -270,561 +283,622 @@ </child> </object> <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> + <property name="name">groups</property> + <property name="title" translatable="yes">Groups</property> + <property name="position">1</property> </packing> </child> - </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="tab1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Search</property> - </object> - <packing> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> <child> - <object class="GtkTreeView" id="groups_treeview"> + <object class="GtkScrolledWindow" id="scrolledwindow2"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="enable_search">False</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="groups_treeview_selection"> - <signal name="changed" handler="on_groups_treeview_selection_changed" after="yes" swapped="no"/> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="states_treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="headers_clickable">False</property> + <property name="enable_search">False</property> + <property name="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="states_treeview_selection"> + <signal name="changed" handler="on_states_treeview_selection_changed" after="yes" swapped="no"/> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="State"> + <child> + <object class="GtkCellRendererText" id="cellrenderertext9"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> </object> </child> + </object> + <packing> + <property name="name">states</property> + <property name="title" translatable="yes">State</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow8"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> <child> - <object class="GtkTreeViewColumn" id="Groups"> + <object class="GtkTreeView" id="repos_treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="headers_clickable">False</property> + <property name="enable_search">False</property> + <property name="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="repos_treeview_selection"> + <signal name="changed" handler="on_repos_treeview_selection_changed" after="yes" swapped="no"/> + </object> + </child> <child> - <object class="GtkCellRendererText" id="cellrenderertext2"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> + <object class="GtkTreeViewColumn" id="Repos"> + <child> + <object class="GtkCellRendererText" id="cellrenderertext10"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> </child> </object> </child> </object> + <packing> + <property name="name">repos</property> + <property name="title" translatable="yes">Repositories</property> + <property name="position">3</property> + </packing> </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="tab2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Groups</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> - </packing> - </child> <child> - <object class="GtkScrolledWindow" id="scrolledwindow2"> + <object class="GtkBox" id="box7"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">3</property> <child> - <object class="GtkTreeView" id="states_treeview"> + <object class="GtkStackSwitcher" id="packages_stackswitcher"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="enable_search">False</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="states_treeview_selection"> - <signal name="changed" handler="on_states_treeview_selection_changed" after="yes" swapped="no"/> + <property name="can_focus">False</property> + <property name="stack">packages_stack</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkStack" id="packages_stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <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="hexpand">True</property> + <property name="vexpand">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="packages_treeview"> + <property name="visible">True</property> + <property name="can_focus">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_packages_treeview_button_press_event" 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> + <child> + <object class="GtkTreeViewColumn" id="packages_state_column"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">40</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="sizing">fixed</property> + <property name="fixed_width">200</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="GtkCellRendererText" id="packages_name_renderertext"> + <property name="wrap_mode">word</property> + </object> + <attributes> + <attribute name="markup">2</attribute> + </attributes> + </child> + </object> + </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="text">3</attribute> + </attributes> + </child> + </object> + </child> + <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> + </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> + </child> + </object> + </child> </object> + <packing> + <property name="name">repos</property> + <property name="title" translatable="yes">Repositories</property> + </packing> </child> <child> - <object class="GtkTreeViewColumn" id="State"> + <object class="GtkScrolledWindow" id="aur_scrolledwindow"> + <property name="width_request">500</property> + <property name="height_request">200</property> + <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> <child> - <object class="GtkCellRendererText" id="cellrenderertext9"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> + <object class="GtkTreeView" id="aur_treeview"> + <property name="visible">True</property> + <property name="can_focus">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> + <property name="enable_grid_lines">horizontal</property> + <signal name="button-press-event" handler="on_aur_treeview_button_press_event" 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> + <child> + <object class="GtkTreeViewColumn" id="aur_state_column"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">40</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="sizing">fixed</property> + <property name="fixed_width">200</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="GtkCellRendererText" id="aur_name_renderertext"> + <property name="wrap_mode">word</property> + </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="text">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">90</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="title" translatable="yes">AUR</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> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="tab3"> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkBox" id="transaction_infobox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="transaction_infos_label"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">State</property> + <property name="halign">start</property> + <property name="margin_left">6</property> </object> <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="scrolledwindow8"> + <object class="GtkButtonBox" id="transaction_infos_buttonbox"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <property name="homogeneous">True</property> + <property name="layout_style">start</property> <child> - <object class="GtkTreeView" id="repos_treeview"> + <object class="GtkButton" id="transaction_infos_details_button"> + <property name="label" translatable="yes">Details</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="enable_search">False</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="repos_treeview_selection"> - <signal name="changed" handler="on_repos_treeview_selection_changed" after="yes" swapped="no"/> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="Repos"> - <child> - <object class="GtkCellRendererText" id="cellrenderertext10"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> + <property name="receives_default">True</property> + <signal name="clicked" handler="on_transaction_infos_details_button_clicked" swapped="no"/> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="transaction_infos_apply_button"> + <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="use_underline">True</property> + <property name="yalign">0.55000001192092896</property> + <signal name="clicked" handler="on_transaction_infos_apply_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="transaction_infos_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> + <signal name="clicked" handler="on_transaction_infos_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="position">3</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="tab4"> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + </object> + <packing> + <property name="name">browse</property> + <property name="title" translatable="yes">Browse</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkButton" id="button_back"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <signal name="clicked" handler="on_button_back_clicked" swapped="no"/> + <child> + <object class="GtkImage" id="back_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Repositories</property> + <property name="icon_name">go-previous-symbolic</property> + <property name="icon_size">1</property> </object> - <packing> - <property name="position">3</property> - <property name="tab_fill">False</property> - </packing> </child> + <style> + <class name="image-button"/> + </style> </object> <packing> - <property name="resize">False</property> - <property name="shrink">False</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkPaned" id="paned2"> + <object class="GtkBox" id="box6"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can_focus">False</property> <property name="orientation">vertical</property> + <property name="spacing">6</property> <child> - <object class="GtkNotebook" id="packages_notebook"> + <object class="GtkBox" id="box8"> <property name="visible">True</property> - <property name="can_focus">True</property> - <signal name="switch-page" handler="on_packages_notebook_switch_page" after="yes" swapped="no"/> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> <child> - <object class="GtkScrolledWindow" id="packages_scrolledwindow"> - <property name="width_request">500</property> - <property name="height_request">200</property> + <object class="GtkLabel" id="name_label"> <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> - <child> - <object class="GtkTreeView" id="packages_treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="search_column">0</property> - <property name="show_expanders">False</property> - <signal name="button-press-event" handler="on_packages_treeview_button_press_event" swapped="no"/> - <signal name="row-activated" handler="on_packages_treeview_row_activated" swapped="no"/> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection"> - <property name="mode">multiple</property> - <signal name="changed" handler="on_packages_treeview_selection_changed" swapped="no"/> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="packages_state_column"> - <property name="resizable">True</property> - <property name="fixed_width">40</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">State</property> - <property name="clickable">True</property> - <signal name="clicked" handler="on_packages_state_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererPixbuf" id="packages_state_rendererpixbuf"/> - <attributes> - <attribute name="pixbuf">1</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="packages_name_column"> - <property name="resizable">True</property> - <property name="fixed_width">150</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Name</property> - <property name="expand">True</property> - <property name="clickable">True</property> - <signal name="clicked" handler="on_packages_name_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="packages_name_renderertext"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="packages_version_column"> - <property name="resizable">True</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> - <signal name="clicked" handler="on_packages_version_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="packages_version_renderertext"/> - <attributes> - <attribute name="text">2</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="packages_repo_column"> - <property name="resizable">True</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> - <signal name="clicked" handler="on_packages_repo_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="packages_repo_renderertext"/> - <attributes> - <attribute name="text">3</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="packages_size_column"> - <property name="resizable">True</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> - <signal name="clicked" handler="on_packages_size_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="packages_size_renderertext"/> - <attributes> - <attribute name="text">4</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_start">6</property> + <property name="margin_end">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> + <property name="selectable">True</property> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="label1"> + <child> + <object class="GtkLabel" id="desc_label"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Repositories</property> + <property name="halign">start</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_start">6</property> + <property name="margin_end">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> + <property name="selectable">True</property> </object> <packing> - <property name="tab_fill">False</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="aur_scrolledwindow"> - <property name="width_request">500</property> - <property name="height_request">200</property> + <object class="GtkLabel" id="link_label"> <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> - <child> - <object class="GtkTreeView" id="aur_treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="search_column">0</property> - <property name="show_expanders">False</property> - <signal name="button-press-event" handler="on_aur_treeview_button_press_event" swapped="no"/> - <signal name="row-activated" handler="on_aur_treeview_row_activated" swapped="no"/> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection12"> - <property name="mode">multiple</property> - <signal name="changed" handler="on_aur_treeview_selection_changed" swapped="no"/> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="aur_state_column"> - <property name="resizable">True</property> - <property name="fixed_width">40</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">State</property> - <property name="clickable">True</property> - <signal name="clicked" handler="on_aur_state_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererPixbuf" id="aur_state_rendererpixbuf"/> - <attributes> - <attribute name="pixbuf">1</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="aur_name_column"> - <property name="resizable">True</property> - <property name="fixed_width">150</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Name</property> - <property name="expand">True</property> - <property name="clickable">True</property> - <signal name="clicked" handler="on_aur_name_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="aur_name_renderertext"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="aur_version_column"> - <property name="resizable">True</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> - <signal name="clicked" handler="on_aur_version_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="aur_version_renderertext"/> - <attributes> - <attribute name="text">2</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="aur_votes_column"> - <property name="resizable">True</property> - <property name="fixed_width">90</property> - <property name="min_width">20</property> - <property name="title" translatable="yes">Votes</property> - <property name="clickable">True</property> - <signal name="clicked" handler="on_aur_votes_column_clicked" swapped="no"/> - <child> - <object class="GtkCellRendererText" id="aur_votes_renderertext"/> - <attributes> - <attribute name="text">3</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_start">6</property> + <property name="margin_end">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> </object> <packing> - <property name="position">1</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="label5"> + <child> + <object class="GtkLabel" id="licenses_label"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">AUR</property> + <property name="halign">start</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_start">6</property> + <property name="margin_end">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> + <property name="selectable">True</property> </object> <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> </packing> </child> </object> <packing> - <property name="resize">True</property> - <property name="shrink">True</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkNotebook" id="properties_notebook"> - <property name="width_request">500</property> - <property name="height_request">150</property> + <object class="GtkStackSwitcher" id="properties_stackswitcher"> <property name="visible">True</property> - <property name="can_focus">True</property> - <signal name="switch-page" handler="on_properties_notebook_switch_page" after="yes" swapped="no"/> - <child> - <object class="GtkScrolledWindow" id="infos_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkViewport" id="viewport2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkBox" id="box4"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="name_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="margin_left">6</property> - <property name="margin_right">6</property> - <property name="margin_start">6</property> - <property name="margin_end">6</property> - <property name="margin_top">6</property> - <property name="margin_bottom">6</property> - <property name="selectable">True</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="halign">start</property> - <property name="margin_left">6</property> - <property name="margin_right">6</property> - <property name="margin_start">6</property> - <property name="margin_end">6</property> - <property name="margin_top">6</property> - <property name="margin_bottom">6</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="link_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="margin_left">6</property> - <property name="margin_right">6</property> - <property name="margin_start">6</property> - <property name="margin_end">6</property> - <property name="margin_top">6</property> - <property name="margin_bottom">6</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="licenses_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="margin_left">6</property> - <property name="margin_right">6</property> - <property name="margin_start">6</property> - <property name="margin_end">6</property> - <property name="margin_top">6</property> - <property name="margin_bottom">6</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">3</property> - </packing> - </child> - </object> - </child> - </object> - </child> - </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Description</property> - </object> - <packing> - <property name="tab_fill">False</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="stack">properties_stack</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkStack" id="properties_stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <object class="GtkScrolledWindow" id="deps_scrolledwindow"> + <object class="GtkScrolledWindow" id="details_scrolledwindow"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="shadow_type">in</property> <child> - <object class="GtkTreeView" id="deps_treeview"> + <object class="GtkTreeView" id="details_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="headers_visible">False</property> <property name="headers_clickable">False</property> <property name="enable_search">False</property> + <property name="search_column">0</property> <property name="show_expanders">False</property> <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection8"> + <object class="GtkTreeSelection" id="treeview-selection9"> <property name="mode">none</property> </object> </child> <child> - <object class="GtkTreeViewColumn" id="dep_type"> + <object class="GtkTreeViewColumn" id="infotype"> <property name="sizing">autosize</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext3"> + <object class="GtkCellRendererText" id="cellrenderertext6"> <property name="yalign">0</property> - <property name="weight">600</property> + <property name="wrap_mode">word</property> </object> <attributes> - <attribute name="text">0</attribute> + <attribute name="markup">0</attribute> </attributes> </child> </object> </child> <child> - <object class="GtkTreeViewColumn" id="deps"> + <object class="GtkTreeViewColumn" id="info"> <property name="sizing">autosize</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext5"/> + <object class="GtkCellRendererText" id="cellrenderertext7"> + <property name="wrap_mode">word</property> + </object> <attributes> <attribute name="text">1</attribute> </attributes> @@ -835,61 +909,46 @@ </child> </object> <packing> - <property name="position">1</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="label8"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Dependencies</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> + <property name="name">details</property> + <property name="title" translatable="yes">Details</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="details_scrolledwindow"> + <object class="GtkScrolledWindow" id="deps_scrolledwindow"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="shadow_type">in</property> <child> - <object class="GtkTreeView" id="details_treeview"> + <object class="GtkTreeView" id="deps_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="headers_visible">False</property> <property name="headers_clickable">False</property> <property name="enable_search">False</property> - <property name="search_column">0</property> <property name="show_expanders">False</property> + <property name="activate_on_single_click">True</property> + <signal name="row-activated" handler="on_deps_treeview_row_activated" swapped="no"/> <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection10"> - <property name="mode">none</property> - </object> + <object class="GtkTreeSelection" id="deps_treeview_selection"/> </child> <child> - <object class="GtkTreeViewColumn" id="infotype"> + <object class="GtkTreeViewColumn" id="dep_type_treeview_column"> <property name="sizing">autosize</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext6"> + <object class="GtkCellRendererText" id="cellrenderertext3"> <property name="yalign">0</property> - <property name="weight">600</property> - <property name="wrap_mode">word</property> </object> <attributes> - <attribute name="text">0</attribute> + <attribute name="markup">0</attribute> </attributes> </child> </object> </child> <child> - <object class="GtkTreeViewColumn" id="info"> + <object class="GtkTreeViewColumn" id="deps_treeview_column"> <property name="sizing">autosize</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext7"> - <property name="wrap_mode">word</property> - </object> + <object class="GtkCellRendererText" id="cellrenderertext5"/> <attributes> <attribute name="text">1</attribute> </attributes> @@ -900,18 +959,9 @@ </child> </object> <packing> - <property name="position">2</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="label9"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Details</property> - </object> - <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> + <property name="name">deps</property> + <property name="title" translatable="yes">Dependencies</property> + <property name="position">1</property> </packing> </child> <child> @@ -933,36 +983,29 @@ </child> </object> <packing> - <property name="position">3</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="files_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Files</property> - </object> - <packing> - <property name="position">3</property> - <property name="tab_fill">False</property> + <property name="name">files</property> + <property name="title" translatable="yes">Files</property> + <property name="position">2</property> </packing> </child> </object> <packing> - <property name="resize">True</property> - <property name="shrink">False</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> </packing> </child> </object> <packing> - <property name="resize">True</property> - <property name="shrink">True</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> </packing> </child> </object> <packing> - <property name="expand">True</property> - <property name="fill">True</property> + <property name="name">details</property> + <property name="title" translatable="yes">Details</property> <property name="position">1</property> </packing> </child> diff --git a/resources/package-available-locked.png b/resources/package-available-locked.png new file mode 100644 index 0000000000000000000000000000000000000000..12e824e52f0443a01648453f850f2d366149312e Binary files /dev/null and b/resources/package-available-locked.png differ diff --git a/resources/pamac.manager.gresource.xml b/resources/pamac.manager.gresource.xml index e66adf513e5bc9cedd151a291db08352031bb3d5..bff4ac1b9b1fc138a00243b38ceebbe8cb352ff4 100644 --- a/resources/pamac.manager.gresource.xml +++ b/resources/pamac.manager.gresource.xml @@ -5,6 +5,7 @@ <file preprocess="xml-stripblanks">history_dialog.ui</file> <file preprocess="xml-stripblanks">choose_dep_dialog.ui</file> <file preprocess="to-pixdata">package-available.png</file> + <file preprocess="to-pixdata">package-available-locked.png</file> <file preprocess="to-pixdata">package-install.png</file> <file preprocess="to-pixdata">package-installed-locked.png</file> <file preprocess="to-pixdata">package-installed-updated.png</file> diff --git a/resources/preferences_dialog.ui b/resources/preferences_dialog.ui index cf77c790da3ca3f90dccf3ecb648cb0d466d0860..bf2615c37a37a2e01b35212f7399409e0be9c786 100644 --- a/resources/preferences_dialog.ui +++ b/resources/preferences_dialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.19.0 --> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.14"/> <object class="GtkAdjustment" id="adjustment"> @@ -9,19 +9,13 @@ <property name="step_increment">1</property> <property name="page_increment">10</property> </object> - <object class="GtkListStore" id="ignorepkgs_liststore"> - <columns> - <!-- column-name name --> - <column type="gchararray"/> - </columns> - </object> <template class="PamacPreferencesDialog" parent="GtkDialog"> <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Preferences</property> <property name="window_position">center-on-parent</property> <property name="icon_name">system-software-install</property> - <property name="type_hint">normal</property> + <property name="type_hint">dialog</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox"> <property name="can_focus">False</property> @@ -54,13 +48,28 @@ </packing> </child> <child> - <object class="GtkNotebook" id="notebook1"> + <object class="GtkStackSwitcher" id="stackswitcher"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="stack">stack</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkStack" id="stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> <child> <object class="GtkBox" id="general_config_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> <property name="margin_start">6</property> <property name="margin_end">6</property> <property name="margin_top">6</property> @@ -168,6 +177,7 @@ <object class="GtkSwitch" id="check_updates_button"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">Check for updates</property> <property name="halign">end</property> </object> <packing> @@ -192,6 +202,7 @@ <object class="GtkLabel" id="refresh_period_label"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_left">24</property> <property name="margin_start">24</property> <property name="hexpand">True</property> <property name="xalign">0</property> @@ -208,6 +219,7 @@ <property name="can_focus">True</property> <property name="tooltip_text" translatable="yes">How often to check for updates, value in hours</property> <property name="halign">end</property> + <property name="text" translatable="yes">6</property> <property name="caps_lock_warning">False</property> <property name="input_purpose">number</property> <property name="adjustment">adjustment</property> @@ -234,8 +246,10 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="margin_left">22</property> <property name="margin_start">22</property> <property name="hexpand">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> @@ -255,6 +269,7 @@ <property name="can_focus">False</property> <property name="halign">start</property> <property name="valign">start</property> + <property name="margin_left">26</property> <property name="margin_start">26</property> <property name="label" translatable="yes">Ignore upgrades for:</property> <property name="xalign">0</property> @@ -269,6 +284,7 @@ <object class="GtkBox" id="box10"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_left">12</property> <property name="margin_start">12</property> <property name="hexpand">True</property> <property name="vexpand">True</property> @@ -284,12 +300,11 @@ <object class="GtkTreeView" id="ignorepkgs_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="model">ignorepkgs_liststore</property> <property name="headers_visible">False</property> <property name="search_column">0</property> <property name="show_expanders">False</property> <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection1"/> + <object class="GtkTreeSelection" id="treeview-selection"/> </child> <child> <object class="GtkTreeViewColumn" id="treeviewcolumn1"> @@ -368,21 +383,17 @@ </packing> </child> </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="tab_label1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">General</property> - </object> <packing> - <property name="tab_fill">False</property> + <property name="name">general</property> + <property name="title" translatable="yes">General</property> </packing> </child> <child> <object class="GtkBox" id="mirrors_config_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> <property name="margin_start">6</property> <property name="margin_end">6</property> <property name="margin_top">6</property> @@ -483,20 +494,11 @@ </child> </object> <packing> + <property name="name">official_repositories</property> + <property name="title" translatable="yes">Official Repositories</property> <property name="position">1</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="tab_label2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Official Repositories</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> - </packing> - </child> <child> <object class="GtkBox" id="aur_config_box"> <property name="visible">True</property> @@ -568,6 +570,8 @@ All AUR users should be familiar with the build process.</property> <object class="GtkLabel" id="enable_aur_label"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> <property name="margin_start">6</property> <property name="margin_end">6</property> <property name="hexpand">True</property> @@ -586,6 +590,8 @@ All AUR users should be familiar with the build process.</property> <property name="can_focus">True</property> <property name="tooltip_text" translatable="yes">Allow Pamac to search and install packages from AUR</property> <property name="halign">end</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> <property name="margin_start">6</property> <property name="margin_end">6</property> </object> @@ -608,8 +614,10 @@ All AUR users should be familiar with the build process.</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="margin_left">24</property> <property name="margin_start">24</property> <property name="hexpand">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> @@ -624,8 +632,10 @@ All AUR users should be familiar with the build process.</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="margin_left">24</property> <property name="margin_start">24</property> <property name="hexpand">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> @@ -640,8 +650,10 @@ All AUR users should be familiar with the build process.</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="margin_left">24</property> <property name="margin_start">24</property> <property name="hexpand">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> @@ -652,25 +664,16 @@ All AUR users should be familiar with the build process.</property> </child> </object> <packing> + <property name="name">aur</property> + <property name="title" translatable="yes">AUR</property> <property name="position">2</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="tab_label3"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">AUR</property> - </object> - <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> - </packing> - </child> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/resources/progress_dialog.ui b/resources/progress_dialog.ui index 9691885666dec9a3976448ef71a31409709bd5d3..d5a171d734485ef5b61bfbaef5048d9a9c011155 100644 --- a/resources/progress_dialog.ui +++ b/resources/progress_dialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.19.0 --> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacProgressDialog" parent="GtkDialog"> @@ -7,11 +7,9 @@ <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Progress</property> - <property name="modal">True</property> <property name="window_position">center-on-parent</property> <property name="icon_name">system-software-install</property> <property name="type_hint">dialog</property> - <property name="deletable">False</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> <property name="visible">True</property> @@ -39,7 +37,7 @@ </child> <child> <object class="GtkButton" id="close_button"> - <property name="label" translatable="yes">_Close</property> + <property name="label" translatable="yes">_Hide</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> diff --git a/resources/transaction_info_dialog.ui b/resources/transaction_info_dialog.ui index 31287c8f67974da2e393ece040bd9538183400de..69b66ff8cfe3fb15c4eb7bd91b75570fc27d9891 100644 --- a/resources/transaction_info_dialog.ui +++ b/resources/transaction_info_dialog.ui @@ -1,11 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacTransactionInfoDialog" parent="GtkDialog"> + <property name="can_focus">False</property> <property name="border_width">6</property> + <property name="modal">True</property> + <property name="window_position">center-on-parent</property> <property name="default_width">300</property> <property name="icon_name">system-software-install</property> <property name="type_hint">dialog</property> + <property name="urgency_hint">True</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox4"> <property name="can_focus">False</property> @@ -21,11 +26,13 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> + <property name="receives_default">False</property> <property name="use_underline">True</property> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">0</property> </packing> </child> </object> @@ -33,6 +40,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> + <property name="position">0</property> </packing> </child> <child> @@ -43,6 +51,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> @@ -83,6 +92,7 @@ <packing> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/resources/transaction_sum_dialog.ui b/resources/transaction_sum_dialog.ui index a237e8919579f9d6dcb2f2e211b459519624ab5d..104573fa0a046aab240161830251dbf4584fb7e0 100644 --- a/resources/transaction_sum_dialog.ui +++ b/resources/transaction_sum_dialog.ui @@ -1,11 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacTransactionSumDialog" parent="GtkDialog"> - <property name="title" translatable="yes">Transaction Summary</property> + <property name="can_focus">False</property> <property name="border_width">6</property> - <property name="type_hint">dialog</property> + <property name="title" translatable="yes">Transaction Summary</property> + <property name="window_position">center-on-parent</property> <property name="icon_name">system-software-install</property> + <property name="type_hint">dialog</property> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox6"> <property name="can_focus">False</property> @@ -21,12 +24,13 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> - <property name="use_underline">True</property> <property name="receives_default">False</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> @@ -34,11 +38,13 @@ <property name="label" translatable="yes">_OK</property> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="receives_default">False</property> <property name="use_underline">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> @@ -46,6 +52,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> + <property name="position">0</property> </packing> </child> <child> @@ -56,6 +63,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> @@ -65,7 +73,7 @@ <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="shadow_type">in</property> - <property name="min_content_width">330</property> + <property name="min_content_width">450</property> <property name="min_content_height">250</property> <child> <object class="GtkTreeView" id="treeview"> @@ -75,7 +83,6 @@ <property name="vexpand">True</property> <property name="headers_visible">False</property> <property name="headers_clickable">False</property> - <property name="enable_search">False</property> <property name="search_column">0</property> <property name="show_expanders">False</property> <child internal-child="selection"> @@ -87,12 +94,11 @@ <object class="GtkTreeViewColumn" id="_action"> <property name="sizing">autosize</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext5"> + <object class="GtkCellRendererText" id="cellrenderertext1"> <property name="yalign">0</property> - <property name="weight">600</property> </object> <attributes> - <attribute name="text">0</attribute> + <attribute name="markup">0</attribute> </attributes> </child> </object> @@ -101,19 +107,38 @@ <object class="GtkTreeViewColumn" id="_packages"> <property name="sizing">autosize</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext6"/> + <object class="GtkCellRendererText" id="cellrenderertext2"/> <attributes> <attribute name="text">1</attribute> </attributes> </child> </object> </child> + <child> + <object class="GtkTreeViewColumn" id="_version"> + <property name="sizing">autosize</property> + <property name="title" translatable="yes">column</property> + <child> + <object class="GtkCellRendererText" id="cellrenderertext3"/> + <attributes> + <attribute name="text">2</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText" id="cellrenderertext4"/> + <attributes> + <attribute name="text">3</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> <child> @@ -124,6 +149,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="position">3</property> </packing> </child> </object> diff --git a/resources/updater_window.ui b/resources/updater_window.ui index d09ed27e9c1114100f22936cd5482aa26198d8ee..9dc6604c1e876c3372afff054a17300f990385c0 100644 --- a/resources/updater_window.ui +++ b/resources/updater_window.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.19.0 --> +<!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.12"/> <template class="PamacUpdaterWindow" parent="GtkApplicationWindow"> @@ -7,9 +7,9 @@ <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Update Manager</property> - <property name="window_position">center</property> - <property name="default_width">500</property> + <property name="default_width">600</property> <property name="icon_name">system-software-update</property> + <property name="gravity">center</property> <child> <object class="GtkBox" id="box1"> <property name="visible">True</property> @@ -30,25 +30,35 @@ </packing> </child> <child> - <object class="GtkNotebook" id="notebook"> + <object class="GtkStackSwitcher" id="stackswitcher"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="stack">stack</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkStack" id="stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> <child> <object class="GtkScrolledWindow" id="repos_scrolledwindow"> - <property name="width_request">400</property> - <property name="height_request">400</property> + <property name="width_request">600</property> + <property name="height_request">450</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> <child> <object class="GtkTreeView" id="repos_updates_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="vexpand">True</property> - <property name="headers_visible">False</property> <property name="headers_clickable">False</property> - <property name="search_column">0</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> @@ -56,6 +66,11 @@ </child> <child> <object class="GtkTreeViewColumn" id="treeviewcolumn3"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">40</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">State</property> <child> <object class="GtkCellRendererToggle" id="repos_select_update"> <signal name="toggled" handler="on_repos_select_update_toggled" swapped="no"/> @@ -68,6 +83,11 @@ </child> <child> <object class="GtkTreeViewColumn" id="treeviewcolumn1"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">200</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">Name</property> <property name="expand">True</property> <child> <object class="GtkCellRendererText" id="repos_update_name"/> @@ -78,45 +98,77 @@ </object> </child> <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn2"> + <object class="GtkTreeViewColumn" id="treeviewcolumn6"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">150</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">Version</property> <child> - <object class="GtkCellRendererText" id="repos_update_download_size"/> + <object class="GtkCellRendererText" id="repos_new_update_version"/> <attributes> <attribute name="text">2</attribute> </attributes> </child> + <child> + <object class="GtkCellRendererText" id="repos_old_update_version"/> + <attributes> + <attribute name="text">3</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn10"> + <property name="resizable">True</property> + <property name="fixed_width">90</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">Repository</property> + <child> + <object class="GtkCellRendererText" id="repos_update_repo"/> + <attributes> + <attribute name="text">4</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn2"> + <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> + <child> + <object class="GtkCellRendererText" id="repos_update_size"/> + <attributes> + <attribute name="text">5</attribute> + </attributes> + </child> </object> </child> </object> </child> </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Repositories</property> - </object> <packing> - <property name="tab_fill">False</property> + <property name="name">repos</property> + <property name="title" translatable="yes">Repositories</property> </packing> </child> <child> <object class="GtkScrolledWindow" id="aur_scrolledwindow"> - <property name="width_request">400</property> - <property name="height_request">400</property> + <property name="width_request">600</property> + <property name="height_request">450</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> <child> <object class="GtkTreeView" id="aur_updates_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="vexpand">True</property> - <property name="headers_visible">False</property> <property name="headers_clickable">False</property> - <property name="search_column">0</property> + <property name="search_column">1</property> + <property name="show_expanders">False</property> <child internal-child="selection"> <object class="GtkTreeSelection" id="treeview-selection2"> <property name="mode">none</property> @@ -124,6 +176,11 @@ </child> <child> <object class="GtkTreeViewColumn" id="treeviewcolumn4"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">40</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">State</property> <child> <object class="GtkCellRendererToggle" id="aur_select_update"> <signal name="toggled" handler="on_aur_select_update_toggled" swapped="no"/> @@ -136,6 +193,11 @@ </child> <child> <object class="GtkTreeViewColumn" id="treeviewcolumn5"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">200</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">Name</property> <property name="expand">True</property> <child> <object class="GtkCellRendererText" id="aur_update_name"/> @@ -145,29 +207,35 @@ </child> </object> </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn8"> + <property name="resizable">True</property> + <property name="sizing">fixed</property> + <property name="fixed_width">150</property> + <property name="min_width">20</property> + <property name="title" translatable="yes">Version</property> + <child> + <object class="GtkCellRendererText" id="aur_update_version"/> + <attributes> + <attribute name="text">2</attribute> + </attributes> + </child> + </object> + </child> </object> </child> </object> <packing> + <property name="name">aur</property> + <property name="title" translatable="yes">AUR</property> <property name="position">1</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">AUR</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> - </packing> - </child> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> <child> @@ -178,7 +246,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">2</property> + <property name="position">3</property> </packing> </child> <child> @@ -277,7 +345,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">3</property> + <property name="position">4</property> </packing> </child> </object> diff --git a/src/Makefile b/src/Makefile index cd818265bb106acd1764dc2fdde14c9b6bdac003..65d4f26c5dfd2ecee964e74ebfae81f2544f7dac 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,30 +1,30 @@ -COMMON_VALA_FLAGS = -X -w \ - --pkg=libalpm \ +ALPM_VALA_FLAGS = --pkg=libalpm \ --pkg=gio-2.0 \ - --pkg=posix \ - --vapidir=./ \ --vapidir=../vapi \ - -X -I../util \ - -X -D_FILE_OFFSET_BITS=64 \ + -X -D_FILE_OFFSET_BITS=64 + +COMMON_VALA_FLAGS = -X -w \ + --pkg=posix \ -X -DGETTEXT_PACKAGE="pamac" \ --target-glib=2.38 -TRANSACTION_VALA_FLAGS = --pkg=json-glib-1.0 \ - --pkg=libsoup-2.4 \ - --pkg=gtk+-3.0 \ +TRANSACTION_VALA_FLAGS = --pkg=gtk+-3.0 \ --pkg=gdk-3.0 \ --pkg=vte-2.91 \ -X -lm -COMMON_SOURCES = ../util/alpm-util.c \ - common.vala \ - pamac_config.vala \ - alpm_config.vala \ +PAMAC_LIB_FLAGS = -X -I. \ + -X -L. \ + -X -lpamac \ + --vapidir=./ \ + --pkg=pamac \ + +COMMON_SOURCES = common.vala \ + pamac_config.vala -TRANSACTION_SOURCES = transaction.vala \ - alpm_utils.vala \ - aur.vala \ +TRANSACTION_SOURCES = package.vala \ + transaction.vala \ choose_provider_dialog.vala \ transaction_sum_dialog.vala \ transaction_info_dialog.vala \ @@ -42,7 +42,7 @@ UPDATER_GRESOURCE_FILE = ../resources/pamac.updater.gresource.xml INSTALLER_GRESOURCE_FILE = ../resources/pamac.installer.gresource.xml -binaries: pamac-refresh pamac-daemon pamac-tray libpamac.so pamac-updater pamac-manager pamac-install +binaries: pamac-refresh pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install clean: rm -f *.c pamac.h pamac.vapi libpamac.so pamac-refresh pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install @@ -55,7 +55,7 @@ pamac-refresh: pamac_config.vala refresh.vala pamac_config.vala \ refresh.vala -pamac-tray: ../vapi/libalpm.vapi $(COMMON_SOURCES) tray.vala +pamac-tray: $(COMMON_SOURCES) alpm_config.vala tray.vala valac -o pamac-tray \ $(COMMON_VALA_FLAGS) \ --pkg=gtk+-3.0 \ @@ -63,20 +63,23 @@ pamac-tray: ../vapi/libalpm.vapi $(COMMON_SOURCES) tray.vala $(COMMON_SOURCES) \ tray.vala -pamac-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl.vapi $(COMMON_SOURCES) aur.vala mirrors_config.vala daemon.vala +pamac-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl.vapi alpm_config.vala $(COMMON_SOURCES) package.vala aur.vala mirrors_config.vala daemon.vala valac -o pamac-daemon \ $(COMMON_VALA_FLAGS) \ + $(ALPM_VALA_FLAGS) \ --pkg=polkit-gobject-1 \ --pkg=libcurl \ --pkg=json-glib-1.0 \ --pkg=libsoup-2.4 \ --thread \ + alpm_config.vala \ $(COMMON_SOURCES) \ + package.vala \ aur.vala \ mirrors_config.vala \ daemon.vala -libpamac.so: ../vapi/libalpm.vapi $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PREFERENCES_SOURCES) ../resources/transaction_resources.c +libpamac.so: $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PREFERENCES_SOURCES) ../resources/transaction_resources.c valac -o libpamac.so \ -X -fPIC \ -X --shared \ @@ -91,33 +94,24 @@ libpamac.so: ../vapi/libalpm.vapi $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PRE $(TRANSACTION_SOURCES) \ $(PREFERENCES_SOURCES) -pamac-manager: libpamac.so choose_dep_dialog.vala history_dialog.vala transaction_info_dialog.vala ../resources/manager_resources.c ../util/alpm-util.c packages_model.vala aur_model.vala manager_window.vala manager.vala +pamac-manager: libpamac.so choose_dep_dialog.vala history_dialog.vala transaction_info_dialog.vala ../resources/manager_resources.c manager_window.vala manager.vala valac -o pamac-manager \ $(COMMON_VALA_FLAGS) \ - -X -I. \ - -X -L. \ - -X -lpamac \ - --pkg=pamac \ + $(PAMAC_LIB_FLAGS) \ --pkg=json-glib-1.0 \ --pkg=gtk+-3.0 \ --pkg=gdk-3.0 \ --gresources=$(MANAGER_GRESOURCE_FILE) \ ../resources/manager_resources.c \ - ../util/alpm-util.c \ choose_dep_dialog.vala \ history_dialog.vala \ - packages_model.vala \ - aur_model.vala \ manager_window.vala \ manager.vala pamac-updater: libpamac.so ../resources/updater_resources.c updater_window.vala updater.vala valac -o pamac-updater \ $(COMMON_VALA_FLAGS) \ - -X -I. \ - -X -L. \ - -X -lpamac \ - --pkg=pamac \ + $(PAMAC_LIB_FLAGS) \ --pkg=json-glib-1.0 \ --pkg=gtk+-3.0 \ --pkg=gdk-3.0 \ @@ -129,10 +123,7 @@ pamac-updater: libpamac.so ../resources/updater_resources.c updater_window.vala pamac-install: libpamac.so installer.vala valac -o pamac-install \ $(COMMON_VALA_FLAGS) \ - -X -I. \ - -X -L. \ - -X -lpamac \ - --pkg=pamac \ + $(PAMAC_LIB_FLAGS) \ --pkg=json-glib-1.0 \ --pkg=gtk+-3.0 \ installer.vala diff --git a/src/alpm_config.vala b/src/alpm_config.vala index e50bb64edd1567eb6f6911d3708c56d67cdf4f59..a3128d9e33072bc32d76a846a07cc41a30a0e535 100644 --- a/src/alpm_config.vala +++ b/src/alpm_config.vala @@ -1,5 +1,5 @@ /* - * pamac-vala + * alpm_config * * Copyright (C) 2014-2016 Guillaume Benoit <guillaume@manjaro.org> * @@ -18,7 +18,7 @@ */ [Compact] -public class AlpmRepo { +class AlpmRepo { public string name; public Alpm.Signature.Level siglevel; public Alpm.Signature.Level siglevel_mask; @@ -42,68 +42,55 @@ public class AlpmRepo { } -[Compact] -public class AlpmConfig { - public string conf_path; - public string? rootdir; - public string? dbpath; - public string? logfile; - public string? gpgdir; - public string? arch; - public double deltaratio; - public int usesyslog; - public int checkspace; - public Alpm.List<string?>? cachedirs; - public Alpm.List<string?>? hookdirs; - public Alpm.List<string?>? ignoregroups; - public Alpm.List<string?>? ignorepkgs; - public Alpm.List<string?>? noextracts; - public Alpm.List<string?>? noupgrades; - public GLib.List<string>? holdpkgs; - public GLib.List<string>? syncfirsts; - public Alpm.Signature.Level siglevel; - public Alpm.Signature.Level localfilesiglevel; - public Alpm.Signature.Level remotefilesiglevel; - public Alpm.Signature.Level siglevel_mask; - public Alpm.Signature.Level localfilesiglevel_mask; - public Alpm.Signature.Level remotefilesiglevel_mask; - public GLib.List<AlpmRepo> repo_order; - public Alpm.Handle? handle; +class AlpmConfig { + string conf_path; + string? rootdir; + string? dbpath; + string? logfile; + string? gpgdir; + string? arch; + double deltaratio; + int usesyslog; + int checkspace; + GLib.List<string> cachedirs; + GLib.List<string> hookdirs; + GLib.List<string> ignoregroups; + GLib.List<string> ignorepkgs; + GLib.List<string> noextracts; + GLib.List<string> noupgrades; + GLib.List<string> holdpkgs; + GLib.List<string> syncfirsts; + Alpm.Signature.Level siglevel; + Alpm.Signature.Level localfilesiglevel; + Alpm.Signature.Level remotefilesiglevel; + Alpm.Signature.Level siglevel_mask; + Alpm.Signature.Level localfilesiglevel_mask; + Alpm.Signature.Level remotefilesiglevel_mask; + GLib.List<AlpmRepo> repo_order; public AlpmConfig (string path) { conf_path = path; reload (); } + public unowned GLib.List<string> get_holdpkgs () { + return holdpkgs; + } + + public unowned GLib.List<string> get_syncfirsts () { + return syncfirsts; + } + public void reload () { // set default options + cachedirs = new GLib.List<string> (); + hookdirs = new GLib.List<string> (); + ignoregroups = new GLib.List<string> (); + ignorepkgs = new GLib.List<string> (); + noextracts = new GLib.List<string> (); + noupgrades = new GLib.List<string> (); holdpkgs = new GLib.List<string> (); syncfirsts = new GLib.List<string> (); - // free internal data of alpm lists - if (cachedirs != null) { - cachedirs.free_data (); - cachedirs = new Alpm.List<string> (); - } - if (hookdirs != null) { - hookdirs.free_data (); - hookdirs = new Alpm.List<string?> (); - } - if (ignoregroups != null) { - ignoregroups.free_data (); - ignoregroups = new Alpm.List<string> (); - } - if (ignorepkgs != null) { - ignorepkgs.free_data (); - ignorepkgs = new Alpm.List<string> (); - } - if (noextracts != null) { - noextracts.free_data (); - noextracts = new Alpm.List<string> (); - } - if (noupgrades != null) { - noupgrades.free_data (); - noupgrades = new Alpm.List<string> (); - } usesyslog = 0; checkspace = 0; deltaratio = 0.7; @@ -131,11 +118,11 @@ public class AlpmConfig { logfile = "/var/log/pacman.log"; } } - if (cachedirs.length == 0) { - cachedirs.add ("/var/cache/pacman/pkg/"); + if (cachedirs.length () == 0) { + cachedirs.append ("/var/cache/pacman/pkg/"); } - if (hookdirs.length == 0) { - hookdirs.add ("/etc/pacman.d/hooks/"); + if (hookdirs.length () == 0) { + hookdirs.append ("/etc/pacman.d/hooks/"); } if (gpgdir == null) { // gpgdir it is not relative to rootdir, even if @@ -147,12 +134,12 @@ public class AlpmConfig { } } - public void set_handle () { + public Alpm.Handle? get_handle () { Alpm.Errno error; - handle = Alpm.Handle.new (rootdir, dbpath, out error); + Alpm.Handle? handle = new Alpm.Handle (rootdir, dbpath, out error); if (handle == null) { - stderr.printf ("Failed to initialize alpm library" + " (%s)\n".printf(Alpm.strerror (error))); - return; + stderr.printf ("Failed to initialize alpm library" + " (%s)\n".printf (Alpm.strerror (error))); + return null; } // define options handle.logfile = logfile; @@ -166,15 +153,24 @@ public class AlpmConfig { remotefilesiglevel = merge_siglevel (siglevel, remotefilesiglevel, remotefilesiglevel_mask); handle.localfilesiglevel = localfilesiglevel; handle.remotefilesiglevel = remotefilesiglevel; - handle.cachedirs = cachedirs; - // add hook directories 1-by-1 to avoid overwriting the system directory + foreach (unowned string cachedir in cachedirs) { + handle.add_cachedir (cachedir); + } foreach (unowned string hookdir in hookdirs) { handle.add_hookdir (hookdir); } - handle.ignoregroups = ignoregroups; - handle.ignorepkgs = ignorepkgs; - handle.noextracts = noextracts; - handle.noupgrades = noupgrades; + foreach (unowned string ignoregroup in ignoregroups) { + handle.add_ignoregroup (ignoregroup); + } + foreach (unowned string ignorepkg in ignorepkgs) { + handle.add_ignorepkg (ignorepkg); + } + foreach (unowned string noextract in noextracts) { + handle.add_noextract (noextract); + } + foreach (unowned string noupgrade in noupgrades) { + handle.add_noupgrade (noupgrade); + } // register dbs foreach (unowned AlpmRepo repo in repo_order) { repo.siglevel = merge_siglevel (siglevel, repo.siglevel, repo.siglevel_mask); @@ -188,9 +184,10 @@ public class AlpmConfig { db.usage = repo.usage; } } + return handle; } - public void parse_file (string path, string? section = null) { + void parse_file (string path, string? section = null) { string? current_section = section; var file = GLib.File.new_for_path (path); if (file.query_exists ()) { @@ -236,11 +233,11 @@ public class AlpmConfig { dbpath = val; } else if (key == "CacheDir") { foreach (unowned string dir in val.split (" ")) { - cachedirs.add (dir); + cachedirs.append (dir); } } else if (key == "HookDir") { foreach (unowned string dir in val.split (" ")) { - hookdirs.add (dir); + hookdirs.append (dir); } } else if (key == "LogFile") { logfile = val; @@ -276,19 +273,19 @@ public class AlpmConfig { } } else if (key == "IgnoreGroup") { foreach (unowned string name in val.split (" ")) { - ignoregroups.add (name); + ignoregroups.append (name); } } else if (key == "IgnorePkg") { foreach (unowned string name in val.split (" ")) { - ignorepkgs.add (name); + ignorepkgs.append (name); } } else if (key == "Noextract") { foreach (unowned string name in val.split (" ")) { - noextracts.add (name); + noextracts.append (name); } } else if (key == "NoUpgrade") { foreach (unowned string name in val.split (" ")) { - noupgrades.add (name); + noupgrades.append (name); } } } else { @@ -364,6 +361,7 @@ public class AlpmConfig { // writing a short string to the stream dos.put_string (new_line); } + reload (); } catch (GLib.Error e) { GLib.stderr.printf("%s\n", e.message); } @@ -372,7 +370,7 @@ public class AlpmConfig { } } - public Alpm.DB.Usage define_usage (string conf_string) { + Alpm.DB.Usage define_usage (string conf_string) { Alpm.DB.Usage usage = 0; foreach (unowned string directive in conf_string.split(" ")) { if (directive == "Sync") { @@ -390,7 +388,7 @@ public class AlpmConfig { return usage; } - public void process_siglevel (string conf_string, ref Alpm.Signature.Level siglevel, ref Alpm.Signature.Level siglevel_mask) { + void process_siglevel (string conf_string, ref Alpm.Signature.Level siglevel, ref Alpm.Signature.Level siglevel_mask) { foreach (unowned string directive in conf_string.split(" ")) { bool affect_package = false; bool affect_database = false; @@ -458,7 +456,7 @@ public class AlpmConfig { siglevel &= ~Alpm.Signature.Level.USE_DEFAULT; } - public Alpm.Signature.Level merge_siglevel(Alpm.Signature.Level sigbase, Alpm.Signature.Level sigover, Alpm.Signature.Level sigmask) { + Alpm.Signature.Level merge_siglevel(Alpm.Signature.Level sigbase, Alpm.Signature.Level sigover, Alpm.Signature.Level sigmask) { return (sigmask != 0) ? (sigover & sigmask) | (sigbase & ~sigmask) : sigover; } } diff --git a/src/aur.vala b/src/aur.vala index 19d2703e4f7fdac72902d2fabefd7d96ca13d6b9..c7b4046689ba68eda16c42b543a605fe2a9423fa 100644 --- a/src/aur.vala +++ b/src/aur.vala @@ -25,107 +25,66 @@ namespace AUR { const string rpc_multiinfo = "&type=info"; const string rpc_multiinfo_arg = "&arg[]="; - public Json.Array search (string[] needles) { - var prev_inter = new Json.Array (); - string uri = rpc_url + rpc_search + Uri.escape_string (needles[0]); + Json.Array rpc_query (string uri) { + var results = new Json.Array (); var session = new Soup.Session (); + // set a 15 seconds timeout because it is also the dbus daemon timeout + session.timeout = 15; var message = new Soup.Message ("GET", uri); var parser = new Json.Parser (); session.send_message (message); try { parser.load_from_data ((string) message.response_body.flatten ().data, -1); } catch (Error e) { - print (e.message); + critical (e.message); } unowned Json.Node? root = parser.get_root (); if (root != null) { if (root.get_object ().get_string_member ("type") == "error") { - stderr.printf ("Failed to search %s from AUR\n", needles[0]); + critical ("Failed to query %s from AUR", uri); } else { - prev_inter = root.get_object ().get_array_member ("results"); + results = root.get_object ().get_array_member ("results"); } } - int needles_length = needles.length; - if (needles_length == 1) { - return prev_inter; - } - int i = 1; - var inter = new Json.Array (); - var found = new Json.Array (); - while (i < needles_length) { - inter = new Json.Array (); - uri = rpc_url + rpc_search + Uri.escape_string (needles[i]); - message = new Soup.Message ("GET", uri); - session.send_message (message); - try { - parser.load_from_data ((string) message.response_body.flatten ().data, -1); - } catch (Error e) { - print (e.message); - } - root = parser.get_root (); - if (root != null) { - if (root.get_object ().get_string_member ("type") == "error") { - stderr.printf ("Failed to search %s from AUR\n", needles[i]); - } else { - found = root.get_object ().get_array_member ("results"); - uint j = 0; - uint k; - uint found_length = found.get_length (); - while (j < found_length) { - unowned Json.Node found_node = found.get_element (j); - k = 0; - uint prev_inter_length = prev_inter.get_length (); - while (k < prev_inter_length) { - unowned Json.Node prev_inter_node = prev_inter.get_element (k); - if (strcmp (found_node.get_object ().get_string_member ("Name"), - prev_inter_node.get_object ().get_string_member ("Name")) == 0) { - inter.add_element (prev_inter_node); - prev_inter.remove_element (k); - break; - } - k++; + return results; + } + + public async Json.Array search (string[] needles) { + if (needles.length == 0) { + return new Json.Array (); + } else if (needles.length == 1) { + return rpc_query (rpc_url + rpc_search + Uri.escape_string (needles[0])); + } else { + var inter = new Json.Array (); + var prev_inter = new Json.Array (); + foreach (unowned string needle in needles) { + inter = new Json.Array (); + var found = rpc_query (rpc_url + rpc_search + Uri.escape_string (needle)); + prev_inter.foreach_element ((prev_inter_array, prev_inter_index, prev_inter_node) => { + found.foreach_element ((found_array, found_index, found_node) => { + if (strcmp (prev_inter_node.get_object ().get_string_member ("Name"), + found_node.get_object ().get_string_member ("Name")) == 0) { + inter.add_element (prev_inter_node); } - j++; - } - } + }); + }); + prev_inter = (owned) inter; } - if (i != (needles_length -1)) { - prev_inter = inter; - } - i++; + return inter; } - return inter; } - public Json.Array multiinfo (string[] pkgnames) { - Json.Array results = new Json.Array (); + public async Json.Array multiinfo (string[] pkgnames) { if (pkgnames.length == 0) { - return results; + return new Json.Array (); } var builder = new StringBuilder (); builder.append (rpc_url); builder.append (rpc_multiinfo); - foreach (string pkgname in pkgnames) { + foreach (unowned string pkgname in pkgnames) { builder.append (rpc_multiinfo_arg); builder.append (Uri.escape_string (pkgname)); } - var session = new Soup.Session (); - var message = new Soup.Message ("GET", builder.str); - session.send_message (message); - var parser = new Json.Parser (); - try { - parser.load_from_data ((string) message.response_body.flatten ().data, -1); - } catch (Error e) { - print (e.message); - } - unowned Json.Node? root = parser.get_root (); - if (root != null) { - if (root.get_object ().get_string_member ("type") == "error") { - stderr.printf ("Failed to multiinfo %s from AUR\n", builder.str); - } else { - results = root.get_object ().get_array_member ("results"); - } - } - return results; + return rpc_query (builder.str); } } diff --git a/src/choose_dep_dialog.vala b/src/choose_dep_dialog.vala index 40e503e4d023482b98739048283ffa4c35447ab2..5d5e77672ac820cc3cfa7fa02169307fd99e10ff 100644 --- a/src/choose_dep_dialog.vala +++ b/src/choose_dep_dialog.vala @@ -32,17 +32,17 @@ namespace Pamac { public ChooseDependenciesDialog (Gtk.ApplicationWindow? window) { Object (transient_for: window, use_header_bar: 0); - deps_list = new Gtk.ListStore (3, typeof (bool), typeof (string), typeof (string)); + deps_list = new Gtk.ListStore (2, typeof (bool), typeof (string)); treeview.set_model (deps_list); } [GtkCallback] void on_renderertoggle_toggled (string path) { Gtk.TreeIter iter; - GLib.Value selected; + bool selected; if (deps_list.get_iter_from_string (out iter, path)) {; - deps_list.get_value (iter, 0, out selected); - deps_list.set_value (iter, 0, !((bool) selected)); + deps_list.get (iter, 0, out selected); + deps_list.set (iter, 0, !selected); } } } diff --git a/src/common.vala b/src/common.vala index 0cfdb767f7bc735f2621ca3892e5ed187d5d6ca3..3dc81ce62ed8d15297f17123b91ddd090a991598 100644 --- a/src/common.vala +++ b/src/common.vala @@ -18,17 +18,26 @@ */ namespace Pamac { - public struct PackageInfos { + public struct UpdateInfos { public string name; - public string version; - public string db_name; + public string old_version; + public string new_version; + public string repo; public uint64 download_size; } + public struct TransactionSummary { + public UpdateInfos[] to_install; + public UpdateInfos[] to_upgrade; + public UpdateInfos[] to_downgrade; + public UpdateInfos[] to_reinstall; + public UpdateInfos[] to_remove; + } + public struct Updates { public bool is_syncfirst; - public PackageInfos[] repos_updates; - public PackageInfos[] aur_updates; + public UpdateInfos[] repos_updates; + public UpdateInfos[] aur_updates; } public struct ErrorInfos { diff --git a/src/daemon.vala b/src/daemon.vala index 65fd953270e19a0ee38bc2fe2f8b4a42991b1314..7fcaa8d1a82c61a614443a4ab5e23a0922edf2fb 100644 --- a/src/daemon.vala +++ b/src/daemon.vala @@ -36,10 +36,15 @@ public class AlpmAction { } } +private int alpm_pkg_compare_name (Alpm.Package pkg_a, Alpm.Package pkg_b) { + return strcmp (pkg_a.name, pkg_b.name); +} + namespace Pamac { [DBus (name = "org.manjaro.pamac")] public class Daemon: Object { private AlpmConfig alpm_config; + private Alpm.Handle? alpm_handle; public Cond provider_cond; public Mutex provider_mutex; public int? choosen_provider; @@ -47,6 +52,8 @@ namespace Pamac { private ThreadPool<AlpmAction> thread_pool; private Mutex databases_lock_mutex; private Json.Array aur_updates_results; + private HashTable<string, Json.Array> aur_search_results; + private HashTable<string, Json.Object> aur_infos; private bool intern_lock; private bool extern_lock; private GLib.File lockfile; @@ -54,6 +61,7 @@ namespace Pamac { public Timer timer; public Cancellable cancellable; public Curl.Easy curl; + private GLib.List<string> aur_dep_list; public signal void emit_event (uint primary_event, uint secondary_event, string[] details); public signal void emit_providers (string depend, string[] providers); @@ -79,6 +87,8 @@ namespace Pamac { alpm_config = new AlpmConfig ("/etc/pacman.conf"); databases_lock_mutex = Mutex (); aur_updates_results = new Json.Array (); + aur_search_results = new HashTable<string, Json.Array> (str_hash, str_equal); + aur_infos = new HashTable<string, Json.Object> (str_hash, str_equal); timer = new Timer (); intern_lock = false; extern_lock = false; @@ -131,20 +141,20 @@ namespace Pamac { } private void refresh_handle () { - alpm_config.set_handle (); - if (alpm_config.handle == null) { + alpm_handle = alpm_config.get_handle (); + if (alpm_handle == null) { current_error = ErrorInfos () { message = _("Failed to initialize alpm library") }; trans_commit_finished (false); } else { - alpm_config.handle.eventcb = (Alpm.EventCallBack) cb_event; - alpm_config.handle.progresscb = (Alpm.ProgressCallBack) cb_progress; - alpm_config.handle.questioncb = (Alpm.QuestionCallBack) cb_question; - alpm_config.handle.fetchcb = (Alpm.FetchCallBack) cb_fetch; - alpm_config.handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload; - alpm_config.handle.logcb = (Alpm.LogCallBack) cb_log; - lockfile = GLib.File.new_for_path (alpm_config.handle.lockfile); + alpm_handle.eventcb = (Alpm.EventCallBack) cb_event; + alpm_handle.progresscb = (Alpm.ProgressCallBack) cb_progress; + alpm_handle.questioncb = (Alpm.QuestionCallBack) cb_question; + alpm_handle.fetchcb = (Alpm.FetchCallBack) cb_fetch; + alpm_handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload; + alpm_handle.logcb = (Alpm.LogCallBack) cb_log; + lockfile = GLib.File.new_for_path (alpm_handle.lockfile); } } @@ -201,8 +211,8 @@ namespace Pamac { } public void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf, GLib.BusName sender) { - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); check_authorization.begin (sender, (obj, res) => { + var pamac_config = new Pamac.Config ("/etc/pamac.conf"); bool authorized = check_authorization.end (res); if (authorized ) { pamac_config.write (new_pamac_conf); @@ -222,7 +232,7 @@ namespace Pamac { alpm_config.reload (); refresh_handle (); } - write_alpm_config_finished ((alpm_config.checkspace == 1)); + write_alpm_config_finished ((alpm_handle.checkspace == 1)); }); } @@ -271,7 +281,6 @@ namespace Pamac { ChildWatch.add (child_pid, (pid, status) => { // Triggered when the child indicated by child_pid exits Process.close_pid (pid); - alpm_config.reload (); refresh_handle (); generate_mirrors_list_finished (); }); @@ -297,7 +306,7 @@ namespace Pamac { check_authorization.begin (sender, (obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { - unowned Alpm.Package? pkg = alpm_config.handle.localdb.get_pkg (pkgname); + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); if (pkg != null) { pkg.reason = (Alpm.Package.Reason) reason; refresh_handle (); @@ -307,31 +316,15 @@ namespace Pamac { }); } - public PackageInfos get_installed_pkg (string pkgname) { - unowned Alpm.Package? pkg = alpm_config.handle.localdb.get_pkg (pkgname); - if (pkg == null) { - return PackageInfos () { - name = "", - version = "", - db_name = "", - download_size = 0 - }; - } - return PackageInfos () { - name = pkg.name, - version = pkg.version, - db_name = pkg.db.name, - download_size = pkg.download_size - }; - } - private void refresh () { intern_lock = true; current_error = ErrorInfos (); int force = (force_refresh) ? 1 : 0; uint success = 0; cancellable.reset (); - foreach (var db in alpm_config.handle.syncdbs) { + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; if (cancellable.is_cancelled ()) { refresh_handle (); refresh_finished (false); @@ -341,12 +334,13 @@ namespace Pamac { if (db.update (force) >= 0) { success++; } + syncdbs.next (); } refresh_handle (); // We should always succeed if at least one DB was upgraded - we may possibly // fail later with unresolved deps, but that should be rare, and would be expected if (success == 0) { - Alpm.Errno errno = alpm_config.handle.errno (); + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to synchronize any databases"); current_error.details = { Alpm.strerror (errno) }; @@ -366,27 +360,767 @@ namespace Pamac { } } + public bool get_checkspace () { + return alpm_handle.checkspace == 1 ? true : false; + } + + public string get_lockfile () { + return alpm_handle.lockfile; + } + + public string[] get_ignorepkgs () { + string[] result = {}; + unowned Alpm.List<unowned string> ignorepkgs = alpm_handle.ignorepkgs; + while (ignorepkgs != null) { + unowned string ignorepkg = ignorepkgs.data; + result += ignorepkg; + ignorepkgs.next (); + } + return result; + } + public void add_ignorepkg (string pkgname) { - alpm_config.handle.add_ignorepkg (pkgname); + alpm_handle.add_ignorepkg (pkgname); } public void remove_ignorepkg (string pkgname) { - alpm_config.handle.remove_ignorepkg (pkgname); + alpm_handle.remove_ignorepkg (pkgname); + } + + public bool should_hold (string pkgname) { + if (alpm_config.get_holdpkgs ().find_custom (pkgname, strcmp) != null) { + return true; + } + return false; + } + + public uint get_pkg_reason (string pkgname) { + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); + if (pkg != null) { + return pkg.reason; + } + return 0; + } + + public uint get_pkg_origin (string pkgname) { + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); + if (pkg != null) { + return pkg.origin; + } else { + pkg = get_syncpkg (pkgname); + if (pkg != null) { + return pkg.origin; + } + } + return 0; + } + + private AlpmPackage initialise_pkg_struct (Alpm.Package? alpm_pkg) { + if (alpm_pkg != null) { + string repo_name = ""; + if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) { + unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name); + if (sync_pkg != null) { + repo_name = sync_pkg.db.name; + } + } else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) { + repo_name = alpm_pkg.db.name; + } + return AlpmPackage () { + name = alpm_pkg.name, + version = alpm_pkg.version, + // desc can be null + desc = alpm_pkg.desc != null ? Markup.escape_text (alpm_pkg.desc) : "", + repo = (owned) repo_name, + size = alpm_pkg.isize, + origin = (uint) alpm_pkg.origin + }; + } else { + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public async AlpmPackage[] get_installed_pkgs () { + AlpmPackage[] pkgs = {}; + unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package alpm_pkg = pkgcache.data; + pkgs += initialise_pkg_struct (alpm_pkg); + pkgcache.next (); + } + return pkgs; + } + + public async AlpmPackage[] get_foreign_pkgs () { + AlpmPackage[] pkgs = {}; + unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package alpm_pkg = pkgcache.data; + bool sync_found = false; + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + unowned Alpm.Package? sync_pkg = db.get_pkg (alpm_pkg.name); + if (sync_pkg != null) { + sync_found = true; + break; + } + syncdbs.next (); + } + if (sync_found == false) { + pkgs += initialise_pkg_struct (alpm_pkg); + } + pkgcache.next (); + } + return pkgs; + } + + public async AlpmPackage[] get_orphans () { + AlpmPackage[] pkgs = {}; + 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.DEPEND) { + Alpm.List<string> requiredby = alpm_pkg.compute_requiredby (); + if (requiredby.length == 0) { + Alpm.List<string> optionalfor = alpm_pkg.compute_optionalfor (); + if (optionalfor.length == 0) { + pkgs += initialise_pkg_struct (alpm_pkg); + } else { + optionalfor.free_inner (GLib.free); + } + } else { + requiredby.free_inner (GLib.free); + } + } + pkgcache.next (); + } + return pkgs; + } + + public AlpmPackage get_installed_pkg (string pkgname) { + return initialise_pkg_struct (alpm_handle.localdb.get_pkg (pkgname)); + } + + public AlpmPackage find_installed_satisfier (string depstring) { + return initialise_pkg_struct (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring)); + } + + private unowned Alpm.Package? get_syncpkg (string name) { + unowned Alpm.Package? pkg = null; + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + pkg = db.get_pkg (name); + if (pkg != null) { + break; + } + syncdbs.next (); + } + return pkg; + } + + public AlpmPackage get_sync_pkg (string pkgname) { + return initialise_pkg_struct (get_syncpkg (pkgname)); + } + + public AlpmPackage find_sync_satisfier (string depstring) { + return initialise_pkg_struct (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring)); + } + + private Alpm.List<unowned Alpm.Package> search_all_dbs (string search_string) { + Alpm.List<unowned string> needles = null; + string[] splitted = search_string.split (" "); + foreach (unowned string part in splitted) { + needles.add (part); + } + Alpm.List<unowned Alpm.Package> result = alpm_handle.localdb.search (needles); + Alpm.List<unowned Alpm.Package> syncpkgs = null; + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + if (syncpkgs.length == 0) { + syncpkgs = db.search (needles); + } else { + syncpkgs.join (db.search (needles).diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); + } + syncdbs.next (); + } + result.join (syncpkgs.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); + //result.sort ((Alpm.List.CompareFunc) alpm_pkg_compare_name); + return result; + } + + public async AlpmPackage[] search_pkgs (string search_string) { + AlpmPackage[] result = {}; + 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; + result += initialise_pkg_struct (alpm_pkg); + list.next (); + } + return result; + } + + AURPackage initialise_aur_struct (Json.Object json_object) { + return AURPackage () { + name = json_object.get_string_member ("Name"), + version = json_object.get_string_member ("Version"), + // desc can be null + desc = json_object.get_null_member ("Description") ? "" : Markup.escape_text (json_object.get_string_member ("Description")), + popularity = json_object.get_double_member ("Popularity") + }; + } + + public async AURPackage[] search_in_aur (string search_string) { + if (!aur_search_results.contains (search_string)) { + Json.Array pkgs = yield AUR.search (search_string.split (" ")); + aur_search_results.insert (search_string, pkgs); + } + AURPackage[] result = {}; + Json.Array aur_pkgs = aur_search_results.get (search_string); + aur_pkgs.foreach_element ((array, index, node) => { + Json.Object aur_pkg = node.get_object (); + // remove results which exist in repos + if (get_syncpkg (aur_pkg.get_string_member ("Name")) == null) { + result += initialise_aur_struct (node.get_object ()); + } + }); + return result; + } + + public async AURPackageDetails get_aur_details (string pkgname) { + string name = ""; + string version = ""; + string desc = ""; + double popularity = 0; + string packagebase = ""; + string url = ""; + string maintainer = ""; + int64 firstsubmitted = 0; + int64 lastmodified = 0; + int64 outofdate = 0; + int64 numvotes = 0; + string[] licenses = {}; + string[] depends = {}; + string[] makedepends = {}; + string[] checkdepends = {}; + string[] optdepends = {}; + string[] provides = {}; + string[] replaces = {}; + string[] conflicts = {}; + var details = AURPackageDetails (); + if (!aur_infos.contains (pkgname)) { + Json.Array results = yield AUR.multiinfo ({pkgname}); + if (results.get_length () > 0) { + aur_infos.insert (pkgname, results.get_object_element (0)); + } + } + unowned Json.Object? json_object = aur_infos.lookup (pkgname); + if (json_object != null) { + // name + name = json_object.get_string_member ("Name"); + // version + version = json_object.get_string_member ("Version"); + // desc can be null + if (!json_object.get_null_member ("Description")) { + desc = Markup.escape_text (json_object.get_string_member ("Description")); + } + popularity = json_object.get_double_member ("Popularity"); + // packagebase + packagebase = json_object.get_string_member ("PackageBase"); + // url can be null + unowned Json.Node? node = json_object.get_member ("URL"); + if (!node.is_null ()) { + url = Markup.escape_text (node.get_string ()); + } + // maintainer can be null + node = json_object.get_member ("Maintainer"); + if (!node.is_null ()) { + maintainer = node.get_string (); + } + // firstsubmitted + firstsubmitted = json_object.get_int_member ("FirstSubmitted"); + // lastmodified + lastmodified = json_object.get_int_member ("LastModified"); + // outofdate can be null + node = json_object.get_member ("OutOfDate"); + if (!node.is_null ()) { + outofdate = node.get_int (); + } + //numvotes + numvotes = json_object.get_int_member ("NumVotes"); + // licenses + node = json_object.get_member ("License"); + if (!node.is_null ()) { + node.get_array ().foreach_element ((array, index, _node) => { + licenses += _node.get_string (); + }); + } else { + licenses += _("Unknown"); + } + // depends + node = json_object.get_member ("Depends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + depends += _node.get_string (); + }); + } + // optdepends + node = json_object.get_member ("OptDepends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + optdepends += _node.get_string (); + }); + } + // makedepends + node = json_object.get_member ("MakeDepends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + makedepends += _node.get_string (); + }); + } + // checkdepends + node = json_object.get_member ("CheckDepends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + checkdepends += _node.get_string (); + }); + } + // provides + node = json_object.get_member ("Provides"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + provides += _node.get_string (); + }); + } + // replaces + node = json_object.get_member ("Replaces"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + replaces += _node.get_string (); + }); + } + // conflicts + node = json_object.get_member ("Conflicts"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + conflicts += _node.get_string (); + }); + } + } + details.name = (owned) name; + details.version = (owned) version ; + details.desc = (owned) desc; + details.popularity = popularity; + details.packagebase = (owned) packagebase; + details.url = (owned) url; + details.maintainer = (owned) maintainer ; + details.firstsubmitted = firstsubmitted; + details.lastmodified = lastmodified; + details.outofdate = outofdate; + details.numvotes = numvotes; + details.licenses = (owned) licenses; + details.depends = (owned) depends; + details.optdepends = (owned) optdepends; + details.checkdepends = (owned) checkdepends; + details.makedepends = (owned) makedepends; + details.provides = (owned) provides; + details.replaces = (owned) replaces; + details.conflicts = (owned) conflicts; + return details; + } + + public async string[] get_aur_build_list (string pkgname) { + string[] results = {}; + aur_dep_list = new GLib.List<string> (); + bool success = yield set_aur_dep_list (pkgname); + if (success) { + foreach (unowned string name in aur_dep_list) { + results += name; + } + } + return results; + } + + private async bool set_aur_dep_list (string pkgname) { + bool success = false; + Json.Array results = yield AUR.multiinfo ({pkgname}); + Json.Object json_object = results.get_object_element (0); + if (json_object != null) { + success = true; + // add aur pkg to global list or move it to the end of the list; + unowned GLib.List<string> element = aur_dep_list.find_custom (pkgname, strcmp); + if (element == null) { + aur_dep_list.append (pkgname); + } else { + aur_dep_list.delete_link (element); + aur_dep_list.append (pkgname); + } + unowned Json.Node? node = json_object.get_member ("MakeDepends"); + if (node != null) { + GLib.List<unowned Json.Node> list = node.get_array ().get_elements (); + foreach (unowned Json.Node? _node in list) { + unowned string depstring = _node.get_string (); + if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) == null) { + if (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring) == null) { + success = yield set_aur_dep_list (depstring); + } + } + if (!success) { + break; + } + } + } + if (success) { + node = json_object.get_member ("Depends"); + if (node != null) { + GLib.List<unowned Json.Node> list = node.get_array ().get_elements (); + foreach (unowned Json.Node? _node in list) { + unowned string depstring = _node.get_string (); + if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) == null) { + if (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring) == null) { + success = yield set_aur_dep_list (depstring); + } + } + if (!success) { + break; + } + } + } + } + if (success) { + node = json_object.get_member ("CheckDepends"); + if (node != null) { + GLib.List<unowned Json.Node> list = node.get_array ().get_elements (); + foreach (unowned Json.Node? _node in list) { + unowned string depstring = _node.get_string (); + if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) == null) { + if (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring) == null) { + success = yield set_aur_dep_list (depstring); + } + } + if (!success) { + break; + } + } + } + } + } else { + stdout.printf ("can't find %s in AUR\n", pkgname); + } + return success; + } + + public string[] get_repos_names () { + string[] repos_names = {}; + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + repos_names += db.name; + syncdbs.next (); + } + return repos_names; + } + + public async AlpmPackage[] get_repo_pkgs (string repo) { + AlpmPackage[] pkgs = {}; + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + if (db.name == repo) { + unowned Alpm.List<unowned Alpm.Package> pkgcache = db.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package sync_pkg = pkgcache.data; + unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (sync_pkg.name); + if (local_pkg != null) { + pkgs += initialise_pkg_struct (local_pkg); + } else { + pkgs += initialise_pkg_struct (sync_pkg); + } + pkgcache.next (); + } + break; + } + syncdbs.next (); + } + return pkgs; + } + + public string[] get_groups_names () { + string[] groups_names = {}; + unowned Alpm.List<unowned Alpm.Group> groupcache = alpm_handle.localdb.groupcache; + while (groupcache != null) { + unowned Alpm.Group group = groupcache.data; + if (!(group.name in groups_names)) { + groups_names += group.name; + } + groupcache.next (); + } + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + groupcache = db.groupcache; + while (groupcache != null) { + unowned Alpm.Group group = groupcache.data; + if (!(group.name in groups_names)) { + groups_names += group.name; + } + groupcache.next (); + } + syncdbs.next (); + } + return groups_names; + } + + private Alpm.List<unowned Alpm.Package> group_pkgs (string group_name) { + Alpm.List<unowned Alpm.Package> result = null; + unowned Alpm.Group? grp = alpm_handle.localdb.get_group (group_name); + if (grp != null) { + unowned Alpm.List<unowned Alpm.Package> packages = grp.packages; + while (packages != null) { + unowned Alpm.Package pkg = packages.data; + result.add (pkg); + packages.next (); + } + } + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + grp = db.get_group (group_name); + if (grp != null) { + unowned Alpm.List<unowned Alpm.Package> packages = grp.packages; + while (packages != null) { + unowned Alpm.Package pkg = packages.data; + if (result.find (pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { + result.add (pkg); + } + packages.next (); + } + } + syncdbs.next (); + } + return result; + } + + public async AlpmPackage[] get_group_pkgs (string groupname) { + AlpmPackage[] pkgs = {}; + Alpm.List<unowned Alpm.Package> alpm_pkgs = group_pkgs (groupname); + unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; + while (list != null) { + unowned Alpm.Package alpm_pkg = list.data; + pkgs += initialise_pkg_struct (alpm_pkg); + list.next (); + } + return pkgs; + } + + public string[] get_pkg_uninstalled_optdeps (string pkgname) { + string[] optdeps = {}; + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg == null) { + alpm_pkg = get_syncpkg (pkgname); + } + if (alpm_pkg != null) { + unowned Alpm.List<unowned Alpm.Depend> optdepends = alpm_pkg.optdepends; + while (optdepends != null) { + unowned Alpm.Depend optdep = optdepends.data; + if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, optdep.name) == null) { + optdeps += optdep.compute_string (); + } + optdepends.next (); + } + } + return optdeps; + } + + public AlpmPackageDetails get_pkg_details (string pkgname) { + string name = ""; + string version = ""; + string desc = ""; + string url = ""; + string repo = ""; + string has_signature = ""; + string reason = ""; + string packager = ""; + string builddate = ""; + string installdate = ""; + string[] groups = {}; + string[] backups = {}; + string[] files = {}; + string[] licenses = {}; + string[] depends = {}; + string[] optdepends = {}; + string[] requiredby = {}; + string[] optionalfor = {}; + string[] provides = {}; + string[] replaces = {}; + string[] conflicts = {}; + var details = AlpmPackageDetails (); + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg == null) { + alpm_pkg = get_syncpkg (pkgname); + } + if (alpm_pkg != null) { + // name + name = alpm_pkg.name; + // version + version = alpm_pkg.version; + // desc can be null + if (alpm_pkg.desc != null) { + desc = Markup.escape_text (alpm_pkg.desc); + } + // url can be null + if (alpm_pkg.url != null) { + url = Markup.escape_text (alpm_pkg.url); + } + // packager can be null + packager = alpm_pkg.packager ?? ""; + // groups + unowned Alpm.List list = alpm_pkg.groups; + while (list != null) { + groups += ((Alpm.List<unowned string>) list).data; + list.next (); + } + // licenses + list = alpm_pkg.licenses; + while (list != null) { + licenses += ((Alpm.List<unowned string>) list).data; + list.next (); + } + // build_date + GLib.Time time = GLib.Time.local ((time_t) alpm_pkg.builddate); + builddate = time.format ("%a %d %b %Y %X %Z"); + // local pkg + if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) { + // repo + unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name); + if (sync_pkg != null) { + repo = sync_pkg.db.name; + } + // reason + if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { + reason = _("Explicitly installed"); + } else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) { + reason = _("Installed as a dependency for another package"); + } else { + reason = _("Unknown"); + } + // install_date + time = GLib.Time.local ((time_t) alpm_pkg.installdate); + installdate = time.format ("%a %d %b %Y %X %Z"); + // backups + list = alpm_pkg.backups; + while (list != null) { + backups += "/" + ((Alpm.List<unowned Alpm.Backup>) list).data.name; + list.next (); + } + // requiredby + Alpm.List<string> pkg_requiredby = alpm_pkg.compute_requiredby (); + list = pkg_requiredby; + while (list != null) { + requiredby += ((Alpm.List<unowned string>) list).data; + list.next (); + } + pkg_requiredby.free_inner (GLib.free); + // optionalfor + Alpm.List<string> pkg_optionalfor = alpm_pkg.compute_optionalfor (); + list = pkg_optionalfor; + while (list != null) { + optionalfor += ((Alpm.List<unowned string>) list).data; + list.next (); + } + pkg_optionalfor.free_inner (GLib.free); + // files + unowned Alpm.FileList filelist = alpm_pkg.files; + Alpm.File* file_ptr = filelist.files; + for (size_t i = 0; i < filelist.count; i++, file_ptr++) { + if (!file_ptr->name.has_suffix ("/")) { + files += "/" + file_ptr->name; + } + } + // sync pkg + } else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) { + // repos + repo = alpm_pkg.db.name; + // signature + has_signature = alpm_pkg.base64_sig != null ? _("Yes") : _("No"); + } + // depends + list = alpm_pkg.depends; + while (list != null) { + depends += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string (); + list.next (); + } + // optdepends + list = alpm_pkg.optdepends; + while (list != null) { + optdepends += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string (); + list.next (); + } + // provides + list = alpm_pkg.provides; + while (list != null) { + provides += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string (); + list.next (); + } + // replaces + list = alpm_pkg.replaces; + while (list != null) { + replaces += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string (); + list.next (); + } + // conflicts + list = alpm_pkg.conflicts; + while (list != null) { + conflicts += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string (); + list.next (); + } + } + details.name = (owned) name; + details.version = (owned) version; + details.desc = (owned) desc; + details.repo = (owned) repo; + details.url = (owned) url; + details.packager = (owned) packager; + details.builddate = (owned) builddate; + details.installdate = (owned) installdate; + details.reason = (owned) reason; + details.has_signature = (owned) has_signature; + details.licenses = (owned) licenses; + details.depends = (owned) depends; + details.optdepends = (owned) optdepends; + details.requiredby = (owned) requiredby; + details.optionalfor = (owned) optionalfor; + details.provides = (owned) provides; + details.replaces = (owned) replaces; + details.conflicts = (owned) conflicts; + details.groups = (owned) groups; + details.backups = (owned) backups; + details.files = (owned) files; + return details; } public void start_get_updates (bool check_aur_updates) { - PackageInfos[] updates_infos = {}; + UpdateInfos[] updates_infos = {}; unowned Alpm.Package? pkg = null; unowned Alpm.Package? candidate = null; - foreach (var name in alpm_config.syncfirsts) { - pkg = Alpm.find_satisfier (alpm_config.handle.localdb.pkgcache, name); + foreach (unowned string name in alpm_config.get_syncfirsts ()) { + pkg = Alpm.find_satisfier (alpm_handle.localdb.pkgcache, name); if (pkg != null) { - candidate = pkg.sync_newversion (alpm_config.handle.syncdbs); + candidate = pkg.sync_newversion (alpm_handle.syncdbs); if (candidate != null) { - var infos = PackageInfos () { + var infos = UpdateInfos () { name = candidate.name, - version = candidate.version, - db_name = candidate.db.name, + old_version = pkg.version, + new_version = candidate.version, + repo = candidate.db.name, download_size = candidate.download_size }; updates_infos += (owned) infos; @@ -403,26 +1137,32 @@ namespace Pamac { return; } else { string[] local_pkgs = {}; - foreach (var installed_pkg in alpm_config.handle.localdb.pkgcache) { + unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package installed_pkg = pkgcache.data; // check if installed_pkg is in IgnorePkg or IgnoreGroup - if (alpm_config.handle.should_ignore (installed_pkg) == 0) { - candidate = installed_pkg.sync_newversion (alpm_config.handle.syncdbs); + if (alpm_handle.should_ignore (installed_pkg) == 0) { + candidate = installed_pkg.sync_newversion (alpm_handle.syncdbs); if (candidate != null) { - var infos = PackageInfos () { + var infos = UpdateInfos () { name = candidate.name, - version = candidate.version, - db_name = candidate.db.name, + old_version = installed_pkg.version, + new_version = candidate.version, + repo = candidate.db.name, download_size = candidate.download_size }; updates_infos += (owned) infos; } else { - if (check_aur_updates) { + if (check_aur_updates && (aur_updates_results.get_length () == 0)) { // check if installed_pkg is a local pkg - foreach (var db in alpm_config.handle.syncdbs) { + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; pkg = Alpm.find_satisfier (db.pkgcache, installed_pkg.name); if (pkg != null) { break; } + syncdbs.next (); } if (pkg == null) { local_pkgs += installed_pkg.name; @@ -430,43 +1170,64 @@ namespace Pamac { } } } + pkgcache.next (); } - PackageInfos[] aur_updates_infos = {}; if (check_aur_updates) { // get aur updates if (aur_updates_results.get_length () == 0) { - aur_updates_results = AUR.multiinfo (local_pkgs); - } - aur_updates_results.foreach_element ((array, index,node) => { - unowned Json.Object pkg_info = node.get_object (); - string version = pkg_info.get_string_member ("Version"); - string name = pkg_info.get_string_member ("Name"); - int cmp = Alpm.pkg_vercmp (version, alpm_config.handle.localdb.get_pkg (name).version); - if (cmp == 1) { - var infos = PackageInfos () { - name = name, - version = version, - db_name = "AUR", - download_size = 0 + AUR.multiinfo.begin (local_pkgs, (obj, res) => { + aur_updates_results = AUR.multiinfo.end (res); + var updates = Updates () { + is_syncfirst = false, + repos_updates = (owned) updates_infos, + aur_updates = get_aur_updates_infos () }; - aur_updates_infos += (owned) infos; - } - }); + get_updates_finished (updates); + }); + } else { + var updates = Updates () { + is_syncfirst = false, + repos_updates = (owned) updates_infos, + aur_updates = get_aur_updates_infos () + }; + get_updates_finished (updates); + } + } else { + var updates = Updates () { + is_syncfirst = false, + repos_updates = (owned) updates_infos, + aur_updates = {} + }; + get_updates_finished (updates); } - var updates = Updates () { - is_syncfirst = false, - repos_updates = (owned) updates_infos, - aur_updates = (owned) aur_updates_infos - }; - get_updates_finished (updates); } } + private UpdateInfos[] get_aur_updates_infos () { + UpdateInfos[] aur_updates_infos = {}; + aur_updates_results.foreach_element ((array, index, node) => { + unowned Json.Object pkg_info = node.get_object (); + unowned string name = pkg_info.get_string_member ("Name"); + unowned string new_version = pkg_info.get_string_member ("Version"); + unowned string old_version = alpm_handle.localdb.get_pkg (name).version; + if (Alpm.pkg_vercmp (new_version, old_version) == 1) { + var infos = UpdateInfos () { + name = name, + old_version = old_version, + new_version = new_version, + repo = "" + }; + aur_updates_infos += (owned) infos; + } + }); + return aur_updates_infos; + } + public bool trans_init (Alpm.TransFlag transflags) { current_error = ErrorInfos (); cancellable.reset (); - if (alpm_config.handle.trans_init (transflags) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + if (alpm_handle.trans_init (transflags) == -1) { + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to init transaction"); current_error.details = { Alpm.strerror (errno) }; @@ -479,8 +1240,8 @@ namespace Pamac { public bool trans_sysupgrade (bool enable_downgrade) { current_error = ErrorInfos (); - if (alpm_config.handle.trans_sysupgrade ((enable_downgrade) ? 1 : 0) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + if (alpm_handle.trans_sysupgrade ((enable_downgrade) ? 1 : 0) == -1) { + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to prepare transaction"); current_error.details = { Alpm.strerror (errno) }; @@ -491,8 +1252,8 @@ namespace Pamac { private bool trans_add_pkg_real (Alpm.Package pkg) { current_error = ErrorInfos (); - if (alpm_config.handle.trans_add_pkg (pkg) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + if (alpm_handle.trans_add_pkg (pkg) == -1) { + Alpm.Errno errno = alpm_handle.errno (); if (errno == Alpm.Errno.TRANS_DUP_TARGET || errno == Alpm.Errno.PKG_IGNORED) { // just skip duplicate or ignored targets return true; @@ -506,20 +1267,9 @@ namespace Pamac { return true; } - private unowned Alpm.Package? get_sync_pkg (string pkgname) { - unowned Alpm.Package? pkg = null; - foreach (var db in alpm_config.handle.syncdbs) { - pkg = db.get_pkg (pkgname); - if (pkg != null) { - break; - } - } - return pkg; - } - public bool trans_add_pkg (string pkgname) { current_error = ErrorInfos (); - unowned Alpm.Package? pkg = get_sync_pkg (pkgname); + unowned Alpm.Package? pkg = get_syncpkg (pkgname); if (pkg == null) { current_error.message = _("Failed to prepare transaction"); current_error.details = { _("target not found: %s").printf (pkgname) }; @@ -530,7 +1280,9 @@ namespace Pamac { if (("linux31" in pkg.name) || ("linux4" in pkg.name)) { string[] installed_kernels = {}; string[] installed_modules = {}; - foreach (var local_pkg in alpm_config.handle.localdb.pkgcache) { + unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package local_pkg = pkgcache.data; if (("linux31" in local_pkg.name) || ("linux4" in local_pkg.name)) { string[] local_pkg_splitted = local_pkg.name.split ("-", 2); if ((local_pkg_splitted[0] in installed_kernels) == false) { @@ -542,6 +1294,7 @@ namespace Pamac { } } } + pkgcache.next (); } string[] splitted = pkg.name.split ("-", 2); if (splitted.length == 2) { @@ -549,7 +1302,7 @@ namespace Pamac { // add the same module for other installed kernels foreach (unowned string installed_kernel in installed_kernels) { string module = installed_kernel + "-" + splitted[1]; - unowned Alpm.Package? module_pkg = get_sync_pkg (module); + unowned Alpm.Package? module_pkg = get_syncpkg (module); if (module_pkg != null) { trans_add_pkg_real (module_pkg); } @@ -559,7 +1312,7 @@ namespace Pamac { // add all installed modules for other kernels foreach (unowned string installed_module in installed_modules) { string module = splitted[0] + "-" + installed_module; - unowned Alpm.Package? module_pkg = get_sync_pkg (module); + unowned Alpm.Package? module_pkg = get_syncpkg (module); if (module_pkg != null) { trans_add_pkg_real (module_pkg); } @@ -573,15 +1326,15 @@ namespace Pamac { public bool trans_load_pkg (string pkgpath) { current_error = ErrorInfos (); - Alpm.Package* pkg = alpm_config.handle.load_file (pkgpath, 1, alpm_config.handle.localfilesiglevel); - if (pkg == null) { - Alpm.Errno errno = alpm_config.handle.errno (); + Alpm.Package* pkg; + if (alpm_handle.load_tarball (pkgpath, 1, alpm_handle.localfilesiglevel, out pkg) == -1) { + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to prepare transaction"); current_error.details = { "%s: %s".printf (pkgpath, Alpm.strerror (errno)) }; return false; - } else if (alpm_config.handle.trans_add_pkg (pkg) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + } else if (alpm_handle.trans_add_pkg (pkg) == -1) { + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to prepare transaction"); current_error.details = { "%s: %s".printf (pkg->name, Alpm.strerror (errno)) }; @@ -594,13 +1347,13 @@ namespace Pamac { public bool trans_remove_pkg (string pkgname) { current_error = ErrorInfos (); - unowned Alpm.Package? pkg = alpm_config.handle.localdb.get_pkg (pkgname); + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); if (pkg == null) { current_error.message = _("Failed to prepare transaction"); current_error.details = { _("target not found: %s").printf (pkgname) }; return false; - } else if (alpm_config.handle.trans_remove_pkg (pkg) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + } else if (alpm_handle.trans_remove_pkg (pkg) == -1) { + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to prepare transaction"); current_error.details = { "%s: %s".printf (pkg.name, Alpm.strerror (errno)) }; @@ -612,9 +1365,9 @@ namespace Pamac { private void trans_prepare () { current_error = ErrorInfos (); string[] details = {}; - Alpm.List<void*> err_data; - if (alpm_config.handle.trans_prepare (out err_data) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + Alpm.List err_data; + if (alpm_handle.trans_prepare (out err_data) == -1) { + Alpm.Errno errno = alpm_handle.errno (); current_error.errno = (uint) errno; current_error.message = _("Failed to prepare transaction"); string detail = Alpm.strerror (errno); @@ -622,26 +1375,31 @@ namespace Pamac { case Alpm.Errno.PKG_INVALID_ARCH: detail += ":"; details += (owned) detail; - foreach (void* i in err_data) { - string* pkgname = i; + unowned Alpm.List<string*> list = err_data; + while (list != null) { + string* pkgname = list.data; details += _("package %s does not have a valid architecture").printf (pkgname); delete pkgname; + list.next (); } break; case Alpm.Errno.UNSATISFIED_DEPS: detail += ":"; details += (owned) detail; - foreach (void* i in err_data) { - Alpm.DepMissing* miss = i; + unowned Alpm.List<Alpm.DepMissing*> list = err_data; + while (list != null) { + Alpm.DepMissing* miss = list.data; details += _("%s: requires %s").printf (miss->target, miss->depend.compute_string ()); delete miss; + list.next (); } break; case Alpm.Errno.CONFLICTING_DEPS: detail += ":"; details += (owned) detail; - foreach (void* i in err_data) { - Alpm.Conflict* conflict = i; + unowned Alpm.List<Alpm.Conflict*> list = err_data; + while (list != null) { + Alpm.Conflict* conflict = list.data; string conflict_detail = _("%s and %s are in conflict").printf (conflict->package1, conflict->package2); // only print reason if it contains new information if (conflict->reason.mod != Alpm.Depend.Mode.ANY) { @@ -649,6 +1407,7 @@ namespace Pamac { } details += (owned) conflict_detail; delete conflict; + list.next (); } break; default: @@ -661,12 +1420,15 @@ namespace Pamac { } else { // Search for holdpkg in target list bool found_locked_pkg = false; - foreach (var pkg in alpm_config.handle.trans_to_remove ()) { - if (alpm_config.holdpkgs.find_custom (pkg.name, strcmp) != null) { + unowned Alpm.List<unowned Alpm.Package> to_remove = alpm_handle.trans_to_remove (); + while (to_remove != null) { + unowned Alpm.Package pkg = to_remove.data; + if (alpm_config.get_holdpkgs ().find_custom (pkg.name, strcmp) != null) { details += _("%s needs to be removed but it is a locked package").printf (pkg.name); found_locked_pkg = true; break; } + to_remove.next (); } if (found_locked_pkg) { current_error.message = _("Failed to prepare transaction"); @@ -694,41 +1456,67 @@ namespace Pamac { provider_mutex.unlock (); } - public PackageInfos[] trans_to_add () { - PackageInfos[] to_add = {}; - foreach (var pkg in alpm_config.handle.trans_to_add ()) { - var infos = PackageInfos () { - name = pkg.name, - version = pkg.version, + public TransactionSummary get_transaction_summary () { + UpdateInfos[] to_install = {}; + UpdateInfos[] to_upgrade = {}; + UpdateInfos[] to_downgrade = {}; + UpdateInfos[] to_reinstall = {}; + UpdateInfos[] to_remove = {}; + unowned Alpm.List<unowned Alpm.Package> pkgs_to_add = alpm_handle.trans_to_add (); + while (pkgs_to_add != null) { + unowned Alpm.Package trans_pkg = pkgs_to_add.data; + unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (trans_pkg.name); + var infos = UpdateInfos () { + name = trans_pkg.name, + old_version = local_pkg != null ? local_pkg.version : "", + new_version = trans_pkg.version, // if pkg was load from a file, pkg.db is null - db_name = pkg.db != null ? pkg.db.name : "", - download_size = pkg.download_size + repo =trans_pkg.db != null ? trans_pkg.db.name : "", + download_size = trans_pkg.download_size }; - to_add += (owned) infos; + if (local_pkg == null) { + to_install += (owned) infos; + } else { + int cmp = Alpm.pkg_vercmp (trans_pkg.version, local_pkg.version); + if (cmp == 1) { + to_upgrade += (owned) infos; + } else if (cmp == 0) { + to_reinstall += (owned) infos; + } else { + to_downgrade += (owned) infos; + } + } + pkgs_to_add.next (); } - return to_add; - } - - public PackageInfos[] trans_to_remove () { - PackageInfos[] to_remove = {}; - foreach (var pkg in alpm_config.handle.trans_to_remove ()) { - var infos = PackageInfos () { - name = pkg.name, - version = pkg.version, - db_name = pkg.db.name, - download_size = pkg.download_size + unowned Alpm.List<unowned Alpm.Package> pkgs_to_remove = alpm_handle.trans_to_remove (); + while (pkgs_to_remove != null) { + unowned Alpm.Package trans_pkg = pkgs_to_remove.data; + var infos = UpdateInfos () { + name = trans_pkg.name, + old_version = trans_pkg.version, + new_version = "", + repo = trans_pkg.db.name }; to_remove += (owned) infos; + pkgs_to_remove.next (); } - return to_remove; + var summary = TransactionSummary () { + to_install = (owned) to_install, + to_upgrade = (owned) to_upgrade, + to_downgrade = (owned) to_downgrade, + to_reinstall = (owned) to_reinstall, + to_remove = (owned) to_remove + }; + return summary; } private void trans_commit () { current_error = ErrorInfos (); bool success = true; - Alpm.List<void*> err_data; - if (alpm_config.handle.trans_commit (out err_data) == -1) { - Alpm.Errno errno = alpm_config.handle.errno (); + Alpm.List err_data; + if (alpm_handle.trans_commit (out err_data) == -1) { + Alpm.Errno errno = alpm_handle.errno (); + current_error.errno = (uint) errno; // cancel the download return an EXTERNAL_DOWNLOAD error if (errno == Alpm.Errno.EXTERNAL_DOWNLOAD && cancellable.is_cancelled ()) { trans_release (); @@ -736,7 +1524,6 @@ namespace Pamac { trans_commit_finished (false); return; } - current_error.errno = (uint) errno; current_error.message = _("Failed to commit transaction"); string detail = Alpm.strerror (errno); string[] details = {}; @@ -744,12 +1531,13 @@ namespace Pamac { case Alpm.Errno.FILE_CONFLICTS: detail += ":"; details += (owned) detail; - //TransFlag flags = alpm_config.handle.trans_get_flags (); + //TransFlag flags = alpm_handle.trans_get_flags (); //if ((flags & TransFlag.FORCE) != 0) { //details += _("unable to %s directory-file conflicts").printf ("--force"); //} - foreach (void* i in err_data) { - Alpm.FileConflict* conflict = i; + unowned Alpm.List<Alpm.FileConflict*> list = err_data; + while (list != null) { + Alpm.FileConflict* conflict = list.data; switch (conflict->type) { case Alpm.FileConflict.Type.TARGET: details += _("%s exists in both %s and %s").printf (conflict->file, conflict->target, conflict->ctarget); @@ -759,6 +1547,7 @@ namespace Pamac { break; } delete conflict; + list.next (); } break; case Alpm.Errno.PKG_INVALID: @@ -767,10 +1556,12 @@ namespace Pamac { case Alpm.Errno.DLT_INVALID: detail += ":"; details += (owned) detail; - foreach (void* i in err_data) { - string* filename = i; + unowned Alpm.List<string*> list = err_data; + while (list != null) { + string* filename = list.data; details += _("%s is invalid or corrupted").printf (filename); delete filename; + list.next (); } break; default: @@ -806,13 +1597,13 @@ namespace Pamac { } public void trans_release () { - alpm_config.handle.trans_release (); + alpm_handle.trans_release (); intern_lock = false; } [DBus (no_reply = true)] public void trans_cancel () { - if (alpm_config.handle.trans_interrupt () == 0) { + if (alpm_handle.trans_interrupt () == 0) { // a transaction is being interrupted // it will end the normal way return; @@ -826,7 +1617,7 @@ namespace Pamac { // the above function will wait for all task in queue // to be processed before return; ThreadPool.free ((owned) thread_pool, false, true); - alpm_config.handle.unlock (); + alpm_handle.unlock (); loop.quit (); } // End of Daemon Object @@ -977,8 +1768,11 @@ private void cb_question (Alpm.Question.Data data) { case Alpm.Question.Type.SELECT_PROVIDER: string depend_str = data.select_provider_depend.compute_string (); string[] providers_str = {}; - foreach (unowned Alpm.Package pkg in data.select_provider_providers) { + unowned Alpm.List<unowned Alpm.Package> list = data.select_provider_providers; + while (list != null) { + unowned Alpm.Package pkg = list.data; providers_str += pkg.name; + list.next (); } pamac_daemon.provider_cond = Cond (); pamac_daemon.provider_mutex = Mutex (); @@ -1040,6 +1834,10 @@ private int cb_download (void* data, uint64 dltotal, uint64 dlnow, uint64 ultota } else if (unlikely (dlnow == 0)) { pamac_daemon.emit_download (filename, dlnow, dltotal); pamac_daemon.timer.start (); + } else if (unlikely (prevprogress == 0)) { + pamac_daemon.emit_download (filename, 0, dltotal); + pamac_daemon.emit_download (filename, dlnow, dltotal); + pamac_daemon.timer.start (); } else if (unlikely (dlnow == dltotal)) { pamac_daemon.emit_download (filename, dlnow, dltotal); pamac_daemon.timer.stop (); diff --git a/src/manager_window.vala b/src/manager_window.vala index cdd199c58a3580ca407aacaa11273835c37384ef..202c945a6bfb10951218da10bbc293ccec607892 100644 --- a/src/manager_window.vala +++ b/src/manager_window.vala @@ -17,13 +17,23 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -const string VERSION = "3.2.1"; +const string VERSION = "4.0.0"; namespace Pamac { - struct SortInfo { - public int column_number; - public Gtk.SortType sort_type; + class ActivableCellRendererPixbuf : Gtk.CellRendererPixbuf { + public signal void activated (Gtk.TreePath path); + + public ActivableCellRendererPixbuf () { + Object (); + this.mode = Gtk.CellRendererMode.ACTIVATABLE; + } + + 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; + } } [GtkTemplate (ui = "/org/manjaro/pamac/manager/manager_window.ui")] @@ -34,35 +44,22 @@ namespace Pamac { public Gdk.Pixbuf? to_install_icon; public Gdk.Pixbuf? to_reinstall_icon; public Gdk.Pixbuf? to_remove_icon; - public Gdk.Pixbuf? locked_icon; + public Gdk.Pixbuf? installed_locked_icon; + public Gdk.Pixbuf? available_locked_icon; // manager objects [GtkChild] - Gtk.TreeView packages_treeview; - [GtkChild] - public Gtk.TreeViewColumn packages_state_column; - [GtkChild] - public Gtk.TreeViewColumn packages_name_column; + Gtk.Stack main_stack; [GtkChild] - public Gtk.TreeViewColumn packages_version_column; - [GtkChild] - public Gtk.TreeViewColumn packages_repo_column; + Gtk.TreeView packages_treeview; [GtkChild] - public Gtk.TreeViewColumn packages_size_column; + Gtk.TreeViewColumn packages_state_column; [GtkChild] Gtk.TreeView aur_treeview; [GtkChild] - Gtk.ScrolledWindow aur_scrolledwindow; - [GtkChild] - public Gtk.TreeViewColumn aur_state_column; - [GtkChild] - public Gtk.TreeViewColumn aur_name_column; + Gtk.TreeViewColumn aur_state_column; [GtkChild] - public Gtk.TreeViewColumn aur_version_column; - [GtkChild] - public Gtk.TreeViewColumn aur_votes_column; - [GtkChild] - Gtk.Notebook filters_notebook; + Gtk.Stack filters_stack; [GtkChild] Gtk.SearchEntry search_entry; [GtkChild] @@ -74,12 +71,14 @@ namespace Pamac { [GtkChild] Gtk.TreeView repos_treeview; [GtkChild] - Gtk.Notebook packages_notebook; + Gtk.Stack packages_stack; [GtkChild] - Gtk.Notebook properties_notebook; + Gtk.StackSwitcher packages_stackswitcher; [GtkChild] Gtk.TreeView deps_treeview; [GtkChild] + Gtk.TreeViewColumn deps_treeview_column; + [GtkChild] Gtk.TreeView details_treeview; [GtkChild] Gtk.ScrolledWindow files_scrolledwindow; @@ -98,9 +97,13 @@ namespace Pamac { [GtkChild] Gtk.Switch search_aur_button; [GtkChild] - Gtk.Button valid_button; + Gtk.Box transaction_infobox; [GtkChild] - Gtk.Button cancel_button; + Gtk.Label transaction_infos_label; + [GtkChild] + Gtk.Button transaction_infos_apply_button; + [GtkChild] + Gtk.Button transaction_infos_cancel_button; // menu Gtk.Menu right_click_menu; @@ -110,29 +113,26 @@ namespace Pamac { Gtk.MenuItem reinstall_item; Gtk.MenuItem install_optional_deps_item; Gtk.MenuItem explicitly_installed_item; - Alpm.List<unowned Alpm.Package?> selected_pkgs; - GLib.List<unowned Json.Object> selected_aur; + GLib.List<string> selected_pkgs; + GLib.List<string> selected_aur; - // liststore + // liststores Gtk.ListStore search_list; Gtk.ListStore groups_list; Gtk.ListStore states_list; Gtk.ListStore repos_list; Gtk.ListStore deps_list; Gtk.ListStore details_list; + Gtk.ListStore packages_list; + Gtk.ListStore aur_list; - PackagesModel packages_list; - AURModel aur_list; - - HashTable<string,Json.Array> aur_search_results; - string current_package_path; - string current_aur_path; + Queue<string> display_package_queue; + string current_package_displayed; public Transaction transaction; - public SortInfo sortinfo; - bool refreshing; + public bool transaction_running; uint search_entry_timeout_id; @@ -140,7 +140,9 @@ namespace Pamac { Object (application: application); support_aur (false, false); + transaction_infobox.visible = false;; refreshing = false; + transaction_running = false; Timeout.add (100, populate_window); } @@ -181,51 +183,133 @@ namespace Pamac { repos_treeview.set_model (repos_list); deps_list = new Gtk.ListStore (2, typeof (string), typeof (string)); deps_treeview.set_model (deps_list); + // title is not visible, it is just defined to find it + deps_treeview_column.title = "deps"; details_list = new Gtk.ListStore (2, typeof (string), typeof (string)); details_treeview.set_model (details_list); + packages_list = new Gtk.ListStore (7, + typeof (uint), //origin + typeof (string), //name + typeof (string), //name+desc + typeof (string), //version + typeof (string), //repo + typeof (uint64), //isize + typeof (string)); //GLib.format (isize) + // sort packages by name by default + packages_list.set_sort_column_id (1, Gtk.SortType.ASCENDING); + 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, true); + 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 (origin == 2 ) { //origin == Alpm.Package.From.LOCALDB) + if (unlikely (transaction.transaction_summary.contains (pkgname))) { + pixbuf = installed_locked_icon; + } else if (unlikely (transaction.should_hold (pkgname))) { + pixbuf = installed_locked_icon; + } else if (unlikely (transaction.to_install.contains (pkgname))) { + pixbuf = to_reinstall_icon; + } else if (unlikely (transaction.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 (transaction.to_install.contains (pkgname))) { + pixbuf = to_install_icon; + } else { + pixbuf = uninstalled_icon; + } + cellrenderer.set ("pixbuf", pixbuf); + }); + packages_state_renderer.activated.connect (on_packages_state_icon_activated); + + aur_list = new Gtk.ListStore (6, + typeof (uint), //origin + typeof (string), //name + typeof (string), //name+desc + typeof (string), //version + typeof (double), //popularity + typeof (string)); //populariy to string + // 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, true); + 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 ((uint) origin == 2 ) { //origin == Alpm.Package.From.LOCALDB) + if (unlikely (transaction.transaction_summary.contains (pkgname))) { + pixbuf = installed_locked_icon; + } else if (unlikely (transaction.should_hold (pkgname))) { + pixbuf = installed_locked_icon; + } else if (unlikely (transaction.to_install.contains (pkgname))) { + pixbuf = to_reinstall_icon; + } else if (unlikely (transaction.to_remove.contains (pkgname))) { + pixbuf = to_remove_icon; + } else { + pixbuf = installed_icon; + } + } else if (unlikely (transaction.to_build.contains (pkgname))) { + pixbuf = to_install_icon; + } else { + pixbuf = uninstalled_icon; + } + cellrenderer.set ("pixbuf", pixbuf); + }); + aur_state_renderer.activated.connect (on_aur_state_icon_activated); + try { installed_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-updated.png"); uninstalled_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available.png"); to_install_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-install.png"); to_reinstall_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-reinstall.png"); to_remove_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-remove.png"); - locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png"); + installed_locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png"); + available_locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available-locked.png"); } catch (GLib.Error e) { stderr.printf (e.message); } transaction = new Transaction (this as Gtk.ApplicationWindow); transaction.mode = Mode.MANAGER; + transaction.start_transaction.connect (on_start_transaction); + transaction.emit_action.connect (on_emit_action); transaction.finished.connect (on_transaction_finished); transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished); transaction.set_pkgreason_finished.connect (on_set_pkgreason_finished); - unowned Alpm.Package? pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "yaourt"); - if (pkg != null) { - support_aur (transaction.pamac_config.enable_aur, transaction.pamac_config.search_aur); + AlpmPackage pkg = transaction.find_installed_satisfier ("yaourt"); + if (pkg.name != "") { + support_aur (transaction.enable_aur, transaction.search_aur); } - set_buttons_sensitive (false); - - // sort by name by default - sortinfo = {0, Gtk.SortType.ASCENDING}; - - aur_search_results = new HashTable<string,Json.Array> (str_hash, str_equal); + display_package_queue = new Queue<string> (); update_lists (); show_default_pkgs (); + search_entry.grab_focus (); + + filters_stack.notify["visible-child"].connect (on_filters_stack_visible_child_changed); + packages_stack.notify["visible-child"].connect (on_packages_stack_visible_child_changed); return false; } void on_write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, bool enable_aur, bool search_aur) { - if (recurse) { - transaction.flags |= Alpm.TransFlag.RECURSE; - } - unowned Alpm.Package? pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "yaourt"); - if (pkg != null) { + AlpmPackage pkg = transaction.find_installed_satisfier ("yaourt"); + if (pkg.name != "") { support_aur (enable_aur, search_aur); } } @@ -236,57 +320,53 @@ namespace Pamac { void support_aur (bool enable_aur, bool search_aur) { if (enable_aur) { - search_aur_button.set_active (search_aur); - search_aur_box.set_visible (true); - aur_scrolledwindow.set_visible (true); + search_aur_button.active = search_aur; + search_aur_box.visible = true; + if (filters_stack.visible_child_name == "search") { + packages_stackswitcher.visible = true; + } } else { - search_aur_button.set_active (false); - search_aur_box.set_visible (false); - aur_scrolledwindow.set_visible (false); + search_aur_button.active = false; + search_aur_box.visible = false; + packages_stackswitcher.visible = false; } } - void set_buttons_sensitive (bool sensitive) { - valid_button.set_sensitive (sensitive); - cancel_button.set_sensitive (sensitive); + void set_pendings_operations () { + if (!transaction_running) { + uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; + if (total_pending == 0) { + transaction_infobox.visible = false; + } else { + string info = dngettext (null, "%u pending operation", "%u pending operations", total_pending).printf (total_pending); + transaction_infos_label.label = info; + transaction_infobox.visible = true; + } + } } void show_default_pkgs () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - get_installed_pkgs.begin ((obj, res) => { - var pkgs = get_installed_pkgs.end (res); - populate_packages_list ((owned) pkgs); + transaction.get_installed_pkgs.begin ((obj, res) => { + populate_packages_list (transaction.get_installed_pkgs.end (res)); }); } void update_lists () { Gtk.TreeIter iter; - Gtk.TreeSelection selection; - selection = repos_treeview.get_selection (); + Gtk.TreeSelection selection = repos_treeview.get_selection (); selection.changed.disconnect (on_repos_treeview_selection_changed); - var groups_names = new GLib.List<string> (); - foreach (var db in transaction.alpm_utils.get_syncdbs ()) { - repos_list.insert_with_values (out iter, -1, 0, db.name); - foreach (var group in db.groupcache) { - if (groups_names.find_custom (group.name, strcmp) == null) { - groups_names.append (group.name); - } - } + foreach (unowned string repo in transaction.get_repos_names ()) { + repos_list.insert_with_values (null, -1, 0, repo); } - repos_list.insert_with_values (out iter, -1, 0, dgettext (null, "local")); repos_list.get_iter_first (out iter); selection.select_iter (iter); selection.changed.connect_after (on_repos_treeview_selection_changed); selection = groups_treeview.get_selection (); selection.changed.disconnect (on_groups_treeview_selection_changed); - foreach (var group in transaction.alpm_utils.get_localdb ().groupcache) { - if (groups_names.find_custom (group.name, strcmp) == null) { - groups_names.append (group.name); - } - } - foreach (unowned string group_name in groups_names) { - groups_list.insert_with_values (out iter, -1, 0, group_name); + foreach (unowned string group in transaction.get_groups_names ()) { + groups_list.insert_with_values (null, -1, 0, group); } groups_list.set_sort_column_id (0, Gtk.SortType.ASCENDING); groups_list.get_iter_first (out iter); @@ -295,484 +375,341 @@ namespace Pamac { selection = states_treeview.get_selection (); selection.changed.disconnect (on_states_treeview_selection_changed); - states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Installed")); - //states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Uninstalled")); - states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Orphans")); - states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To install")); - states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To remove")); + states_list.insert_with_values (null, -1, 0, dgettext (null, "Installed")); + states_list.insert_with_values (null, -1, 0, dgettext (null, "Orphans")); + states_list.insert_with_values (null, -1, 0, dgettext (null, "Foreign")); + states_list.insert_with_values (null, -1, 0, dgettext (null, "Pending")); states_list.get_iter_first (out iter); selection.select_iter (iter); selection.changed.connect_after (on_states_treeview_selection_changed); } - void set_package_infos_list (Alpm.Package pkg) { - name_label.set_markup ("<big><b>%s %s</b></big>".printf (pkg.name, pkg.version)); - desc_label.set_markup (Markup.escape_text (pkg.desc)); - string url = Markup.escape_text (pkg.url); - link_label.set_markup ("<a href=\"%s\">%s</a>".printf (url, url)); + void set_package_details (string pkgname) { + AlpmPackageDetails details = transaction.get_pkg_details (pkgname); + // infos + name_label.set_markup ("<big><b>%s %s</b></big>".printf (details.name, details.version)); + desc_label.set_markup (details.desc); + link_label.set_markup ("<a href=\"%s\">%s</a>".printf (details.url, details.url)); StringBuilder licenses = new StringBuilder (); licenses.append (dgettext (null, "Licenses")); licenses.append (":"); - foreach (unowned string license in pkg.licenses) { + foreach (unowned string license in details.licenses) { licenses.append (" "); licenses.append (license); } licenses_label.set_markup (licenses.str); - } - - async void set_aur_infos_list (Json.Object pkg_info) { - unowned Json.Node? node; - node = pkg_info.get_member ("Name"); - unowned string name = node.get_string (); - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - Json.Object all_infos = yield transaction.get_aur_infos (name); - this.get_window ().set_cursor (null); - node = all_infos.get_member ("Version"); - name_label.set_markup ("<big><b>%s %s</b></big>".printf (name, node.get_string ())); - node = all_infos.get_member ("Description"); - desc_label.set_markup (Markup.escape_text (node.get_string ())); - string url = ""; - node = all_infos.get_member ("URL"); - if (!node.is_null ()) { - url = Markup.escape_text (node.get_string ()); - } - string aur_url = "http://aur.archlinux.org/packages/" + name; - link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (url, url, aur_url, aur_url)); - StringBuilder licenses = new StringBuilder (); - licenses.append (dgettext (null, "Licenses")); - licenses.append (":"); - node = all_infos.get_member ("License"); - if (node != null) { - unowned Json.Array array = node.get_array (); - uint i = 0; - uint length = array.get_length (); - while (i < length) { - licenses.append (" "); - licenses.append (array.get_string_element (i)); - i++; + // details + details_list.clear (); + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Repository") + ":"), + 1, details.repo); + var iter = Gtk.TreeIter (); + if (details.groups.length > 0) { + foreach (unowned string name in details.groups) { + details_list.insert_with_values (out iter, -1, + 1, name); + } + Gtk.TreePath path = details_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.groups.length - 1); + details_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + details_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Groups") + ":")); + } + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Packager") + ":"), + 1, details.packager); + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Build Date") + ":"), + 1, details.builddate); + if (details.installdate != "") { + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Install Date") + ":"), + 1, details.installdate); + } + if (details.reason != "") { + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Install Reason") + ":"), + 1, details.reason); + } + if (details.has_signature != "") { + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Signatures") + ":"), + 1, details.has_signature); + } + if (details.backups.length > 0) { + foreach (unowned string name in details.backups) { + details_list.insert_with_values (out iter, -1, + 1, name); } - } else { - licenses.append (dgettext (null, "Unknown")); + Gtk.TreePath path = details_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.backups.length - 1); + details_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + details_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Backup files") + ":")); } - licenses_label.set_markup (licenses.str); - } - - void set_package_deps_list (Alpm.Package pkg) { + // deps deps_list.clear (); - Gtk.TreeIter iter; - unowned Alpm.List<unowned Alpm.Depend> deps = pkg.depends; - unowned Alpm.List<unowned Alpm.Depend>? list; - if (deps.length != 0) { - list = deps; - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Depends On") + ":", - 1, list.data.compute_string ()); - for (list = list.next (); list != null; list = list.next ()) { + if (details.depends.length > 0) { + foreach (unowned string name in details.depends) { deps_list.insert_with_values (out iter, -1, - 1, list.data.compute_string ()); + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.depends.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Depends On") + ":")); } - deps = pkg.optdepends; - if (deps.length != 0) { - list = deps; - string optdep_str = list.data.compute_string (); - var optdep = new StringBuilder (optdep_str); - if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str) != null) { - optdep.append (" ["); - optdep.append (dgettext (null, "Installed")); - optdep.append ("]"); - } - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Optional Dependencies") + ":", - 1, optdep.str); - for (list = list.next (); list != null; list = list.next ()) { - optdep_str = list.data.compute_string (); - optdep = new StringBuilder (optdep_str); - if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str) != null) { + if (details.optdepends.length > 0) { + foreach (unowned string name in details.optdepends) { + var optdep = new StringBuilder (name); + if (transaction.find_installed_satisfier (optdep.str).name != "") { optdep.append (" ["); optdep.append (dgettext (null, "Installed")); optdep.append ("]"); } - deps_list.insert_with_values (out iter, -1, 1, optdep.str); - } - } - if (pkg.origin == Alpm.Package.From.LOCALDB) { - Alpm.List<string> requiredby = pkg.compute_requiredby (); - unowned Alpm.List<string>? list2; - if (requiredby.length != 0) { - list2 = requiredby; - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Required By") + ":", - 1, list2.data); - for (list2 = list2.next (); list2 != null; list2 = list2.next ()) { - deps_list.insert_with_values (out iter, -1, - 1, list2.data); - } - } - requiredby.free_data (); - Alpm.List<string> optionalfor = pkg.compute_optionalfor (); - if (optionalfor.length != 0) { - list2 = optionalfor; - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Optional For") + ":", - 1, list2.data); - for (list2 = list2.next (); list2 != null; list2 = list2.next ()) { - deps_list.insert_with_values (out iter, -1, - 1, list2.data); - } - } - optionalfor.free_data (); - } - deps = pkg.provides; - if (deps.length != 0) { - list = deps; - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Provides") + ":", - 1, list.data.compute_string ()); - for (list = list.next (); list != null; list = list.next ()) { deps_list.insert_with_values (out iter, -1, - 1, list.data.compute_string ()); + 1, optdep.str); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.optdepends.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Optional Dependencies") + ":")); } - deps = pkg.replaces; - if (deps.length != 0) { - list = deps; - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Replaces") + ":", - 1, list.data.compute_string ()); - for (list = list.next (); list != null; list = list.next ()) { + if (details.requiredby.length > 0) { + foreach (unowned string name in details.requiredby) { deps_list.insert_with_values (out iter, -1, - 1, list.data.compute_string ()); + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.requiredby.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Required By") + ":")); } - deps = pkg.conflicts; - if (deps.length != 0) { - list = deps; - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Conflicts With") + ":", - 1, list.data.compute_string ()); - for (list = list.next (); list != null; list = list.next ()) { + if (details.optionalfor.length > 0) { + foreach (unowned string name in details.optionalfor) { deps_list.insert_with_values (out iter, -1, - 1, list.data.compute_string ()); + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.optionalfor.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Optional For") + ":")); } - } - - async void set_aur_deps_list (Json.Object pkg_info) { - deps_list.clear (); - Gtk.TreeIter iter; - unowned Json.Node? node; - node = pkg_info.get_member ("Name"); - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - Json.Object all_infos = yield transaction.get_aur_infos (node.get_string ()); - this.get_window ().set_cursor (null); - unowned Json.Array deps; - uint i; - uint length; - node = all_infos.get_member ("Depends"); - if (node != null) { - deps = node.get_array (); - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Depends On") + ":", - 1, deps.get_string_element (0)); - i = 1; - length = deps.get_length (); - while (i < length) { + if (details.provides.length > 0) { + foreach (unowned string name in details.provides) { deps_list.insert_with_values (out iter, -1, - 1, deps.get_string_element (i)); - i++; + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.provides.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Provides") + ":")); } - node = all_infos.get_member ("MakeDepends"); - if (node != null) { - deps = node.get_array (); - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Make Dependencies") + ":", - 1, deps.get_string_element (0)); - i = 1; - length = deps.get_length (); - while (i < length) { + if (details.replaces.length > 0) { + foreach (unowned string name in details.replaces) { deps_list.insert_with_values (out iter, -1, - 1, deps.get_string_element (i)); - i++; + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.replaces.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Replaces") + ":")); } - node = all_infos.get_member ("CheckDepends"); - if (node != null) { - deps = node.get_array (); - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Check Dependencies") + ":", - 1, deps.get_string_element (0)); - i = 1; - length = deps.get_length (); - while (i < length) { + if (details.conflicts.length > 0) { + foreach (unowned string name in details.conflicts) { deps_list.insert_with_values (out iter, -1, - 1, deps.get_string_element (i)); - i++; + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.conflicts.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Conflicts With") + ":")); } - node = all_infos.get_member ("OptDepends"); - if (node != null) { - deps = node.get_array (); - string optdep_str = deps.get_string_element (0); - var optdep = new StringBuilder (optdep_str); - if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str) != null) { - optdep.append (" ["); - optdep.append (dgettext (null, "Installed")); - optdep.append ("]"); - } - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Optional Dependencies") + ":", - 1, optdep.str); - i = 1; - length = deps.get_length (); - while (i < length) { - optdep_str = deps.get_string_element (i); - optdep = new StringBuilder (optdep_str); - if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str.split (": ", 2)[0]) != null) { - optdep.append (" ["); - optdep.append (dgettext (null, "Installed")); - optdep.append ("]"); - } - deps_list.insert_with_values (out iter, -1, 1, optdep.str); - i++; - } - } - node = all_infos.get_member ("Provides"); - if (node != null) { - deps = node.get_array (); - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Provides") + ":", - 1, deps.get_string_element (0)); - i = 1; - length = deps.get_length (); - while (i < length) { - deps_list.insert_with_values (out iter, -1, - 1, deps.get_string_element (i)); - i++; - } - } - node = all_infos.get_member ("Replaces"); - if (node != null) { - deps = node.get_array (); - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Replaces") + ":", - 1, deps.get_string_element (0)); - i = 1; - length = deps.get_length (); - while (i < length) { - deps_list.insert_with_values (out iter, -1, - 1, deps.get_string_element (i)); - i++; - } - } - node = all_infos.get_member ("Conflicts"); - if (node != null) { - deps = node.get_array (); - deps_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Conflicts With") + ":", - 1, deps.get_string_element (0)); - i = 1; - length = deps.get_length (); - while (i < length) { - deps_list.insert_with_values (out iter, -1, - 1, deps.get_string_element (1)); - i++; + // files + if (details.files.length > 0) { + files_scrolledwindow.visible = true; + StringBuilder text = new StringBuilder (); + foreach (unowned string file in details.files) { + text.append (file); + text.append ("\n"); } + files_textview.buffer.set_text (text.str, (int) text.len); + } else { + files_scrolledwindow.visible = false; } } - void set_package_details_list (Alpm.Package pkg) { + void set_aur_details (string pkgname) { + name_label.set_text (""); + desc_label.set_text (""); + link_label.set_text (""); + licenses_label.set_text (""); details_list.clear (); - Gtk.TreeIter iter; - if (pkg.origin == Alpm.Package.From.SYNCDB) { - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Repository") + ":", - 1, pkg.db.name); - } - unowned Alpm.List<unowned string> groups = pkg.groups; - if (groups.length != 0) { - unowned Alpm.List<unowned string>? list = groups; - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Groups") + ":", - 1, list.data); - for (list = list.next (); list != null; list = list.next ()) { - details_list.insert_with_values (out iter, -1, - 1, list.data); + deps_list.clear (); + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } + transaction.get_aur_details.begin (pkgname, (obj, res) => { + AURPackageDetails details = transaction.get_aur_details.end (res); + // infos + name_label.set_markup ("<big><b>%s %s</b></big>".printf (details.name, details.version)); + desc_label.set_text (details.desc); + 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 (details.url, details.url, aur_url, aur_url)); + StringBuilder licenses = new StringBuilder (); + licenses.append (dgettext (null, "Licenses")); + licenses.append (":"); + foreach (unowned string license in details.licenses) { + licenses.append (" "); + licenses.append (license); + } + licenses_label.set_text (licenses.str); + // details + details_list.clear (); + if (details.packagebase != details.name) { + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Package Base") + ":"), + 1, details.packagebase); + } + if (details.maintainer != "") { + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Maintainer") + ":"), + 1, details.maintainer); + } + GLib.Time time = GLib.Time.local ((time_t) details.firstsubmitted); + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "First Submitted") + ":"), + 1, time.format ("%a %d %b %Y %X %Z")); + time = GLib.Time.local ((time_t) details.lastmodified); + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Last Modified") + ":"), + 1, time.format ("%a %d %b %Y %X %Z")); + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Votes") + ":"), + 1, details.numvotes.to_string ()); + if (details.outofdate != 0) { + time = GLib.Time.local ((time_t) details.outofdate); + details_list.insert_with_values (null, -1, + 0, "<b>%s</b>".printf (dgettext (null, "Out of Date") + ":"), + 1, time.format ("%a %d %b %Y %X %Z")); + } + // deps + deps_list.clear (); + var iter = Gtk.TreeIter (); + if (details.depends.length > 0) { + foreach (unowned string name in details.depends) { + deps_list.insert_with_values (out iter, -1, + 1, name); + } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.depends.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Depends On") + ":")); + } + if (details.optdepends.length > 0) { + foreach (unowned string name in details.optdepends) { + var optdep = new StringBuilder (name); + if (transaction.find_installed_satisfier (optdep.str).name != "") { + optdep.append (" ["); + optdep.append (dgettext (null, "Installed")); + optdep.append ("]"); + } + deps_list.insert_with_values (out iter, -1, + 1, optdep.str); + } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.optdepends.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Optional Dependencies") + ":")); } - } - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Packager") + ":", - 1, pkg.packager); - GLib.Time time = GLib.Time.local ((time_t) pkg.builddate); - string build_date = time.format ("%a %d %b %Y %X %Z"); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Build Date") + ":", - 1, build_date); - if (pkg.origin == Alpm.Package.From.LOCALDB) { - time = GLib.Time.local ((time_t) pkg.installdate); - string install_date = time.format ("%a %d %b %Y %X %Z"); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Install Date") + ":", - 1, install_date); - string reason; - if (pkg.reason == Alpm.Package.Reason.EXPLICIT) { - reason = dgettext (null, "Explicitly installed"); - } else if (pkg.reason == Alpm.Package.Reason.DEPEND) { - reason = dgettext (null, "Installed as a dependency for another package"); - } else { - reason = dgettext (null, "Unknown"); + if (details.provides.length > 0) { + foreach (unowned string name in details.provides) { + deps_list.insert_with_values (out iter, -1, + 1, name); + } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.provides.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Provides") + ":")); } - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Install Reason") + ":", - 1, reason); - } - if (pkg.origin == Alpm.Package.From.SYNCDB) { - string has_signature = pkg.base64_sig != null ? dgettext (null, "Yes") : dgettext (null, "No"); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Signatures") + ":", - 1, has_signature); - } - if (pkg.origin == Alpm.Package.From.LOCALDB) { - unowned Alpm.List<unowned Alpm.Backup> backups = pkg.backups; - if (backups.length != 0) { - unowned Alpm.List<unowned Alpm.Backup>? list = backups; - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Backup files") + ":", - 1, "/" + list.data.name); - for (list = list.next (); list != null; list = list.next ()) { - details_list.insert_with_values (out iter, -1, - 1, "/" + list.data.name); + if (details.replaces.length > 0) { + foreach (unowned string name in details.replaces) { + deps_list.insert_with_values (out iter, -1, + 1, name); } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.replaces.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Replaces") + ":")); } - } - } - - void set_aur_details_list (Json.Object pkg_info) { - details_list.clear (); - Gtk.TreeIter iter; - unowned Json.Node? node; - node = pkg_info.get_member ("PackageBase"); - unowned string package_base = node.get_string (); - node = pkg_info.get_member ("Name"); - if (package_base != node.get_string ()) { - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Package Base") + ":", - 1, package_base); - } - node = pkg_info.get_member ("Maintainer"); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Maintainer") + ":", - 1, node.get_string()); - node = pkg_info.get_member ("FirstSubmitted"); - GLib.Time time = GLib.Time.local ((time_t) node.get_int ()); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "First Submitted") + ":", - 1, time.format ("%a %d %b %Y %X %Z")); - node = pkg_info.get_member ("LastModified"); - time = GLib.Time.local ((time_t) node.get_int ()); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Last Modified") + ":", - 1, time.format ("%a %d %b %Y %X %Z")); - node = pkg_info.get_member ("NumVotes"); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Votes") + ":", - 1, node.get_int ().to_string ()); - node = pkg_info.get_member ("OutOfDate"); - if (!node.is_null ()) { - time = GLib.Time.local ((time_t) node.get_int ()); - details_list.insert_with_values (out iter, -1, - 0, dgettext (null, "Out of Date") + ":", - 1, time.format ("%a %d %b %Y %X %Z")); - } - } - - void set_package_files_list (Alpm.Package pkg) { - StringBuilder text = new StringBuilder (); - foreach (var file in pkg.files) { - if (text.len != 0) { - text.append ("\n"); + if (details.conflicts.length > 0) { + foreach (unowned string name in details.conflicts) { + deps_list.insert_with_values (out iter, -1, + 1, name); + } + Gtk.TreePath path = deps_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (details.conflicts.length - 1); + deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Conflicts With") + ":")); } - text.append ("/"); - text.append (file.name); - } - files_textview.buffer.set_text (text.str, (int) text.len); + this.get_window ().set_cursor (null); + }); } - void populate_packages_list (owned Alpm.List<unowned Alpm.Package?>? pkgs) { - Gtk.TreeSelection selection = packages_treeview.get_selection (); - selection.changed.disconnect (on_packages_treeview_selection_changed); - + void populate_packages_list (AlpmPackage[] pkgs) { // populate liststore - packages_list = new PackagesModel ((owned) pkgs, this); - - // sort liststore - int column = sortinfo.column_number; - switch (column) { - case 0: - packages_list.sort_by_name (sortinfo.sort_type); - break; - case 1: - packages_list.sort_by_state (sortinfo.sort_type); - break; - case 2: - packages_list.sort_by_version (sortinfo.sort_type); - break; - case 3: - packages_list.sort_by_repo (sortinfo.sort_type); - break; - case 4: - packages_list.sort_by_size (sortinfo.sort_type); - break; - default: - break; - } - - packages_treeview.set_model (packages_list); - selection.changed.connect (on_packages_treeview_selection_changed); - - display_package_properties (); + packages_treeview.freeze_notify (); + packages_treeview.freeze_child_notify (); + packages_list.clear (); + foreach (unowned AlpmPackage pkg in pkgs) { + packages_list.insert_with_values (null, -1, + 0, pkg.origin, + 1, pkg.name, + 2, "<b>%s</b>\n%s".printf (pkg.name, pkg.desc), + 3, pkg.version, + 4, pkg.repo, + 5, pkg.size, + 6, GLib.format_size (pkg.size)); + } + packages_treeview.thaw_child_notify (); + packages_treeview.thaw_notify (); this.get_window ().set_cursor (null); } - void populate_aur_list (Json.Array? pkgs_infos) { - Gtk.TreeSelection selection = aur_treeview.get_selection (); - selection.changed.disconnect (on_aur_treeview_selection_changed); - + void populate_aur_list (AURPackage[] pkgs) { // populate liststore - aur_list = new AURModel (pkgs_infos, this); - - // sort liststore - int column = sortinfo.column_number; - switch (column) { - case 0: - aur_list.sort_by_name (sortinfo.sort_type); - break; - case 1: - aur_list.sort_by_state (sortinfo.sort_type); - break; - case 2: - aur_list.sort_by_version (sortinfo.sort_type); - break; - case 3: - aur_list.sort_by_votes (sortinfo.sort_type); - break; - default: - break; + aur_treeview.freeze_notify (); + aur_treeview.freeze_child_notify (); + aur_list.clear (); + foreach (unowned AURPackage aur_pkg in pkgs) { + AlpmPackage alpm_pkg = transaction.get_installed_pkg (aur_pkg.name); + if (alpm_pkg.name != "") { + aur_list.insert_with_values (null, -1, + 0, alpm_pkg.origin, + 1, alpm_pkg.name, + 2, "<b>%s</b>\n%s".printf (alpm_pkg.name, alpm_pkg.desc), + 3, alpm_pkg.version, + 4, aur_pkg.popularity, + 5, "%.2f".printf (aur_pkg.popularity)); + } else { + aur_list.insert_with_values (null, -1, + 0, 0, + 1, aur_pkg.name, + 2, "<b>%s</b>\n%s".printf (aur_pkg.name, aur_pkg.desc), + 3, aur_pkg.version, + 4, aur_pkg.popularity, + 5, "%.2f".printf (aur_pkg.popularity)); + } } - - aur_treeview.set_model (aur_list); - selection.changed.connect (on_aur_treeview_selection_changed); - - display_package_properties(); + aur_treeview.thaw_child_notify (); + aur_treeview.thaw_notify (); this.get_window ().set_cursor (null); } void refresh_packages_list () { - switch (filters_notebook.get_current_page ()) { - case 0: - if (search_aur_button.get_active ()) { - aur_scrolledwindow.set_visible (true); + switch (filters_stack.visible_child_name) { + case "search": + if (search_aur_box.visible) { + packages_stackswitcher.visible = true; } Gtk.TreeSelection selection = search_treeview.get_selection (); if (selection.get_selected (null, null)) { @@ -781,16 +718,19 @@ namespace Pamac { show_default_pkgs (); } break; - case 1: - aur_scrolledwindow.set_visible (false); + case "groups": + packages_stack.visible_child_name = "repos"; + packages_stackswitcher.visible = false; on_groups_treeview_selection_changed (); break; - case 2: - aur_scrolledwindow.set_visible (false); + case "states": + packages_stack.visible_child_name = "repos"; + packages_stackswitcher.visible = false; on_states_treeview_selection_changed (); break; - case 3: - aur_scrolledwindow.set_visible (false); + case "repos": + packages_stack.visible_child_name = "repos"; + packages_stackswitcher.visible = false; on_repos_treeview_selection_changed (); break; default: @@ -798,282 +738,232 @@ namespace Pamac { } } - void display_package_properties () { - switch (packages_notebook.get_current_page ()) { - case 0: - Gtk.TreeSelection selection = packages_treeview.get_selection (); - GLib.List<Gtk.TreePath> selected = selection.get_selected_rows (null); - unowned GLib.List<Gtk.TreePath>? first_element = selected.nth (0); - if (first_element == null) { - Gtk.TreeIter? iter; - if (current_package_path == null) { - packages_list.get_iter_first (out iter); - selection.select_iter (iter); - current_package_path = packages_list.get_path (iter).to_string (); - } else { - // check if current_package_path is valid else select first iter - if (packages_list.get_iter_from_string (out iter, current_package_path)) { - selection.select_iter (iter); - } else { - packages_list.get_iter_first (out iter); - selection.select_iter (iter); - current_package_path = packages_list.get_path (iter).to_string (); - } - } - } else { - // display info for the first package of the selection - current_package_path = first_element.data.to_string (); - } - unowned Alpm.Package? pkg = packages_list.get_pkg_at_path (new Gtk.TreePath.from_string (current_package_path)); - if (pkg == null) { - return; - } - if (pkg.origin == Alpm.Package.From.LOCALDB) { - files_scrolledwindow.visible = true; - } else { - files_scrolledwindow.visible = false; - } - switch (properties_notebook.get_current_page ()) { - case 0: - set_package_infos_list (pkg); - break; - case 1: - set_package_deps_list (pkg); - break; - case 2: - set_package_details_list (pkg); - break; - case 3: - if (pkg.origin == Alpm.Package.From.LOCALDB) { - set_package_files_list (pkg); - } - break; - default: - break; - } - break; - case 1: - Gtk.TreeSelection selection = aur_treeview.get_selection (); - GLib.List<Gtk.TreePath> selected = selection.get_selected_rows (null); - unowned GLib.List<Gtk.TreePath>? first_element = selected.nth (0); - if (first_element == null) { - Gtk.TreeIter? iter; - if (current_aur_path == null) { - aur_list.get_iter_first (out iter); - selection.select_iter (iter); - current_aur_path = aur_list.get_path (iter).to_string (); - } else { - // check if current_package_path is valid else select first iter - if (aur_list.get_iter_from_string (out iter, current_aur_path)) { - selection.select_iter (iter); - } else { - aur_list.get_iter_first (out iter); - selection.select_iter (iter); - current_aur_path = aur_list.get_path (iter).to_string (); - } - } - } else { - // display info for the first package of the selection - current_aur_path = first_element.data.to_string (); - } - unowned Json.Object? pkg_info = aur_list.get_pkg_at_path (new Gtk.TreePath.from_string (current_aur_path)); - if (pkg_info == null) { - return; - } - unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkg_info.get_string_member ("Name")); - if (pkg == null) { - files_scrolledwindow.visible = false; - switch (properties_notebook.get_current_page ()) { - case 0: - set_aur_infos_list.begin (pkg_info); - break; - case 1: - set_aur_deps_list.begin (pkg_info); - break; - case 2: - set_aur_details_list (pkg_info); - break; - case 3: - break; - default: - break; - } - } else { - files_scrolledwindow.visible = true; - switch (properties_notebook.get_current_page ()) { - case 0: - set_package_infos_list (pkg); - break; - case 1: - set_package_deps_list (pkg); - break; - case 2: - set_package_details_list (pkg); - break; - case 3: - set_package_files_list (pkg); - break; - default: - break; - } - } - break; - default: - break; - } + void display_package_properties (string pkgname) { + current_package_displayed = pkgname; + set_package_details (pkgname); } - [GtkCallback] - void on_packages_treeview_selection_changed () { - display_package_properties (); + void display_aur_properties (string pkgname) { + current_package_displayed = pkgname; + files_scrolledwindow.visible = false; + set_aur_details (pkgname); } [GtkCallback] - void on_aur_treeview_selection_changed () { - display_package_properties (); + void on_packages_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; + packages_list.get_iter (out iter, path); + string pkgname; + packages_list.get (iter, 1, out pkgname); + display_package_properties (pkgname); + } } [GtkCallback] - void on_properties_notebook_switch_page (Gtk.Widget page, uint page_num) { - display_package_properties (); + void on_deps_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) { + if (column.title == "deps") { + if (display_package_queue.find_custom (current_package_displayed, strcmp) == null) { + display_package_queue.push_tail (current_package_displayed); + } + var treemodel = treeview.get_model (); + Gtk.TreeIter iter; + treemodel.get_iter (out iter, path); + string val; + treemodel.get (iter, 1, out val); + string pkgname = val.split (":", 2)[0].replace (" [" + dgettext (null, "Installed") + "]", ""); + // just search for the name first to search for AUR after + AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + if (pkg.name == "") { + pkg = transaction.get_sync_pkg (pkgname); + } + if (pkg.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 (); + } + transaction.get_aur_details.begin (pkgname, (obj, res) => { + this.get_window ().set_cursor (null); + if (transaction.get_aur_details.end (res).name != "") { + display_aur_properties (pkgname); + } else { + pkg = transaction.find_installed_satisfier (pkgname); + if (pkg.name == "") { + pkg = transaction.find_sync_satisfier (pkgname); + } + if (pkg.name != "") { + display_package_properties (pkgname); + } + } + }); + } else { + display_package_properties (pkgname); + } + } } - [GtkCallback] - void on_packages_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) { - unowned Alpm.Package? pkg = packages_list.get_pkg_at_path (path); - if (pkg != null) { - if (transaction.to_add.remove (pkg.name)) { - } else if (transaction.to_remove.remove (pkg.name)) { + 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 (transaction.to_install.remove (pkgname)) { + } else if (transaction.to_remove.remove (pkgname)) { } else { - if (pkg.origin == Alpm.Package.From.LOCALDB) { - if (transaction.alpm_utils.get_holdpkgs ().find_custom (pkg.name, strcmp) == null) { - transaction.to_remove.add (pkg.name); + if (origin == 2) { //Alpm.Package.From.LOCALDB + if (!transaction.should_hold (pkgname)) { + transaction.to_remove.add (pkgname); } } else { - transaction.to_add.add (pkg.name); + transaction.to_install.add (pkgname); } } } - if ((transaction.to_add.length == 0) && (transaction.to_remove.length == 0)) { - set_buttons_sensitive (false); - } else { - set_buttons_sensitive (true); - } - // force a display refresh packages_treeview.queue_draw (); + set_pendings_operations (); } [GtkCallback] void on_aur_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) { - unowned Json.Object? pkg_info = aur_list.get_pkg_at_path (path); - if (pkg_info != null) { - unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkg_info.get_string_member ("Name")); - if (pkg != null) { - if (pkg.origin == Alpm.Package.From.LOCALDB) { - if (transaction.alpm_utils.get_holdpkgs ().find_custom (pkg.name, strcmp) == null) { - transaction.to_remove.add (pkg.name); - } - } - } else if (transaction.to_build.remove (pkg_info.get_string_member ("Name"))) { + 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 (origin == 2) { //Alpm.Package.From.LOCALDB + display_package_properties (pkgname); } else { - transaction.to_build.add (pkg_info.get_string_member ("Name")); + display_aur_properties (pkgname); } } - if ((transaction.to_build.length == 0) && (transaction.to_remove.length == 0)) { - set_buttons_sensitive (false); + } + + 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 (origin == 2) { //Alpm.Package.From.LOCALDB + if (!transaction.transaction_summary.contains (pkgname)) { + if (transaction.to_remove.remove (pkgname)) { + } else if (!transaction.should_hold (pkgname)) { + transaction.to_remove.add (pkgname); + } + } + } else if (transaction.to_build.remove (pkgname)) { } else { - set_buttons_sensitive (true); + transaction.to_build.add (pkgname); } - // force a display refresh - aur_treeview.queue_draw (); + set_pendings_operations (); } - void on_install_item_activate () { - foreach (var pkg in selected_pkgs) { - if (pkg.origin == Alpm.Package.From.SYNCDB) { - transaction.to_add.add (pkg.name); + [GtkCallback] + void on_button_back_clicked () { + string? pkgname = display_package_queue.pop_tail (); + if (pkgname != null) { + AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + if (pkg.name == "") { + pkg = transaction.get_sync_pkg (pkgname); + } + if (pkg.name == "") { + transaction.get_aur_details.begin (pkgname, (obj, res) => { + if (transaction.get_aur_details.end (res).name != "") { + display_aur_properties (pkgname); + } else { + pkg = transaction.find_installed_satisfier (pkgname); + if (pkg.name == "") { + pkg = transaction.find_sync_satisfier (pkgname); + } + if (pkg.name != "") { + display_package_properties (pkgname); + } + } + }); + } else { + display_package_properties (pkgname); } + } else { + main_stack.visible_child_name = "browse"; } - foreach (var pkg_info in selected_aur) { - transaction.to_build.add (pkg_info.get_string_member ("Name")); + } + + void on_install_item_activate () { + foreach (unowned string pkgname in selected_pkgs) { + if (transaction.get_pkg_origin (pkgname) == 3) { //Alpm.Package.From.SYNCDB + transaction.to_install.add (pkgname); + } } - if (transaction.to_add.length != 0 || transaction.to_build.length != 0) { - set_buttons_sensitive (true); + foreach (unowned string pkgname in selected_aur) { + transaction.to_build.add (pkgname); } + set_pendings_operations (); } void on_reinstall_item_activate () { - foreach (var pkg in selected_pkgs) { - transaction.to_remove.remove (pkg.name); - if (pkg.origin == Alpm.Package.From.LOCALDB) { - transaction.to_add.add (pkg.name); + foreach (unowned string pkgname in selected_pkgs) { + transaction.to_remove.remove (pkgname); + if (transaction.get_pkg_origin (pkgname) == 2) { //Alpm.Package.From.LOCALDB + transaction.to_install.add (pkgname); } } - if (transaction.to_add.length != 0) { - set_buttons_sensitive (true); - } + set_pendings_operations (); } void on_remove_item_activate () { - foreach (var pkg in selected_pkgs) { - transaction.to_add.remove (pkg.name); - if (transaction.alpm_utils.get_holdpkgs ().find_custom (pkg.name, strcmp) == null) { - if (pkg.origin == Alpm.Package.From.LOCALDB) { - transaction.to_remove.add (pkg.name); + foreach (unowned string pkgname in selected_pkgs) { + transaction.to_install.remove (pkgname); + if (!transaction.should_hold (pkgname)) { + if (transaction.get_pkg_origin (pkgname) == 2) { //Alpm.Package.From.LOCALDB + transaction.to_remove.add (pkgname); } } } - if (transaction.to_remove.length != 0) { - set_buttons_sensitive (true); - } + set_pendings_operations (); } void on_deselect_item_activate () { - foreach (var pkg in selected_pkgs) { - if (transaction.to_add.remove (pkg.name)) { + foreach (unowned string pkgname in selected_pkgs) { + if (transaction.to_install.remove (pkgname)) { } else { - transaction.to_remove.remove (pkg.name); + transaction.to_remove.remove (pkgname); } } - foreach (var pkg_info in selected_aur) { - transaction.to_build.remove (pkg_info.get_string_member ("Name")); - } - if ((transaction.to_add.length == 0) - && (transaction.to_remove.length == 0) - && (transaction.to_load.length == 0) - && (transaction.to_build.length == 0)) { - set_buttons_sensitive (false); + foreach (unowned string pkgname in selected_aur) { + transaction.to_build.remove (pkgname); } + set_pendings_operations (); } - void choose_opt_dep (Alpm.List<unowned Alpm.Package?> pkgs) { - foreach (var pkg in pkgs) { + void choose_opt_dep (GLib.List<string> pkgnames) { + foreach (unowned string pkgname in pkgnames) { var choose_dep_dialog = new ChooseDependenciesDialog (this); - Gtk.TreeIter iter; int length = 0; - foreach (var optdep in pkg.optdepends) { - if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep.name) == null) { - length++; - choose_dep_dialog.deps_list.insert_with_values (out iter, -1, - 0, false, - 1, optdep.name, - 2, optdep.desc); - } + foreach (unowned string optdep in transaction.get_pkg_uninstalled_optdeps (pkgname)) { + length++; + choose_dep_dialog.deps_list.insert_with_values (null, -1, + 0, false, + 1, optdep); } choose_dep_dialog.label.set_markup ("<b>%s</b>".printf ( ngettext ("%s has %u uninstalled optional dependency.\nChoose if you would like to install it", - "%s has %u uninstalled optional dependencies.\nChoose those you would like to install", length).printf (pkg.name, length))); + "%s has %u uninstalled optional dependencies.\nChoose those you would like to install", length).printf (pkgname, length))); if (choose_dep_dialog.run () == Gtk.ResponseType.OK) { choose_dep_dialog.deps_list.foreach ((model, path, iter) => { - GLib.Value val; + bool selected; + string name; // get value at column 0 to know if it is selected - choose_dep_dialog.deps_list.get_value (iter, 0, out val); - if ((bool) val) { - // get value at column 1 to get the pkg name - choose_dep_dialog.deps_list.get_value (iter, 1, out val); - unowned Alpm.Package? sync_pkg = transaction.alpm_utils.get_sync_pkg ((string) val); - if (sync_pkg != null) { - transaction.to_add.add (sync_pkg.name); + choose_dep_dialog.deps_list.get (iter, 0, out selected, 1, out name); + if (selected) { + // get value at column 1 to get the pkgname + AlpmPackage sync_pkg = transaction.get_sync_pkg (name); + if (sync_pkg.name != "") { + transaction.to_install.add (sync_pkg.name); } } return false; @@ -1088,124 +978,135 @@ namespace Pamac { void on_install_optional_deps_item_activate () { choose_opt_dep (selected_pkgs); - if (transaction.to_add.length != 0) { - set_buttons_sensitive (true); - } + set_pendings_operations (); } void on_explicitly_installed_item_activate () { - foreach (var pkg in selected_pkgs) { - transaction.start_set_pkgreason (pkg.name, Alpm.Package.Reason.EXPLICIT); + foreach (unowned string pkgname in selected_pkgs) { + transaction.start_set_pkgreason (pkgname, 0); //Alpm.Package.Reason.EXPLICIT } } - async void search_in_aur (string search_string) { - if (!aur_search_results.contains (search_string)) { - Json.Array results = AUR.search (search_string.split (" ")); - aur_search_results.insert (search_string, results); + void on_packages_stack_visible_child_changed () { + // do nothing if it we want to see pendings AUR operations + switch (filters_stack.visible_child_name) { + case "search": + Gtk.TreeIter iter; + Gtk.TreeSelection selection = search_treeview.get_selection (); + if (selection.get_selected (null, out iter)) { + 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 search_string; + search_list.get (iter, 0, out search_string); + switch (packages_stack.visible_child_name) { + case "repos": + transaction.search_pkgs.begin (search_string, (obj, res) => { + populate_packages_list (transaction.search_pkgs.end (res)); + }); + break; + case "aur": + transaction.search_in_aur.begin (search_string, (obj, res) => { + populate_aur_list (transaction.search_in_aur.end (res)); + }); + break; + default: + break; + } + } + break; + default: + break; } - } - - [GtkCallback] - void on_packages_notebook_switch_page (Gtk.Widget page, uint page_num) { - Gtk.TreeModel model; - Gtk.TreeIter? iter; - Gtk.TreeSelection selection = search_treeview.get_selection (); - if (selection.get_selected (out model, out iter)) { - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - GLib.Value val; - model.get_value (iter, 0, out val); - string search_string = val.get_string (); - switch (packages_notebook.get_current_page ()) { - case 0: - search_all_dbs.begin (search_string, (obj, res) => { - var pkgs = search_all_dbs.end (res); - populate_packages_list ((owned) pkgs); - }); - break; - case 1: - search_in_aur.begin (search_string, (obj, res) => { - populate_aur_list (aur_search_results.lookup (search_string)); - }); - break; - default: - break; - } + if (packages_stack.visible_child_name == "aur") { + var attention_val = GLib.Value (typeof (bool)); + attention_val.set_boolean (false); + packages_stack.child_set_property (packages_stack.get_child_by_name ("aur"), + "needs-attention", + attention_val); } } [GtkCallback] bool on_packages_treeview_button_press_event (Gdk.EventButton event) { - packages_treeview.grab_focus (); // Check if right mouse button was clicked if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) { - Gtk.TreePath? treepath; - unowned Alpm.Package? clicked_pkg; - Gtk.TreeSelection selection = packages_treeview.get_selection (); - packages_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null); - clicked_pkg = packages_list.get_pkg_at_path (treepath); - if (clicked_pkg == null) { - return true; - } - if (!selection.path_is_selected (treepath)) { - selection.unselect_all (); - selection.select_path (treepath); - } - GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null); - deselect_item.set_sensitive (false); - install_item.set_sensitive (false); - remove_item.set_sensitive (false); - reinstall_item.set_sensitive (false); - install_optional_deps_item.set_sensitive (false); - explicitly_installed_item.set_sensitive (false); - selected_pkgs = new Alpm.List<unowned Alpm.Package?> (); - foreach (unowned Gtk.TreePath path in selected_paths) { - selected_pkgs.add (packages_list.get_pkg_at_path (path)); - } - foreach (var pkg in selected_pkgs) { - if (transaction.to_add.contains (pkg.name) - || transaction.to_remove.contains (pkg.name)) { - deselect_item.set_sensitive (true); - break; - } - } - foreach (var pkg in selected_pkgs) { - if (pkg.origin == Alpm.Package.From.SYNCDB) { - install_item.set_sensitive (true); - break; - } - } - foreach (var pkg in selected_pkgs) { - if (pkg.origin == Alpm.Package.From.LOCALDB) { - remove_item.set_sensitive (true); - break; + 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); } - } - if (selected_pkgs.length == 1) { - clicked_pkg = selected_pkgs.data; - if (clicked_pkg.origin == Alpm.Package.From.LOCALDB) { - foreach (var optdep in clicked_pkg.optdepends) { - if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep.name) == null) { - install_optional_deps_item.set_sensitive (true); - break; + GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null); + selected_pkgs = new GLib.List<string> (); + deselect_item.sensitive = false; + install_item.sensitive = false; + remove_item.sensitive = false; + reinstall_item.sensitive = false; + install_optional_deps_item.sensitive = false; + explicitly_installed_item.sensitive = 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); + if (transaction.to_install.contains (pkgname) + || transaction.to_remove.contains (pkgname)) { + deselect_item.sensitive = true; + } else if (origin == 2) { //Alpm.Package.From.LOCALDB + remove_item.sensitive = true; + foreach (unowned string optdep in transaction.get_pkg_uninstalled_optdeps (pkgname)) { + if (transaction.find_installed_satisfier (optdep).name == "") { + install_optional_deps_item.sensitive = true; + break; + } } + if (transaction.get_pkg_reason (pkgname) == 1) { //Alpm.Package.Reason.DEPEND + explicitly_installed_item.sensitive = true; + } + AlpmPackage find_pkg = transaction.get_sync_pkg (pkgname); + if (find_pkg.name != "") { + if (find_pkg.version == pkgversion) { + reinstall_item.sensitive = true; + } + } + } else if (origin == 3) { //Alpm.Package.From.SYNCDB + install_item.sensitive = true; } - if (clicked_pkg.reason == Alpm.Package.Reason.DEPEND) { - explicitly_installed_item.set_sensitive (true); - } - unowned Alpm.Package? find_pkg = transaction.alpm_utils.get_sync_pkg (clicked_pkg.name); - if (find_pkg != null) { - if (Alpm.pkg_vercmp (find_pkg.version, clicked_pkg.version) == 0) { - reinstall_item.set_sensitive (true); + } else { + 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.sensitive) { + if (transaction.to_install.contains (pkgname) + || transaction.to_remove.contains (pkgname)) { + deselect_item.sensitive = true; + } + } + if (origin == 3) { //Alpm.Package.From.SYNCDB + install_item.sensitive = true; + } + if (origin == 2) { //Alpm.Package.From.LOCALDB + remove_item.sensitive = true; } } } + right_click_menu.popup (null, null, null, event.button, event.time); + return true; } - right_click_menu.popup (null, null, null, event.button, event.time); - return true; - } else { - return false; - } + } + return false; } [GtkCallback] @@ -1214,212 +1115,53 @@ namespace Pamac { // Check if right mouse button was clicked if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) { Gtk.TreePath? treepath; - unowned Json.Object? clicked_pkg_info; Gtk.TreeSelection selection = aur_treeview.get_selection (); - aur_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null); - clicked_pkg_info = aur_list.get_pkg_at_path (treepath); - if (clicked_pkg_info == null) { - return true; - } - if (!selection.path_is_selected (treepath)) { - selection.unselect_all (); - selection.select_path (treepath); - } - GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null); - deselect_item.set_sensitive (false); - install_item.set_sensitive (false); - remove_item.set_sensitive (false); - reinstall_item.set_sensitive (false); - install_optional_deps_item.set_sensitive (false); - explicitly_installed_item.set_sensitive (false); - selected_pkgs = new Alpm.List<unowned Alpm.Package?> (); - selected_aur = new GLib.List<unowned Json.Object> (); - foreach (unowned Gtk.TreePath path in selected_paths) { - unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (clicked_pkg_info.get_string_member ("Name")); - if (pkg != null) { - selected_pkgs.add (pkg); - // there is for sure a pkg to remove - remove_item.set_sensitive (true); - } else { - selected_aur.append (aur_list.get_pkg_at_path (path)); + 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); } - } - foreach (var pkg_info in selected_aur) { - if (transaction.to_build.contains (pkg_info.get_string_member ("Name"))) { - deselect_item.set_sensitive (true); - break; + 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.sensitive = false; + install_item.sensitive = false; + remove_item.sensitive = false; + reinstall_item.sensitive = false; + install_optional_deps_item.sensitive = false; + explicitly_installed_item.sensitive = 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); + AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + if (pkg.name != "") { + selected_pkgs.append (pkgname); + // there is for sure a pkg to remove + remove_item.sensitive = true; + } else { + selected_aur.append (pkgname); + } } - } - foreach (var pkg_info in selected_aur) { - if (!transaction.to_build.contains (pkg_info.get_string_member ("Name"))) { - install_item.set_sensitive (true); - break; + foreach (unowned string pkgname in selected_aur) { + if (transaction.to_build.contains (pkgname)) { + deselect_item.sensitive = true; + } else { + install_item.sensitive = true; + } } - } - foreach (var pkg in selected_pkgs) { - if (transaction.to_remove.contains (pkg.name)) { - deselect_item.set_sensitive (true); - break; + foreach (unowned string pkgname in selected_pkgs) { + if (transaction.to_remove.contains (pkgname)) { + deselect_item.sensitive = true; + break; + } } - } - right_click_menu.popup (null, null, null, event.button, event.time); - return true; - } else { - return false; - } - } - - [GtkCallback] - void on_packages_name_column_clicked () { - Gtk.SortType new_order; - if (!packages_name_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - packages_list.sort_by_name (new_order); - // force a display refresh - packages_treeview.queue_draw (); - } - - [GtkCallback] - void on_aur_name_column_clicked () { - Gtk.SortType new_order; - if (!aur_name_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - aur_list.sort_by_name (new_order); - // force a display refresh - aur_treeview.queue_draw (); - } - - [GtkCallback] - void on_packages_state_column_clicked () { - Gtk.SortType new_order; - if (!packages_state_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - packages_list.sort_by_state (new_order); - // force a display refresh - packages_treeview.queue_draw (); - } - - [GtkCallback] - void on_aur_state_column_clicked () { - Gtk.SortType new_order; - if (!aur_state_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - aur_list.sort_by_state (new_order); - // force a display refresh - aur_treeview.queue_draw (); - } - - [GtkCallback] - void on_packages_version_column_clicked () { - Gtk.SortType new_order; - if (!packages_version_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - packages_list.sort_by_version (new_order); - // force a display refresh - packages_treeview.queue_draw (); - } - - [GtkCallback] - void on_aur_version_column_clicked () { - Gtk.SortType new_order; - if (!aur_version_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - aur_list.sort_by_version (new_order); - // force a display refresh - aur_treeview.queue_draw (); - } - - [GtkCallback] - void on_packages_repo_column_clicked () { - Gtk.SortType new_order; - if (!packages_repo_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - packages_list.sort_by_repo (new_order); - // force a display refresh - packages_treeview.queue_draw (); - } - - [GtkCallback] - void on_packages_size_column_clicked () { - Gtk.SortType new_order; - if (!packages_size_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; - } - } - packages_list.sort_by_size (new_order); - // force a display refresh - packages_treeview.queue_draw (); - } - - [GtkCallback] - void on_aur_votes_column_clicked () { - Gtk.SortType new_order; - if (!aur_votes_column.sort_indicator) { - new_order = Gtk.SortType.ASCENDING; - } else { - if (sortinfo.sort_type == Gtk.SortType.ASCENDING) { - new_order = Gtk.SortType.DESCENDING; - } else { - new_order = Gtk.SortType.ASCENDING; + right_click_menu.popup (null, null, null, event.button, event.time); + return true; } } - aur_list.sort_by_votes (new_order); - // force a display refresh - aur_treeview.queue_draw (); + return false; } [GtkCallback] @@ -1428,15 +1170,15 @@ namespace Pamac { if (search_string != "") { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); Gtk.TreeModel model; - Gtk.TreeIter? iter; + Gtk.TreeIter iter; Gtk.TreeSelection selection = search_treeview.get_selection (); // add search string in search_list if needed bool found = false; // check if search string is already selected in search list if (selection.get_selected (out model, out iter)) { - GLib.Value selected_string; - model.get_value (iter, 0, out selected_string); - if ((string) selected_string == search_string) { + string selected_string; + model.get (iter, 0, out selected_string); + if (selected_string == search_string) { on_search_treeview_selection_changed (); found = true; } @@ -1444,9 +1186,9 @@ namespace Pamac { // check if search string exists in search list if (!found) { search_list.foreach ((_model, _path, _iter) => { - GLib.Value line; - _model.get_value (_iter, 0, out line); - if ((string) line == search_string) { + 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 list with the selection changed signal @@ -1480,65 +1222,46 @@ namespace Pamac { } } - async Alpm.List<unowned Alpm.Package?> search_all_dbs (string search_string) { - return transaction.alpm_utils.search_all_dbs (search_string); - } - - async Alpm.List<unowned Alpm.Package?> get_group_pkgs (string group_name) { - return transaction.alpm_utils.get_group_pkgs (group_name); - } - - async Alpm.List<unowned Alpm.Package?> get_installed_pkgs () { - return transaction.alpm_utils.get_installed_pkgs (); - } - - async Alpm.List<unowned Alpm.Package?> get_orphans () { - return transaction.alpm_utils.get_orphans (); - } - - async Alpm.List<unowned Alpm.Package?> get_local_pkgs () { - return transaction.alpm_utils.get_local_pkgs (); - } - - async Alpm.List<unowned Alpm.Package?> get_repo_pkgs (string repo_name) { - return transaction.alpm_utils.get_repo_pkgs (repo_name); - } - [GtkCallback] void on_search_treeview_selection_changed () { - Gtk.TreeModel model; - Gtk.TreeIter? iter; + Gtk.TreeIter iter; Gtk.TreeSelection selection = search_treeview.get_selection (); - if (selection.get_selected (out model, out iter)) { + if (selection.get_selected (null, out iter)) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - GLib.Value val; - model.get_value (iter, 0, out val); - string search_string = val.get_string (); - switch (packages_notebook.get_current_page ()) { - case 0: - search_all_dbs.begin (search_string, (obj, res) => { - var pkgs = search_all_dbs.end (res); + string search_string; + search_list.get (iter, 0, out search_string); + switch (packages_stack.visible_child_name) { + case "repos": + transaction.search_pkgs.begin (search_string, (obj, res) => { + var pkgs = transaction.search_pkgs.end (res); + populate_packages_list (pkgs); if (search_aur_button.get_active ()) { - search_in_aur.begin (search_string, (obj, res) => { - if (pkgs.length == 0) { - if (aur_search_results.lookup (search_string) != null) { - packages_notebook.set_current_page (1); + if (pkgs.length == 0) { + transaction.search_in_aur.begin (search_string, (obj, res) => { + if (transaction.search_in_aur.end (res).length != 0) { + packages_stack.visible_child_name = "aur"; } - } else { - if (aur_search_results.lookup (search_string) != null) { + }); + } else { + transaction.search_in_aur.begin (search_string, (obj, res) => { + if (transaction.search_in_aur.end (res).length != 0) { + var attention_val = GLib.Value (typeof (bool)); + attention_val.set_boolean (true); + packages_stack.child_set_property (packages_stack.get_child_by_name ("aur"), + "needs-attention", + attention_val); } - } - populate_packages_list ((owned) pkgs); - }); - } else { - populate_packages_list ((owned) pkgs); + }); + } } }); + aur_list.clear (); break; - case 1: - search_in_aur.begin (search_string, (obj, res) => { - populate_aur_list (aur_search_results.lookup (search_string)); + case "aur": + transaction.search_in_aur.begin (search_string, (obj, res) => { + populate_aur_list (transaction.search_in_aur.end (res)); }); + packages_list.clear (); break; default: break; @@ -1548,96 +1271,106 @@ namespace Pamac { [GtkCallback] void on_groups_treeview_selection_changed () { - Gtk.TreeModel model; - Gtk.TreeIter? iter; + Gtk.TreeIter iter; Gtk.TreeSelection selection = groups_treeview.get_selection (); - if (selection.get_selected (out model, out iter)) { + if (selection.get_selected (null, out iter)) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - GLib.Value grp_name; - model.get_value (iter, 0, out grp_name); - get_group_pkgs.begin ((string) grp_name, (obj, res) => { - var pkgs = get_group_pkgs.end (res); - populate_packages_list ((owned) pkgs); + string group_name; + groups_list.get (iter, 0, out group_name); + transaction.get_group_pkgs.begin (group_name, (obj, res) => { + populate_packages_list (transaction.get_group_pkgs.end (res)); }); } } [GtkCallback] void on_states_treeview_selection_changed () { - Gtk.TreeModel model; - Gtk.TreeIter? treeiter; + Gtk.TreeIter iter; Gtk.TreeSelection selection = states_treeview.get_selection (); - if (selection.get_selected (out model, out treeiter)) { + if (selection.get_selected (null, out iter)) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - GLib.Value val; - model.get_value (treeiter, 0, out val); - unowned string state = val.get_string (); - if (state == dgettext (null, "To install")) { - var pkgs = new Alpm.List<unowned Alpm.Package?> (); - foreach (unowned string pkgname in transaction.to_add) { - unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkgname); - if (pkg == null) { - pkg = transaction.alpm_utils.get_sync_pkg (pkgname); + packages_stackswitcher.visible = false; + string state; + states_list.get (iter, 0, out state); + if (state == dgettext (null, "Installed")) { + transaction.get_installed_pkgs.begin ((obj, res) => { + populate_packages_list (transaction.get_installed_pkgs.end (res)); + }); + } else if (state == dgettext (null, "Orphans")) { + transaction.get_orphans.begin ((obj, res) => { + populate_packages_list (transaction.get_orphans.end (res)); + }); + } else if (state == dgettext (null, "Foreign")) { + transaction.get_foreign_pkgs.begin ((obj, res) => { + populate_packages_list (transaction.get_foreign_pkgs.end (res)); + }); + } else if (state == dgettext (null, "Pending")) { + AlpmPackage[] pkgs = {}; + foreach (unowned string pkgname in transaction.to_install) { + AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + if (pkg.name == "") { + pkg = transaction.get_sync_pkg (pkgname); } - if (pkg != null) { - pkgs.add (pkg); + if (pkg.name != "") { + pkgs += pkg; } } - populate_packages_list ((owned) pkgs); - } else if (state == dgettext (null, "To remove")) { - var pkgs = new Alpm.List<unowned Alpm.Package?> (); foreach (unowned string pkgname in transaction.to_remove) { - unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkgname); - if (pkg != null) { - pkgs.add (pkg); + AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + if (pkg.name != "") { + pkgs += pkg; + } + } + populate_packages_list (pkgs); + if (transaction.to_build.length != 0) { + packages_stackswitcher.visible = true; + AURPackage[] aur_pkgs = {}; + foreach (unowned string pkgname in transaction.to_build) { + transaction.get_aur_details.begin (pkgname, (obj, res) => { + AURPackageDetails details_pkg = transaction.get_aur_details.end (res); + if (details_pkg.name != "") { + var aur_pkg = AURPackage () { + name = details_pkg.name, + version = details_pkg.version, + desc = details_pkg.desc, + popularity = details_pkg.popularity + }; + aur_pkgs += aur_pkg; + populate_aur_list (aur_pkgs); + if (aur_pkgs.length > 0 ) { + if (pkgs.length == 0) { + packages_stack.visible_child_name = "aur"; + } else { + var attention_val = GLib.Value (typeof (bool)); + attention_val.set_boolean (true); + packages_stack.child_set_property (packages_stack.get_child_by_name ("aur"), + "needs-attention", + attention_val); + } + } + } + }); } } - populate_packages_list ((owned) pkgs); - } else if (state == dgettext (null, "Installed")) { - get_installed_pkgs.begin ((obj, res) => { - var pkgs = get_installed_pkgs.end (res); - populate_packages_list ((owned) pkgs); - }); - } else if (state == dgettext (null, "Uninstalled")) { - //get_sync_pkgs.begin ((obj, res) => { - //var pkgs = get_sync_pkgs.end (res); - //populate_packages_list ((owned) pkgs); - //}); - } else if (state == dgettext (null, "Orphans")) { - get_orphans.begin ((obj, res) => { - var pkgs = get_orphans.end (res); - populate_packages_list ((owned) pkgs); - }); } } } [GtkCallback] void on_repos_treeview_selection_changed () { - Gtk.TreeModel model; - Gtk.TreeIter? iter; + Gtk.TreeIter iter; Gtk.TreeSelection selection = repos_treeview.get_selection (); - if (selection.get_selected (out model, out iter)) { + if (selection.get_selected (null, out iter)) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - GLib.Value val; - model.get_value (iter, 0, out val); - unowned string repo = val.get_string (); - if (repo == dgettext (null, "local")) { - get_local_pkgs.begin ((obj, res) => { - var pkgs = get_local_pkgs.end (res); - populate_packages_list ((owned) pkgs); - }); - } else { - get_repo_pkgs.begin (repo, (obj, res) => { - var pkgs = get_repo_pkgs.end (res); - populate_packages_list ((owned) pkgs); - }); - } + string repo; + repos_list.get (iter, 0, out repo); + transaction.get_repo_pkgs.begin (repo, (obj, res) => { + populate_packages_list (transaction.get_repo_pkgs.end (res)); + }); } } - [GtkCallback] - void on_filters_notebook_switch_page (Gtk.Widget page, uint page_num) { + void on_filters_stack_visible_child_changed () { refresh_packages_list (); } @@ -1700,6 +1433,7 @@ namespace Pamac { while (Gtk.events_pending ()) { Gtk.main_iteration (); } + transaction_running = true; transaction.run (); } } else { @@ -1729,18 +1463,38 @@ namespace Pamac { } [GtkCallback] - void on_valid_button_clicked () { - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + void on_transaction_infos_details_button_clicked () { + if (transaction_running) { + transaction.show_progress (); + } else { + Gtk.TreeIter iter; + // show "Pending" in states_list + // "Pending" is at indice 3 + states_list.get_iter (out iter, new Gtk.TreePath.from_indices (3)); + Gtk.TreeSelection selection = states_treeview.get_selection (); + selection.changed.disconnect (on_states_treeview_selection_changed); + selection.select_iter (iter); + selection.changed.connect_after (on_states_treeview_selection_changed); + filters_stack.visible_child_name = "states"; + } + } + + [GtkCallback] + void on_transaction_infos_apply_button_clicked () { + //this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + transaction_running = true; transaction.run (); } [GtkCallback] - void on_cancel_button_clicked () { - transaction.clear_lists (); - set_buttons_sensitive (false); - // force a display refresh - packages_treeview.queue_draw (); - aur_treeview.queue_draw (); + void on_transaction_infos_cancel_button_clicked () { + if (transaction_running) { + transaction.cancel (); + } else { + transaction.clear_lists (); + set_pendings_operations (); + refresh_packages_list (); + } } [GtkCallback] @@ -1748,23 +1502,34 @@ namespace Pamac { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); refreshing = true; transaction.start_refresh (false); + transaction_infos_apply_button.visible = false; + transaction_infobox.visible = true; + } + + void on_start_transaction () { + transaction_infos_cancel_button.visible = false; + transaction_infos_apply_button.visible = false; + } + + void on_emit_action (string action) { + transaction_infos_label.label = action; } void on_transaction_finished (bool success) { - if (transaction.to_add.length == 0 - && transaction.to_remove.length == 0 - && transaction.to_load.length == 0 - && transaction.to_build.length == 0) { - set_buttons_sensitive (false); - } refresh_packages_list (); transaction.to_load.remove_all (); if (refreshing) { if (success) { + transaction_running = true; transaction.sysupgrade (false); } refreshing = false; + } else { + transaction_running = false; + transaction_infos_cancel_button.visible = true; + transaction_infos_apply_button.visible = true; } + set_pendings_operations (); } } } diff --git a/src/mirrors_config.vala b/src/mirrors_config.vala index 3414562767088b21402945eb2e8fc3fcdcc6da7f..5c3130344ad3f08acd0dba64dbbe147af4f59d03 100644 --- a/src/mirrors_config.vala +++ b/src/mirrors_config.vala @@ -18,13 +18,32 @@ */ namespace Pamac { - [Compact] - public class MirrorsConfig { - public string conf_path; - public string mirrorlists_dir; - public string choosen_generation_method; - public string choosen_country; - public GLib.List<string> countrys; + class MirrorsConfig { + string conf_path; + GLib.List<string> _countrys ; + + + public string mirrorlists_dir { get; private set; } + public string choosen_generation_method { get; private set; } + public string choosen_country { get; private set; } + public unowned GLib.List<string> countrys { + get { + try { + var directory = GLib.File.new_for_path (mirrorlists_dir); + var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0); + FileInfo file_info; + _countrys = new GLib.List<string> (); + while ((file_info = enumerator.next_file ()) != null) { + _countrys.append(file_info.get_name ()); + } + _countrys.sort (strcmp); + } catch (Error e) { + stderr.printf ("%s\n", e.message); + } + return _countrys; + } + } + public MirrorsConfig (string path) { conf_path = path; @@ -39,22 +58,7 @@ namespace Pamac { parse_file (conf_path); } - public void get_countrys () { - try { - var directory = GLib.File.new_for_path (mirrorlists_dir); - var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0); - FileInfo file_info; - countrys = new GLib.List<string> (); - while ((file_info = enumerator.next_file ()) != null) { - countrys.append(file_info.get_name ()); - } - countrys.sort (strcmp); - } catch (Error e) { - stderr.printf ("%s\n", e.message); - } - } - - public void parse_file (string path) { + void parse_file (string path) { var file = GLib.File.new_for_path (path); if (file.query_exists ()) { try { diff --git a/src/package.vala b/src/package.vala new file mode 100644 index 0000000000000000000000000000000000000000..681078d4d2431f8d94075f2b721400d04fe8ee20 --- /dev/null +++ b/src/package.vala @@ -0,0 +1,82 @@ +/* + * pamac-vala + * + * Copyright (C) 2014-2016 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 { + public struct AlpmPackage { + public string name; + public string version; + public string desc; + public string repo; + public uint64 size; + public uint origin; + } + + public struct AlpmPackageDetails { + public string name; + public string version; + public string desc; + public string repo; + public string url; + public string packager; + public string builddate; + public string installdate; + public string reason; + public string has_signature; + public string[] licenses; + public string[] depends; + public string[] optdepends; + public string[] requiredby; + public string[] optionalfor; + public string[] provides; + public string[] replaces; + public string[] conflicts; + public string[] groups; + public string[] backups; + public string[] files; + } + + public struct AURPackage { + public string name; + public string version; + public string desc; + public double popularity; + } + + public struct AURPackageDetails { + public string name; + public string version; + public string desc; + public double popularity; + public string packagebase; + public string url; + public string maintainer; + public int64 firstsubmitted; + public int64 lastmodified; + public int64 outofdate; + public int64 numvotes; + public string[] licenses; + public string[] depends; + public string[] makedepends; + public string[] checkdepends; + public string[] optdepends; + public string[] provides; + public string[] replaces; + public string[] conflicts; + } +} diff --git a/src/pamac_config.vala b/src/pamac_config.vala index c263ba9dfe7fc97d3af9afb0462834c541033f64..f56466c465e2e51b1836a4fdf4bd544a13f42bcb 100644 --- a/src/pamac_config.vala +++ b/src/pamac_config.vala @@ -18,43 +18,48 @@ */ namespace Pamac { - [Compact] - public class Config { - public string conf_path; - public bool recurse; - public uint64 refresh_period; - public bool no_update_hide_icon; - public bool enable_aur; - public bool search_aur; - public bool check_aur_updates; - public bool no_confirm_build; - public HashTable<string,string> environment_variables; + class Config { + string conf_path; + HashTable<string,string> _environment_variables; + + public bool recurse { get; private set; } + public uint64 refresh_period { get; private set; } + public bool no_update_hide_icon { get; private set; } + public bool enable_aur { get; private set; } + public bool search_aur { get; private set; } + public bool check_aur_updates { get; private set; } + public bool no_confirm_build { get; private set; } + public unowned HashTable<string,string> environment_variables { + get { + return _environment_variables; + } + } public Config (string path) { conf_path = path; //get environment variables - environment_variables = new HashTable<string,string> (str_hash, str_equal); + _environment_variables = new HashTable<string,string> (str_hash, str_equal); var utsname = Posix.utsname(); - environment_variables.insert ("HTTP_USER_AGENT", "pamac (%s %s)".printf (utsname.sysname, utsname.machine)); + _environment_variables.insert ("HTTP_USER_AGENT", "pamac (%s %s)".printf (utsname.sysname, utsname.machine)); unowned string? variable = Environment.get_variable ("http_proxy"); if (variable != null) { - environment_variables.insert ("http_proxy", variable); + _environment_variables.insert ("http_proxy", variable); } variable = Environment.get_variable ("https_proxy"); if (variable != null) { - environment_variables.insert ("https_proxy", variable); + _environment_variables.insert ("https_proxy", variable); } variable = Environment.get_variable ("ftp_proxy"); if (variable != null) { - environment_variables.insert ("ftp_proxy", variable); + _environment_variables.insert ("ftp_proxy", variable); } variable = Environment.get_variable ("socks_proxy"); if (variable != null) { - environment_variables.insert ("socks_proxy", variable); + _environment_variables.insert ("socks_proxy", variable); } variable = Environment.get_variable ("no_proxy"); if (variable != null) { - environment_variables.insert ("no_proxy", variable); + _environment_variables.insert ("no_proxy", variable); } // set default option refresh_period = 6; @@ -72,7 +77,7 @@ namespace Pamac { parse_file (conf_path); } - public void parse_file (string path) { + void parse_file (string path) { var file = GLib.File.new_for_path (path); if (file.query_exists ()) { try { diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala index 9f34882ea4c576d69f2db3831b077775a97842d7..7beb3c31089e53745ca12753512611218559a949 100644 --- a/src/preferences_dialog.vala +++ b/src/preferences_dialog.vala @@ -37,8 +37,6 @@ namespace Pamac { [GtkChild] Gtk.Box ignorepkgs_box; [GtkChild] - Gtk.ListStore ignorepkgs_liststore; - [GtkChild] Gtk.TreeView ignorepkgs_treeview; [GtkChild] Gtk.Box mirrors_config_box; @@ -59,6 +57,7 @@ namespace Pamac { [GtkChild] Gtk.CheckButton no_confirm_build_checkbutton; + Gtk.ListStore ignorepkgs_liststore; Transaction transaction; uint64 previous_refresh_period; @@ -67,9 +66,9 @@ namespace Pamac { this.transaction = transaction; refresh_period_label.set_markup (dgettext (null, "How often to check for updates, value in hours") +":"); - remove_unrequired_deps_button.active = transaction.pamac_config.recurse; - check_space_button.active = (transaction.alpm_utils.get_checkspace () == 1); - if (transaction.pamac_config.refresh_period == 0) { + remove_unrequired_deps_button.active = transaction.recurse; + check_space_button.active = transaction.get_checkspace (); + if (transaction.refresh_period == 0) { check_updates_button.active = false; refresh_period_label.sensitive = false; // set default value @@ -80,15 +79,16 @@ namespace Pamac { ignorepkgs_box.sensitive = false; } else { check_updates_button.active = true; - refresh_period_spin_button.value = transaction.pamac_config.refresh_period; - previous_refresh_period = transaction.pamac_config.refresh_period; + refresh_period_spin_button.value = transaction.refresh_period; + previous_refresh_period = transaction.refresh_period; } - no_update_hide_icon_checkbutton.active = transaction.pamac_config.no_update_hide_icon; + no_update_hide_icon_checkbutton.active = transaction.no_update_hide_icon; // populate ignorepkgs_liststore - Gtk.TreeIter iter; - foreach (unowned string ignorepkg in transaction.alpm_utils.get_ignorepkgs ()) { - ignorepkgs_liststore.insert_with_values (out iter, -1, 0, ignorepkg); + ignorepkgs_liststore = new Gtk.ListStore (1, typeof (string)); + ignorepkgs_treeview.set_model (ignorepkgs_liststore); + foreach (unowned string ignorepkg in transaction.get_ignorepkgs ()) { + ignorepkgs_liststore.insert_with_values (null, -1, 0, ignorepkg); } remove_unrequired_deps_button.state_set.connect (on_remove_unrequired_deps_button_state_set); check_space_button.state_set.connect (on_check_space_button_state_set); @@ -98,15 +98,14 @@ namespace Pamac { no_update_hide_icon_checkbutton.toggled.connect (on_no_update_hide_icon_checkbutton_toggled); transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished); - unowned Alpm.Package? pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "pacman-mirrorlist"); - if (pkg == null) { + AlpmPackage pkg = transaction.find_installed_satisfier ("pacman-mirrorlist"); + if (pkg.name == "") { mirrors_config_box.visible = false; } else { var mirrors_config = new MirrorsConfig ("/etc/pacman-mirrors.conf"); mirrors_country_comboboxtext.append_text (dgettext (null, "Worldwide")); mirrors_country_comboboxtext.active = 0; int index = 1; - mirrors_config.get_countrys (); foreach (unowned string country in mirrors_config.countrys) { mirrors_country_comboboxtext.append_text (country); if (country == mirrors_config.choosen_country) { @@ -126,17 +125,17 @@ namespace Pamac { transaction.write_mirrors_config_finished.connect (on_write_mirrors_config_finished); } - pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "yaourt"); - if (pkg == null) { + pkg = transaction.find_installed_satisfier ("yaourt"); + if (pkg.name == "") { aur_config_box.visible = false; } else { - enable_aur_button.active = transaction.pamac_config.enable_aur; - search_aur_checkbutton.active = transaction.pamac_config.search_aur; - search_aur_checkbutton.sensitive = transaction.pamac_config.enable_aur; - check_aur_updates_checkbutton.active = transaction.pamac_config.check_aur_updates; - check_aur_updates_checkbutton.sensitive = transaction.pamac_config.enable_aur; - no_confirm_build_checkbutton.active = transaction.pamac_config.no_confirm_build; - no_confirm_build_checkbutton.sensitive = transaction.pamac_config.enable_aur; + enable_aur_button.active = transaction.enable_aur; + search_aur_checkbutton.active = transaction.search_aur; + search_aur_checkbutton.sensitive = transaction.enable_aur; + check_aur_updates_checkbutton.active = transaction.check_aur_updates; + check_aur_updates_checkbutton.sensitive = transaction.enable_aur; + no_confirm_build_checkbutton.active = transaction.no_confirm_build; + no_confirm_build_checkbutton.sensitive = transaction.enable_aur; enable_aur_button.state_set.connect (on_enable_aur_button_state_set); search_aur_checkbutton.toggled.connect (on_search_aur_checkbutton_toggled); check_aur_updates_checkbutton.toggled.connect (on_check_aur_updates_checkbutton_toggled); @@ -248,40 +247,45 @@ namespace Pamac { [GtkCallback] void on_add_ignorepkgs_button_clicked () { var choose_ignorepkgs_dialog = new ChooseIgnorepkgsDialog (this); - foreach (var pkg in transaction.alpm_utils.get_installed_pkgs ()) { - Gtk.TreeIter iter; - if (transaction.alpm_utils.get_ignorepkgs ().find_str (pkg.name) == null) { - choose_ignorepkgs_dialog.pkgs_list.insert_with_values (out iter, -1, 0, false, 1, pkg.name); - } else { - choose_ignorepkgs_dialog.pkgs_list.insert_with_values (out iter, -1, 0, true, 1, pkg.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 (); } - if (choose_ignorepkgs_dialog.run () == Gtk.ResponseType.OK) { - var ignorepkg_string = new StringBuilder (); - choose_ignorepkgs_dialog.pkgs_list.foreach ((model, path, iter) => { - GLib.Value val; - // get value at column 0 to know if it is selected - choose_ignorepkgs_dialog.pkgs_list.get_value (iter, 0, out val); - if ((bool) val) { - // get value at column 1 to get the pkg name - choose_ignorepkgs_dialog.pkgs_list.get_value (iter, 1, out val); - if (ignorepkg_string.len != 0) { - ignorepkg_string.append (" "); - } - ignorepkg_string.append ((string) val); + transaction.get_installed_pkgs.begin ((obj, res) => { + var pkgs = transaction.get_installed_pkgs.end (res); + foreach (unowned AlpmPackage pkg in pkgs) { + if (pkg.name in transaction.get_ignorepkgs ()) { + choose_ignorepkgs_dialog.pkgs_list.insert_with_values (null, -1, 0, true, 1, pkg.name); + } else { + choose_ignorepkgs_dialog.pkgs_list.insert_with_values (null, -1, 0, false, 1, pkg.name); } - return false; - }); - if (ignorepkg_string.len != 0) { + } + this.get_window ().set_cursor (null); + if (choose_ignorepkgs_dialog.run () == Gtk.ResponseType.OK) { + var ignorepkg_string = new StringBuilder (); + choose_ignorepkgs_dialog.pkgs_list.foreach ((model, path, iter) => { + GLib.Value val; + // get value at column 0 to know if it is selected + model.get_value (iter, 0, out val); + if ((bool) val) { + // get value at column 1 to get the pkg name + model.get_value (iter, 1, out val); + if (ignorepkg_string.len != 0) { + ignorepkg_string.append (" "); + } + ignorepkg_string.append ((string) val); + } + return false; + }); var new_alpm_conf = new HashTable<string,Variant> (str_hash, str_equal); new_alpm_conf.insert ("IgnorePkg", new Variant.string (ignorepkg_string.str)); transaction.start_write_alpm_config (new_alpm_conf); } - } - choose_ignorepkgs_dialog.destroy (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } + choose_ignorepkgs_dialog.destroy (); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } + }); } [GtkCallback] @@ -293,7 +297,7 @@ namespace Pamac { var ignorepkg_string = new StringBuilder (); ignorepkgs_liststore.foreach ((model, path, iter) => { GLib.Value name; - ignorepkgs_liststore.get_value (iter, 0, out name); + model.get_value (iter, 0, out name); if (ignorepkg_string.len != 0) { ignorepkg_string.append (" "); } @@ -303,16 +307,15 @@ namespace Pamac { var new_alpm_conf = new HashTable<string,Variant> (str_hash, str_equal); new_alpm_conf.insert ("IgnorePkg", new Variant.string (ignorepkg_string.str)); transaction.start_write_alpm_config (new_alpm_conf); + } } void on_write_alpm_config_finished (bool checkspace) { check_space_button.state = checkspace; - // re-populate ignorepkgs_liststore - Gtk.TreeIter iter; ignorepkgs_liststore.clear (); - foreach (unowned string ignorepkg in transaction.alpm_utils.get_ignorepkgs ()) { - ignorepkgs_liststore.insert_with_values (out iter, -1, 0, ignorepkg); + foreach (unowned string ignorepkg in transaction.get_ignorepkgs ()) { + ignorepkgs_liststore.insert_with_values (null, -1, 0, ignorepkg); } } diff --git a/src/transaction.vala b/src/transaction.vala index fcec28f9e66ec8d70b455dfc80a40c56ddbfe9d2..3c0e66da7722566e6645aabad89f59078164ac37 100644 --- a/src/transaction.vala +++ b/src/transaction.vala @@ -28,20 +28,40 @@ namespace Pamac { public abstract void start_write_mirrors_config (HashTable<string,Variant> new_mirrors_conf) throws IOError; public abstract void start_generate_mirrors_list () throws IOError; public abstract void start_set_pkgreason (string pkgname, uint reason) throws IOError; - public abstract PackageInfos get_installed_pkg (string pkgname) throws IOError; + public abstract AlpmPackage get_installed_pkg (string pkgname) throws IOError; public abstract void start_refresh (bool force) throws IOError; + public abstract bool get_checkspace () throws IOError; + public abstract string[] get_ignorepkgs () throws IOError; + public abstract bool should_hold (string pkgname) throws IOError; + public abstract uint get_pkg_reason (string pkgname) throws IOError; + public abstract uint get_pkg_origin (string pkgname) throws IOError; + public abstract async AlpmPackage[] get_installed_pkgs () throws IOError; + public abstract async AlpmPackage[] get_foreign_pkgs () throws IOError; + public abstract async AlpmPackage[] get_orphans () throws IOError; + public abstract AlpmPackage find_installed_satisfier (string depstring) throws IOError; + public abstract AlpmPackage get_sync_pkg (string pkgname) throws IOError; + public abstract AlpmPackage find_sync_satisfier (string depstring) throws IOError; + public abstract async AlpmPackage[] search_pkgs (string search_string) throws IOError; + public abstract async AURPackage[] search_in_aur (string search_string) throws IOError; + public abstract async string[] get_aur_build_list (string pkgname) throws IOError; + public abstract string[] get_repos_names () throws IOError; + public abstract async AlpmPackage[] get_repo_pkgs (string repo) throws IOError; + public abstract string[] get_groups_names () throws IOError; + public abstract async AlpmPackage[] get_group_pkgs (string groupname) throws IOError; + public abstract AlpmPackageDetails get_pkg_details (string pkgname) throws IOError; + public abstract async AURPackageDetails get_aur_details (string pkgname) throws IOError; + public abstract string[] get_pkg_uninstalled_optdeps (string pkgname) throws IOError; public abstract void add_ignorepkg (string pkgname) throws IOError; public abstract void remove_ignorepkg (string pkgname) throws IOError; public abstract void start_get_updates (bool check_aur_updates) throws IOError; - public abstract bool trans_init (Alpm.TransFlag transflags) throws IOError; + public abstract bool trans_init (int transflags) throws IOError; public abstract bool trans_sysupgrade (bool enable_downgrade) throws IOError; public abstract bool trans_add_pkg (string pkgname) throws IOError; public abstract bool trans_remove_pkg (string pkgname) throws IOError; public abstract bool trans_load_pkg (string pkgpath) throws IOError; public abstract void start_trans_prepare () throws IOError; public abstract void choose_provider (int provider) throws IOError; - public abstract PackageInfos[] trans_to_add () throws IOError; - public abstract PackageInfos[] trans_to_remove () throws IOError; + public abstract TransactionSummary get_transaction_summary () throws IOError; public abstract void start_trans_commit () throws IOError; public abstract void trans_release () throws IOError; [DBus (no_reply = true)] @@ -84,24 +104,32 @@ namespace Pamac { Daemon daemon; - public AlpmUtils alpm_utils; - public Pamac.Config pamac_config; + Pamac.Config pamac_config; + public bool check_aur_updates { get { return pamac_config.check_aur_updates; } } + public bool enable_aur { get { return pamac_config.enable_aur; } } + public unowned GLib.HashTable<string,string> environment_variables { get {return pamac_config.environment_variables; } } + public bool no_confirm_build { get { return pamac_config.no_confirm_build; } } + public bool no_update_hide_icon { get { return pamac_config.no_update_hide_icon; } } + public bool recurse { get { return pamac_config.no_confirm_build; } } + public uint64 refresh_period { get { return pamac_config.refresh_period; } } + public bool search_aur { get { return pamac_config.search_aur; } } - public Alpm.TransFlag flags; + //Alpm.TransFlag + int flags; - public GenericSet<string?> to_add; + public GenericSet<string?> to_install; public GenericSet<string?> to_remove; public GenericSet<string?> to_load; public GenericSet<string?> to_build; + GenericSet<string?> previous_to_install; + GenericSet<string?> previous_to_remove; + public GenericSet<string?> transaction_summary; public GenericSet<string?> temporary_ignorepkgs; - HashTable<string,Json.Object> aur_infos; - - public Mode mode; + public Mode mode { get; set; } uint64 total_download; uint64 already_downloaded; - string previous_label; string previous_textbar; float previous_percent; string previous_filename; @@ -112,7 +140,6 @@ namespace Pamac { uint64 download_rate; uint64 rates_nb; Timer timer; - bool database_modified; bool success; //dialogs @@ -120,8 +147,11 @@ namespace Pamac { TransactionInfoDialog transaction_info_dialog; ProgressDialog progress_dialog; //parent window - public Gtk.ApplicationWindow? application_window; + public Gtk.ApplicationWindow? application_window { get; private set; } + public signal void start_transaction (); + public signal void emit_action (string action); + public signal void alpm_handle_refreshed (); public signal void finished (bool success); public signal void set_pkgreason_finished (); public signal void get_updates_finished (Updates updates); @@ -132,36 +162,36 @@ namespace Pamac { public signal void write_mirrors_config_finished (string choosen_country, string choosen_generation_method); public Transaction (Gtk.ApplicationWindow? application_window) { - alpm_utils = new AlpmUtils ("/etc/pacman.conf"); pamac_config = new Pamac.Config ("/etc/pamac.conf"); - flags = Alpm.TransFlag.CASCADE; + flags = (1 << 4); //Alpm.TransFlag.CASCADE if (pamac_config.recurse) { - flags |= Alpm.TransFlag.RECURSE; + flags |= (1 << 5); //Alpm.TransFlag.RECURSE } - to_add = new GenericSet<string?> (str_hash, str_equal); + to_install = new GenericSet<string?> (str_hash, str_equal); to_remove = new GenericSet<string?> (str_hash, str_equal); to_load = new GenericSet<string?> (str_hash, str_equal); to_build = new GenericSet<string?> (str_hash, str_equal); + previous_to_install = new GenericSet<string?> (str_hash, str_equal); + previous_to_remove = new GenericSet<string?> (str_hash, str_equal); + transaction_summary = new GenericSet<string?> (str_hash, str_equal); temporary_ignorepkgs = new GenericSet<string?> (str_hash, str_equal); - aur_infos = new HashTable<string,Json.Object> (str_hash, str_equal); connecting_dbus_signals (); //creating dialogs this.application_window = application_window; transaction_sum_dialog = new TransactionSumDialog (application_window); transaction_info_dialog = new TransactionInfoDialog (application_window); progress_dialog = new ProgressDialog (application_window); - progress_dialog.close_button.clicked.connect (on_progress_dialog_close_button_clicked); + progress_dialog.close_button.clicked.connect (hide_progress); + progress_dialog.delete_event.connect (progress_dialog.hide_on_delete); progress_dialog.cancel_button.clicked.connect (on_progress_dialog_cancel_button_clicked); // connect to child_exited signal which will only be emit after a call to watch_child progress_dialog.term.child_exited.connect (on_term_child_exited); // progress data - previous_label = ""; previous_textbar = ""; previous_filename = ""; sysupgrade_after_trans = false; timer = new Timer (); - database_modified = false; success = false; } @@ -224,16 +254,31 @@ namespace Pamac { } } + public void show_progress () { + progress_dialog.show (); + } + + public void hide_progress () { + progress_dialog.hide (); + } + + void reset_progress_dialog (string action, + bool cancel_button_visible = true, + bool expander_expanded = false) { + progress_dialog.spawn_in_term ({"echo", action}); + progress_dialog.action_label.label = action; + progress_dialog.progressbar.fraction = 0; + progress_dialog.progressbar.text = ""; + progress_dialog.cancel_button.visible = cancel_button_visible; + progress_dialog.expander.expanded = expander_expanded; + if (expander_expanded) { + progress_dialog.width_request = 700; + } + } + public void start_generate_mirrors_list () { string action = dgettext (null, "Refreshing mirrors list") + "..."; - progress_dialog.spawn_in_term ({"echo", action}); - progress_dialog.action_label.set_text (action); - progress_dialog.progressbar.set_fraction (0); - progress_dialog.progressbar.set_text (""); - progress_dialog.cancel_button.set_visible (false); - progress_dialog.close_button.set_visible (false); - progress_dialog.expander.set_expanded (true); - progress_dialog.width_request = 700; + reset_progress_dialog (action, false, true); pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_dialog.progressbar.pulse); progress_dialog.show (); while (Gtk.events_pending ()) { @@ -247,9 +292,9 @@ namespace Pamac { } } - public void start_set_pkgreason (string pkgname, Alpm.Package.Reason reason) { + public void start_set_pkgreason (string pkgname, uint reason) { try { - daemon.start_set_pkgreason (pkgname, (uint) reason); + daemon.start_set_pkgreason (pkgname, reason); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -257,15 +302,13 @@ namespace Pamac { public void start_refresh (bool force) { string action = dgettext (null, "Synchronizing package databases") + "..."; - progress_dialog.spawn_in_term ({"echo", action}); - progress_dialog.action_label.set_text (action); - progress_dialog.progressbar.set_fraction (0); - progress_dialog.progressbar.set_text (""); - progress_dialog.cancel_button.set_visible (true); - progress_dialog.close_button.set_visible (false); - progress_dialog.show (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); + reset_progress_dialog (action); + emit_action (action); + if (mode != Mode.MANAGER) { + progress_dialog.show (); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } } try { daemon.refresh_finished.connect (on_refresh_finished); @@ -273,12 +316,264 @@ namespace Pamac { } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); daemon.refresh_finished.disconnect (on_refresh_finished); - database_modified = true; success = false; finish_transaction (); } } + public bool get_checkspace () { + bool checkspace = false; + try { + checkspace = daemon.get_checkspace (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return checkspace; + } + + public string[] get_ignorepkgs () { + string[] ignorepkgs = {}; + try { + ignorepkgs = daemon.get_ignorepkgs (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return ignorepkgs; + } + + public AlpmPackage get_installed_pkg (string pkgname) { + try { + return daemon.get_installed_pkg (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public AlpmPackage find_installed_satisfier (string depstring) { + try { + return daemon.find_installed_satisfier (depstring); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public bool should_hold (string pkgname) { + bool should_hold = false; + try { + should_hold = daemon.should_hold (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return should_hold; + } + + public uint get_pkg_reason (string pkgname) { + uint reason = 0; + try { + reason = daemon.get_pkg_reason (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return reason; + } + + public uint get_pkg_origin (string pkgname) { + uint origin = 0; + try { + origin = daemon.get_pkg_origin (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return origin; + } + + public async AlpmPackage[] get_installed_pkgs () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield daemon.get_installed_pkgs (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_foreign_pkgs () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield daemon.get_foreign_pkgs (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_orphans () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield daemon.get_orphans (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public AlpmPackage get_sync_pkg (string pkgname) { + try { + return daemon.get_sync_pkg (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public AlpmPackage find_sync_satisfier (string depstring) { + try { + return daemon.find_sync_satisfier (depstring); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public async AlpmPackage[] search_pkgs (string search_string) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield daemon.search_pkgs (search_string); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public async AURPackage[] search_in_aur (string search_string) { + AURPackage[] pkgs = {}; + try { + pkgs = yield daemon.search_in_aur (search_string); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public async string[] get_aur_build_list (string pkgname) { + string[] names = {}; + try { + names = yield daemon.get_aur_build_list (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return names; + } + + public string[] get_repos_names () { + string[] repos_names = {}; + try { + repos_names = daemon.get_repos_names (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return repos_names; + } + + public async AlpmPackage[] get_repo_pkgs (string repo) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield daemon.get_repo_pkgs (repo); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public string[] get_groups_names () { + string[] groups_names = {}; + try { + groups_names = daemon.get_groups_names (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return groups_names; + } + + public async AlpmPackage[] get_group_pkgs (string group_name) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield daemon.get_group_pkgs (group_name); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkgs; + } + + public string[] get_pkg_uninstalled_optdeps (string pkgname) { + string[] optdeps = {}; + try { + optdeps = daemon.get_pkg_uninstalled_optdeps (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return optdeps; + } + + public AlpmPackageDetails get_pkg_details (string pkgname) { + try { + return daemon.get_pkg_details (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + return AlpmPackageDetails () { + name = "", + version = "", + desc = "", + repo = "", + url = "", + packager = "", + builddate = "", + installdate = "", + reason = "", + has_signature = "" + }; + } + } + + public async AURPackageDetails get_aur_details (string pkgname) { + var pkg = AURPackageDetails () { + name = "", + version = "", + desc = "", + packagebase = "", + url = "", + maintainer = "" + }; + try { + pkg = yield daemon.get_aur_details (pkgname); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return pkg; + } + public void start_get_updates () { daemon.get_updates_finished.connect (on_get_updates_finished); try { @@ -318,7 +613,7 @@ namespace Pamac { } } - public bool init (Alpm.TransFlag flags) { + public bool init (int flags) { foreach (unowned string pkgname in temporary_ignorepkgs) { add_ignorepkg (pkgname); } @@ -331,8 +626,8 @@ namespace Pamac { } void sysupgrade_simple (bool enable_downgrade) { - progress_dialog.progressbar.set_fraction (0); - progress_dialog.cancel_button.set_visible (true); + progress_dialog.progressbar.fraction = 0; + progress_dialog.cancel_button.visible = true; success = init (0); if (success) { try { @@ -342,9 +637,11 @@ namespace Pamac { success = false; } if (success) { - progress_dialog.show (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); + if (mode != Mode.MANAGER) { + progress_dialog.show (); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } } try { daemon.start_trans_prepare (); @@ -366,15 +663,8 @@ namespace Pamac { public void sysupgrade (bool enable_downgrade) { this.enable_downgrade = enable_downgrade; string action = dgettext (null, "Starting full system upgrade") + "..."; - progress_dialog.spawn_in_term ({"echo", action}); - progress_dialog.action_label.set_text (action); - progress_dialog.progressbar.set_fraction (0); - progress_dialog.progressbar.set_text (""); - progress_dialog.cancel_button.set_visible (true); - progress_dialog.close_button.set_visible (false); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } + reset_progress_dialog (action); + emit_action (action); start_get_updates_for_sysupgrade (); } @@ -391,15 +681,15 @@ namespace Pamac { if (mode == Mode.MANAGER) { sysupgrade_after_trans = true; } - foreach (unowned PackageInfos infos in updates.repos_updates) { - to_add.add (infos.name); + foreach (unowned UpdateInfos infos in updates.repos_updates) { + to_install.add (infos.name); } // run as a standard transaction run (); } else { if (updates.aur_updates.length != 0) { clear_lists (); - foreach (unowned PackageInfos infos in updates.aur_updates) { + foreach (unowned UpdateInfos infos in updates.aur_updates) { if (!(infos.name in temporary_ignorepkgs)) { to_build.add (infos.name); } @@ -408,35 +698,34 @@ namespace Pamac { if (updates.repos_updates.length != 0) { sysupgrade_simple (enable_downgrade); } else { - progress_dialog.show (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } on_trans_prepare_finished (true); } } } public void clear_lists () { - to_add.remove_all (); + to_install.remove_all (); to_remove.remove_all (); to_build.remove_all (); } + void clear_previous_lists () { + previous_to_install.remove_all (); + previous_to_remove.remove_all (); + } + public void run () { string action = dgettext (null, "Preparing") + "..."; - progress_dialog.spawn_in_term ({"echo", action}); - progress_dialog.action_label.set_text (action); - progress_dialog.progressbar.set_fraction (0); - progress_dialog.progressbar.set_text (""); - progress_dialog.cancel_button.set_visible (true); - progress_dialog.close_button.set_visible (false); - progress_dialog.show (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); + reset_progress_dialog (action); + emit_action (action); + if (mode != Mode.MANAGER) { + progress_dialog.show (); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } } // run - if (to_add.length == 0 + if (to_install.length == 0 && to_remove.length == 0 && to_load.length == 0 && to_build.length != 0) { @@ -451,7 +740,7 @@ namespace Pamac { } if (success) { success = false; - foreach (unowned string name in to_add) { + foreach (unowned string name in to_install) { try { success = daemon.trans_add_pkg (name); } catch (IOError e) { @@ -523,142 +812,116 @@ namespace Pamac { // return 0 if transaction_sum is empty, 2, if there are only aur updates, 1 otherwise Type type = 0; uint64 dsize = 0; - PackageInfos[] prepared_to_add = {}; - PackageInfos[] prepared_to_remove = {}; - string[] to_downgrade = {}; - string[] to_install = {}; - string[] to_reinstall = {}; - string[] to_update = {}; - string[] _to_build = {}; - Gtk.TreeIter iter; + transaction_summary.remove_all (); + var summary = TransactionSummary (); transaction_sum_dialog.top_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "Transaction Summary"))); transaction_sum_dialog.sum_list.clear (); try { - prepared_to_add = daemon.trans_to_add (); - prepared_to_remove = daemon.trans_to_remove (); + summary = daemon.get_transaction_summary (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } - foreach (unowned PackageInfos pkg_info in prepared_to_add) { - dsize += pkg_info.download_size; - try { - PackageInfos local_pkg_info = daemon.get_installed_pkg (pkg_info.name); - if (local_pkg_info.name == "") { - to_install += "%s %s".printf (pkg_info.name, pkg_info.version); - } else { - int cmp = Alpm.pkg_vercmp (pkg_info.version, local_pkg_info.version); - if (cmp == 1) { - to_update += "%s %s".printf (pkg_info.name, pkg_info.version); - } else if (cmp == 0) { - to_reinstall += "%s %s".printf (pkg_info.name, pkg_info.version); - } else { - to_downgrade += "%s %s".printf (pkg_info.name, pkg_info.version); - } - } - } catch (IOError e) { - stderr.printf ("IOError: %s\n", e.message); - } - } - foreach (unowned string name in to_build) { - _to_build += name; - } - int len = prepared_to_remove.length; - int i; - if (len != 0) { + var iter = Gtk.TreeIter (); + if (summary.to_remove.length > 0) { type |= Type.STANDARD; - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 0, dgettext (null, "To remove") + ":", - 1, "%s %s".printf (prepared_to_remove[0].name, prepared_to_remove[0].version)); - i = 1; - while (i < len) { + foreach (unowned UpdateInfos infos in summary.to_remove) { + transaction_summary.add (infos.name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, "%s %s".printf (prepared_to_remove[i].name, prepared_to_remove[i].version)); - i++; + 1, infos.name, + 2, infos.old_version); } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_remove.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To remove") + ":")); } - len = to_downgrade.length; - if (len != 0) { + if (summary.to_downgrade.length > 0) { type |= Type.STANDARD; - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 0, dgettext (null, "To downgrade") + ":", - 1, to_downgrade[0]); - i = 1; - while (i < len) { + foreach (unowned UpdateInfos infos in summary.to_downgrade) { + dsize += infos.download_size; + transaction_summary.add (infos.name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, to_downgrade[i]); - i++; + 1, infos.name, + 2, infos.new_version, + 3, "(%s)".printf (infos.old_version)); } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_downgrade.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To downgrade") + ":")); } - len = _to_build.length; - if (len != 0) { + if (to_build.length > 0) { type |= Type.BUILD; - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 0, dgettext (null, "To build") + ":", - 1, _to_build[0]); - i = 1; - while (i < len) { + foreach (unowned string name in to_build) { + transaction_summary.add (name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, _to_build[i]); - i++; + 1, name); } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - ((int) to_build.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To build") + ":")); } - len = to_install.length; - if (len != 0) { + if (summary.to_install.length > 0) { type |= Type.STANDARD; - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 0, dgettext (null, "To install") + ":", - 1, to_install[0]); - i = 1; - while (i < len) { + foreach (unowned UpdateInfos infos in summary.to_install) { + dsize += infos.download_size; + transaction_summary.add (infos.name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, to_install[i]); - i++; + 1, infos.name, + 2, infos.new_version); } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_install.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To install") + ":")); } - len = to_reinstall.length; - if (len != 0) { + if (summary.to_reinstall.length > 0) { type |= Type.STANDARD; - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 0, dgettext (null, "To reinstall") + ":", - 1, to_reinstall[0]); - i = 1; - while (i < len) { + foreach (unowned UpdateInfos infos in summary.to_reinstall) { + dsize += infos.download_size; + transaction_summary.add (infos.name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, to_reinstall[i]); - i++; + 1, infos.name, + 2, infos.old_version); } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_reinstall.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To reinstall") + ":")); } - len = to_update.length; - if (len != 0) { + if (summary.to_upgrade.length > 0) { type |= Type.UPDATE; if (mode != Mode.UPDATER) { - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 0, dgettext (null, "To update") + ":", - 1, to_update[0]); - i = 1; - while (i < len) { + foreach (unowned UpdateInfos infos in summary.to_upgrade) { + dsize += infos.download_size; + transaction_summary.add (infos.name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, to_update[i]); - i++; + 1, infos.name, + 2, infos.new_version, + 3, "(%s)".printf (infos.old_version)); } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_upgrade.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To update") + ":")); } } if (dsize == 0) { - transaction_sum_dialog.bottom_label.set_visible (false); + transaction_sum_dialog.bottom_label.visible = false; } else { transaction_sum_dialog.bottom_label.set_markup ("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size (dsize))); - transaction_sum_dialog.bottom_label.set_visible (true); + transaction_sum_dialog.bottom_label.visible = true; } return type; } public void start_commit () { - progress_dialog.cancel_button.set_visible (false); + progress_dialog.cancel_button.visible = false; try { daemon.start_trans_commit (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); - database_modified = true; success = false; finish_transaction (); } @@ -666,16 +929,15 @@ namespace Pamac { public void build_aur_packages () { string action = dgettext (null, "Building packages") + "..."; - progress_dialog.spawn_in_term ({"echo", action}); - progress_dialog.action_label.set_text (action); - progress_dialog.progressbar.set_fraction (0); - progress_dialog.progressbar.set_text (""); - progress_dialog.cancel_button.set_visible (false); - progress_dialog.close_button.set_visible (false); - progress_dialog.expander.set_expanded (true); - progress_dialog.width_request = 700; + reset_progress_dialog (action, false, true); + emit_action (action); progress_dialog.term.grab_focus (); pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_dialog.progressbar.pulse); + progress_dialog.close_button.visible = false; + progress_dialog.show (); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } string[] cmds = {"yaourt", "-S"}; if (pamac_config.no_confirm_build) { cmds += "--noconfirm"; @@ -687,14 +949,15 @@ namespace Pamac { progress_dialog.spawn_in_term (cmds, out child_pid); // watch_child is needed in order to have the child_exited signal emitted progress_dialog.term.watch_child (child_pid); - } - - public async Json.Object get_aur_infos (string aur_name) { - if (!aur_infos.contains (aur_name)) { - Json.Array results = AUR.multiinfo ({aur_name}); - aur_infos.insert (aur_name, results.get_object_element (0)); - } - return aur_infos.lookup (aur_name); +//~ foreach (unowned string pkgname in to_build) { +//~ stdout.printf("aur deps for %s:\n", pkgname); +//~ get_aur_build_list.begin (pkgname, (obj, res) => { +//~ string[] names = get_aur_build_list.end (res); +//~ foreach (unowned string name in names) { +//~ stdout.printf("\t%s\n", name); +//~ } +//~ }); +//~ } } public void cancel () { @@ -703,7 +966,9 @@ namespace Pamac { } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } - progress_dialog.expander.set_expanded (false); + progress_dialog.hide (); + progress_dialog.spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction cancelled") + ".\n"}); + progress_dialog.expander.expanded = false; Gtk.TextIter start_iter; Gtk.TextIter end_iter; transaction_info_dialog.textbuffer.get_start_iter (out start_iter); @@ -731,188 +996,167 @@ namespace Pamac { } void on_emit_event (uint primary_event, uint secondary_event, string[] details) { - string msg; + string? action = null; + string? detailed_action = null; switch (primary_event) { - case Alpm.Event.Type.HOOK_START: - switch (secondary_event) { - case Alpm.HookWhen.PRE_TRANSACTION: - msg = dgettext (null, "Running pre-transaction hooks") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); - break; - case Alpm.HookWhen.POST_TRANSACTION: - msg = dgettext (null, "Running post-transaction hooks") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); - break; - default: - break; - } - break; - case Alpm.Event.Type.HOOK_RUN_START: - string textbar = "%s/%s".printf (details[2], details[3]); - if (textbar != previous_textbar) { - previous_textbar = textbar; - progress_dialog.progressbar.set_text (textbar); - } - float fraction = (float) int.parse (details[2]) / int.parse (details[3]); - if (fraction != previous_percent) { - previous_percent = fraction; - progress_dialog.progressbar.set_fraction (fraction); - } - if (details[1] != "") { - msg = details[1] + ":"; - } else { - msg = details[0] + ":"; - } - progress_dialog.spawn_in_term ({"echo", msg}); - break; - case Alpm.Event.Type.CHECKDEPS_START: - msg = dgettext (null, "Checking dependencies") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 1: //Alpm.Event.Type.CHECKDEPS_START + action = dgettext (null, "Checking dependencies") + "..."; break; - case Alpm.Event.Type.FILECONFLICTS_START: - msg = dgettext (null, "Checking file conflicts") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 3: //Alpm.Event.Type.FILECONFLICTS_START + action = dgettext (null, "Checking file conflicts") + "..."; break; - case Alpm.Event.Type.RESOLVEDEPS_START: - msg = dgettext (null, "Resolving dependencies") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 5: //Alpm.Event.Type.RESOLVEDEPS_START + action = dgettext (null, "Resolving dependencies") + "..."; break; - case Alpm.Event.Type.INTERCONFLICTS_START: - msg = dgettext (null, "Checking inter-conflicts") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 7: //Alpm.Event.Type.INTERCONFLICTS_START + action = dgettext (null, "Checking inter-conflicts") + "..."; break; - case Alpm.Event.Type.TRANSACTION_START: - progress_dialog.cancel_button.set_visible (false); + case 9: //Alpm.Event.Type.TRANSACTION_START + progress_dialog.cancel_button.visible = false; + start_transaction (); break; - case Alpm.Event.Type.PACKAGE_OPERATION_START: + case 11: //Alpm.Event.Type.PACKAGE_OPERATION_START switch (secondary_event) { - case Alpm.Package.Operation.INSTALL: + // special cases handle differently + case 1: //Alpm.Package.Operation.INSTALL previous_filename = details[0]; - msg = dgettext (null, "Installing %s").printf (details[0]) + "..."; - progress_dialog.action_label.set_text (msg); - msg = dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."; - progress_dialog.spawn_in_term ({"echo", msg}); + string msg = dgettext (null, "Installing %s").printf (details[0]) + "..."; + progress_dialog.action_label.label = msg; + emit_action (msg); + progress_dialog.spawn_in_term ({"echo", dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."}); break; - case Alpm.Package.Operation.REINSTALL: + case 2: //Alpm.Package.Operation.UPGRADE previous_filename = details[0]; - msg = dgettext (null, "Reinstalling %s").printf (details[0]) + "..."; - progress_dialog.action_label.set_text (msg); - msg = dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."; - progress_dialog.spawn_in_term ({"echo", msg}); + string msg = dgettext (null, "Upgrading %s").printf (details[0]) + "..."; + progress_dialog.action_label.label = msg; + emit_action (msg); + progress_dialog.spawn_in_term ({"echo", dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "..."}); break; - case Alpm.Package.Operation.REMOVE: + case 3: //Alpm.Package.Operation.REINSTALL previous_filename = details[0]; - msg = dgettext (null, "Removing %s").printf (details[0]) + "..."; - progress_dialog.action_label.set_text (msg); - msg = dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."; - progress_dialog.spawn_in_term ({"echo", msg}); + string msg = dgettext (null, "Reinstalling %s").printf (details[0]) + "..."; + progress_dialog.action_label.label = msg; + emit_action (msg); + progress_dialog.spawn_in_term ({"echo", dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."}); break; - case Alpm.Package.Operation.UPGRADE: + case 4: //Alpm.Package.Operation.DOWNGRADE previous_filename = details[0]; - msg = dgettext (null, "Upgrading %s").printf (details[0]) + "..."; - progress_dialog.action_label.set_text (msg); - msg = dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "..."; - progress_dialog.spawn_in_term ({"echo", msg}); + string msg = dgettext (null, "Downgrading %s").printf (details[0]) + "..."; + progress_dialog.action_label.label = msg; + emit_action (msg); + progress_dialog.spawn_in_term ({"echo", dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "..."}); break; - case Alpm.Package.Operation.DOWNGRADE: + case 5: //Alpm.Package.Operation.REMOVE previous_filename = details[0]; - msg = dgettext (null, "Downgrading %s").printf (details[0]) + "..."; - progress_dialog.action_label.set_text (msg); - msg = dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "..."; - progress_dialog.spawn_in_term ({"echo", msg}); + string msg = dgettext (null, "Removing %s").printf (details[0]) + "..."; + progress_dialog.action_label.label = msg; + emit_action (msg); + progress_dialog.spawn_in_term ({"echo", dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."}); break; } break; - case Alpm.Event.Type.INTEGRITY_START: - msg = dgettext (null, "Checking integrity") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 13: //Alpm.Event.Type.INTEGRITY_START + action = dgettext (null, "Checking integrity") + "..."; break; - case Alpm.Event.Type.KEYRING_START: - progress_dialog.cancel_button.set_visible (true); - msg = dgettext (null, "Checking keyring") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 15: //Alpm.Event.Type.LOAD_START + action = dgettext (null, "Loading packages files") + "..."; break; - case Alpm.Event.Type.KEY_DOWNLOAD_START: - msg = dgettext (null, "Downloading required keys") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 17: //Alpm.Event.Type.DELTA_INTEGRITY_START + action = dgettext (null, "Checking delta integrity") + "..."; break; - case Alpm.Event.Type.LOAD_START: - msg = dgettext (null, "Loading packages files") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 19: //Alpm.Event.Type.DELTA_PATCHES_START + action = dgettext (null, "Applying deltas") + "..."; break; - case Alpm.Event.Type.DELTA_INTEGRITY_START: - msg = dgettext (null, "Checking delta integrity") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 21: //Alpm.Event.Type.DELTA_PATCH_START + detailed_action = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "..."; break; - case Alpm.Event.Type.DELTA_PATCHES_START: - msg = dgettext (null, "Applying deltas") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 22: //Alpm.Event.Type.DELTA_PATCH_DONE + detailed_action = dgettext (null, "Generation succeeded") + "..."; break; - case Alpm.Event.Type.DELTA_PATCH_START: - msg = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 23: //Alpm.Event.Type.DELTA_PATCH_FAILED + detailed_action = dgettext (null, "Generation failed") + "..."; break; - case Alpm.Event.Type.DELTA_PATCH_DONE: - msg = dgettext (null, "Generation succeeded") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 24: //Alpm.Event.Type.SCRIPTLET_INFO + progress_dialog.expander.expanded = true; + action = dgettext (null, "Configuring %s").printf (previous_filename) + "..."; + detailed_action = details[0].replace ("\n", ""); break; - case Alpm.Event.Type.DELTA_PATCH_FAILED: - msg = dgettext (null, "Generation failed") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 25: //Alpm.Event.Type.RETRIEVE_START + progress_dialog.cancel_button.visible = true; + action = dgettext (null, "Downloading") + "..."; break; - case Alpm.Event.Type.SCRIPTLET_INFO: - progress_dialog.action_label.set_text (dgettext (null, "Configuring %s").printf (previous_filename) + "..."); - progress_dialog.expander.set_expanded (true); - progress_dialog.spawn_in_term ({"echo", "-n", details[0]}); + case 28: //Alpm.Event.Type.PKGDOWNLOAD_START + string name_version_release = details[0].slice (0, details[0].last_index_of_char ('-')); + string name_version = name_version_release.slice (0, name_version_release.last_index_of_char ('-')); + string name = name_version.slice (0, name_version.last_index_of_char ('-')); + action = dgettext (null, "Downloading %s").printf (name) + "..."; break; - case Alpm.Event.Type.RETRIEVE_START: - progress_dialog.cancel_button.set_visible (true); - msg = dgettext (null, "Downloading") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); + case 31: //Alpm.Event.Type.DISKSPACE_START + action = dgettext (null, "Checking available disk space") + "..."; break; - case Alpm.Event.Type.DISKSPACE_START: - msg = dgettext (null, "Checking available disk space") + "..."; - progress_dialog.action_label.set_text (msg); - progress_dialog.spawn_in_term ({"echo", msg}); - break; - case Alpm.Event.Type.OPTDEP_REMOVAL: - msg = dgettext (null, "%s optionally requires %s").printf (details[0], details[1]); - progress_dialog.spawn_in_term ({"echo", msg}); + case 33: //Alpm.Event.Type.OPTDEP_REMOVAL + detailed_action = dgettext (null, "%s optionally requires %s").printf (details[0], details[1]); Gtk.TextIter end_iter; - msg += "\n"; + string msg = detailed_action + "\n"; transaction_info_dialog.textbuffer.get_end_iter (out end_iter); transaction_info_dialog.textbuffer.insert (ref end_iter, msg, msg.length); break; - case Alpm.Event.Type.DATABASE_MISSING: - progress_dialog.spawn_in_term ({"echo", dgettext (null, "Database file for %s does not exist").printf (details[0])}); + case 34: //Alpm.Event.Type.DATABASE_MISSING + detailed_action = dgettext (null, "Database file for %s does not exist").printf (details[0]); + break; + case 35: //Alpm.Event.Type.KEYRING_START + progress_dialog.cancel_button.visible = true; + action = dgettext (null, "Checking keyring") + "..."; break; - case Alpm.Event.Type.PACNEW_CREATED: - progress_dialog.spawn_in_term ({"echo", dgettext (null, "%s installed as %s.pacnew").printf (details[0])}); + case 37: //Alpm.Event.Type.KEY_DOWNLOAD_START + action = dgettext (null, "Downloading required keys") + "..."; break; - case Alpm.Event.Type.PACSAVE_CREATED: - progress_dialog.spawn_in_term ({"echo", dgettext (null, "%s installed as %s.pacsave").printf (details[0])}); + case 39: //Alpm.Event.Type.PACNEW_CREATED + detailed_action = dgettext (null, "%s installed as %s.pacnew").printf (details[0]); + break; + case 40: //Alpm.Event.Type.PACSAVE_CREATED + detailed_action = dgettext (null, "%s installed as %s.pacsave").printf (details[0]); + break; + case 41: //Alpm.Event.Type.HOOK_START + switch (secondary_event) { + case 1: //Alpm.HookWhen.PRE_TRANSACTION + action = dgettext (null, "Running pre-transaction hooks") + "..."; + break; + case 2: //Alpm.HookWhen.POST_TRANSACTION + action = dgettext (null, "Running post-transaction hooks") + "..."; + break; + default: + break; + } + break; + case 43: // Alpm.Event.Type.HOOK_RUN_START + string textbar = "%s/%s".printf (details[2], details[3]); + if (textbar != previous_textbar) { + previous_textbar = textbar; + progress_dialog.progressbar.text = textbar; + } + float fraction = (float) int.parse (details[2]) / int.parse (details[3]); + if (fraction != previous_percent) { + previous_percent = fraction; + progress_dialog.progressbar.fraction = fraction; + } + if (details[1] != "") { + detailed_action = details[1] + ":"; + } else { + detailed_action = details[0] + ":"; + } + break; default: break; } - while (Gtk.events_pending ()) { - Gtk.main_iteration (); + if (action != null) { + progress_dialog.action_label.label = action; + progress_dialog.spawn_in_term ({"echo", action}); + emit_action (action); + } + if (detailed_action != null) { + progress_dialog.spawn_in_term ({"echo", detailed_action}); } } @@ -923,18 +1167,18 @@ namespace Pamac { void on_emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target) { float fraction; switch (progress) { - case Alpm.Progress.ADD_START: - case Alpm.Progress.UPGRADE_START: - case Alpm.Progress.DOWNGRADE_START: - case Alpm.Progress.REINSTALL_START: - case Alpm.Progress.REMOVE_START: + case 0: //Alpm.Progress.ADD_START + case 1: //Alpm.Progress.UPGRADE_START + case 2: //Alpm.Progress.DOWNGRADE_START + case 3: //Alpm.Progress.REINSTALL_START + case 4: //Alpm.Progress.REMOVE_START fraction = ((float) (current_target - 1) / n_targets) + ((float) percent / (100 * n_targets)); break; - case Alpm.Progress.CONFLICTS_START: - case Alpm.Progress.DISKSPACE_START: - case Alpm.Progress.INTEGRITY_START: - case Alpm.Progress.KEYRING_START: - case Alpm.Progress.LOAD_START: + case 5: //Alpm.Progress.CONFLICTS_START + case 6: //Alpm.Progress.DISKSPACE_START + case 7: //Alpm.Progress.INTEGRITY_START + case 8: //Alpm.Progress.LOAD_START + case 9: //Alpm.Progress.KEYRING_START default: fraction = (float) percent / 100; break; @@ -942,34 +1186,17 @@ namespace Pamac { string textbar = "%lu/%lu".printf (current_target, n_targets); if (textbar != previous_textbar) { previous_textbar = textbar; - progress_dialog.progressbar.set_text (textbar); + progress_dialog.progressbar.text = textbar; } if (fraction != previous_percent) { previous_percent = fraction; - progress_dialog.progressbar.set_fraction (fraction); + progress_dialog.progressbar.fraction = fraction; } -//~ while (Gtk.events_pending ()) { -//~ Gtk.main_iteration (); -//~ } } void on_emit_download (string filename, uint64 xfered, uint64 total) { - string label; var text = new StringBuilder (); float fraction; - if (filename != previous_filename) { - previous_filename = filename; - if (filename.has_suffix (".db")) { - label = dgettext (null, "Refreshing %s").printf (filename.replace (".db", "")) + "..."; - } else { - label = dgettext (null, "Downloading %s").printf (filename.replace (".pkg.tar.xz", "")) + "..."; - } - if (label != previous_label) { - previous_label = label; - progress_dialog.action_label.set_text (label); - progress_dialog.spawn_in_term ({"echo", label}); - } - } if (total_download > 0) { if (xfered == 0) { previous_xfered = 0; @@ -1017,6 +1244,13 @@ namespace Pamac { rates_nb = 0; fraction = 0; timer.start (); + // start download pkg is handled by Alpm.Event.Type.PKGDOWNLOAD_START + if (filename.has_suffix (".db")) { + string action = dgettext (null, "Refreshing %s").printf (filename.replace (".db", "")) + "..."; + progress_dialog.action_label.label = action; + progress_dialog.spawn_in_term ({"echo", action}); + emit_action (action); + } } else if (xfered == total) { timer.stop (); fraction = 1; @@ -1053,11 +1287,11 @@ namespace Pamac { } if (fraction != previous_percent) { previous_percent = fraction; - progress_dialog.progressbar.set_fraction (fraction); + progress_dialog.progressbar.fraction = fraction; } if (text.str != previous_textbar) { previous_textbar = text.str; - progress_dialog.progressbar.set_text (text.str); + progress_dialog.progressbar.text = text.str; } } @@ -1078,7 +1312,13 @@ namespace Pamac { // msg ends with \n string? line = null; Gtk.TextIter end_iter; - if ((Alpm.LogLevel) level == Alpm.LogLevel.WARNING) { + if (level == 1) { //Alpm.LogLevel.ERROR + if (previous_filename != "") { + line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg; + } else { + line = dgettext (null, "Error") + ": " + msg; + } + } else if (level == (1 << 1)) { //Alpm.LogLevel.WARNING // do not show warning when manjaro-system remove db.lck if (previous_filename != "manjaro-system") { if (previous_filename != "") { @@ -1089,25 +1329,18 @@ namespace Pamac { transaction_info_dialog.textbuffer.get_end_iter (out end_iter); transaction_info_dialog.textbuffer.insert (ref end_iter, msg, msg.length); } - } else if ((Alpm.LogLevel) level == Alpm.LogLevel.ERROR) { - if (previous_filename != "") { - line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg; - } else { - line = dgettext (null, "Error") + ": " + msg; - } } if (line != null) { - progress_dialog.expander.set_expanded (true); - progress_dialog.spawn_in_term ({"echo", "-n", line}); + display_error (line, {}); } } void show_warnings () { if (transaction_info_dialog.textbuffer.text != "") { - transaction_info_dialog.set_title (dgettext (null, "Warning")); - transaction_info_dialog.label.set_visible (false); - transaction_info_dialog.expander.set_visible (true); - transaction_info_dialog.expander.set_expanded (true); + transaction_info_dialog.title = dgettext (null, "Warning"); + transaction_info_dialog.label.visible = false; + transaction_info_dialog.expander.visible = true; + transaction_info_dialog.expander.expanded = true; transaction_info_dialog.run (); transaction_info_dialog.hide (); while (Gtk.events_pending ()) { @@ -1121,57 +1354,58 @@ namespace Pamac { } } - void handle_error (ErrorInfos error) { - if (error.message != "") { - progress_dialog.action_label.set_text (""); - progress_dialog.progressbar.set_fraction (0); - progress_dialog.expander.set_expanded (true); - progress_dialog.spawn_in_term ({"echo", "-n", error.message}); - Gtk.TextIter start_iter; - Gtk.TextIter end_iter; - transaction_info_dialog.set_title (dgettext (null, "Error")); - transaction_info_dialog.label.set_visible (true); - transaction_info_dialog.label.set_markup (error.message); - if (error.details.length != 0) { - transaction_info_dialog.textbuffer.get_start_iter (out start_iter); - transaction_info_dialog.textbuffer.get_end_iter (out end_iter); - transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter); - transaction_info_dialog.expander.set_visible (true); - transaction_info_dialog.expander.set_expanded (true); - progress_dialog.spawn_in_term ({"echo", ":"}); - foreach (unowned string detail in error.details) { - progress_dialog.spawn_in_term ({"echo", detail}); - string str = detail + "\n"; - transaction_info_dialog.textbuffer.get_end_iter (out end_iter); - transaction_info_dialog.textbuffer.insert (ref end_iter, str, str.length); - } - } else { - transaction_info_dialog.expander.set_visible (false); - } - progress_dialog.spawn_in_term ({"echo"}); - transaction_info_dialog.run (); - transaction_info_dialog.hide (); + void display_error (string message, string[] details) { + progress_dialog.spawn_in_term ({"echo", "-n", message}); + Gtk.TextIter start_iter; + Gtk.TextIter end_iter; + transaction_info_dialog.title = dgettext (null, "Error"); + transaction_info_dialog.label.visible = true; + transaction_info_dialog.label.label = message; + if (details.length != 0) { transaction_info_dialog.textbuffer.get_start_iter (out start_iter); transaction_info_dialog.textbuffer.get_end_iter (out end_iter); transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter); - progress_dialog.spawn_in_term ({"echo"}); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); + transaction_info_dialog.expander.visible = true; + transaction_info_dialog.expander.expanded = true; + progress_dialog.spawn_in_term ({"echo", ":"}); + foreach (unowned string detail in details) { + progress_dialog.spawn_in_term ({"echo", detail}); + string str = detail + "\n"; + transaction_info_dialog.textbuffer.get_end_iter (out end_iter); + transaction_info_dialog.textbuffer.insert (ref end_iter, str, str.length); } + } else { + transaction_info_dialog.expander.visible = false; + } + transaction_info_dialog.run (); + transaction_info_dialog.hide (); + transaction_info_dialog.textbuffer.get_start_iter (out start_iter); + transaction_info_dialog.textbuffer.get_end_iter (out end_iter); + transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } + } + + void handle_error (ErrorInfos error) { + if (error.message != "") { + progress_dialog.action_label.label = ""; + progress_dialog.progressbar.fraction = 0; + display_error (error.message, error.details); + progress_dialog.spawn_in_term ({"echo"}); + progress_dialog.spawn_in_term ({"echo"}); } finish_transaction (); } void finish_transaction () { - if (database_modified) { - alpm_utils.reload (); - database_modified = false; - } - if (progress_dialog.expander.get_expanded ()) { - progress_dialog.cancel_button.set_visible (false); - progress_dialog.close_button.set_visible (true); + transaction_summary.remove_all (); + if (progress_dialog.expander.expanded) { + progress_dialog.show (); + progress_dialog.cancel_button.visible = false; + progress_dialog.close_button.clicked.connect (hide_progress_and_finish); } else { - on_progress_dialog_close_button_clicked (); + hide_progress_and_finish (); } } @@ -1179,38 +1413,26 @@ namespace Pamac { this.success = success; clear_lists (); if (success) { - // database is modified - alpm_utils.reload (); finished (success); - if (mode == Mode.UPDATER) { - progress_dialog.hide (); - } + progress_dialog.hide (); success = false; } else { - database_modified = true; handle_error (get_current_error ()); } previous_filename = ""; daemon.refresh_finished.disconnect (on_refresh_finished); } - void on_progress_dialog_close_button_clicked () { + void hide_progress_and_finish () { finished (success); progress_dialog.hide (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } + progress_dialog.expander.expanded = false; success = false; + progress_dialog.close_button.clicked.connect (hide_progress); } void on_progress_dialog_cancel_button_clicked () { cancel (); - clear_lists (); - progress_dialog.spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction cancelled") + ".\n"}); - progress_dialog.hide (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } } void on_trans_prepare_finished (bool success) { @@ -1232,15 +1454,24 @@ namespace Pamac { release (); on_trans_commit_finished (true); } else { + // backup to_install and to_remove + foreach (unowned string name in to_install) { + previous_to_install.add (name); + } + foreach (unowned string name in to_remove) { + previous_to_remove.add (name); + } + to_install.remove_all (); + to_remove.remove_all (); start_commit (); } } else { transaction_sum_dialog.hide (); unowned string action = dgettext (null, "Transaction cancelled"); progress_dialog.spawn_in_term ({"echo", action + ".\n"}); - progress_dialog.action_label.set_text (action); + progress_dialog.action_label.label = action; release (); - //to_build.remove_all (); + transaction_summary.remove_all (); sysupgrade_after_trans = false; success = false; finish_transaction (); @@ -1263,14 +1494,14 @@ namespace Pamac { this.success = success; if (success) { if (to_build.length != 0) { - if (to_add.length != 0 - || to_remove.length != 0 + if (previous_to_install.length != 0 + || previous_to_remove.length != 0 || to_load.length != 0) { progress_dialog.spawn_in_term ({"echo", dgettext (null, "Transaction successfully finished") + ".\n"}); } build_aur_packages (); } else { - clear_lists (); + clear_previous_lists (); show_warnings (); if (sysupgrade_after_trans) { sysupgrade_after_trans = false; @@ -1278,19 +1509,24 @@ namespace Pamac { } else { unowned string action = dgettext (null, "Transaction successfully finished"); progress_dialog.spawn_in_term ({"echo", action + ".\n"}); - progress_dialog.action_label.set_text (action); - database_modified = true; + progress_dialog.action_label.label = action; finish_transaction (); } } } else { // if it is an authentication or a download error, database was not modified var err = get_current_error (); - if (err.message != dgettext (null, "Authentication failed") - && err.errno != Alpm.Errno.EXTERNAL_DOWNLOAD) { - clear_lists (); - database_modified = true; + if (err.message == dgettext (null, "Authentication failed") + || err.errno == 54) { //Alpm.Errno.EXTERNAL_DOWNLOAD + // recover old pkgnames + foreach (unowned string name in previous_to_install) { + to_install.add (name); + } + foreach (unowned string name in previous_to_remove) { + to_remove.add (name); + } } + clear_previous_lists (); handle_error (err); } total_download = 0; @@ -1300,29 +1536,28 @@ namespace Pamac { void on_term_child_exited (int status) { Source.remove (pulse_timeout_id); - clear_lists (); + clear_previous_lists (); + to_build.remove_all (); // let the time to the daemon to update databases Timeout.add (1000, () => { if (status == 0) { success = true; unowned string action = dgettext (null, "Transaction successfully finished"); progress_dialog.spawn_in_term ({"echo", action + ".\n"}); - progress_dialog.action_label.set_text (action); + progress_dialog.action_label.label = action; } else { success = false; progress_dialog.spawn_in_term ({"echo"}); } - progress_dialog.progressbar.set_fraction (1); - alpm_utils.reload (); - database_modified = false; - progress_dialog.cancel_button.set_visible (false); - progress_dialog.close_button.set_visible (true); + transaction_summary.remove_all (); + progress_dialog.progressbar.fraction = 1; + progress_dialog.close_button.clicked.connect (hide_progress_and_finish); + progress_dialog.close_button.visible = true; return false; }); } void on_set_pkgreason_finished () { - alpm_utils.reload (); set_pkgreason_finished (); } @@ -1330,13 +1565,15 @@ namespace Pamac { bool enable_aur, bool search_aur, bool check_aur_updates, bool no_confirm_build) { pamac_config.reload (); + if (recurse) { + flags |= (1 << 5); //Alpm.TransFlag.RECURSE + } write_pamac_config_finished (recurse, refresh_period, no_update_hide_icon, enable_aur, search_aur, check_aur_updates, no_confirm_build); } void on_write_alpm_config_finished (bool checkspace) { - alpm_utils.reload (); write_alpm_config_finished (checkspace); } diff --git a/src/transaction_sum_dialog.vala b/src/transaction_sum_dialog.vala index 43f792fb73edbba89b1fce8f5179f012fbc9b022..cef47976c8ca10a357adcf3a023532eadb4d2ccc 100644 --- a/src/transaction_sum_dialog.vala +++ b/src/transaction_sum_dialog.vala @@ -34,7 +34,7 @@ namespace Pamac { public TransactionSumDialog (Gtk.ApplicationWindow? window) { Object (transient_for: window, use_header_bar: 0); - sum_list = new Gtk.ListStore (2, typeof (string), typeof (string)); + sum_list = new Gtk.ListStore (4, typeof (string), typeof (string), typeof (string), typeof (string)); treeview.set_model (sum_list); } } diff --git a/src/tray.vala b/src/tray.vala index bb7cf47dd057279592d84acaea9d6c4a824fa444..7aaee090887d6ab003110bd828a820f99ab4ca9b 100644 --- a/src/tray.vala +++ b/src/tray.vala @@ -27,6 +27,7 @@ const string noupdate_info = _("Your system is up-to-date"); namespace Pamac { [DBus (name = "org.manjaro.pamac")] interface Daemon : Object { + public abstract string get_lockfile () throws IOError; public abstract void start_refresh (bool force) throws IOError; public abstract void start_get_updates (bool check_aur_updates) throws IOError; [DBus (no_reply = true)] @@ -320,10 +321,14 @@ namespace Pamac { Notify.init (_("Update Manager")); - var alpm_config = new AlpmConfig ("/etc/pacman.conf"); - alpm_config.set_handle (); - lockfile = GLib.File.new_for_path (alpm_config.handle.lockfile); start_daemon (); + try { + lockfile = GLib.File.new_for_path (daemon.get_lockfile ()); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + //try standard lock file + lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck"); + } Timeout.add (200, check_pacman_running); start_refresh (); launch_refresh_timeout (pamac_config.refresh_period); diff --git a/src/updater_window.vala b/src/updater_window.vala index e69db2bc62fa6d2c82cf443c986990aa3b03df10..685fc1bd3cfc15bb2b2f6cc2bcec95b9407ca583 100644 --- a/src/updater_window.vala +++ b/src/updater_window.vala @@ -25,7 +25,7 @@ namespace Pamac { [GtkChild] Gtk.Label top_label; [GtkChild] - Gtk.Notebook notebook; + Gtk.StackSwitcher stackswitcher; [GtkChild] Gtk.ScrolledWindow repos_scrolledwindow; [GtkChild] @@ -51,10 +51,10 @@ namespace Pamac { public UpdaterWindow (Gtk.Application application) { Object (application: application); - bottom_label.set_visible (false); - apply_button.set_sensitive (false); - notebook.set_show_tabs (false); - aur_scrolledwindow.set_visible (false); + bottom_label.visible = false; + apply_button.sensitive = false; + stackswitcher.visible = false; + aur_scrolledwindow.visible = false; Timeout.add (100, populate_window); } @@ -62,9 +62,9 @@ namespace Pamac { bool populate_window () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - repos_updates_list = new Gtk.ListStore (3, typeof (bool), typeof (string), typeof (string)); + repos_updates_list = new Gtk.ListStore (6, typeof (bool), typeof (string), typeof (string), typeof (string),typeof (string), typeof (string)); repos_updates_treeview.set_model (repos_updates_list); - aur_updates_list = new Gtk.ListStore (2, typeof (bool), typeof (string)); + aur_updates_list = new Gtk.ListStore (3, typeof (bool), typeof (string), typeof (string)); aur_updates_treeview.set_model (aur_updates_list); transaction = new Transaction (this as Gtk.ApplicationWindow); @@ -80,31 +80,29 @@ namespace Pamac { void set_apply_button_sensitive () { bool sensitive = false; repos_updates_list.foreach ((model, path, iter) => { - GLib.Value selected; - repos_updates_list.get_value (iter, 0, out selected); - sensitive = (bool) selected; + bool selected; + repos_updates_list.get (iter, 0, out selected); + sensitive = selected; return sensitive; }); if (!sensitive) { aur_updates_list.foreach ((model, path, iter) => { - GLib.Value selected; - aur_updates_list.get_value (iter, 0, out selected); - sensitive = (bool) selected; + bool selected; + aur_updates_list.get (iter, 0, out selected); + sensitive = selected; return sensitive; }); } - apply_button.set_sensitive (sensitive); + apply_button.sensitive = sensitive; } [GtkCallback] void on_repos_select_update_toggled (string path) { Gtk.TreePath treepath = new Gtk.TreePath.from_string (path); Gtk.TreeIter iter; - GLib.Value name_string; + string pkgname; repos_updates_list.get_iter (out iter, treepath); - repos_updates_list.get_value (iter, 1, out name_string); - // string has the form "pkgname pkgversion" - string pkgname = name_string.get_string ().split (" ", 2)[0]; + repos_updates_list.get (iter, 1, out pkgname); if (repos_select_update.active) { repos_updates_list.set (iter, 0, false); transaction.temporary_ignorepkgs.add (pkgname); @@ -119,11 +117,9 @@ namespace Pamac { void on_aur_select_update_toggled (string path) { Gtk.TreePath treepath = new Gtk.TreePath.from_string (path); Gtk.TreeIter iter; - GLib.Value name_string; + string pkgname; aur_updates_list.get_iter (out iter, treepath); - aur_updates_list.get_value (iter, 1, out name_string); - // string has the form "pkgname pkgversion" - string pkgname = name_string.get_string ().split (" ", 2)[0]; + aur_updates_list.get (iter, 1, out pkgname); if (aur_select_update.active) { aur_updates_list.set (iter, 0, false); transaction.temporary_ignorepkgs.add (pkgname); @@ -166,34 +162,32 @@ namespace Pamac { void on_get_updates_finished (Updates updates) { top_label.set_markup (""); repos_updates_list.clear (); - notebook.set_show_tabs (false); - repos_scrolledwindow.set_visible (true); + stackswitcher.visible = false; + repos_scrolledwindow.visible = true; aur_updates_list.clear (); - aur_scrolledwindow.set_visible (false); - bottom_label.set_visible (false); - Gtk.TreeIter iter; + aur_scrolledwindow.visible = false; + bottom_label.visible = false; uint64 dsize = 0; uint repos_updates_nb = 0; uint aur_updates_nb = 0; - foreach (unowned PackageInfos infos in updates.repos_updates) { - string name = infos.name + " " + infos.version; + foreach (unowned UpdateInfos infos in updates.repos_updates) { string size = infos.download_size != 0 ? format_size (infos.download_size) : ""; dsize += infos.download_size; repos_updates_nb++; - if (infos.name in transaction.temporary_ignorepkgs) { - repos_updates_list.insert_with_values (out iter, -1, 0, false, 1, name, 2, size); - } else { - repos_updates_list.insert_with_values (out iter, -1, 0, true, 1, name, 2, size); - } + repos_updates_list.insert_with_values (null, -1, + 0, !transaction.temporary_ignorepkgs.contains (infos.name), + 1, infos.name, + 2, infos.new_version, + 3, "(%s)".printf (infos.old_version), + 4, infos.repo, + 5, size); } - foreach (unowned PackageInfos infos in updates.aur_updates) { - string name = infos.name + " " + infos.version; + foreach (unowned UpdateInfos infos in updates.aur_updates) { aur_updates_nb++; - if (infos.name in transaction.temporary_ignorepkgs) { - aur_updates_list.insert_with_values (out iter, -1, 0, false, 1, name); - } else { - aur_updates_list.insert_with_values (out iter, -1, 0, true, 1, name); - } + aur_updates_list.insert_with_values (null, -1, + 0, !transaction.temporary_ignorepkgs.contains (infos.name), + 1, infos.name, + 2, "%s\t (%s)".printf (infos.new_version, infos.old_version)); } uint updates_nb = repos_updates_nb + aur_updates_nb; if (updates_nb == 0) { @@ -204,16 +198,16 @@ namespace Pamac { set_apply_button_sensitive (); if (dsize != 0) { bottom_label.set_markup("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size(dsize))); - bottom_label.set_visible (true); + bottom_label.visible = true; } else { - bottom_label.set_visible (false); + bottom_label.visible = false; } if (aur_updates_nb != 0) { - aur_scrolledwindow.set_visible (true); + aur_scrolledwindow.visible = true; if (repos_updates_nb == 0) { - repos_scrolledwindow.set_visible (false); + repos_scrolledwindow.visible = false; } - notebook.set_show_tabs (true); + stackswitcher.visible = true; } this.get_window ().set_cursor (null); } diff --git a/vapi/libalpm.vapi b/vapi/libalpm.vapi index 12ce4c4b0c2d43c10c0d549207f6a86647d7e04c..83e82c624f384129a1501063968a0fb5ca8d3d89 100644 --- a/vapi/libalpm.vapi +++ b/vapi/libalpm.vapi @@ -1,8 +1,7 @@ /* - * libalpm-vala * Vala bindings for libalpm * - * Copyright (C) 2014-2015 Guillaume Benoit <guillaume@manjaro.org> + * Copyright (C) 2014-2016 Guillaume Benoit <guillaume@manjaro.org> * Copyright (c) 2011 Rémy Oudompheng <remy@archlinux.org> * * This program is free software; you can redistribute it and/or modify @@ -45,7 +44,11 @@ namespace Alpm { public int pkg_vercmp(string a, string b); - public unowned Alpm.List<unowned Package?> find_group_pkgs(Alpm.List<DB> dbs, string name); + /** Find group members across a list of databases. + * If a member exists in several databases, only the first database is used. + * IgnorePkg is also handled. + */ + public Alpm.List<unowned Package?> find_group_pkgs(Alpm.List<DB> dbs, string name); /** Returns the string corresponding to an error number. */ public unowned string strerror(Errno err); @@ -57,7 +60,7 @@ namespace Alpm { [Compact] public class Handle { [CCode (cname = "alpm_initialize")] - public static Handle? @new(string root, string dbpath, out Alpm.Errno error); + public Handle (string root, string dbpath, out Alpm.Errno error); public unowned string root { [CCode (cname = "alpm_option_get_root")] get; @@ -69,7 +72,7 @@ namespace Alpm { [CCode (cname = "alpm_option_get_arch")] get; [CCode (cname = "alpm_option_set_arch")] set; } - public unowned Alpm.List<unowned string?> cachedirs { + public unowned Alpm.List<unowned string> cachedirs { [CCode (cname = "alpm_option_get_cachedirs")] get; [CCode (cname = "alpm_option_set_cachedirs")] set; } @@ -78,7 +81,7 @@ namespace Alpm { [CCode (cname = "alpm_option_remove_cachedir")] public int remove_cachedir(string cachedir); - public unowned Alpm.List<unowned string?> hookdirs { + public unowned Alpm.List<unowned string> hookdirs { [CCode (cname = "alpm_option_get_hookdirs")] get; [CCode (cname = "alpm_option_set_hookdirs")] set; } @@ -103,7 +106,7 @@ namespace Alpm { /** Sets whether to use syslog (0 is FALSE, TRUE otherwise). */ [CCode (cname = "alpm_option_set_usesyslog")] set; } - public unowned Alpm.List<unowned string?> noupgrades { + public unowned Alpm.List<unowned string> noupgrades { [CCode (cname = "alpm_option_get_noupgrades")] get; [CCode (cname = "alpm_option_set_noupgrades")] set; } @@ -112,7 +115,7 @@ namespace Alpm { [CCode (cname = "alpm_option_remove_noupgrade")] public int remove_noupgrade(string path); - public unowned Alpm.List<unowned string?> noextracts { + public unowned Alpm.List<unowned string> noextracts { [CCode (cname = "alpm_option_get_noextracts")] get; [CCode (cname = "alpm_option_set_noextracts")] set; } @@ -123,7 +126,7 @@ namespace Alpm { [CCode (cname = "alpm_option_match_noextract")] public int match_noextract(string path); - public unowned Alpm.List<unowned string?> ignorepkgs { + public unowned Alpm.List<unowned string> ignorepkgs { [CCode (cname = "alpm_option_get_ignorepkgs")] get; [CCode (cname = "alpm_option_set_ignorepkgs")] set; } @@ -132,7 +135,7 @@ namespace Alpm { [CCode (cname = "alpm_option_remove_ignorepkg")] public int remove_ignorepkg(string pkg); - public unowned Alpm.List<unowned string?> ignoregroups { + public unowned Alpm.List<unowned string> ignoregroups { [CCode (cname = "alpm_option_get_ignoregroups")] get; [CCode (cname = "alpm_option_set_ignoregroups")] set; } @@ -141,7 +144,7 @@ namespace Alpm { [CCode (cname = "alpm_option_remove_ignorepkg")] public int remove_ignoregroup(string grp); - public unowned Alpm.List<unowned Depend?> assumeinstalled { + public unowned Alpm.List<unowned Depend> assumeinstalled { [CCode (cname = "alpm_option_get_assumeinstalled")] get; [CCode (cname = "alpm_option_set_assumeinstalled")] set; } @@ -178,10 +181,10 @@ namespace Alpm { [CCode (cname = "alpm_option_set_remote_file_siglevel")] set; } - public unowned DB? localdb { + public unowned DB localdb { [CCode (cname = "alpm_get_localdb")] get; } - public unowned Alpm.List<unowned DB?> syncdbs { + public unowned Alpm.List<unowned DB> syncdbs { [CCode (cname = "alpm_get_syncdbs")] get; } @@ -218,14 +221,14 @@ namespace Alpm { public int unlock(); [CCode (cname = "alpm_register_syncdb")] - public unowned DB? register_syncdb(string treename, Signature.Level level); + public unowned DB register_syncdb(string treename, Signature.Level level); [CCode (cname = "alpm_unregister_all_syncdbs")] public int unregister_all_syncdbs(); // the return package can be freed except if it is added to a transaction, // it will be freed upon Handle.trans_release() invocation. - [CCode (cname = "alpm_pkg_load_file")] - public Package? load_file(string filename, int full, Signature.Level level); + [CCode (cname = "alpm_pkg_load")] + public int load_tarball(string filename, int full, Signature.Level level, out Package pkg); /** Test if a package should be ignored. * Checks if the package is ignored via IgnorePkg, or if the package is @@ -252,11 +255,11 @@ namespace Alpm { /** Returns a list of packages added by the transaction.*/ [CCode (cname = "alpm_trans_get_add")] - public unowned Alpm.List<unowned Package?> trans_to_add(); + public unowned Alpm.List<unowned Package> trans_to_add(); /** Returns the list of packages removed by the transaction.*/ [CCode (cname = "alpm_trans_get_remove")] - public unowned Alpm.List<unowned Package?> trans_to_remove(); + public unowned Alpm.List<unowned Package> trans_to_remove(); /** Initialize the transaction. * @param flags flags of the transaction (like nodeps, etc) @@ -333,16 +336,16 @@ namespace Alpm { [CCode (cname = "alpm_db_get_siglevel")] get; } - public unowned Alpm.List<unowned string?> servers { + public unowned Alpm.List<unowned string> servers { [CCode (cname = "alpm_db_get_servers")] get; [CCode (cname = "alpm_db_set_servers")] set; } - public unowned Alpm.List<unowned Package?> pkgcache { + public unowned Alpm.List<unowned Package> pkgcache { [CCode (cname = "alpm_db_get_pkgcache")] get; } - public unowned Alpm.List<unowned Group?> groupcache { + public unowned Alpm.List<unowned Group> groupcache { [CCode (cname = "alpm_db_get_groupcache")] get; } @@ -368,7 +371,7 @@ namespace Alpm { public unowned Package? get_pkg(string name); public unowned Group? get_group(string name); - public Alpm.List<unowned Package?> search(Alpm.List<string> needles); + public Alpm.List<unowned Package> search(Alpm.List<string> needles); public int check_pgp_signature(out SigList siglist); } @@ -440,37 +443,37 @@ namespace Alpm { */ [CCode (cname = "alpm_pkg_set_reason")] set; } - public unowned Alpm.List<unowned string?> licenses { + public unowned Alpm.List<unowned string> licenses { [CCode (cname = "alpm_pkg_get_licenses")] get; } - public unowned Alpm.List<unowned string?> groups { + public unowned Alpm.List<unowned string> groups { [CCode (cname = "alpm_pkg_get_groups")] get; } - public unowned Alpm.List<unowned Depend?> depends { + public unowned Alpm.List<unowned Depend> depends { [CCode (cname = "alpm_pkg_get_depends")] get; } - public unowned Alpm.List<unowned Depend?> optdepends { + public unowned Alpm.List<unowned Depend> optdepends { [CCode (cname = "alpm_pkg_get_optdepends")] get; } - public unowned Alpm.List<unowned Depend?> conflicts { + public unowned Alpm.List<unowned Depend> conflicts { [CCode (cname = "alpm_pkg_get_conflicts")] get; } - public unowned Alpm.List<unowned Depend?> provides { + public unowned Alpm.List<unowned Depend> provides { [CCode (cname = "alpm_pkg_get_provides")] get; } - public unowned Alpm.List<unowned string?> deltas { + public unowned Alpm.List<unowned string> deltas { [CCode (cname = "alpm_pkg_get_deltas")] get; } - public unowned Alpm.List<unowned Depend?> replaces { + public unowned Alpm.List<unowned Depend> replaces { [CCode (cname = "alpm_pkg_get_replaces")] get; } - public unowned Alpm.List<unowned File?> files { - [CCode (cname = "alpm_pkg_get_files_list")] get; + public unowned FileList files { + [CCode (cname = "alpm_pkg_get_files")] get; } - public unowned Alpm.List<unowned string?> unused_deltas { + public unowned Alpm.List<unowned string> unused_deltas { [CCode (cname = "alpm_pkg_unused_deltas")] get; } - public unowned Alpm.List<unowned Backup?> backups { + public unowned Alpm.List<unowned Backup> backups { [CCode (cname = "alpm_pkg_get_backup")] get; } public unowned DB? db { @@ -528,8 +531,8 @@ namespace Alpm { public int checkmd5sum(); public int has_scriptlet(); - public Alpm.List<string?> compute_requiredby(); - public Alpm.List<string?> compute_optionalfor(); + public Alpm.List<string> compute_requiredby(); + public Alpm.List<string> compute_optionalfor(); [CCode (cname = "alpm_sync_newversion")] public unowned Package? sync_newversion(Alpm.List<DB> dbs); @@ -613,13 +616,15 @@ namespace Alpm { /** Package group */ [CCode (cname = "alpm_group_t", has_type_id = false)] + [Compact] public class Group { public string name; - public unowned Alpm.List<unowned Package?> packages; + public unowned Alpm.List<unowned Package> packages; } /** Package upgrade delta */ [CCode (cname = "alpm_delta_t", has_type_id = false)] + [Compact] public class Delta { /** filename of the delta patch */ public string delta; @@ -637,6 +642,7 @@ namespace Alpm { /** File in a package */ [CCode (cname = "alpm_file_t", has_type_id = false)] + [Compact] public class File { public string name; public uint64 size; @@ -645,10 +651,15 @@ namespace Alpm { /** Package filelist container */ [CCode (cname = "alpm_filelist_t", has_type_id = false)] + [Compact] public class FileList { + // Usage: + // Alpm.File* files = filelist.files; + // for (size_t i = 0; i < filelist.count; i++, files++) { + // stdout.printf("%s\n", files->name); + // } public size_t count; - [CCode (array_length_cname = "count", array_length_type = "size_t")] - public unowned Alpm.File[] files; + public Alpm.File* files; /** Determines whether a package filelist contains a given path. * The provided path should be relative to the install root with no leading * slashes, e.g. "etc/localtime". When searching for directories, the path must @@ -662,6 +673,7 @@ namespace Alpm { /** Local package or package file backup entry */ [CCode (cname = "alpm_backup_t", has_type_id = false)] + [Compact] public class Backup { public string name; public string hash; @@ -669,6 +681,7 @@ namespace Alpm { namespace Signature { [CCode (cname = "alpm_pgpkey_t", has_type_id = false)] + [Compact] public class PGPKey { public void *data; public string fingerprint; @@ -687,6 +700,7 @@ namespace Alpm { * signature. */ [CCode (cname = "alpm_sigresult_t", has_type_id = false)] + [Compact] public class Result { public PGPKey key; public Status status; @@ -865,12 +879,14 @@ namespace Alpm { } [CCode (cname = "alpm_event_any_t", has_type_id = false)] + [Compact] public class Any { /** Type of event. */ public Type type; } [CCode (cname = "alpm_event_package_operation_t", has_type_id = false)] + [Compact] public class PackageOperation { /** Type of event. */ public Type type; @@ -883,6 +899,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_optdep_removal_t", has_type_id = false)] + [Compact] public class OptDepRemoval { /** Type of event. */ public Type type; @@ -893,6 +910,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_delta_patch_t", has_type_id = false)] + [Compact] public class DeltaPatch { /** Type of event. */ public Type type; @@ -901,6 +919,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_scriptlet_info_t", has_type_id = false)] + [Compact] public class ScriptletInfo { /** Type of event. */ public Type type; @@ -909,6 +928,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_database_missing_t", has_type_id = false)] + [Compact] public class DatabaseMissing { /** Type of event. */ public Type type; @@ -917,6 +937,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_pkgdownload_t", has_type_id = false)] + [Compact] public class PkgDownload { /** Type of event. */ public Type type; @@ -925,6 +946,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_pacnew_created_t", has_type_id = false)] + [Compact] public class PacnewCreated { /** Type of event. */ public Type type; @@ -939,6 +961,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_pacsave_created_t", has_type_id = false)] + [Compact] public class PacsaveCreated { /** Type of event. */ public Type type; @@ -949,6 +972,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_hook_t", has_type_id = false)] + [Compact] public class Hook { /** Type of event.*/ public Type type; @@ -957,6 +981,7 @@ namespace Alpm { } [CCode (cname = "alpm_event_hook_run_t", has_type_id = false)] + [Compact] public class HookRun { /** Type of event.*/ public Type type; @@ -975,6 +1000,7 @@ namespace Alpm { * typecast the pointer to the right structure, or use the union field, in order * to access event-specific data. */ [CCode (cname = "alpm_event_t", has_type_id = false)] + [Compact] public class Data { /** Type of event. */ public Type type; @@ -1054,6 +1080,7 @@ namespace Alpm { } [CCode (cname = "alpm_question_any_t", has_type_id = false)] + [Compact] public class Any { /** Type of question. */ public Type type; @@ -1062,6 +1089,7 @@ namespace Alpm { } [CCode (cname = "alpm_question_install_ignorepkg_t", has_type_id = false)] + [Compact] public class InstallIgnorePkg { /** Type of question. */ public Type type; @@ -1072,6 +1100,7 @@ namespace Alpm { } [CCode (cname = "alpm_question_replace_t", has_type_id = false)] + [Compact] public class Replace { /** Type of question. */ public Type type; @@ -1086,6 +1115,7 @@ namespace Alpm { } [CCode (cname = "alpm_question_conflict_t", has_type_id = false)] + [Compact] public class Conflict { /** Type of question. */ public Type type; @@ -1096,6 +1126,7 @@ namespace Alpm { } [CCode (cname = "alpm_question_corrupted_t", has_type_id = false)] + [Compact] public class Corrupted { /** Type of question. */ public Type type; @@ -1108,28 +1139,31 @@ namespace Alpm { } [CCode (cname = "alpm_question_remove_pkgs_t", has_type_id = false)] + [Compact] public class RemovePkgs { /** Type of question. */ public Type type; /** Answer: whether or not to skip packages. */ public int skip; /** List of alpm_pkg_t* with unresolved dependencies. */ - public unowned Alpm.List<unowned Package?> packages; + public unowned Alpm.List<unowned Package> packages; } [CCode (cname = "alpm_question_select_provider_t", has_type_id = false)] + [Compact] public class SelectProvider { /** Type of question. */ public Type type; /** Answer: which provider to use (index from providers). */ public int use_index; /** List of alpm_pkg_t* as possible providers. */ - public unowned Alpm.List<unowned Package?> providers; + public unowned Alpm.List<unowned Package> providers; /** What providers provide for. */ public unowned Depend depend; } [CCode (cname = "alpm_question_import_key_t", has_type_id = false)] + [Compact] public class ImportKey { /** Type of question. */ public Type type; @@ -1144,6 +1178,7 @@ namespace Alpm { * typecast the pointer to the right structure, or use the union field, in order * to access question-specific data. */ [CCode (cname = "alpm_question_t", has_type_id = false)] + [Compact] public class Data { public Type type; // Any any; @@ -1179,12 +1214,12 @@ namespace Alpm { [CCode (cname = "remove_pkgs.skip")] public int remove_pkgs_skip; [CCode (cname = "remove_pkgs.packages")] - public unowned Alpm.List<unowned Package?> remove_pkgs_packages; + public unowned Alpm.List<unowned Package> remove_pkgs_packages; // SelectProvider select_provider; [CCode (cname = "select_provider.use_index")] public int select_provider_use_index; [CCode (cname = "select_provider.providers")] - public unowned Alpm.List<unowned Package?> select_provider_providers; + public unowned Alpm.List<unowned Package> select_provider_providers; [CCode (cname = "select_provider.depend")] public unowned Depend select_provider_depend; // ImportKey import_key; @@ -1348,24 +1383,25 @@ namespace Alpm { GPGME } - [CCode (cname = "alpm_list_t", cprefix = "alpm_list_", cheader_filename = "alpm_list.h,alpm-util.h", + [CCode (cname = "alpm_list_t", cprefix = "alpm_list_", cheader_filename = "alpm_list.h", dup_function = "alpm_list_copy", free_function = "alpm_list_free")] [Compact] public class List<G> { - public List (); - /* comparator */ [CCode (cname = "alpm_list_fn_cmp", has_target = false)] public delegate int CompareFunc<G>(G a, G b); + /* deallocator */ + [CCode (cname = "alpm_list_fn_free", has_target = false)] + public delegate void FreeFunc<G>(G a); /* properties */ public size_t length { [CCode (cname = "alpm_list_count")] get; } - public unowned G? data { - [CCode (cname = "alpm_list_get_data")] get; - } + + /* field */ + public G data; /* item mutators */ [ReturnsModifiedPointer ()] @@ -1374,42 +1410,32 @@ namespace Alpm { [ReturnsModifiedPointer ()] public void join(owned List<G> list); + [CCode (cname = "alpm_list_msort", has_target = false)] [ReturnsModifiedPointer ()] - public void sort(CompareFunc fn); + public void sort(size_t n, CompareFunc fn); [ReturnsModifiedPointer ()] public void remove(G data, CompareFunc fn, out G removed_data ); /* free the internal data of this */ - public void free_data(); + public void free_inner(FreeFunc fn); public List<unowned G> copy(); - public List<G> copy_data(); [ReturnsModifiedPointer ()] public void reverse (); /* item accessors */ - public unowned List<G>? first(); - public unowned List<G>? last(); - public unowned List<G>? nth(size_t index); - public unowned List<G>? next(); - public unowned List<G>? previous(); + public unowned List<G> nth(size_t index); + [ReturnsModifiedPointer ()] + public void next(); /* misc */ - public unowned G? find(G needle, CompareFunc fn); + public unowned G find(G needle, CompareFunc fn); public unowned string? find_str(string needle); /** @return a list containing all items in `this` not present in `list` */ - public List<unowned G>? diff(List<G>? list, CompareFunc fn); - - /* iterator */ - public Iterator<G> iterator(); - - [CCode (cname = "alpm_list_iterator_t", cprefix = "alpm_list_iterator_")] - public struct Iterator<G> { - public unowned G? next_value(); - } + public List<unowned G> diff(List<G> list, CompareFunc fn); } }