Graphical package manager for pacman based on pamac 5.x.x
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

manager_window.vala 39KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. /*
  2. * pamac-vala
  3. *
  4. * Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a get of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. using Gtk;
  20. using Alpm;
  21. const string VERSION = "2.0";
  22. namespace Pamac {
  23. public struct SortInfo {
  24. public int column_number;
  25. public Gtk.SortType sort_type;
  26. }
  27. [GtkTemplate (ui = "/org/manjaro/pamac/manager/manager_window.ui")]
  28. public class ManagerWindow : Gtk.ApplicationWindow {
  29. // icons
  30. public Gdk.Pixbuf? installed_icon;
  31. public Gdk.Pixbuf? uninstalled_icon;
  32. public Gdk.Pixbuf? to_install_icon;
  33. public Gdk.Pixbuf? to_reinstall_icon;
  34. public Gdk.Pixbuf? to_remove_icon;
  35. public Gdk.Pixbuf? locked_icon;
  36. // manager objects
  37. [GtkChild]
  38. public TreeView packages_treeview;
  39. [GtkChild]
  40. public TreeViewColumn state_column;
  41. [GtkChild]
  42. public TreeViewColumn name_column;
  43. [GtkChild]
  44. public TreeViewColumn version_column;
  45. [GtkChild]
  46. public TreeViewColumn repo_column;
  47. [GtkChild]
  48. public TreeViewColumn size_column;
  49. [GtkChild]
  50. public Notebook filters_notebook;
  51. [GtkChild]
  52. public SearchEntry search_entry;
  53. [GtkChild]
  54. public TreeView search_treeview;
  55. [GtkChild]
  56. public TreeView groups_treeview;
  57. [GtkChild]
  58. public TreeView states_treeview;
  59. [GtkChild]
  60. public TreeView repos_treeview;
  61. [GtkChild]
  62. public TreeView deps_treeview;
  63. [GtkChild]
  64. public TreeView details_treeview;
  65. [GtkChild]
  66. public ScrolledWindow deps_scrolledwindow;
  67. [GtkChild]
  68. public ScrolledWindow details_scrolledwindow;
  69. [GtkChild]
  70. public ScrolledWindow files_scrolledwindow;
  71. [GtkChild]
  72. public Label name_label;
  73. [GtkChild]
  74. public Label desc_label;
  75. [GtkChild]
  76. public Label link_label;
  77. [GtkChild]
  78. public Label licenses_label;
  79. [GtkChild]
  80. public TextView files_textview;
  81. [GtkChild]
  82. public Switch search_aur_button;
  83. [GtkChild]
  84. public Button valid_button;
  85. [GtkChild]
  86. public Button cancel_button;
  87. // menu
  88. Gtk.Menu right_click_menu;
  89. Gtk.MenuItem deselect_item;
  90. Gtk.MenuItem install_item;
  91. Gtk.MenuItem remove_item;
  92. Gtk.SeparatorMenuItem separator_item;
  93. Gtk.MenuItem reinstall_item;
  94. Gtk.MenuItem install_optional_deps_item;
  95. Gtk.MenuItem explicitly_installed_item;
  96. GLib.List<Pamac.Package> selected_pkgs;
  97. // liststore
  98. ListStore search_list;
  99. ListStore groups_list;
  100. ListStore states_list;
  101. ListStore repos_list;
  102. ListStore deps_list;
  103. ListStore details_list;
  104. PackagesModel packages_list;
  105. HashTable<string, Json.Array> aur_results;
  106. Pamac.Config pamac_config;
  107. public Transaction transaction;
  108. public SortInfo sortinfo;
  109. //dialogs
  110. HistoryDialog history_dialog;
  111. PackagesChooserDialog packages_chooser_dialog;
  112. PreferencesDialog preferences_dialog;
  113. public ManagerWindow (Gtk.Application application) {
  114. Object (application: application);
  115. aur_results = new HashTable<string, Json.Array> (str_hash, str_equal);
  116. right_click_menu = new Gtk.Menu ();
  117. deselect_item = new Gtk.MenuItem.with_label (dgettext (null, "Deselect"));
  118. deselect_item.activate.connect (on_deselect_item_activate);
  119. right_click_menu.append (deselect_item);
  120. install_item = new Gtk.MenuItem.with_label (dgettext (null, "Install"));
  121. install_item.activate.connect (on_install_item_activate);
  122. right_click_menu.append (install_item);
  123. remove_item = new Gtk.MenuItem.with_label (dgettext (null, "Remove"));
  124. remove_item.activate.connect (on_remove_item_activate);
  125. right_click_menu.append (remove_item);
  126. separator_item = new Gtk.SeparatorMenuItem ();
  127. right_click_menu.append (separator_item);
  128. reinstall_item = new Gtk.MenuItem.with_label (dgettext (null, "Reinstall"));
  129. reinstall_item.activate.connect (on_reinstall_item_activate);
  130. right_click_menu.append (reinstall_item);
  131. install_optional_deps_item = new Gtk.MenuItem.with_label (dgettext (null, "Install optional dependencies"));
  132. install_optional_deps_item.activate.connect (on_install_optional_deps_item_activate);
  133. right_click_menu.append (install_optional_deps_item);
  134. explicitly_installed_item = new Gtk.MenuItem.with_label (dgettext (null, "Mark as explicitly installed"));
  135. explicitly_installed_item.activate.connect (on_explicitly_installed_item_activate);
  136. right_click_menu.append (explicitly_installed_item);
  137. right_click_menu.show_all ();
  138. search_list = new Gtk.ListStore (1, typeof (string));
  139. search_treeview.set_model (search_list);
  140. groups_list = new Gtk.ListStore (1, typeof (string));
  141. groups_treeview.set_model (groups_list);
  142. states_list = new Gtk.ListStore (1, typeof (string));
  143. states_treeview.set_model (states_list);
  144. repos_list = new Gtk.ListStore (1, typeof (string));
  145. repos_treeview.set_model (repos_list);
  146. deps_list = new Gtk.ListStore (2, typeof (string), typeof (string));
  147. deps_treeview.set_model (deps_list);
  148. details_list = new Gtk.ListStore (2, typeof (string), typeof (string));
  149. details_treeview.set_model (details_list);;
  150. try {
  151. installed_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-updated.png");
  152. uninstalled_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available.png");
  153. to_install_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-install.png");
  154. to_reinstall_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-reinstall.png");
  155. to_remove_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-remove.png");
  156. locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png");
  157. } catch (GLib.Error e) {
  158. stderr.printf (e.message);
  159. }
  160. pamac_config = new Pamac.Config ("/etc/pamac.conf");
  161. transaction = new Pamac.Transaction (this as ApplicationWindow);
  162. transaction.check_aur = pamac_config.enable_aur;
  163. transaction.finished.connect (on_emit_trans_finished);
  164. history_dialog = new HistoryDialog (this);
  165. packages_chooser_dialog = new PackagesChooserDialog (this, transaction);
  166. preferences_dialog = new PreferencesDialog (this as ApplicationWindow);
  167. set_buttons_sensitive (false);
  168. search_aur_button.set_active (pamac_config.enable_aur);
  169. // sort by name by default
  170. sortinfo = {0, SortType.ASCENDING};
  171. update_lists ();
  172. }
  173. public void enable_aur (bool enable) {
  174. search_aur_button.set_active (enable);
  175. }
  176. public void set_buttons_sensitive (bool sensitive) {
  177. valid_button.set_sensitive (sensitive);
  178. cancel_button.set_sensitive (sensitive);
  179. }
  180. public void show_all_pkgs () {
  181. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  182. populate_packages_list (get_all_pkgs (transaction.handle));
  183. this.get_window ().set_cursor (null);
  184. }
  185. public void update_lists () {
  186. string[] grps = {};
  187. TreeIter iter;
  188. TreeSelection selection;
  189. selection = repos_treeview.get_selection ();
  190. selection.changed.disconnect (on_repos_treeview_selection_changed);
  191. foreach (unowned DB db in transaction.handle.syncdbs) {
  192. repos_list.insert_with_values (out iter, -1, 0, db.name);
  193. foreach (unowned Group grp in db.groupcache) {
  194. if ((grp.name in grps) == false) {
  195. grps += grp.name;
  196. }
  197. }
  198. }
  199. repos_list.insert_with_values (out iter, -1, 0, dgettext (null, "local"));
  200. repos_list.get_iter_first (out iter);
  201. selection.select_iter (iter);
  202. selection.changed.connect_after (on_repos_treeview_selection_changed);
  203. selection = groups_treeview.get_selection ();
  204. selection.changed.disconnect (on_groups_treeview_selection_changed);
  205. foreach (string name in grps)
  206. groups_list.insert_with_values (out iter, -1, 0, name);
  207. groups_list.set_sort_column_id (0, SortType.ASCENDING);
  208. groups_list.get_iter_first (out iter);
  209. selection.select_iter (iter);
  210. selection.changed.connect_after (on_groups_treeview_selection_changed);
  211. selection = states_treeview.get_selection ();
  212. selection.changed.disconnect (on_states_treeview_selection_changed);
  213. states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Installed"));
  214. //states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Uninstalled"));
  215. states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Orphans"));
  216. states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To install"));
  217. states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To remove"));
  218. states_list.get_iter_first (out iter);
  219. selection.select_iter (iter);
  220. selection.changed.connect_after (on_states_treeview_selection_changed);
  221. }
  222. public void set_infos_list (Pamac.Package pkg) {
  223. name_label.set_markup ("<big><b>%s %s</b></big>".printf (pkg.name, pkg.version));
  224. // fix &,-,>,< in desc
  225. string desc;
  226. if (pkg.alpm_pkg != null)
  227. desc = pkg.alpm_pkg.desc;
  228. else
  229. desc = pkg.aur_json.get_string_member ("Description");
  230. desc = desc.replace ("&", "&amp;");
  231. desc = desc.replace ("<->", "/");
  232. desc_label.set_markup (desc);
  233. // fix & in url
  234. string url;
  235. if (pkg.alpm_pkg != null)
  236. url = pkg.alpm_pkg.url;
  237. else
  238. url = pkg.aur_json.get_string_member ("URL");
  239. url = url.replace ("&", "&amp;");
  240. link_label.set_markup ("<a href=\"%s\">%s</a>".printf (url, url));
  241. StringBuilder licenses = new StringBuilder ();
  242. licenses.append (dgettext (null, "Licenses"));
  243. licenses.append (":");
  244. if (pkg.alpm_pkg != null) {
  245. foreach (unowned string license in pkg.alpm_pkg.licenses) {
  246. licenses.append (" ");
  247. licenses.append (license);
  248. }
  249. } else {
  250. licenses.append (" ");
  251. licenses.append (pkg.aur_json.get_string_member ("License"));
  252. }
  253. licenses_label.set_markup (licenses.str);
  254. }
  255. public void set_deps_list (Alpm.Package pkg) {
  256. deps_list.clear ();
  257. TreeIter iter;
  258. unowned Alpm.List<Depend?> list = pkg.depends;
  259. size_t len = list.length;
  260. size_t i;
  261. if (len != 0) {
  262. deps_list.insert_with_values (out iter, -1,
  263. 0, dgettext (null, "Depends On") + ":",
  264. 1, list.nth_data (0).compute_string ());
  265. i = 1;
  266. while (i < len) {
  267. deps_list.insert_with_values (out iter, -1,
  268. 1, list.nth_data (i).compute_string ());
  269. i++;
  270. }
  271. }
  272. list = pkg.optdepends;
  273. len = list.length;
  274. if (len != 0) {
  275. unowned Depend optdep = list.nth_data (0);
  276. unowned Alpm.Package? satisfier = find_satisfier (
  277. transaction.handle.localdb.pkgcache,
  278. optdep.name);
  279. string optdep_str = optdep.compute_string ();
  280. if (satisfier != null)
  281. optdep_str = optdep_str + " [" + dgettext (null, "Installed") + "]";
  282. deps_list.insert_with_values (out iter, -1,
  283. 0, dgettext (null, "Optional Dependencies") + ":",
  284. 1, optdep_str);
  285. i = 1;
  286. while (i < len) {
  287. optdep = list.nth_data (i);
  288. satisfier = find_satisfier (
  289. transaction.handle.localdb.pkgcache,
  290. optdep.name);
  291. optdep_str = optdep.compute_string ();
  292. if (satisfier != null)
  293. optdep_str = optdep_str + " [" + dgettext (null, "Installed") + "]";
  294. deps_list.insert_with_values (out iter, -1, 1, optdep_str);
  295. i++;
  296. }
  297. }
  298. if (pkg.origin == PkgFrom.LOCALDB) {
  299. Alpm.List<string?> str_list = pkg.compute_requiredby ();
  300. len = str_list.length;
  301. if (len != 0) {
  302. deps_list.insert_with_values (out iter, -1,
  303. 0, dgettext (null, "Required By") + ":",
  304. 1, str_list.nth_data (0));
  305. i = 1;
  306. while (i < len) {
  307. deps_list.insert_with_values (out iter, -1,
  308. 1, str_list.nth_data (i));
  309. i++;
  310. }
  311. }
  312. }
  313. list = pkg.provides;
  314. len = list.length;
  315. if (len != 0) {
  316. deps_list.insert_with_values (out iter, -1,
  317. 0, dgettext (null, "Provides") + ":",
  318. 1, list.nth_data (0).compute_string ());
  319. i = 1;
  320. while (i < len) {
  321. deps_list.insert_with_values (out iter, -1,
  322. 1, list.nth_data (i).compute_string ());
  323. i++;
  324. }
  325. }
  326. list = pkg.replaces;
  327. len = list.length;
  328. if (len != 0) {
  329. deps_list.insert_with_values (out iter, -1,
  330. 0, dgettext (null, "Replaces") + ":",
  331. 1, list.nth_data (0).compute_string ());
  332. i = 1;
  333. while (i < len) {
  334. deps_list.insert_with_values (out iter, -1,
  335. 1, list.nth_data (i).compute_string ());
  336. i++;
  337. }
  338. }
  339. list = pkg.conflicts;
  340. len = list.length;
  341. if (len != 0) {
  342. deps_list.insert_with_values (out iter, -1,
  343. 0, dgettext (null, "Conflicts With") + ":",
  344. 1, list.nth_data (0).compute_string ());
  345. i = 1;
  346. while (i < len) {
  347. deps_list.insert_with_values (out iter, -1,
  348. 1, list.nth_data (i).compute_string ());
  349. i++;
  350. }
  351. }
  352. }
  353. public void set_details_list (Alpm.Package pkg) {
  354. details_list.clear ();
  355. TreeIter iter;
  356. if (pkg.origin == PkgFrom.SYNCDB) {
  357. details_list.insert_with_values (out iter, -1,
  358. 0, dgettext (null, "Repository") + ":",
  359. 1, pkg.db.name);
  360. }
  361. unowned Alpm.List<string?> list = pkg.groups;
  362. size_t len = list.length;
  363. size_t i;
  364. if (len != 0) {
  365. details_list.insert_with_values (out iter, -1,
  366. 0, dgettext (null, "Groups") + ":",
  367. 1, list.nth_data (0));
  368. i = 1;
  369. while (i < len) {
  370. details_list.insert_with_values (out iter, -1,
  371. 1, list.nth_data (i));
  372. i++;
  373. }
  374. }
  375. details_list.insert_with_values (out iter, -1,
  376. 0, dgettext (null, "Packager") + ":",
  377. 1, pkg.packager);
  378. if (pkg.origin == PkgFrom.LOCALDB) {
  379. GLib.Time time = GLib.Time.local ((time_t) pkg.installdate);
  380. string strtime = time.format ("%a %d %b %Y %X %Z");
  381. details_list.insert_with_values (out iter, -1,
  382. 0, dgettext (null, "Install Date") + ":",
  383. 1, strtime);
  384. string reason;
  385. if (pkg.reason == PkgReason.EXPLICIT)
  386. reason = dgettext (null, "Explicitly installed");
  387. else if (pkg.reason == PkgReason.EXPLICIT)
  388. reason = dgettext (null, "Installed as a dependency for another package");
  389. else
  390. reason = dgettext (null, "Unknown");
  391. details_list.insert_with_values (out iter, -1,
  392. 0, dgettext (null, "Install Reason") + ":",
  393. 1, reason);
  394. }
  395. if (pkg.origin == PkgFrom.SYNCDB) {
  396. details_list.insert_with_values (out iter, -1,
  397. 0, dgettext (null, "Signatures") + ":",
  398. 1, pkg.base64_sig != null ? "Yes" : "No");
  399. }
  400. if (pkg.origin == PkgFrom.LOCALDB) {
  401. unowned Alpm.List<Backup?> backup_list = pkg.backup;
  402. len = backup_list.length;
  403. if (len != 0) {
  404. details_list.insert_with_values (out iter, -1,
  405. 0, dgettext (null, "Backup files") + ":",
  406. 1, "/" + backup_list.nth_data (0).name);
  407. i = 1;
  408. while (i < len) {
  409. details_list.insert_with_values (out iter, -1,
  410. 1, "/" + backup_list.nth_data (i).name);
  411. i++;
  412. }
  413. }
  414. }
  415. }
  416. public void set_files_list (Alpm.Package pkg) {
  417. StringBuilder text = new StringBuilder ();
  418. foreach (unowned Alpm.File file in pkg.files) {
  419. if (text.len != 0)
  420. text.append ("\n");
  421. text.append ("/");
  422. text.append (file.name);
  423. }
  424. files_textview.buffer.set_text (text.str, (int) text.len);
  425. }
  426. public async unowned Alpm.List<Alpm.Package?> search_pkgs (string search_string, out Json.Array aur_pkgs) {
  427. unowned Alpm.List<string?> needles = null;
  428. string[] splitted = search_string.split (" ");
  429. foreach (unowned string part in splitted)
  430. needles.add (part);
  431. unowned Alpm.List<Alpm.Package?> pkgs = search_all_dbs (transaction.handle, needles);
  432. if (search_aur_button.get_active()) {
  433. if (aur_results.contains (search_string)) {
  434. aur_pkgs = aur_results.get (search_string);
  435. } else {
  436. aur_pkgs = AUR.search (splitted);
  437. aur_results.insert (search_string, aur_pkgs);
  438. }
  439. } else {
  440. aur_pkgs = new Json.Array ();
  441. }
  442. return pkgs;
  443. }
  444. public void populate_packages_list (Alpm.List<Alpm.Package?>? pkgs, Json.Array? aur_pkgs = null) {
  445. packages_treeview.freeze_child_notify ();
  446. packages_treeview.set_model (null);
  447. // populate liststore
  448. packages_list = new PackagesModel (pkgs, aur_pkgs, this);
  449. // sort liststore
  450. int column = sortinfo.column_number;
  451. if (column == 0)
  452. packages_list.sort_by_name (sortinfo.sort_type);
  453. else if (column == 1)
  454. packages_list.sort_by_state (sortinfo.sort_type);
  455. else if (column == 2)
  456. packages_list.sort_by_version (sortinfo.sort_type);
  457. else if (column == 3)
  458. packages_list.sort_by_repo (sortinfo.sort_type);
  459. else if (column == 4)
  460. packages_list.sort_by_size (sortinfo.sort_type);
  461. packages_treeview.set_model (packages_list);
  462. packages_treeview.thaw_child_notify ();
  463. this.get_window ().set_cursor (null);
  464. }
  465. public void refresh_packages_list () {
  466. int current_page = filters_notebook.get_current_page ();
  467. if (current_page == 0) {
  468. TreeModel model;
  469. TreeIter? iter;
  470. TreeSelection selection = search_treeview.get_selection ();
  471. if (selection.get_selected (out model, out iter)) {
  472. on_search_treeview_selection_changed ();
  473. }
  474. } else if (current_page == 1) {
  475. on_groups_treeview_selection_changed ();
  476. } else if (current_page == 2) {
  477. on_states_treeview_selection_changed ();
  478. } else if (current_page == 3) {
  479. on_repos_treeview_selection_changed ();
  480. }
  481. }
  482. [GtkCallback]
  483. public void on_packages_treeview_selection_changed () {
  484. TreeModel model;
  485. TreeSelection selection = packages_treeview.get_selection ();
  486. GLib.List<TreePath> selected = selection.get_selected_rows (out model);
  487. if (selected.length () == 1) {
  488. TreeIter iter;
  489. model.get_iter (out iter, selected.nth_data (0));
  490. Pamac.Package pkg = (Pamac.Package) iter.user_data;
  491. if (pkg.alpm_pkg != null) {
  492. set_infos_list (pkg);
  493. set_deps_list (pkg.alpm_pkg);
  494. set_details_list (pkg.alpm_pkg);
  495. deps_scrolledwindow.visible = true;
  496. details_scrolledwindow.visible = true;
  497. if (pkg.alpm_pkg.origin == PkgFrom.LOCALDB) {
  498. set_files_list (pkg.alpm_pkg);
  499. files_scrolledwindow.visible = true;
  500. } else {
  501. files_scrolledwindow.visible = false;
  502. }
  503. } else if (pkg.aur_json != null) {
  504. set_infos_list (pkg);
  505. deps_scrolledwindow.visible = false;
  506. details_scrolledwindow.visible = false;
  507. files_scrolledwindow.visible = false;
  508. }
  509. }
  510. }
  511. [GtkCallback]
  512. public void on_packages_treeview_row_activated (TreeView treeview, TreePath path, TreeViewColumn column) {
  513. TreeIter iter;
  514. if (packages_list.get_iter (out iter, path)) {
  515. GLib.Value val;
  516. packages_list.get_value (iter, 0, out val);
  517. string name = val.get_string ();
  518. if (name != dgettext (null, "No package found")) {
  519. if (transaction.to_add.steal (name)) {
  520. } else if (transaction.to_remove.steal (name)) {
  521. } else if (transaction.to_build.steal (name)) {
  522. } else {
  523. packages_list.get_value (iter, 3, out val);
  524. string db_name = val.get_string ();
  525. if (db_name == "local") {
  526. if ((name in transaction.holdpkg) == false) {
  527. transaction.to_remove.insert (name, name);
  528. }
  529. } else if (db_name == "AUR") {
  530. transaction.to_build.insert (name, name);
  531. } else {
  532. transaction.to_add.insert (name, name);
  533. }
  534. }
  535. }
  536. }
  537. if (transaction.to_add.size () + transaction.to_remove.size () + transaction.to_build.size () == 0) {
  538. set_buttons_sensitive (false);
  539. } else {
  540. set_buttons_sensitive (true);
  541. }
  542. // force a display refresh
  543. packages_treeview.queue_draw ();
  544. }
  545. void on_install_item_activate () {
  546. unowned Alpm.Package? find_pkg = null;
  547. foreach (Pamac.Package pkg in selected_pkgs) {
  548. if (pkg.repo == "AUR")
  549. transaction.to_build.insert (pkg.name, pkg.name);
  550. else {
  551. find_pkg = transaction.handle.localdb.get_pkg (pkg.name);
  552. if (find_pkg == null)
  553. transaction.to_add.insert (pkg.name, pkg.name);
  554. }
  555. }
  556. if (transaction.to_add.size () != 0 || transaction.to_build.size () != 0) {
  557. set_buttons_sensitive (true);
  558. }
  559. }
  560. void on_reinstall_item_activate () {
  561. foreach (Pamac.Package pkg in selected_pkgs) {
  562. if (pkg.repo == "local")
  563. transaction.to_add.insert (pkg.name, pkg.name);
  564. }
  565. if (transaction.to_add.size () != 0)
  566. set_buttons_sensitive (true);
  567. }
  568. void on_remove_item_activate () {
  569. foreach (Pamac.Package pkg in selected_pkgs) {
  570. if ((pkg.name in transaction.holdpkg) == false) {
  571. if (pkg.repo == "local")
  572. transaction.to_remove.insert (pkg.name, pkg.name);
  573. }
  574. }
  575. if (transaction.to_remove.size () != 0)
  576. set_buttons_sensitive (true);
  577. }
  578. void on_deselect_item_activate () {
  579. foreach (Pamac.Package pkg in selected_pkgs) {
  580. if (transaction.to_add.steal (pkg.name)) {
  581. } else if (transaction.to_remove.steal (pkg.name)) {
  582. } else if (transaction.to_build.steal (pkg.name)) {
  583. }
  584. }
  585. if (transaction.to_add.size () == 0 && transaction.to_remove.size () == 0
  586. && transaction.to_load.size () == 0 && transaction.to_build.size () == 0) {
  587. set_buttons_sensitive (false);
  588. }
  589. }
  590. public void choose_opt_dep (GLib.List<Pamac.Package> pkgs) {
  591. uint nb;
  592. TreeIter iter;
  593. unowned Alpm.Package? found;
  594. foreach (Pamac.Package pkg in pkgs) {
  595. var choose_dep_dialog = new ChooseDependenciesDialog (this);
  596. nb = 0;
  597. foreach (unowned Depend opt_dep in pkg.alpm_pkg.optdepends) {
  598. found = find_satisfier (transaction.handle.localdb.pkgcache, opt_dep.compute_string ());
  599. if (found == null) {
  600. choose_dep_dialog.deps_list.insert_with_values (out iter, -1,
  601. 0, false,
  602. 1, opt_dep.name,
  603. 2, opt_dep.desc);
  604. nb += 1;
  605. }
  606. }
  607. choose_dep_dialog.label.set_markup ("<b>%s</b>".printf (dgettext (null, "%s has %u uninstalled optional dependencies.\nChoose those you would like to install:").printf (pkg.name, nb)));
  608. choose_dep_dialog.run ();
  609. choose_dep_dialog.hide ();
  610. while (Gtk.events_pending ())
  611. Gtk.main_iteration ();
  612. choose_dep_dialog.deps_list.foreach ((model, path, iter) => {
  613. GLib.Value val;
  614. bool selected;
  615. string name;
  616. choose_dep_dialog.deps_list.get_value (iter, 0, out val);
  617. selected = val.get_boolean ();
  618. if (selected) {
  619. choose_dep_dialog.deps_list.get_value (iter, 1, out val);
  620. name = val.get_string ();
  621. transaction.to_add.insert (name, name);
  622. }
  623. return false;
  624. });
  625. }
  626. }
  627. void on_install_optional_deps_item_activate () {
  628. choose_opt_dep (selected_pkgs);
  629. if (transaction.to_add.size () != 0)
  630. set_buttons_sensitive (true);
  631. }
  632. void on_explicitly_installed_item_activate () {
  633. foreach (Pamac.Package pkg in selected_pkgs) {
  634. transaction.set_pkgreason (pkg.name, PkgReason.EXPLICIT);
  635. }
  636. transaction.refresh_alpm_config ();
  637. refresh_packages_list ();
  638. }
  639. [GtkCallback]
  640. public bool on_packages_treeview_button_press_event (Gdk.EventButton event) {
  641. packages_treeview.grab_focus ();
  642. // Check if right mouse button was clicked
  643. if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) {
  644. TreeIter iter;
  645. TreePath? treepath;
  646. Pamac.Package clicked_pkg;
  647. TreeSelection selection = packages_treeview.get_selection ();
  648. packages_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null);
  649. packages_list.get_iter (out iter, treepath);
  650. clicked_pkg = (Pamac.Package) iter.user_data;
  651. if (clicked_pkg.name == dgettext (null, "No package found"))
  652. return true;
  653. if (selection.path_is_selected (treepath) == false) {
  654. selection.unselect_all ();
  655. selection.select_path (treepath);
  656. }
  657. GLib.List<TreePath> selected_paths = selection.get_selected_rows (null);
  658. deselect_item.set_sensitive (false);
  659. install_item.set_sensitive (false);
  660. remove_item.set_sensitive (false);
  661. reinstall_item.set_sensitive (false);
  662. install_optional_deps_item.set_sensitive (false);
  663. explicitly_installed_item.set_sensitive (false);
  664. selected_pkgs = new GLib.List<Pamac.Package> ();
  665. foreach (TreePath path in selected_paths) {
  666. packages_list.get_iter (out iter, path);
  667. clicked_pkg = (Pamac.Package) iter.user_data;
  668. selected_pkgs.append (clicked_pkg);
  669. }
  670. foreach (Pamac.Package pkg in selected_pkgs) {
  671. if (transaction.to_add.contains (pkg.name)
  672. || transaction.to_remove.contains (pkg.name)
  673. || transaction.to_build.contains (pkg.name)) {
  674. deselect_item.set_sensitive (true);
  675. break;
  676. }
  677. }
  678. foreach (Pamac.Package pkg in selected_pkgs) {
  679. if (pkg.repo != "local") {
  680. install_item.set_sensitive (true);
  681. break;
  682. }
  683. }
  684. foreach (Pamac.Package pkg in selected_pkgs) {
  685. if (pkg.repo == "local") {
  686. remove_item.set_sensitive (true);
  687. break;
  688. }
  689. }
  690. if (selected_pkgs.length () == 1) {
  691. unowned Alpm.Package? find_pkg = null;
  692. clicked_pkg = selected_pkgs.nth_data (0);
  693. if (clicked_pkg.repo == "local") {
  694. unowned Alpm.List<Depend?> optdepends = clicked_pkg.alpm_pkg.optdepends;
  695. if (optdepends.length != 0) {
  696. uint nb = 0;
  697. unowned Alpm.Package? found;
  698. foreach (unowned Depend opt_dep in optdepends) {
  699. found = find_satisfier (transaction.handle.localdb.pkgcache, opt_dep.compute_string ());
  700. if (found == null)
  701. nb += 1;
  702. }
  703. if (nb != 0)
  704. install_optional_deps_item.set_sensitive (true);
  705. }
  706. if (clicked_pkg.alpm_pkg.reason == PkgReason.DEPEND)
  707. explicitly_installed_item.set_sensitive (true);
  708. find_pkg = get_syncpkg (transaction.handle, clicked_pkg.name);
  709. if (find_pkg != null) {
  710. if (pkg_vercmp (find_pkg.version, clicked_pkg.version) == 0)
  711. reinstall_item.set_sensitive (true);
  712. }
  713. }
  714. }
  715. right_click_menu.popup (null, null, null, event.button, event.time);
  716. return true;
  717. } else
  718. return false;
  719. }
  720. [GtkCallback]
  721. public void on_name_column_clicked () {
  722. SortType new_order;
  723. if (name_column.sort_indicator == false)
  724. new_order = SortType.ASCENDING;
  725. else {
  726. if (sortinfo.sort_type == SortType.ASCENDING)
  727. new_order = SortType.DESCENDING;
  728. else
  729. new_order = SortType.ASCENDING;
  730. }
  731. packages_list.sort_by_name (new_order);
  732. // force a display refresh
  733. packages_treeview.queue_draw ();
  734. }
  735. [GtkCallback]
  736. public void on_state_column_clicked () {
  737. SortType new_order;
  738. if (state_column.sort_indicator == false)
  739. new_order = SortType.ASCENDING;
  740. else {
  741. if (sortinfo.sort_type == SortType.ASCENDING)
  742. new_order = SortType.DESCENDING;
  743. else
  744. new_order = SortType.ASCENDING;
  745. }
  746. packages_list.sort_by_state (new_order);
  747. // force a display refresh
  748. packages_treeview.queue_draw ();
  749. }
  750. [GtkCallback]
  751. public void on_version_column_clicked () {
  752. SortType new_order;
  753. if (version_column.sort_indicator == false)
  754. new_order = SortType.ASCENDING;
  755. else {
  756. if (sortinfo.sort_type == SortType.ASCENDING)
  757. new_order = SortType.DESCENDING;
  758. else
  759. new_order = SortType.ASCENDING;
  760. }
  761. packages_list.sort_by_version (new_order);
  762. // force a display refresh
  763. packages_treeview.queue_draw ();
  764. }
  765. [GtkCallback]
  766. public void on_repo_column_clicked () {
  767. SortType new_order;
  768. if (repo_column.sort_indicator == false)
  769. new_order = SortType.ASCENDING;
  770. else {
  771. if (sortinfo.sort_type == SortType.ASCENDING)
  772. new_order = SortType.DESCENDING;
  773. else
  774. new_order = SortType.ASCENDING;
  775. }
  776. packages_list.sort_by_repo (new_order);
  777. // force a display refresh
  778. packages_treeview.queue_draw ();
  779. }
  780. [GtkCallback]
  781. public void on_size_column_clicked () {
  782. SortType new_order;
  783. if (size_column.sort_indicator == false)
  784. new_order = SortType.ASCENDING;
  785. else {
  786. if (sortinfo.sort_type == SortType.ASCENDING)
  787. new_order = SortType.DESCENDING;
  788. else
  789. new_order = SortType.ASCENDING;
  790. }
  791. packages_list.sort_by_size (new_order);
  792. // force a display refresh
  793. packages_treeview.queue_draw ();
  794. }
  795. [GtkCallback]
  796. public void on_search_entry_activate () {
  797. string search_string = search_entry.get_text ();
  798. if (search_string != "") {
  799. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  800. while (Gtk.events_pending ())
  801. Gtk.main_iteration ();
  802. search_pkgs.begin (search_string, (obj, res) => {
  803. Json.Array aur_pkgs;
  804. unowned Alpm.List<Alpm.Package?> pkgs = search_pkgs.end (res, out aur_pkgs);
  805. if (pkgs.length != 0 || aur_pkgs.get_length () != 0) {
  806. // add search string in search_list if needed
  807. bool found = false;
  808. TreeIter? iter;
  809. TreeModel model;
  810. TreeSelection selection = search_treeview.get_selection ();
  811. // check if search string is already selected in search list
  812. if (selection.get_selected (out model, out iter)) {
  813. GLib.Value val;
  814. model.get_value (iter, 0, out val);
  815. string selected_string = val.get_string ();
  816. if (selected_string == search_string) {
  817. found = true;
  818. // we need to populate packages_list
  819. populate_packages_list (pkgs, aur_pkgs);
  820. } else {
  821. search_list.foreach ((_model, _path, _iter) => {
  822. GLib.Value line;
  823. model.get_value (_iter, 0, out line);
  824. if ((string) line == search_string) {
  825. found = true;
  826. // block the signal to not populate when we select the iter in search_list
  827. selection.changed.disconnect (on_search_treeview_selection_changed);
  828. selection.select_iter (_iter);
  829. selection.changed.connect_after (on_search_treeview_selection_changed);
  830. populate_packages_list (pkgs, aur_pkgs);
  831. }
  832. return found;
  833. });
  834. }
  835. }
  836. if (found == false) {
  837. search_list.insert_with_values (out iter, -1, 0, search_string);
  838. // block the signal to not populate when we select the iter in search_list
  839. selection.changed.disconnect (on_search_treeview_selection_changed);
  840. selection.select_iter (iter);
  841. selection.changed.connect_after (on_search_treeview_selection_changed);
  842. populate_packages_list (pkgs, aur_pkgs);
  843. }
  844. } else {
  845. // populate with empty lists
  846. populate_packages_list (pkgs, aur_pkgs);
  847. }
  848. });
  849. }
  850. }
  851. [GtkCallback]
  852. public void on_search_entry_icon_press (EntryIconPosition p0, Gdk.Event? p1) {
  853. on_search_entry_activate ();
  854. }
  855. [GtkCallback]
  856. public void on_search_treeview_selection_changed () {
  857. TreeModel model;
  858. TreeIter? iter;
  859. TreeSelection selection = search_treeview.get_selection ();
  860. if (selection.get_selected (out model, out iter)) {
  861. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  862. while (Gtk.events_pending ())
  863. Gtk.main_iteration ();
  864. GLib.Value val;
  865. model.get_value (iter, 0, out val);
  866. string search_string = val.get_string ();
  867. search_pkgs.begin (search_string, (obj, res) => {
  868. Json.Array aur_pkgs;
  869. unowned Alpm.List<Alpm.Package?> pkgs = search_pkgs.end (res, out aur_pkgs);
  870. populate_packages_list (pkgs, aur_pkgs);
  871. });
  872. }
  873. }
  874. [GtkCallback]
  875. public void on_groups_treeview_selection_changed () {
  876. TreeModel model;
  877. TreeIter? iter;
  878. TreeSelection selection = groups_treeview.get_selection ();
  879. if (selection.get_selected (out model, out iter)) {
  880. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  881. while (Gtk.events_pending ())
  882. Gtk.main_iteration ();
  883. GLib.Value val;
  884. model.get_value (iter, 0, out val);
  885. string grp_name = val.get_string ();
  886. unowned Alpm.List<Alpm.Package?> pkgs = group_pkgs_all_dbs (transaction.handle, grp_name);
  887. populate_packages_list (pkgs);
  888. }
  889. }
  890. [GtkCallback]
  891. public void on_states_treeview_selection_changed () {
  892. TreeModel model;
  893. TreeIter? iter;
  894. TreeSelection selection = states_treeview.get_selection ();
  895. if (selection.get_selected (out model, out iter)) {
  896. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  897. while (Gtk.events_pending ())
  898. Gtk.main_iteration ();
  899. GLib.Value val;
  900. model.get_value (iter, 0, out val);
  901. string state = val.get_string ();
  902. unowned Alpm.List<Alpm.Package?> pkgs = null;
  903. unowned Alpm.Package? find_pkg = null;
  904. if (state == dgettext (null, "To install")) {
  905. foreach (string name in transaction.to_add.get_keys ()) {
  906. find_pkg = transaction.handle.localdb.get_pkg (name);
  907. if (find_pkg != null)
  908. pkgs.add (find_pkg);
  909. else {
  910. find_pkg = get_syncpkg (transaction.handle, name);
  911. if (find_pkg != null)
  912. pkgs.add (find_pkg);
  913. }
  914. }
  915. } else if (state == dgettext (null, "To remove")) {
  916. foreach (string name in transaction.to_remove.get_keys ()) {
  917. find_pkg = transaction.handle.localdb.get_pkg (name);
  918. if (find_pkg != null)
  919. pkgs.add (find_pkg);
  920. }
  921. } else if (state == dgettext (null, "Installed")) {
  922. pkgs = transaction.handle.localdb.pkgcache;
  923. } else if (state == dgettext (null, "Uninstalled")) {
  924. foreach (unowned DB db in transaction.handle.syncdbs) {
  925. if (pkgs.length == 0)
  926. pkgs = db.pkgcache.copy ();
  927. else {
  928. pkgs.join (db.pkgcache.diff (pkgs, (Alpm.List.CompareFunc) pkgcmp));
  929. }
  930. }
  931. } else if (state == dgettext (null, "Orphans")) {
  932. foreach (unowned Alpm.Package pkg in transaction.handle.localdb.pkgcache) {
  933. if (pkg.reason == PkgReason.DEPEND) {
  934. if (pkg.compute_requiredby().length == 0)
  935. pkgs.add (pkg);
  936. }
  937. }
  938. }
  939. populate_packages_list (pkgs);
  940. }
  941. }
  942. [GtkCallback]
  943. public void on_repos_treeview_selection_changed () {
  944. TreeModel model;
  945. TreeIter? iter;
  946. TreeSelection selection = repos_treeview.get_selection ();
  947. if (selection.get_selected (out model, out iter)) {
  948. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  949. while (Gtk.events_pending ())
  950. Gtk.main_iteration ();
  951. GLib.Value val;
  952. model.get_value (iter, 0, out val);
  953. string repo = val.get_string ();
  954. unowned Alpm.List<Alpm.Package?> pkgs = null;
  955. unowned Alpm.Package? find_pkg = null;
  956. if (repo == dgettext (null, "local")) {
  957. foreach (unowned Alpm.Package pkg in transaction.handle.localdb.pkgcache) {
  958. find_pkg = get_syncpkg (transaction.handle, pkg.name);
  959. if (find_pkg == null)
  960. pkgs.add (pkg);
  961. }
  962. } else {
  963. foreach (unowned DB db in transaction.handle.syncdbs) {
  964. if (db.name == repo) {
  965. foreach (unowned Alpm.Package pkg in db.pkgcache) {
  966. find_pkg = transaction.handle.localdb.get_pkg (pkg.name);
  967. if (find_pkg != null)
  968. pkgs.add (find_pkg);
  969. else
  970. pkgs.add (pkg);
  971. }
  972. }
  973. }
  974. }
  975. populate_packages_list (pkgs);
  976. }
  977. }
  978. [GtkCallback]
  979. public void on_filters_notebook_switch_page (Widget page, uint page_num) {
  980. refresh_packages_list ();
  981. }
  982. [GtkCallback]
  983. public void on_history_item_activate () {
  984. var file = GLib.File.new_for_path ("/var/log/pamac.log");
  985. if (!file.query_exists ())
  986. GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ());
  987. else {
  988. StringBuilder text = new StringBuilder ();
  989. try {
  990. // Open file for reading and wrap returned FileInputStream into a
  991. // DataInputStream, so we can read line by line
  992. var dis = new DataInputStream (file.read ());
  993. string line;
  994. // Read lines until end of file (null) is reached
  995. while ((line = dis.read_line (null)) != null) {
  996. text.append (line);
  997. text.append ("\n");
  998. }
  999. } catch (GLib.Error e) {
  1000. GLib.stderr.printf("%s\n", e.message);
  1001. }
  1002. history_dialog.textview.buffer.set_text (text.str, (int) text.len);
  1003. history_dialog.run ();
  1004. history_dialog.hide ();
  1005. while (Gtk.events_pending ())
  1006. Gtk.main_iteration ();
  1007. }
  1008. }
  1009. [GtkCallback]
  1010. public void on_local_item_activate () {
  1011. int response = packages_chooser_dialog.run ();
  1012. if (response== ResponseType.ACCEPT) {
  1013. SList<string> packages_paths = packages_chooser_dialog.get_filenames ();
  1014. if (packages_paths.length () != 0) {
  1015. foreach (string path in packages_paths) {
  1016. transaction.to_load.insert (path, path);
  1017. }
  1018. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  1019. packages_chooser_dialog.hide ();
  1020. while (Gtk.events_pending ())
  1021. Gtk.main_iteration ();
  1022. transaction.run ();
  1023. }
  1024. } else
  1025. packages_chooser_dialog.hide ();
  1026. while (Gtk.events_pending ())
  1027. Gtk.main_iteration ();
  1028. }
  1029. [GtkCallback]
  1030. public void on_preferences_item_activate () {
  1031. bool enable_aur = pamac_config.enable_aur;
  1032. bool recurse = pamac_config.recurse;
  1033. uint64 refresh_period = pamac_config.refresh_period;
  1034. preferences_dialog.enable_aur_button.set_active (enable_aur);
  1035. preferences_dialog.remove_unrequired_deps_button.set_active (recurse);
  1036. preferences_dialog.refresh_period_spin_button.set_value (refresh_period);
  1037. int response = preferences_dialog.run ();
  1038. while (Gtk.events_pending ())
  1039. Gtk.main_iteration ();
  1040. if (response == ResponseType.OK) {
  1041. HashTable<string,string> new_conf = new HashTable<string,string> (str_hash, str_equal);
  1042. enable_aur = preferences_dialog.enable_aur_button.get_active ();
  1043. recurse = preferences_dialog.remove_unrequired_deps_button.get_active ();
  1044. refresh_period = (uint64) preferences_dialog.refresh_period_spin_button.get_value ();
  1045. if (enable_aur != pamac_config.enable_aur) {
  1046. search_aur_button.set_active (enable_aur);
  1047. new_conf.insert ("EnableAUR", enable_aur.to_string ());
  1048. }
  1049. if (recurse != pamac_config.recurse)
  1050. new_conf.insert ("RemoveUnrequiredDeps", recurse.to_string ());
  1051. if (refresh_period != pamac_config.refresh_period)
  1052. new_conf.insert ("RefreshPeriod", refresh_period.to_string ());
  1053. if (new_conf.size () != 0) {
  1054. transaction.write_config (new_conf);
  1055. pamac_config.reload ();
  1056. search_aur_button.set_active (pamac_config.enable_aur);
  1057. }
  1058. }
  1059. preferences_dialog.hide ();
  1060. while (Gtk.events_pending ())
  1061. Gtk.main_iteration ();
  1062. }
  1063. [GtkCallback]
  1064. public void on_about_item_activate () {
  1065. Gtk.show_about_dialog (
  1066. this,
  1067. "program_name", "Pamac",
  1068. "logo_icon_name", "system-software-install",
  1069. "comments", dgettext (null, "A Gtk3 frontend for libalpm"),
  1070. "copyright", "Copyright © 2014 Guillaume Benoit",
  1071. "version", VERSION,
  1072. "license_type", License.GPL_3_0,
  1073. "website", "http://manjaro.org");
  1074. }
  1075. [GtkCallback]
  1076. public void on_valid_button_clicked () {
  1077. this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
  1078. while (Gtk.events_pending ())
  1079. Gtk.main_iteration ();
  1080. if (pamac_config.recurse)
  1081. transaction.flags |= Alpm.TransFlag.RECURSE;
  1082. transaction.run ();
  1083. }
  1084. [GtkCallback]
  1085. public void on_cancel_button_clicked () {
  1086. transaction.clear_lists ();
  1087. set_buttons_sensitive (false);
  1088. // force a display refresh
  1089. packages_treeview.queue_draw ();
  1090. }
  1091. [GtkCallback]
  1092. public void on_refresh_button_clicked () {
  1093. transaction.refresh (0);
  1094. }
  1095. public void on_emit_trans_finished (bool error) {
  1096. print ("transaction finished\n");
  1097. if (error == false) {
  1098. set_buttons_sensitive (false);
  1099. refresh_packages_list ();
  1100. }
  1101. transaction.to_load.steal_all ();
  1102. this.get_window ().set_cursor (null);
  1103. }
  1104. }
  1105. }