libyui-gtk-pkg  2.42.9
 All Classes
ygtkpkgmenubar.cc
1 /********************************************************************
2  * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
3  ********************************************************************/
4 /* YGtkPkgMenuBar, menu bar */
5 // check the header file for information about this widget
6 
7 /*
8  Textdomain "gtk"
9  */
10 
11 #include "YGi18n.h"
12 #include "config.h"
13 #include "YGDialog.h"
14 #include "YGUtils.h"
15 #include "ygtkpkgmenubar.h"
16 #include <gtk/gtk.h>
17 #include <glib/gstdio.h>
18 #include <stdio.h>
19 #include <gdk/gdkkeysyms.h>
20 #include "yzyppwrapper.h"
21 #include "YGPackageSelector.h"
22 
23 // flags handling
24 
25 #define YAST_GTK_SYSCONFIG "/etc/sysconfig/yast2-gtk"
26 
27 struct Flags {
28  Flags() {
29  keys = g_key_file_new();
30  g_key_file_load_from_file (keys, YAST_GTK_SYSCONFIG, G_KEY_FILE_NONE, NULL);
31  modified = false;
32  }
33 
34  ~Flags() {
35  if (modified)
36  writeFile();
37  g_key_file_free (keys);
38  }
39 
40  bool hasKey (const char *variable) {
41  return g_key_file_has_key (keys, "zypp", variable, NULL);
42  }
43 
44  bool getBool (const char *variable) {
45  return g_key_file_get_boolean (keys, "zypp", variable, NULL);
46  }
47 
48  void setBool (const char *variable, bool value) {
49  g_key_file_set_boolean (keys, "zypp", variable, value);
50  modified = true;
51  }
52 
53  private:
54  void writeFile() {
55  FILE *out = fopen (YAST_GTK_SYSCONFIG, "w");
56  if (out) {
57  gsize size;
58  gchar *data = g_key_file_to_data (keys, &size, NULL);
59  fwrite (data, sizeof (char), size, out);
60  g_free (data);
61  fclose (out);
62  }
63  }
64 
65  GKeyFile *keys;
66  bool modified;
67 };
68 
69 // utilities
70 
71 static GtkWidget *append_menu_item (GtkWidget *menu, const char *_text,
72  const char *stock, GCallback callback, gpointer callback_data)
73 {
74  std::string text;
75  if (_text)
76  text = YGUtils::mapKBAccel (_text);
77  GtkWidget *item;
78  if (stock && _text) {
79  GtkWidget *icon = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
80  item = gtk_image_menu_item_new_with_mnemonic (text.c_str());
81  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), icon);
82  }
83  else if (_text)
84  item = gtk_menu_item_new_with_mnemonic (text.c_str());
85  else if (stock)
86  item = gtk_image_menu_item_new_from_stock (stock, NULL);
87  else
88  item = gtk_separator_menu_item_new();
89  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
90  if (callback)
91  g_signal_connect (G_OBJECT (item), "activate", callback, callback_data);
92  return item;
93 }
94 
95 static void errorMsg (const std::string &message)
96 {
97  GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
98  GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
99  _("Error"));
100  gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
101  "%s", message.c_str());
102  gtk_dialog_run (GTK_DIALOG (dialog));
103  gtk_widget_destroy (dialog);
104 }
105 
106 // callback implementations
107 // code from yast2-qt
108 
109 #include <zypp/SysContent.h>
110 #include <zypp/ui/Status.h>
111 #include <zypp/ui/Selectable.h>
112 #include <zypp/ResPoolProxy.h>
113 #include <zypp/ZYppFactory.h>
114 #include <fstream>
115 
116 using zypp::ui::S_Protected;
117 using zypp::ui::S_Taboo;
118 using zypp::ui::S_Del;
119 using zypp::ui::S_Update;
120 using zypp::ui::S_Install;
121 using zypp::ui::S_AutoDel;
122 using zypp::ui::S_AutoUpdate;
123 using zypp::ui::S_AutoInstall;
124 using zypp::ui::S_KeepInstalled;
125 using zypp::ui::S_NoInst;
126 typedef zypp::ui::Selectable::Ptr ZyppSel;
127 typedef zypp::ui::Status ZyppStatus;
128 typedef zypp::ResPoolProxy::const_iterator ZyppPoolIterator;
129 typedef zypp::ResPoolProxy ZyppPool;
130 //inline ZyppPool zyppPool() { return zypp::getZYpp()->poolProxy(); }
131 template<class T> ZyppPoolIterator zyppBegin() { return zyppPool().byKindBegin<T>(); }
132 template<class T> ZyppPoolIterator zyppEnd() { return zyppPool().byKindEnd<T>(); }
133 inline ZyppPoolIterator zyppPkgBegin() { return zyppBegin<zypp::Package>(); }
134 inline ZyppPoolIterator zyppPkgEnd() { return zyppEnd<zypp::Package>(); }
135 inline ZyppPoolIterator zyppPatternsBegin() { return zyppBegin<zypp::Pattern>(); }
136 inline ZyppPoolIterator zyppPatternsEnd() { return zyppEnd<zypp::Pattern>(); }
137 
138 #define DEFAULT_EXPORT_FILE_NAME "user-packages.xml"
139 
140 static void
141 importSelectable( ZyppSel selectable,
142  bool isWanted,
143  const char * kind )
144 {
145  ZyppStatus oldStatus = selectable->status();
146  ZyppStatus newStatus = oldStatus;
147 
148  if ( isWanted )
149  {
150  //
151  // Make sure this selectable does not get installed
152  //
153 
154  switch ( oldStatus )
155  {
156  case S_Install:
157  case S_AutoInstall:
158  case S_KeepInstalled:
159  case S_Protected:
160  case S_Update:
161  case S_AutoUpdate:
162  newStatus = oldStatus;
163  break;
164 
165  case S_Del:
166  case S_AutoDel:
167  newStatus = S_KeepInstalled;
168  yuiDebug() << "Keeping " << kind << " " << selectable->name() << std::endl;
169  break;
170 
171  case S_NoInst:
172  case S_Taboo:
173 
174  if ( selectable->hasCandidateObj() )
175  {
176  newStatus = S_Install;
177  yuiDebug() << "Adding " << kind << " " << selectable->name() << std::endl;
178  }
179  else
180  {
181  yuiDebug() << "Can't add " << kind << " " << selectable->name()
182  << ": No candidate" << std::endl;
183  }
184  break;
185  }
186  }
187  else // ! isWanted
188  {
189  //
190  // Make sure this selectable does not get installed
191  //
192 
193  switch ( oldStatus )
194  {
195  case S_Install:
196  case S_AutoInstall:
197  case S_KeepInstalled:
198  case S_Protected:
199  case S_Update:
200  case S_AutoUpdate:
201  newStatus = S_Del;
202  yuiDebug() << "Deleting " << kind << " " << selectable->name() << std::endl;
203  break;
204 
205  case S_Del:
206  case S_AutoDel:
207  case S_NoInst:
208  case S_Taboo:
209  newStatus = oldStatus;
210  break;
211  }
212  }
213 
214  if ( oldStatus != newStatus )
215  selectable->setStatus( newStatus );
216 }
217 
218 static void import_file_cb (GtkMenuItem *item)
219 {
220  GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Import from"),
221  YGDialog::currentWindow(), GTK_FILE_CHOOSER_ACTION_OPEN,
222  GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
223  GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
224 
225  GtkFileFilter *filter = gtk_file_filter_new();
226  gtk_file_filter_set_name (filter, "*.xml");
227  gtk_file_filter_add_pattern (filter, "*.xml");
228  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
229  filter = gtk_file_filter_new();
230  gtk_file_filter_set_name (filter, "*");
231  gtk_file_filter_add_pattern (filter, "*");
232  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
233 
234  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), DEFAULT_EXPORT_FILE_NAME);
235  gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
236 
237  int ret = gtk_dialog_run (GTK_DIALOG (dialog));
238  if ( ret == GTK_RESPONSE_ACCEPT )
239  {
240  char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
241  yuiMilestone() << "Importing package list from " << filename << std::endl;
242 
243  try
244  {
245  std::ifstream importFile( filename );
246  zypp::syscontent::Reader reader( importFile );
247 
248  //
249  // Put reader contents into maps
250  //
251 
252  typedef zypp::syscontent::Reader::Entry ZyppReaderEntry;
253  typedef std::pair<std::string, ZyppReaderEntry> ImportMapPair;
254 
255  std::map<std::string, ZyppReaderEntry> importPkg;
256  std::map<std::string, ZyppReaderEntry> importPatterns;
257 
258  for ( zypp::syscontent::Reader::const_iterator it = reader.begin();
259  it != reader.end();
260  ++ it )
261  {
262  std::string kind = it->kind();
263 
264  if ( kind == "package" ) importPkg.insert ( ImportMapPair( it->name(), *it ) );
265  else if ( kind == "pattern" ) importPatterns.insert( ImportMapPair( it->name(), *it ) );
266  }
267 
268  yuiDebug() << "Found " << importPkg.size()
269  <<" packages and " << importPatterns.size()
270  << " patterns in " << filename
271  << std::endl;
272 
273 
274  //
275  // Set status of all patterns and packages according to import map
276  //
277 
278  for ( ZyppPoolIterator it = zyppPatternsBegin();
279  it != zyppPatternsEnd();
280  ++it )
281  {
282  ZyppSel selectable = *it;
283  importSelectable( *it, importPatterns.find( selectable->name() ) != importPatterns.end(), "pattern" );
284  }
285 
286  for ( ZyppPoolIterator it = zyppPkgBegin();
287  it != zyppPkgEnd();
288  ++it )
289  {
290  ZyppSel selectable = *it;
291  importSelectable( *it, importPkg.find( selectable->name() ) != importPkg.end(), "package" );
292  }
293 
294  YGPackageSelector::get()->popupChanges();
295  }
296  catch (const zypp::Exception & exception)
297  {
298  yuiWarning() << "Error reading package list from " << filename << std::endl;
299  std::string str (_("Could not open:"));
300  str += " "; str += filename;
301  errorMsg (str);
302  }
303 
304  g_free (filename);
305  Ypp::runSolver();
306  }
307 
308  gtk_widget_destroy (dialog);
309 }
310 
311 static void export_file_cb (GtkMenuItem *item)
312 {
313  GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Export to"),
314  YGDialog::currentWindow(), GTK_FILE_CHOOSER_ACTION_SAVE,
315  GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
316  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
317 
318  GtkFileFilter *filter = gtk_file_filter_new();
319  gtk_file_filter_set_name (filter, "*.xml");
320  gtk_file_filter_add_pattern (filter, "*.xml");
321  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
322  filter = gtk_file_filter_new();
323  gtk_file_filter_set_name (filter, "*");
324  gtk_file_filter_add_pattern (filter, "*");
325  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
326 
327  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), DEFAULT_EXPORT_FILE_NAME);
328  gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
329  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
330 
331  int ret = gtk_dialog_run (GTK_DIALOG (dialog));
332  if (ret == GTK_RESPONSE_ACCEPT) {
333  char *filename;
334  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
335 
336  zypp::syscontent::Writer writer;
337  const zypp::ResPool & pool = zypp::getZYpp()->pool();
338 
339  // The ZYPP obfuscated C++ contest proudly presents:
340 
341  for_each( pool.begin(), pool.end(),
342  boost::bind( &zypp::syscontent::Writer::addIf,
343  boost::ref( writer ),
344  _1 ) );
345  // Yuck. What a mess.
346  //
347  // Does anybody seriously believe this kind of thing is easier to read,
348  // let alone use? Get real. This is an argument in favour of all C++
349  // haters. And it's one that is really hard to counter.
350  //
351  // -sh 2006-12-13
352 
353  try
354  {
355  std::ofstream exportFile( filename );
356  exportFile.exceptions( std::ios_base::badbit | std::ios_base::failbit );
357  exportFile << writer;
358 
359  yuiMilestone() << "Package list exported to " << filename << std::endl;
360  }
361  catch ( std::exception & exception )
362  {
363  yuiWarning() << "Error exporting package list to " << filename << std::endl;
364 
365  // The export might have left over a partially written file.
366  // Try to delete it. Don't care if it doesn't exist and unlink() fails.
367  g_remove (filename);
368 
369  // Post error popup
370  std::string str (_("Could not save to:"));
371  str += " "; str += filename;
372  errorMsg (str);
373  }
374 
375  g_free (filename);
376  }
377 
378  gtk_widget_destroy (dialog);
379 }
380 
381 static void create_solver_testcase_cb (GtkMenuItem *item)
382 {
383  const char *dirname = "/var/log/YaST2/solverTestcase";
384  std::string msg (_("Use this to generate extensive logs to help tracking "
385  "down bugs in the dependencies resolver."));
386  msg += "\n"; msg += _("The logs will be saved to the directory:");
387  msg += " "; msg += dirname;
388 
389  GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
390  GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL,
391  // Translators: if there is no direct translation to Dependencies Resolver, then translate it to e.g. Dependencies Manager
392  "%s", _("Generate Dependencies Resolver Testcase"));
393  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", msg.c_str());
394  int ret = gtk_dialog_run (GTK_DIALOG (dialog));
395  gtk_widget_destroy (dialog);
396 
397  if (ret == GTK_RESPONSE_OK) {
398  bool success;
399  yuiMilestone() << "Generating solver test case START" << std::endl;
400  success = zypp::getZYpp()->resolver()->createSolverTestcase (dirname);
401  yuiMilestone() << "Generating solver test case END" << std::endl;
402 
403  if (success) {
404  GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
405  GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
406  GTK_BUTTONS_YES_NO, "%s", _("Success"));
407  msg = _("Dependencies resolver test case written to:");
408  msg += " <tt>";
409  msg += dirname;
410  msg += "</tt>\n";
411  msg += _("Also create a <tt>y2logs.tgz</tt> tar archive to attach to bugzilla?");
412  gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
413  "%s", msg.c_str());
414  ret = gtk_dialog_run (GTK_DIALOG (dialog));
415  gtk_widget_destroy (dialog);
416  if (ret == GTK_RESPONSE_YES)
417  YGUI::ui()->askSaveLogs();
418  }
419  else {
420  msg = _("Failed to create dependencies resolver testcase.\n"
421  "Please check disk space and permissions for:");
422  msg += " <tt>"; msg += dirname; msg += "</tt>";
423  errorMsg (msg.c_str());
424  }
425  }
426 }
427 
428 static void repoManager()
429 {
430  yuiMilestone() << "Closing PackageSelector with \"RepoManager\"" << std::endl;
431  YGUI::ui()->sendEvent( new YMenuEvent( "repo_mgr" ) );
432 }
433 
434 static void onlineUpdateConfiguration()
435 {
436  yuiMilestone() << "Closing PackageSelector with \"OnlineUpdateConfiguration\"" << std::endl;
437  YGUI::ui()->sendEvent( new YMenuEvent( "online_update_configuration" ) );
438 }
439 
440 static void manualResolvePackageDependencies()
441 { Ypp::runSolver (true); }
442 
443 // check menu item flags
444 
446  CheckMenuFlag (GtkWidget *menu, const char *text) {
447  std::string str (YGUtils::mapKBAccel(text));
448  m_item = gtk_check_menu_item_new_with_mnemonic (str.c_str());
449  g_object_set_data_full (G_OBJECT (m_item), "this", this, destructor);
450  gtk_menu_shell_append (GTK_MENU_SHELL (menu), m_item);
451  }
452 
453  void init (Flags *flags) {
454  bool check = getZyppValue();
455 
456  const char *var = variable();
457  if (flags->hasKey (var)) {
458  bool c = flags->getBool (var);
459  if (c != check)
460  setZyppValue (c);
461  check = c;
462  }
463 
464  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (m_item), check);
465  g_signal_connect_after (G_OBJECT (m_item), "toggled", G_CALLBACK (toggled_cb), this);
466  }
467 
468  virtual const char *variable() = 0;
469  virtual bool getZyppValue() = 0;
470  virtual void setZyppValue (bool on) = 0;
471  virtual void runtimeSync() {}
472 
473  void writeFile (bool on) {
474  Flags flags;
475  flags.setBool (variable(), on);
476  }
477 
478  static void toggled_cb (GtkCheckMenuItem *item, CheckMenuFlag *pThis) {
479  bool on = gtk_check_menu_item_get_active (item);
480  pThis->setZyppValue (on);
481  pThis->runtimeSync();
482  pThis->writeFile (on);
483  }
484 
485  static void destructor (gpointer data) {
486  delete ((CheckMenuFlag *) data);
487  }
488 
489  GtkWidget *m_item;
490 };
491 
492 struct AutoCheckItem : public CheckMenuFlag {
493  AutoCheckItem (GtkWidget *menu, const char *text, Flags *flags)
494  : CheckMenuFlag (menu, text) { init (flags); }
495  virtual const char *variable() { return "auto-check"; }
496  virtual bool getZyppValue() { return Ypp::isSolverEnabled(); }
497  virtual void setZyppValue (bool on) { Ypp::setEnableSolver (on); }
498 };
499 
501  ShowDevelCheckItem (GtkWidget *menu, const char *text, Flags *flags)
502  : CheckMenuFlag (menu, text) { init (flags); }
503  virtual const char *variable() { return "show-devel"; }
504  virtual bool getZyppValue() { return true; }
505  virtual void setZyppValue (bool on)
506  { YGPackageSelector::get()->filterPkgSuffix ("-devel", !on); }
507 };
508 
510  ShowDebugCheckItem (GtkWidget *menu, const char *text, Flags *flags)
511  : CheckMenuFlag (menu, text) { init (flags); }
512  virtual const char *variable() { return "show-debug"; }
513  virtual bool getZyppValue() { return true; }
514  virtual void setZyppValue (bool on) {
515  YGPackageSelector::get()->filterPkgSuffix ("-debuginfo", !on);
516  YGPackageSelector::get()->filterPkgSuffix ("-debugsource", !on);
517  }
518 };
519 
521  SystemVerificationCheckItem (GtkWidget *menu, const char *text, Flags *flags)
522  : CheckMenuFlag (menu, text) { init (flags); }
523  virtual const char *variable() { return "system-verification"; }
524  virtual bool getZyppValue() {
525  return zypp::getZYpp()->resolver()->systemVerification();
526  }
527  virtual void setZyppValue (bool on) {
528  zypp::getZYpp()->resolver()->setSystemVerification (on);
529  }
530  virtual void runtimeSync() {}
531 };
532 
534  IgnoreAlreadyRecommendedCheckItem (GtkWidget *menu, const char *text, Flags *flags)
535  : CheckMenuFlag (menu, text) { init (flags); }
536  virtual const char *variable() { return "ignore-already-recommended"; }
537  virtual bool getZyppValue() {
538  return zypp::getZYpp()->resolver()->ignoreAlreadyRecommended();
539  }
540  virtual void setZyppValue (bool on) {
541  zypp::getZYpp()->resolver()->setIgnoreAlreadyRecommended(on);
542  }
543  virtual void runtimeSync() { Ypp::runSolver(); }
544 };
545 
546 #if ZYPP_VERSION > 6031004
547 
548 struct CleanupDepsCheckItem : public CheckMenuFlag {
549  CleanupDepsCheckItem (GtkWidget *menu, const char *text, Flags *flags)
550  : CheckMenuFlag (menu, text) { init (flags); }
551  virtual const char *variable() { return "cleanup-deps"; }
552  virtual bool getZyppValue() {
553  return zypp::getZYpp()->resolver()->cleandepsOnRemove();
554  }
555  virtual void setZyppValue (bool on) {
556  zypp::getZYpp()->resolver()->setCleandepsOnRemove( on );
557  }
558  virtual void runtimeSync() { Ypp::runSolver(); }
559 };
560 
561 struct AllowVendorChangeCheckItem : public CheckMenuFlag {
562  AllowVendorChangeCheckItem (GtkWidget *menu, const char *text, Flags *flags)
563  : CheckMenuFlag (menu, text) { init (flags); }
564  virtual const char *variable() { return "allow-vendor-change"; }
565  virtual bool getZyppValue() {
566  return zypp::getZYpp()->resolver()->allowVendorChange();
567  }
568  virtual void setZyppValue (bool on) {
569  zypp::getZYpp()->resolver()->setAllowVendorChange( on );
570  }
571  virtual void runtimeSync() { Ypp::runSolver(); }
572 };
573 
574 #endif
575 
576 static void installSubPkgs (std::string suffix)
577 {
578  // Find all matching packages and put them into a QMap
579 
580  std::map<std::string, ZyppSel> subPkgs;
581 
582  for ( ZyppPoolIterator it = zyppPkgBegin(); it != zyppPkgEnd(); ++it )
583  {
584  std::string name = (*it)->name();
585 
586  if (YGUtils::endsWith (name, suffix))
587  {
588  subPkgs[ name ] = *it;
589  yuiDebug() << "Found subpackage: " << name << std::endl;
590  }
591  }
592 
593 
594  // Now go through all packages and look if there is a corresponding subpackage in the QMap
595 
596  for ( ZyppPoolIterator it = zyppPkgBegin(); it != zyppPkgEnd(); ++it )
597  {
598  std::string name = (*it)->name();
599 
600  std::string subPkgName( name + suffix );
601  if ( subPkgs.find( subPkgName ) != subPkgs.end() )
602  {
603  ZyppSel subPkg = subPkgs[ subPkgName ];
604 
605  switch ( (*it)->status() )
606  {
607  case S_AutoDel:
608  case S_NoInst:
609  case S_Protected:
610  case S_Taboo:
611  case S_Del:
612  // Don't install the subpackage
613  yuiMilestone() << "Ignoring unwanted subpackage " << subPkgName << std::endl;
614  break;
615 
616  case S_AutoInstall:
617  case S_Install:
618  case S_KeepInstalled:
619 
620  // Install the subpackage, but don't try to update it
621 
622  if ( ! subPkg->installedObj() )
623  {
624  subPkg->setStatus( S_Install );
625  yuiMilestone() << "Installing subpackage " << subPkgName << std::endl;
626  }
627  break;
628 
629 
630  case S_Update:
631  case S_AutoUpdate:
632 
633  // Install or update the subpackage
634 
635  if ( ! subPkg->installedObj() )
636  {
637  subPkg->setStatus( S_Install );
638  yuiMilestone() << "Installing subpackage " << subPkgName << std::endl;
639  }
640  else
641  {
642  subPkg->setStatus( S_Update );
643  yuiMilestone() << "Updating subpackage " << subPkgName << std::endl;
644  }
645  break;
646 
647  // Intentionally omitting 'default' branch so the compiler can
648  // catch unhandled enum states
649  }
650  }
651  }
652 
653  Ypp::runSolver();
654  YGPackageSelector::get()->popupChanges();
655 }
656 
657 static void install_all_devel_pkgs_cb()
658 { installSubPkgs ("-devel"); }
659 
660 static void install_all_debug_info_pkgs_cb()
661 { installSubPkgs ("-debuginfo"); }
662 
663 static void install_all_debug_source_pkgs_cb()
664 { installSubPkgs ("-debugsource"); }
665 
666 static void show_pkg_changes_cb()
667 { YGPackageSelector::get()->popupChanges(); }
668 
669 static void show_log_changes_cb()
670 { YGPackageSelector::get()->showHistoryDialog(); }
671 
672 #ifdef HAS_VESTIGIAL_DIALOG
673 static void show_vestigial_packages_cb()
674 { YGPackageSelector::get()->showVestigialDialog(); }
675 #endif
676 
677 static void reset_ignored_dependency_conflicts_cb()
678 { zypp::getZYpp()->resolver()->undo(); }
679 
680 #include "ygtkpkgproductdialog.h"
681 
682 static void show_products_cb()
683 {
684  YGtkPkgProductDialog dialog;
685  dialog.popup();
686 }
687 
688 static void accept_item_cb (GtkMenuItem *item, YGPackageSelector *selector)
689 { selector->apply(); }
690 
691 static void reject_item_cb (GtkMenuItem *item, YGPackageSelector *selector)
692 { selector->cancel(); }
693 
694 YGtkPkgMenuBar::YGtkPkgMenuBar()
695 {
696  YGPackageSelector *selector = YGPackageSelector::get();
697  m_menu = gtk_menu_bar_new();
698  Flags flags;
699 
700  GtkWidget *menu_bar = m_menu, *item, *submenu;
701  item = append_menu_item (menu_bar, _("F&ile"), NULL, NULL, NULL);
702  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), (submenu = gtk_menu_new()));
703  append_menu_item (submenu, _("&Import..."), NULL,
704  G_CALLBACK (import_file_cb), this);
705  append_menu_item (submenu, _("&Export..."), NULL,
706  G_CALLBACK (export_file_cb), this);
707  append_menu_item (submenu, NULL, NULL, NULL, NULL);
708  append_menu_item (submenu, NULL, GTK_STOCK_APPLY, G_CALLBACK (accept_item_cb), selector);
709  append_menu_item (submenu, NULL, GTK_STOCK_QUIT, G_CALLBACK (reject_item_cb), selector);
710  if (selector->repoMgrEnabled()) {
711  item = append_menu_item (menu_bar, _("&Configuration"), NULL, NULL, NULL);
712  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), (submenu = gtk_menu_new()));
713  append_menu_item (submenu, _("&Repositories..."), NULL,
714  G_CALLBACK (repoManager), this);
715  if (selector->onlineUpdateMode())
716  append_menu_item (submenu, _("&Online Update..."), NULL,
717  G_CALLBACK (onlineUpdateConfiguration), this);
718  }
719  item = append_menu_item (menu_bar, _("&Dependencies"), NULL, NULL, NULL);
720  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), (submenu = gtk_menu_new()));
721  append_menu_item (submenu, _("&Check Now"), NULL,
722  G_CALLBACK (manualResolvePackageDependencies), this);
723  new AutoCheckItem (submenu, _("&Autocheck"), &flags);
724 
725  if (!selector->onlineUpdateMode()) {
726  item = append_menu_item (menu_bar, _("&Options"), NULL, NULL, NULL);
727  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), (submenu = gtk_menu_new()));
728  // Translators: don't translate the "-devel"
729  new ShowDevelCheckItem (submenu, _("Show -de&vel Packages"), &flags);
730  // Translators: don't translate the "-debuginfo/-debugsource" part
731  new ShowDebugCheckItem (submenu, _("Show -&debuginfo/-debugsource Packages"), &flags);
732  new SystemVerificationCheckItem (submenu, _("&System Verification Mode"), &flags);
733  new IgnoreAlreadyRecommendedCheckItem (submenu, _("&Ignore recommended packages for already installed packages"), &flags);
734 
735 #if ZYPP_VERSION > 6031004
736  new CleanupDepsCheckItem (submenu, _("&Cleanup when deleting packages"), &flags);
737  new AllowVendorChangeCheckItem (submenu, _("&Allow vendor change"), &flags);
738 #endif
739  }
740 
741  item = append_menu_item (menu_bar, _("E&xtras"), NULL, NULL, NULL);
742  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), (submenu = gtk_menu_new()));
743  append_menu_item (submenu, _("Show &Products"), NULL,
744  G_CALLBACK (show_products_cb), this);
745  append_menu_item (submenu, _("Show &Changes"), NULL,
746  G_CALLBACK (show_pkg_changes_cb), this);
747  if (!selector->onlineUpdateMode()) {
748  append_menu_item (submenu, _("Show &History"), NULL,
749  G_CALLBACK (show_log_changes_cb), this);
750 #ifdef HAS_VESTIGIAL_DIALOG
751  append_menu_item (submenu, _("Show &Unneeded Dependencies"), NULL,
752  G_CALLBACK (show_vestigial_packages_cb), this);
753 #endif
754  }
755  append_menu_item (submenu, NULL, NULL, NULL, NULL);
756  // Translators: keep "-_devel" untranslated
757  append_menu_item (submenu, _("Install All Matching -&devel Packages"), NULL,
758  G_CALLBACK (install_all_devel_pkgs_cb), this);
759  // Translators: keep "-debug-_info" untranslated
760  append_menu_item (submenu, _("Install All Matching -debug-&info Packages"), NULL,
761  G_CALLBACK (install_all_debug_info_pkgs_cb), this);
762  // Translators: keep "-debug-_source" untranslated
763  append_menu_item (submenu, _("Install All Matching -debug-&source Packages"), NULL,
764  G_CALLBACK (install_all_debug_source_pkgs_cb), this);
765  append_menu_item (submenu, NULL, NULL, NULL, NULL);
766  append_menu_item (submenu, _("Generate Dependencies Resolver &Testcase"), NULL,
767  G_CALLBACK (create_solver_testcase_cb), this);
768  append_menu_item (submenu, _("Reset &Ignored Dependencies Conflicts"), NULL,
769  G_CALLBACK (reset_ignored_dependency_conflicts_cb), this);
770 
771  //** TEMP: work-around global-menubar-applet: see bug 595560
772  //** will call show_all() at YGPackageSelector.cc
773  //gtk_widget_show_all (m_menu);
774 }
775