libyui-qt-pkg  2.42.13
 All Classes Functions Variables Enumerations
YQPackageSelector.cc
1 /**************************************************************************
2 Copyright (C) 2000 - 2010 Novell, Inc.
3 All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19 **************************************************************************/
20 
21 
22 /*---------------------------------------------------------------------\
23 | |
24 | __ __ ____ _____ ____ |
25 | \ \ / /_ _/ ___|_ _|___ \ |
26 | \ V / _` \___ \ | | __) | |
27 | | | (_| |___) || | / __/ |
28 | |_|\__,_|____/ |_| |_____| |
29 | |
30 | core system |
31 | (C) SuSE GmbH |
32 \----------------------------------------------------------------------/
33 
34  File: YQPackageSelector.cc
35  See also: YQPackageSelectorHelp.cc
36 
37  Author: Stefan Hundhammer <sh@suse.de>
38 
39  Textdomain "qt-pkg"
40 
41  /-*/
42 
43 #define CHECK_DEPENDENCIES_ON_STARTUP 1
44 #define DEPENDENCY_FEEDBACK_IF_OK 1
45 #define AUTO_CHECK_DEPENDENCIES_DEFAULT true
46 #define ALWAYS_SHOW_PATCHES_VIEW_IF_PATCHES_AVAILABLE 0
47 #define GLOBAL_UPDATE_CONFIRMATION_THRESHOLD 20
48 #define ENABLE_SOURCE_RPMS 0
49 #define BRAINDEAD_LIB_NAMING_SCHEME 1
50 #define MARGIN 6 // around the widget
51 #define SPACING_BELOW_MENU_BAR 4
52 #define SPLITTER_HALF_SPACING 4
53 
54 
55 #include <fstream>
56 #include <boost/bind.hpp>
57 
58 #include <QHBoxLayout>
59 #include <QVBoxLayout>
60 #include <QAction>
61 #include <QShortcut>
62 #include <QApplication>
63 #include <QCheckBox>
64 #include <QDialog>
65 #include <QFileDialog>
66 #include <QLabel>
67 #include <QMap>
68 #include <QMenuBar>
69 #include <QMessageBox>
70 #include <QPushButton>
71 #include <QSplitter>
72 #include <QTabWidget>
73 #include <QTimer>
74 #include <QMenu>
75 #include <QSettings>
76 
77 #define YUILogComponent "qt-pkg"
78 #include "YUILog.h"
79 
80 #include "QY2LayoutUtils.h"
81 
82 #include "YQZypp.h"
83 #include "YQPackageSelector.h"
84 #include "YQPkgChangeLogView.h"
85 #include "YQPkgChangesDialog.h"
86 #include "YQPkgConflictDialog.h"
87 #include "YQPkgConflictList.h"
88 #include "YQPkgDependenciesView.h"
89 #include "YQPkgDescriptionView.h"
90 #include "YQPkgDiskUsageList.h"
91 #include "YQPkgDiskUsageWarningDialog.h"
92 #include "YQPkgFileListView.h"
93 #include "YQPkgFilterTab.h"
94 #include "YQPkgHistoryDialog.h"
95 #include "YQPkgLangList.h"
96 #include "YQPkgList.h"
97 #include "YQPkgPackageKitGroupsFilterView.h"
98 #include "YQPkgPatchFilterView.h"
99 #include "YQPkgPatchList.h"
100 #include "YQPkgPatternList.h"
101 #include "YQPkgProductDialog.h"
102 #include "YQPkgRepoFilterView.h"
103 #include "YQPkgRepoList.h"
104 #include "YQPkgRpmGroupTagsFilterView.h"
105 #include "YQPkgSearchFilterView.h"
106 #include "YQPkgStatusFilterView.h"
107 #include "YQPkgTechnicalDetailsView.h"
108 #include "YQPkgTextDialog.h"
109 #include "YQPkgUpdateProblemFilterView.h"
110 #include "YQPkgVersionsView.h"
111 
112 #include "zypp/SysContent.h"
113 #include "zypp/base/String.h"
114 
115 #include "QY2ComboTabWidget.h"
116 #include "YQDialog.h"
117 #include "YQApplication.h"
118 #include "utf8.h"
119 #include "YQUI.h"
120 #include "YEvent.h"
121 #include "YQi18n.h"
122 
123 
124 
125 using std::max;
126 using std::string;
127 using std::map;
128 using std::pair;
129 
130 #define DEFAULT_EXPORT_FILE_NAME "user-packages.xml"
131 #define FAST_SOLVER 1
132 
133 #define SETTINGS_DIR "YaST2"
134 
135 
136 
137 
138 YQPackageSelector::YQPackageSelector( YWidget * parent,
139  long modeFlags )
140  : YQPackageSelectorBase( parent, modeFlags )
141 {
142  _showChangesDialog = true;
143  _autoDependenciesAction = 0;
144  _detailsViews = 0;
145  _filters = 0;
146  _langList = 0;
147  _packageKitGroupsFilterView = 0;
148  _patchFilterView = 0;
149  _patchList = 0;
150  _patternList = 0;
151  _pkgChangeLogView = 0;
152  _pkgDependenciesView = 0;
153  _pkgDescriptionView = 0;
154  _pkgFileListView = 0;
155  _pkgList = 0;
156  _pkgTechnicalDetailsView = 0;
157  _pkgVersionsView = 0;
158  _repoFilterView = 0;
159  _rpmGroupTagsFilterView = 0;
160  _searchFilterView = 0;
161  _statusFilterView = 0;
162  _updateProblemFilterView = 0;
163  _excludeDevelPkgs = 0;
164  _excludeDebugInfoPkgs = 0;
165 
166  yuiMilestone() << "This is libyui-qt-pkg " << VERSION << std::endl;
167 
168  if ( onlineUpdateMode() ) yuiMilestone() << "Online update mode" << std::endl;
169  if ( updateMode() ) yuiMilestone() << "Update mode" << std::endl;
170 
171  basicLayout();
172  addMenus(); // Only after all widgets are created!
173  loadSettings(); // Only after menus are created!
174  makeConnections();
175  emit loadData();
176 
177  _filters->loadSettings();
178  bool pagesRestored = _filters->tabCount() > 0;
179 
180  if ( _pkgList )
181  _pkgList->clear();
182 
183  if ( ! pagesRestored )
184  {
185  yuiDebug() << "No page configuration saved, using fallbacks" << std::endl;
186 
187  //
188  // Add a number of default tabs in the desired order
189  //
190 
191  if ( _searchFilterView ) _filters->showPage( _searchFilterView );
192 
193  if ( ! searchMode() && ! summaryMode()
194  && _patternList ) _filters->showPage( _patternList );
195  else if ( _rpmGroupTagsFilterView ) _filters->showPage( _rpmGroupTagsFilterView );
196 
197  if ( _statusFilterView ) _filters->showPage( _statusFilterView );
198  }
199 
200 
201  //
202  // Move the desired tab to the foreground
203  //
204 
205  if ( _patchFilterView && onlineUpdateMode() )
206  {
207  if ( _patchFilterView && _patchList )
208  {
209  _filters->showPage( _patchFilterView );
210  _patchList->filter();
211  }
212  }
213  else if ( _repoFilterView && repoMode() )
214  {
216  {
217  _filters->showPage( _repoFilterView );
218  _repoFilterView->filter();
219  }
220  }
221  else if ( _updateProblemFilterView )
222  {
223  _filters->showPage( _updateProblemFilterView );
224  _updateProblemFilterView->filter();
225  }
226  else if ( searchMode() && _searchFilterView )
227  {
228  _filters->showPage( _searchFilterView );
229  _searchFilterView->filter();
230  QTimer::singleShot( 0, _searchFilterView, SLOT( setFocus() ) );
231  }
232  else if ( summaryMode() && _statusFilterView )
233  {
234  _filters->showPage( _statusFilterView );
235  _statusFilterView->filter();
236  _pkgList->selectNextItem();
237  }
238  else if ( _patternList )
239  {
240  _filters->showPage( _patternList );
241  _patternList->filter();
242  }
243 
244 
245  if ( _filters->diskUsageList() )
246  _filters->diskUsageList()->updateDiskUsage();
247 
248  yuiMilestone() << "PackageSelector init done" << std::endl;
249 
250 
251 #if CHECK_DEPENDENCIES_ON_STARTUP
252 
253  if ( ! testMode() )
254  {
255  // Fire up the first dependency check in the main loop.
256  // Don't do this right away - wait until all initializations are finished.
257  QTimer::singleShot( 0, this, SLOT( resolveDependencies() ) );
258 
259  }
260 #endif
261 
262 }
263 
264 
265 std::string
266 YQPackageSelector::iconPath( const std::string &name, int size )
267 {
268  // FIXME
269  #define PREFIX "/usr/"
270  return zypp::str::form("%s/share/icons/hicolor/%dx%d/apps/%s.png",
271  PREFIX, size, size, name.c_str() );
272 }
273 
274 
275 void
276 YQPackageSelector::basicLayout()
277 {
278  QVBoxLayout *layout = new QVBoxLayout();
279  setLayout( layout );
280  layout->setContentsMargins( MARGIN, // left
281  0, // top
282  MARGIN, // right
283  MARGIN ); // bottom
284  layout->setSpacing( SPACING_BELOW_MENU_BAR );
285  layoutMenuBar( this );
286 
287  QString settingsName = "YQPackageSelector";
288 
289  if ( onlineUpdateMode() ) settingsName = "YQOnlineUpdate";
290  if ( updateMode() ) settingsName = "YQSystemUpdate";
291 
292  _filters = new YQPkgFilterTab( this, settingsName );
293  YUI_CHECK_NEW( _filters );
294 
295  layout->addWidget( _filters );
296  layoutFilters( this );
297  layoutRightPane( _filters->rightPane() );
298 }
299 
300 
301 void
302 YQPackageSelector::layoutFilters( QWidget *parent )
303 {
304  //
305  // Update problem view
306  //
307 
308  if ( updateMode() )
309  {
311  || testMode() )
312  {
313  _updateProblemFilterView = new YQPkgUpdateProblemFilterView( parent );
314  YUI_CHECK_NEW( _updateProblemFilterView );
315  _filters->addPage( _( "&Update Problems" ), _updateProblemFilterView, "update_problems" );
316  }
317  }
318 
319 
320  //
321  // Patches view
322  //
323 
324  if ( onlineUpdateMode()
325 #if ALWAYS_SHOW_PATCHES_VIEW_IF_PATCHES_AVAILABLE
326  || ! zyppPool().empty<zypp::Patch>()
327 #endif
328  )
329  {
331  }
332 
333 
334  //
335  // Patterns view
336  //
337 
338  if ( ! zyppPool().empty<zypp::Pattern>() || testMode() )
339  {
340  _patternList = new YQPkgPatternList( parent, true );
341  YUI_CHECK_NEW( _patternList );
342  _filters->addPage( _( "Patter&ns" ), _patternList, "patterns" );
343 
344  connect( _patternList, SIGNAL( statusChanged() ),
345  this, SLOT ( autoResolveDependencies() ) );
346 
347  connect( this, SIGNAL( refresh() ),
348  _patternList, SLOT ( updateItemStates() ) );
349 
350  if ( _pkgConflictDialog )
351  {
352  connect( _pkgConflictDialog, SIGNAL( updatePackages() ),
353  _patternList, SLOT ( updateItemStates() ) );
354  }
355  }
356 
357 
358  //
359  // PackageKit group view
360  //
361 
362  _packageKitGroupsFilterView = new YQPkgPackageKitGroupsFilterView( parent );
363  YUI_CHECK_NEW( _packageKitGroupsFilterView );
364  _filters->addPage( _( "Package &Groups" ), _packageKitGroupsFilterView, "package_groups" );
365 
366  connect( this, SIGNAL( loadData() ),
367  _packageKitGroupsFilterView, SLOT ( filter() ) );
368 
369 
370  //
371  // RPM group tags view
372  //
373 
374  _rpmGroupTagsFilterView = new YQPkgRpmGroupTagsFilterView( parent );
375  YUI_CHECK_NEW( _rpmGroupTagsFilterView );
376  _filters->addPage( _( "&RPM Groups" ), _rpmGroupTagsFilterView, "rpm_groups" );
377 
378  connect( this, SIGNAL( loadData() ),
379  _rpmGroupTagsFilterView, SLOT ( filter() ) );
380 
381 
382  //
383  // Languages view
384  //
385 
386  _langList = new YQPkgLangList( parent );
387  YUI_CHECK_NEW( _langList );
388 
389  _filters->addPage( _( "&Languages" ), _langList, "languages" );
390  _langList->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) ); // hor/vert
391 
392  connect( _langList, SIGNAL( statusChanged() ),
393  this, SLOT ( autoResolveDependencies() ) );
394 
395  connect( this, SIGNAL( refresh() ),
396  _langList, SLOT ( updateItemStates() ) );
397 
398 
399  //
400  // Repository view
401  //
402 
403  _repoFilterView = new YQPkgRepoFilterView( parent );
404  YUI_CHECK_NEW( _repoFilterView );
405  _filters->addPage( _( "&Repositories" ), _repoFilterView, "repos" );
406  // hide and show the upgrade label when tabs change, or when the user
407  // selects repositories
408  connect(_repoFilterView, SIGNAL(filterStart()), this, SLOT(updateRepositoryUpgradeLabel()));
409  connect(this, SIGNAL(refresh()), this, SLOT(updateRepositoryUpgradeLabel()));
410  connect(_filters, SIGNAL(currentChanged(QWidget *)), this, SLOT(updateRepositoryUpgradeLabel()));
411 
412  //
413  // Package search view
414  //
415 
416  _searchFilterView = new YQPkgSearchFilterView( parent );
417  YUI_CHECK_NEW( _searchFilterView );
418  _filters->addPage( _( "S&earch" ), _searchFilterView, "search" );
419 
420 
421 
422 #if 0
423  // DEBUG
424 
425  _filters->addPage( _( "&Keywords" ), new QLabel( "Keywords\nfilter\n\nfor future use", this ), "keywords" );
426 #endif
427 
428  //
429  // Status change view
430  //
431 
432  _statusFilterView = new YQPkgStatusFilterView( parent );
433  YUI_CHECK_NEW( _statusFilterView );
434  _filters->addPage( _( "&Installation Summary" ), _statusFilterView, "inst_summary" );
435 }
436 
437 
438 YQPackageSelector::~YQPackageSelector()
439 {
440  saveSettings();
441 }
442 
443 QWidget *
444 YQPackageSelector::layoutRightPane( QWidget *parent )
445 {
446  QVBoxLayout *layout = new QVBoxLayout( parent );
447  YUI_CHECK_NEW( layout );
448  layout->setContentsMargins( SPLITTER_HALF_SPACING, // left
449  0, // top
450  0, // right
451  0 ); // bottom
452 
453  QSplitter * splitter = new QSplitter( Qt::Vertical, parent );
454  YUI_CHECK_NEW( splitter );
455  layout->addWidget(splitter);
456 
457  layoutPkgList( splitter );
458  layoutDetailsViews( splitter );
459  layoutButtons( parent );
460 
461  return parent;
462 }
463 
464 
465 void
466 YQPackageSelector::layoutPkgList( QWidget *parent )
467 {
468  // this is made visible when activating the repository
469  // filter
470  QWidget *_notificationsContainer = new QWidget(parent);
471  QVBoxLayout *layout = new QVBoxLayout(_notificationsContainer);
472 
473  _repoUpgradingLabel = new QLabel(_notificationsContainer);
474  _repoUpgradingLabel->setTextFormat(Qt::RichText);
475  _repoUpgradingLabel->setWordWrap(true);
476  _repoUpgradingLabel->setVisible(false);
477 
478  _repoUpgradeLabel = new QLabel(_notificationsContainer);
479  _repoUpgradeLabel->setTextFormat(Qt::RichText);
480  _repoUpgradeLabel->setWordWrap(true);
481  _repoUpgradeLabel->setVisible(false);
482  _repoUpgradeLabel->setObjectName( "RepoUpgradeLabel");
483 
484  layout->addWidget(_repoUpgradingLabel);
485  layout->addWidget(_repoUpgradeLabel);
486 
487  // if the user clicks on a link on the label, we have to check
488  // which repository upgrade job to add or remove, for that
489  // we will encode the links as repoupgradeadd://alias and
490  // repoupgraderemove:://alias
491  connect(_repoUpgradeLabel, SIGNAL(linkActivated(const QString &)), this, SLOT(slotRepoUpgradeLabelLinkClicked(const QString &)));
492  connect(_repoUpgradingLabel, SIGNAL(linkActivated(const QString &)), this, SLOT(slotRepoUpgradeLabelLinkClicked(const QString &)));
493 
495 
496  _pkgList= new YQPkgList( parent );
497  YUI_CHECK_NEW( _pkgList );
498 
499  connect( _pkgList, SIGNAL( statusChanged() ),
500  this, SLOT ( autoResolveDependencies() ) );
501 }
502 
503 void
504 YQPackageSelector::layoutDetailsViews( QWidget *parent )
505 {
506  bool haveInstalledPkgs = YQPkgList::haveInstalledPkgs();
507 
508 
509  _detailsViews = new QTabWidget( parent );
510  YUI_CHECK_NEW( _detailsViews );
511 
512  //
513  // Description
514  //
515 
516  _pkgDescriptionView = new YQPkgDescriptionView( _detailsViews, confirmUnsupported() );
517  YUI_CHECK_NEW( _pkgDescriptionView );
518 
519  _detailsViews->addTab( _pkgDescriptionView, _( "D&escription" ) );
520  _detailsViews->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); // hor/vert
521 
522  connect( _pkgList, SIGNAL( currentItemChanged ( ZyppSel ) ),
523  _pkgDescriptionView, SLOT ( showDetailsIfVisible( ZyppSel ) ) );
524 
525  //
526  // Technical details
527  //
528 
529  _pkgTechnicalDetailsView = new YQPkgTechnicalDetailsView( _detailsViews );
530  YUI_CHECK_NEW( _pkgTechnicalDetailsView );
531 
532  _detailsViews->addTab( _pkgTechnicalDetailsView, _( "&Technical Data" ) );
533 
534  connect( _pkgList, SIGNAL( currentItemChanged ( ZyppSel ) ),
535  _pkgTechnicalDetailsView, SLOT ( showDetailsIfVisible( ZyppSel ) ) );
536 
537 
538  //
539  // Dependencies
540  //
541 
542  _pkgDependenciesView = new YQPkgDependenciesView( _detailsViews );
543  YUI_CHECK_NEW( _pkgDependenciesView );
544 
545  _detailsViews->addTab( _pkgDependenciesView, _( "Dependencies" ) );
546  _detailsViews->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); // hor/vert
547 
548  connect( _pkgList, SIGNAL( currentItemChanged ( ZyppSel ) ),
549  _pkgDependenciesView, SLOT ( showDetailsIfVisible( ZyppSel ) ) );
550 
551 
552 
553  //
554  // Versions
555  //
556 
557  _pkgVersionsView = new YQPkgVersionsView( _detailsViews,
558  true ); // userCanSwitchVersions
559  YUI_CHECK_NEW( _pkgVersionsView );
560 
561  _detailsViews->addTab( _pkgVersionsView, _( "&Versions" ) );
562 
563  connect( _pkgList, SIGNAL( currentItemChanged ( ZyppSel ) ),
564  _pkgVersionsView, SLOT ( showDetailsIfVisible( ZyppSel ) ) );
565 
566  connect( _pkgList, SIGNAL( statusChanged() ),
567  _pkgVersionsView, SLOT ( slotRefreshDetails() ) );
568 
569 
570  //
571  // File List
572  //
573 
574  if ( haveInstalledPkgs ) // file list information is only available for installed pkgs
575  {
576  _pkgFileListView = new YQPkgFileListView( _detailsViews );
577  YUI_CHECK_NEW( _pkgFileListView );
578 
579  _detailsViews->addTab( _pkgFileListView, _( "File List" ) );
580  _detailsViews->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); // hor/vert
581 
582  connect( _pkgList, SIGNAL( currentItemChanged ( ZyppSel ) ),
583  _pkgFileListView, SLOT ( showDetailsIfVisible( ZyppSel ) ) );
584  }
585 
586 
587  //
588  // Change Log
589  //
590 
591  if ( haveInstalledPkgs ) // change log information is only available for installed pkgs
592  {
593  _pkgChangeLogView = new YQPkgChangeLogView( _detailsViews );
594  YUI_CHECK_NEW( _pkgChangeLogView );
595 
596  _detailsViews->addTab( _pkgChangeLogView, _( "Change Log" ) );
597  _detailsViews->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); // hor/vert
598 
599  connect( _pkgList, SIGNAL( currentItemChanged ( ZyppSel ) ),
600  _pkgChangeLogView, SLOT ( showDetailsIfVisible( ZyppSel ) ) );
601  }
602 }
603 
604 
605 void
606 YQPackageSelector::layoutButtons( QWidget *parent )
607 {
608  QWidget * button_box = new QWidget( parent );
609  YUI_CHECK_NEW( button_box );
610  parent->layout()->addWidget( button_box );
611 
612  QHBoxLayout * layout = new QHBoxLayout( button_box );
613  YUI_CHECK_NEW( layout );
614 
615  button_box->setLayout( layout );
616  layout->setContentsMargins( 2, // left
617  2, // top
618  2, // right
619  2 ); // bottom
620 
621  layout->addStretch();
622 
623  QPushButton * cancel_button = new QPushButton( _( "&Cancel" ), button_box );
624  YUI_CHECK_NEW( cancel_button );
625  layout->addWidget(cancel_button);
626 
627  cancel_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
628 
629  connect( cancel_button, SIGNAL( clicked() ),
630  this, SLOT ( reject() ) );
631 
632 
633  QPushButton * accept_button = new QPushButton( _( "&Accept" ), button_box );
634  YUI_CHECK_NEW( accept_button );
635  layout->addWidget(accept_button);
636  accept_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
637 
638  connect( accept_button, SIGNAL( clicked() ),
639  this, SLOT ( accept() ) );
640 
641  button_box->setFixedHeight( button_box->sizeHint().height() );
642 }
643 
644 
645 void
646 YQPackageSelector::layoutMenuBar( QWidget *parent )
647 {
648  _menuBar = new QMenuBar( parent );
649  YUI_CHECK_NEW( _menuBar );
650  parent->layout()->addWidget(_menuBar);
651 
652  _fileMenu = 0;
653  _optionsMenu = 0;
654  _pkgMenu = 0;
655  _patchMenu = 0;
656  _extrasMenu = 0;
657  _configMenu = 0;
658  _dependencyMenu = 0;
659  _helpMenu = 0;
660 
661 }
662 
663 
664 void
666 {
667 
668 
669  //
670  // File menu
671  //
672 
673  _fileMenu = new QMenu( _menuBar );
674  YUI_CHECK_NEW( _fileMenu );
675  QAction * action = _menuBar->addMenu( _fileMenu );
676  action->setText( _( "&File" ));
677 
678  _fileMenu->addAction( _( "&Import..." ), this, SLOT( pkgImport() ) );
679  _fileMenu->addAction( _( "&Export..." ), this, SLOT( pkgExport() ) );
680 
681  _fileMenu->addSeparator();
682 
683  _fileMenu->addAction( _( "E&xit -- Discard Changes" ), this, SLOT( reject() ) );
684  _fileMenu->addAction( _( "&Quit -- Save Changes" ), this, SLOT( accept() ) );
685 
686 
687  if ( _pkgList )
688  {
689  //
690  // Package menu
691  //
692 
693  _pkgMenu = new QMenu( _menuBar );
694  YUI_CHECK_NEW( _pkgMenu );
695  action = _menuBar->addMenu( _pkgMenu );
696  action->setText(_( "&Package" ));
697 
698  _pkgMenu->addAction(_pkgList->actionSetCurrentInstall);
699  _pkgMenu->addAction(_pkgList->actionSetCurrentDontInstall);
700  _pkgMenu->addAction(_pkgList->actionSetCurrentKeepInstalled);
701  _pkgMenu->addAction(_pkgList->actionSetCurrentDelete);
702  _pkgMenu->addAction(_pkgList->actionSetCurrentUpdate);
703  _pkgMenu->addAction(_pkgList->actionSetCurrentUpdateForce);
704  _pkgMenu->addAction(_pkgList->actionSetCurrentTaboo);
705  _pkgMenu->addAction(_pkgList->actionShowCurrentSolverInfo);
706 
707 #if ENABLE_SOURCE_RPMS
708  _pkgMenu->addSeparator();
709 
710  _pkgMenu->addAction(_pkgList->actionInstallSourceRpm);
711  _pkgMenu->addAction(_pkgList->actionDontInstallSourceRpm);
712 #endif
713 
714  _pkgMenu->addSeparator();
715  QMenu * submenu = _pkgList->addAllInListSubMenu( _pkgMenu );
716  YUI_CHECK_NEW( submenu );
717 
718 #if ENABLE_SOURCE_RPMS
719  submenu->addSeparator();
720 
721  _pkgMenu->addAction(_pkgList->actionInstallListSourceRpms);
722  _pkgMenu->addAction(_pkgList->actionDontInstallListSourceRpms);
723 #endif
724 
725  //
726  // Submenu for all packages
727  //
728 
729  submenu = new QMenu( _pkgMenu );
730  YUI_CHECK_NEW( submenu );
731 
732  // Translators: Unlike the "all in this list" submenu, this submenu
733  // refers to all packages globally, not only to those that are
734  // currently visible in the packages list.
735  action = _pkgMenu->addMenu( submenu );
736  action->setText(_( "All Packages" ));
737 
738  submenu->addAction( _( "Update if newer version available" ),
739  this, SLOT( globalUpdatePkg() ) );
740 
741  submenu->addAction( _( "Update unconditionally" ),
742  this, SLOT( globalUpdatePkgForce() ) );
743  }
744 
745 
746  if ( _patchList )
747  {
748  //
749  // Patch menu
750  //
751 
752  _patchMenu = new QMenu( _menuBar );
753  YUI_CHECK_NEW( _patchMenu );
754  action = _menuBar->addMenu( _patchMenu );
755  action->setText(_( "&Patch" ));
756 
757  _patchMenu->addAction(_patchList->actionSetCurrentInstall);
758  _patchMenu->addAction(_patchList->actionSetCurrentDontInstall);
759  _patchMenu->addAction(_patchList->actionSetCurrentKeepInstalled);
760 
761 #if ENABLE_DELETING_PATCHES
762  _patchMenu->addAction(_patchList->actionSetCurrentDelete);
763 #endif
764  _patchMenu->addAction(_patchList->actionSetCurrentUpdate);
765  _patchMenu->addAction(_patchList->actionSetCurrentUpdateForce);
766  _patchMenu->addAction(_patchList->actionSetCurrentTaboo);
767 
768  _patchMenu->addSeparator();
769  _patchList->addAllInListSubMenu( _patchMenu );
770  }
771 
772 
773  //
774  // Configuration menu
775  //
776 
777  if ( repoMgrEnabled() )
778  {
779  _configMenu = new QMenu( _menuBar );
780  YUI_CHECK_NEW( _configMenu );
781  action = _menuBar->addMenu( _configMenu );
782  action->setText(_( "Confi&guration" ));
783  _configMenu->addAction( _( "&Repositories..." ), this, SLOT( repoManager() ), Qt::CTRL + Qt::Key_R );
784  _configMenu->addAction( _( "&Online Update..." ), this, SLOT( onlineUpdateConfiguration() ), Qt::CTRL + Qt::Key_O );
785  }
786 
787  //
788  // Dependency menu
789  //
790 
791  _dependencyMenu = new QMenu( _menuBar );
792  YUI_CHECK_NEW( _dependencyMenu );
793  action = _menuBar->addMenu( _dependencyMenu );
794  action->setText(_( "&Dependencies" ));
795 
796  _dependencyMenu->addAction( _( "&Check Now" ), this, SLOT( manualResolvePackageDependencies() ) );
797  _autoDependenciesAction = new QAction( _( "&Autocheck" ), this );
798  _autoDependenciesAction->setCheckable( true );
799  _dependencyMenu->addAction( _autoDependenciesAction );
800 
801 
802  //
803  // View menu
804  //
805 
806  _optionsMenu = new QMenu( _menuBar );
807  YUI_CHECK_NEW( _optionsMenu );
808  action = _menuBar->addMenu( _optionsMenu );
809  // Translators: Menu for view options (Use a noun, not a verb!)
810  action->setText(_( "&Options" ));
811 
812  // Translators: This is about packages ending in "-devel", so don't translate that "-devel"!
813  _showDevelAction = _optionsMenu->addAction( _( "Show -de&vel Packages" ),
814  this, SLOT( pkgExcludeDevelChanged( bool ) ), Qt::Key_F7 );
815  _showDevelAction->setCheckable(true);
816 
817  _excludeDevelPkgs = new YQPkgObjList::ExcludeRule( _pkgList, QRegExp( ".*(\\d+bit)?-devel(-\\d+bit)?$" ), _pkgList->nameCol() );
818  YUI_CHECK_NEW( _excludeDevelPkgs );
819  _excludeDevelPkgs->enable( false );
820 
821  // Translators: This is about packages ending in "-debuginfo", so don't translate that "-debuginfo"!
822  _showDebugAction = _optionsMenu->addAction( _( "Show -&debuginfo/-debugsource Packages" ),
823  this, SLOT( pkgExcludeDebugChanged( bool ) ), Qt::Key_F8 );
824  _showDebugAction->setCheckable(true);
825  _excludeDebugInfoPkgs = new YQPkgObjList::ExcludeRule( _pkgList, QRegExp( ".*(-\\d+bit)?-(debuginfo|debugsource)(-32bit)?$" ), _pkgList->nameCol() );
826  YUI_CHECK_NEW( _excludeDebugInfoPkgs );
827  _excludeDebugInfoPkgs->enable( false );
828 
829 
830  _verifySystemModeAction = _optionsMenu->addAction( _( "&System Verification Mode" ),
831  this, SLOT( pkgVerifySytemModeChanged( bool ) ) );
832  _verifySystemModeAction->setCheckable(true);
833 
834 
835  _ignoreAlreadyRecommendAction = _optionsMenu->addAction( _( "&Ignore Recommended Packages for Already Installed Packages" ),
836  this, SLOT( pkgIgnoreAlreadyRecommendedChanged( bool ) ) );
837  _ignoreAlreadyRecommendAction->setCheckable(true);
838 
839 
840 
841  _cleanDepsOnRemoveAction = _optionsMenu->addAction( _( "&Cleanup when deleting packages" ),
842  this, SLOT( pkgCleanDepsOnRemoveChanged( bool ) ) );
843  _cleanDepsOnRemoveAction->setCheckable(true);
844 
845  _allowVendorChangeAction = _optionsMenu->addAction( _( "&Allow vendor change" ),
846  this, SLOT( pkgAllowVendorChangeChanged( bool ) ) );
847  _allowVendorChangeAction->setCheckable(true);
848 
849 
850 
851  //
852  // Extras menu
853  //
854 
855  _extrasMenu = new QMenu( _menuBar );
856  YUI_CHECK_NEW( _extrasMenu );
857  action = _menuBar->addMenu( _extrasMenu );
858  action->setText(_( "E&xtras" ));
859 
860  _extrasMenu->addAction( _( "Show &Products" ), this, SLOT( showProducts() ) );
861  _extrasMenu->addAction( _( "Show P&ackage Changes" ), this, SLOT( showAutoPkgList() ), Qt::CTRL + Qt::Key_A );
862  _extrasMenu->addAction( _( "Show &History" ), this, SLOT( showHistory() ) );
863 
864  _extrasMenu->addSeparator();
865 
866 #if BRAINDEAD_LIB_NAMING_SCHEME
867  // See bug #434042: libcddb2 vs. libcddb-devel
868 #else
869  // Translators: This is about packages ending in "-devel", so don't translate that "-devel"!
870  _extrasMenu->addAction( _( "Install All Matching -&devel Packages" ), this, SLOT( installDevelPkgs() ) );
871 #endif
872 
873  // Translators: This is about packages ending in "-debuginfo", so don't translate that "-debuginfo"!
874  _extrasMenu->addAction( _( "Install All Matching -de&buginfo Packages" ), this, SLOT( installDebugInfoPkgs() ) );
875 
876  // Translators: This is about packages ending in "-debugsource", so don't translate that "-debugsource"!
877  _extrasMenu->addAction( _( "Install All Matching -debug&source Packages" ), this, SLOT( installDebugSourcePkgs() ) );
878 
879  _extrasMenu->addSeparator();
880 
881  if ( _pkgConflictDialog )
882  _extrasMenu->addAction( _( "Generate Dependency Resolver &Test Case" ),
883  _pkgConflictDialog, SLOT( askCreateSolverTestCase() ) );
884 
885  if ( _actionResetIgnoredDependencyProblems )
886  _extrasMenu->addAction(_actionResetIgnoredDependencyProblems);
887 
888 #ifdef FIXME
889  if ( _patchList )
890  _extrasMenu->addAction(_patchList->actionShowRawPatchInfo);
891 #endif
892 
893 
894  //
895  // Help menu
896  //
897 
898  _helpMenu = new QMenu( _menuBar );
899  YUI_CHECK_NEW( _helpMenu );
900  _menuBar->addSeparator();
901  action = _menuBar->addMenu( _helpMenu );
902  action->setText(_( "&Help" ));
903 
904  // Note: The help functions and their texts are moved out
905  // to a separate source file YQPackageSelectorHelp.cc
906 
907  // Menu entry for help overview
908  _helpMenu->addAction( _( "&Overview" ), this, SLOT( help() ), Qt::Key_F1 );
909 
910  // Menu entry for help about used symbols ( icons )
911  _helpMenu->addAction( _( "&Symbols" ), this, SLOT( symbolHelp() ), Qt::SHIFT + Qt::Key_F1 );
912 
913  // Menu entry for keyboard help
914  _helpMenu->addAction( _( "&Keys" ), this, SLOT( keyboardHelp() ) );
915 }
916 
917 
918 void
920  QWidget * pkgList,
921  bool hasUpdateSignal )
922 {
923  if ( ! filter ) return;
924  if ( ! pkgList ) return;
925 
926  if ( _filters )
927  {
928  connect( _filters, SIGNAL( currentChanged(QWidget *) ),
929  filter, SLOT ( filterIfVisible() ) );
930  }
931 
932  connect( this, SIGNAL( refresh() ),
933  filter, SLOT ( filterIfVisible() ) );
934 
935  connect( filter, SIGNAL( filterStart() ),
936  pkgList, SLOT ( clear() ) );
937 
938  connect( filter, SIGNAL( filterMatch( ZyppSel, ZyppPkg ) ),
939  pkgList, SLOT ( addPkgItem ( ZyppSel, ZyppPkg ) ) );
940 
941  connect( filter, SIGNAL( filterFinished() ),
942  pkgList, SLOT ( resort() ) );
943 
944  connect( filter, SIGNAL( filterFinished() ),
945  pkgList, SLOT ( selectSomething() ) );
946 
947  connect( filter, SIGNAL( filterFinished() ),
948  pkgList, SLOT ( logExcludeStatistics() ) );
949 
950  connect( filter, SIGNAL( filterFinished() ),
951  pkgList, SLOT ( setFocus() ) );
952 
953 
954  if ( hasUpdateSignal && _filters->diskUsageList() )
955  {
956  connect( filter, SIGNAL( updatePackages() ),
957  pkgList, SLOT ( updateItemStates() ) );
958 
959  if ( _filters->diskUsageList() )
960  {
961  connect( filter, SIGNAL( updatePackages() ),
962  _filters->diskUsageList(), SLOT ( updateDiskUsage() ) );
963  }
964  }
965 }
966 
967 
968 void
970 {
971  connectFilter( _updateProblemFilterView, _pkgList, false );
972  connectFilter( _patternList, _pkgList );
973  connectFilter( _langList, _pkgList );
974  connectFilter( _repoFilterView, _pkgList, false );
975  connectFilter( _packageKitGroupsFilterView, _pkgList, false );
976  connectFilter( _rpmGroupTagsFilterView, _pkgList, false );
977  connectFilter( _statusFilterView, _pkgList, false );
978  connectFilter( _searchFilterView, _pkgList, false );
979 
980  // FIXME
981  // connectFilter( _langList, _pkgList );
982 
983  if ( _searchFilterView && _pkgList )
984  {
985  connect( _searchFilterView, SIGNAL( message( const QString & ) ),
986  _pkgList, SLOT ( message( const QString & ) ) );
987  }
988 
989  if ( _repoFilterView && _pkgList )
990  {
991  connect( _repoFilterView, SIGNAL( filterNearMatch ( ZyppSel, ZyppPkg ) ),
992  _pkgList, SLOT ( addPkgItemDimmed ( ZyppSel, ZyppPkg ) ) );
993  }
994 
995  if ( _pkgList && _filters->diskUsageList() )
996  {
997 
998  connect( _pkgList, SIGNAL( statusChanged() ),
999  _filters->diskUsageList(), SLOT ( updateDiskUsage() ) );
1000  }
1001 
1002  connectPatchList();
1003 
1004 
1005 
1006  //
1007  // Connect package conflict dialog
1008  //
1009 
1010  if ( _pkgConflictDialog )
1011  {
1012  if (_pkgList )
1013  {
1014  connect( _pkgConflictDialog, SIGNAL( updatePackages() ),
1015  _pkgList, SLOT ( updateItemStates() ) );
1016  }
1017 
1018  if ( _patternList )
1019  {
1020  connect( _pkgConflictDialog, SIGNAL( updatePackages() ),
1021  _patternList, SLOT ( updateItemStates() ) );
1022  }
1023 
1024 
1025  if ( _filters->diskUsageList() )
1026  {
1027  connect( _pkgConflictDialog, SIGNAL( updatePackages() ),
1028  _filters->diskUsageList(), SLOT ( updateDiskUsage() ) );
1029  }
1030  }
1031 
1032 
1033  //
1034  // Connect package versions view
1035  //
1036 
1037  if ( _pkgVersionsView && _pkgList )
1038  {
1039  connect( _pkgVersionsView, SIGNAL( candidateChanged( ZyppObj ) ),
1040  _pkgList, SLOT ( updateItemData() ) );
1041 
1042  connect( _pkgVersionsView, SIGNAL( multiversionSelectionChanged( ) ),
1043  _pkgList, SLOT ( updateItemData() ) );
1044  }
1045 
1046 
1047  //
1048  // Hotkey to enable "patches" filter view on the fly
1049  //
1050 
1051  QShortcut * accel = new QShortcut( Qt::Key_F2, this, SLOT( hotkeyInsertPatchFilterView() ) );
1052  YUI_CHECK_NEW( accel );
1053 
1054  //
1055  // Update actions just before opening menus
1056  //
1057 
1058  if ( _pkgMenu && _pkgList )
1059  {
1060  connect( _pkgMenu, SIGNAL( aboutToShow() ),
1061  _pkgList, SLOT ( updateActions() ) );
1062  }
1063 
1064  if ( _patchMenu && _patchList )
1065  {
1066  connect( _patchMenu, SIGNAL( aboutToShow() ),
1067  _patchList, SLOT ( updateActions() ) );
1068  }
1069 }
1070 
1071 
1072 void
1074 {
1075  if ( _autoDependenciesAction && ! _autoDependenciesAction->isChecked() )
1076  return;
1077 
1079 }
1080 
1081 
1082 int
1084 {
1085  if ( ! _pkgConflictDialog )
1086  {
1087  yuiError() << "No package conflict dialog existing" << std::endl;
1088  return QDialog::Accepted;
1089  }
1090 
1091  YQUI::ui()->busyCursor();
1092  int result = _pkgConflictDialog->solveAndShowConflicts();
1093  YQUI::ui()->normalCursor();
1094 
1095 #if DEPENDENCY_FEEDBACK_IF_OK
1096 
1097  if ( result == QDialog::Accepted )
1098  {
1099  QMessageBox::information( this, "",
1100  _( "All package dependencies are OK." ),
1101  QMessageBox::Ok );
1102  }
1103 #endif
1104 
1105  return result;
1106 }
1107 
1108 
1109 void
1111 {
1112  if ( ! _patchFilterView )
1113  {
1114  _patchFilterView = new YQPkgPatchFilterView( this );
1115  YUI_CHECK_NEW( _patchFilterView );
1116  _filters->addPage( _( "P&atches" ), _patchFilterView, "patches" );
1117 
1118  _patchList = _patchFilterView->patchList();
1119  YUI_CHECK_PTR( _patchList );
1120 
1121  connectPatchList();
1122  }
1123 }
1124 
1125 
1126 void
1128 {
1129  if ( ! _patchFilterView )
1130  {
1131  yuiMilestone() << "Activating patches filter view" << std::endl;
1132 
1134  connectPatchList();
1135 
1136  _filters->showPage( _patchFilterView );
1137  _pkgList->clear();
1138  _patchList->filter();
1139  }
1140  else
1141  {
1142  _filters->showPage( _patchFilterView );
1143  }
1144 }
1145 
1146 
1147 void
1149 {
1150  if ( _pkgList && _patchList )
1151  {
1152  connectFilter( _patchList, _pkgList );
1153 
1154  connect( _patchList, SIGNAL( filterMatch ( const QString &, const QString &, FSize ) ),
1155  _pkgList, SLOT ( addPassiveItem( const QString &, const QString &, FSize ) ) );
1156 
1157  connect( _patchList, SIGNAL( statusChanged() ),
1158  this, SLOT ( autoResolveDependencies() ) );
1159 
1160  if ( _pkgConflictDialog )
1161  {
1162  connect( _pkgConflictDialog,SIGNAL( updatePackages() ),
1163  _patchList, SLOT ( updateItemStates() ) );
1164  }
1165 
1166  connect( this, SIGNAL( refresh() ),
1167  _patchList, SLOT ( updateItemStates() ) );
1168 
1169  }
1170 }
1171 
1172 
1173 void
1175 {
1176  QString filename = YQApplication::askForSaveFileName( QString( DEFAULT_EXPORT_FILE_NAME ), // startsWith
1177  QString( "*.xml;;*" ), // filter
1178  _( "Save Package List" ) );
1179 
1180  if ( ! filename.isEmpty() )
1181  {
1182  zypp::syscontent::Writer writer;
1183  const zypp::ResPool & pool = zypp::getZYpp()->pool();
1184 
1185  // The ZYPP obfuscated C++ contest proudly presents:
1186 
1187  for_each( pool.begin(), pool.end(),
1188  boost::bind( &zypp::syscontent::Writer::addIf,
1189  boost::ref( writer ),
1190  _1 ) );
1191  // Yuck. What a mess.
1192  //
1193  // Does anybody seriously believe this kind of thing is easier to read,
1194  // let alone use? Get real. This is an argument in favour of all C++
1195  // haters. And it's one that is really hard to counter.
1196  //
1197  // -sh 2006-12-13
1198 
1199  try
1200  {
1201  std::ofstream exportFile( toUTF8( filename ).c_str() );
1202  exportFile.exceptions( std::ios_base::badbit | std::ios_base::failbit );
1203  exportFile << writer;
1204 
1205  yuiMilestone() << "Package list exported to " << filename << std::endl;
1206  }
1207  catch ( std::exception & exception )
1208  {
1209  yuiWarning() << "Error exporting package list to " << filename << std::endl;
1210 
1211  // The export might have left over a partially written file.
1212  // Try to delete it. Don't care if it doesn't exist and unlink() fails.
1213  QFile::remove(filename);
1214 
1215  // Post error popup
1216  QMessageBox::warning( this, // parent
1217  _( "Error" ), // caption
1218  _( "Error exporting package list to %1" ).arg( filename ),
1219  QMessageBox::Ok | QMessageBox::Default, // button0
1220  Qt::NoButton, // button1
1221  Qt::NoButton ); // button2
1222  }
1223  }
1224 }
1225 
1226 
1227 void
1229 {
1230  QString filename = QFileDialog::getOpenFileName( this, _( "Load Package List" ), DEFAULT_EXPORT_FILE_NAME,
1231  "*.xml+;;*"// filter
1232  );
1233 
1234  if ( ! filename.isEmpty() )
1235  {
1236  yuiMilestone() << "Importing package list from " << filename << std::endl;
1237 
1238  try
1239  {
1240  std::ifstream importFile( toUTF8( filename ).c_str() );
1241  zypp::syscontent::Reader reader( importFile );
1242 
1243  //
1244  // Put reader contents into maps
1245  //
1246 
1247  typedef zypp::syscontent::Reader::Entry ZyppReaderEntry;
1248  typedef std::pair<string, ZyppReaderEntry> ImportMapPair;
1249 
1250  map<string, ZyppReaderEntry> importPkg;
1251  map<string, ZyppReaderEntry> importPatterns;
1252 
1253  for ( zypp::syscontent::Reader::const_iterator it = reader.begin();
1254  it != reader.end();
1255  ++ it )
1256  {
1257  string kind = it->kind();
1258 
1259  if ( kind == "package" ) importPkg.insert ( ImportMapPair( it->name(), *it ) );
1260  else if ( kind == "pattern" ) importPatterns.insert( ImportMapPair( it->name(), *it ) );
1261  }
1262 
1263  yuiDebug() << "Found " << importPkg.size()
1264  <<" packages and " << importPatterns.size()
1265  << " patterns in " << filename
1266  << std::endl;
1267 
1268 
1269  //
1270  // Set status of all patterns and packages according to import map
1271  //
1272 
1273  for ( ZyppPoolIterator it = zyppPatternsBegin();
1274  it != zyppPatternsEnd();
1275  ++it )
1276  {
1277  ZyppSel selectable = *it;
1278  importSelectable( *it, importPatterns.find( selectable->name() ) != importPatterns.end(), "pattern" );
1279  }
1280 
1281  for ( ZyppPoolIterator it = zyppPkgBegin();
1282  it != zyppPkgEnd();
1283  ++it )
1284  {
1285  ZyppSel selectable = *it;
1286  importSelectable( *it, importPkg.find( selectable->name() ) != importPkg.end(), "package" );
1287  }
1288 
1289 
1290  //
1291  // Display result
1292  //
1293 
1294  emit refresh();
1295 
1296  if ( _statusFilterView )
1297  {
1298  // Switch to "Installation Summary" filter view
1299 
1300  _filters->showPage( _statusFilterView );
1301  _statusFilterView->filter();
1302  }
1303 
1304  }
1305  catch ( const zypp::Exception & exception )
1306  {
1307  yuiWarning() << "Error reading package list from " << filename << std::endl;
1308 
1309  // Post error popup
1310  QMessageBox::warning( this, // parent
1311  _( "Error" ), // caption
1312  _( "Error loading package list from %1" ).arg( filename ),
1313  QMessageBox::Ok | QMessageBox::Default, // button0
1314  QMessageBox::NoButton, // button1
1315  QMessageBox::NoButton ); // button2
1316  }
1317  }
1318 }
1319 
1320 
1321 void
1323  bool isWanted,
1324  const char * kind )
1325 {
1326  ZyppStatus oldStatus = selectable->status();
1327  ZyppStatus newStatus = oldStatus;
1328 
1329  if ( isWanted )
1330  {
1331  //
1332  // Make sure this selectable does not get installed
1333  //
1334 
1335  switch ( oldStatus )
1336  {
1337  case S_Install:
1338  case S_AutoInstall:
1339  case S_KeepInstalled:
1340  case S_Protected:
1341  case S_Update:
1342  case S_AutoUpdate:
1343  newStatus = oldStatus;
1344  break;
1345 
1346  case S_Del:
1347  case S_AutoDel:
1348  newStatus = S_KeepInstalled;
1349  yuiDebug() << "Keeping " << kind << " " << selectable->name() << std::endl;
1350  break;
1351 
1352  case S_NoInst:
1353  case S_Taboo:
1354 
1355  if ( selectable->hasCandidateObj() )
1356  {
1357  newStatus = S_Install;
1358  yuiDebug() << "Adding " << kind << " " << selectable->name() << std::endl;
1359  }
1360  else
1361  {
1362  yuiDebug() << "Can't add " << kind << " " << selectable->name()
1363  << ": No candidate" << std::endl;
1364  }
1365  break;
1366  }
1367  }
1368  else // ! isWanted
1369  {
1370  //
1371  // Make sure this selectable does not get installed
1372  //
1373 
1374  switch ( oldStatus )
1375  {
1376  case S_Install:
1377  case S_AutoInstall:
1378  case S_KeepInstalled:
1379  case S_Protected:
1380  case S_Update:
1381  case S_AutoUpdate:
1382  newStatus = S_Del;
1383  yuiDebug() << "Deleting " << kind << " " << selectable->name() << std::endl;
1384  break;
1385 
1386  case S_Del:
1387  case S_AutoDel:
1388  case S_NoInst:
1389  case S_Taboo:
1390  newStatus = oldStatus;
1391  break;
1392  }
1393  }
1394 
1395  if ( oldStatus != newStatus )
1396  selectable->setStatus( newStatus );
1397 }
1398 
1399 
1400 void
1402 {
1403  if ( ! _pkgList )
1404  return;
1405 
1406  int count = _pkgList->globalSetPkgStatus( S_Update, force,
1407  true ); // countOnly
1408  yuiMilestone() << count << " pkgs found for update" << std::endl;
1409 
1410  if ( count >= GLOBAL_UPDATE_CONFIRMATION_THRESHOLD )
1411  {
1412  if ( QMessageBox::question( this, "", // caption
1413  // Translators: %1 is the number of affected packages
1414  _( "%1 packages will be updated" ).arg( count ),
1415  _( "&Continue" ), _( "C&ancel" ),
1416  0, // defaultButtonNumber (from 0)
1417  1 ) // escapeButtonNumber
1418  == 1 ) // "Cancel"?
1419  {
1420  return;
1421  }
1422  }
1423 
1424  (void) _pkgList->globalSetPkgStatus( S_Update, force,
1425  false ); // countOnly
1426 
1427  if ( _statusFilterView )
1428  {
1429  _filters->showPage( _statusFilterView );
1430  _statusFilterView->clear();
1431  _statusFilterView->showTransactions();
1432  _statusFilterView->filter();
1433  }
1434 }
1435 
1436 void
1438 {
1439  zypp::ResPool::repository_iterator it;
1440  _repoUpgradeLabel->setText("");
1441  _repoUpgradingLabel->setText("");
1442 
1443  // we iterate twice to show first the repo upgrades that
1444  // can be cancelled, and then the repo that can be added
1445  for ( it = zypp::getZYpp()->pool().knownRepositoriesBegin();
1446  it != zypp::getZYpp()->pool().knownRepositoriesEnd();
1447  ++it )
1448  {
1449  zypp::Repository repo(*it);
1450  // add the option to cancel the upgrade job against this
1451  // repository if there is a job for it
1452  if ( zypp::getZYpp()->resolver()->upgradingRepo(repo) )
1453  {
1454  _repoUpgradingLabel->setText(_repoUpgradingLabel->text() + _("<p><small><a href=\"repoupgraderemove:///%1\">Cancel switching</a> system packages to versions in repository %2</small></p>")
1455  .arg(fromUTF8(repo.alias().c_str()))
1456  .arg(fromUTF8(repo.name().c_str()))
1457  );
1458  }
1459  }
1460 
1461  for ( it = zypp::getZYpp()->pool().knownRepositoriesBegin();
1462  it != zypp::getZYpp()->pool().knownRepositoriesEnd();
1463  ++it )
1464  {
1465  zypp::Repository repo(*it);
1466  // add the option to upgrade to this repo packages if it is not the system
1467  // repository and there is no upgrade job in the solver for it
1468  // and the repo is the one selected right now
1469  if ( ! zypp::getZYpp()->resolver()->upgradingRepo(repo) &&
1470  ! repo.isSystemRepo() &&
1471  _repoFilterView->selectedRepo() == repo )
1472  {
1473  _repoUpgradeLabel->setText(_repoUpgradeLabel->text() + _("<p><a href=\"repoupgradeadd:///%1\">Switch system packages</a> to the versions in this repository (%2)</p>")
1474  .arg(fromUTF8(repo.alias().c_str()))
1475  .arg(fromUTF8(repo.name().c_str()))
1476  );
1477  }
1478  }
1479  _repoUpgradeLabel->setVisible(!_repoUpgradeLabel->text().isEmpty() &&
1480  _repoFilterView->isVisible() );
1481  _repoUpgradingLabel->setVisible(!_repoUpgradingLabel->text().isEmpty());
1482 }
1483 
1484 void
1486 {
1487  yuiDebug() << "link " << link << " clicked on label" << std::endl;
1488 
1489  QUrl url(link);
1490  if (url.scheme() == "repoupgradeadd")
1491  {
1492  yuiDebug() << "looking for repo " << url.path() << std::endl;
1493  std::string alias(url.path().remove(0,1).toStdString());
1494  zypp::Repository repo(zypp::getZYpp()->pool().reposFind(alias));
1495  yuiDebug() << repo << std::endl;
1496 
1497  if ( repo != zypp::Repository::noRepository )
1498  zypp::getZYpp()->resolver()->addUpgradeRepo(repo);
1499  }
1500  else if (url.scheme() == "repoupgraderemove")
1501  {
1502  std::string alias(url.path().remove(0,1).toStdString());
1503  zypp::Repository repo(zypp::getZYpp()->pool().reposFind(alias));
1504 
1505  if ( repo != zypp::Repository::noRepository )
1506  zypp::getZYpp()->resolver()->removeUpgradeRepo(repo);
1507  }
1508  else
1509  yuiDebug() << "unknown link operation " << url.scheme() << std::endl;
1510 
1512  emit refresh();
1513 }
1514 
1515 void
1517 {
1519 }
1520 
1521 
1522 void
1524 {
1526 }
1527 
1528 void
1530 {
1531  installSubPkgs( "-devel" );
1532 }
1533 
1534 
1535 void
1537 {
1538  installSubPkgs( "-debuginfo" );
1539 }
1540 
1541 
1542 void
1544 {
1545  installSubPkgs( "-debugsource" );
1546 }
1547 
1548 
1549 void
1551 {
1552  if ( _optionsMenu && _pkgList )
1553  {
1554  if ( _excludeDebugInfoPkgs )
1555  _excludeDebugInfoPkgs->enable( ! on );
1556 
1557  _pkgList->applyExcludeRules();
1558  }
1559 }
1560 
1561 
1562 void
1563 YQPackageSelector::pkgExcludeDevelChanged( bool on )
1564 {
1565  if ( _optionsMenu && _pkgList )
1566  {
1567  if ( _excludeDevelPkgs )
1568  _excludeDevelPkgs->enable( ! on );
1569 
1570  _pkgList->applyExcludeRules();
1571  }
1572 }
1573 
1574 
1575 void
1576 YQPackageSelector::pkgVerifySytemModeChanged( bool on )
1577 {
1578  zypp::getZYpp()->resolver()->setSystemVerification( on );
1579 }
1580 
1581 void
1582 YQPackageSelector::pkgIgnoreAlreadyRecommendedChanged( bool on )
1583 {
1584  zypp::getZYpp()->resolver()->setIgnoreAlreadyRecommended( on );
1586 }
1587 
1588 void
1589 YQPackageSelector::pkgCleanDepsOnRemoveChanged( bool on )
1590 {
1591  zypp::getZYpp()->resolver()->setCleandepsOnRemove( on );
1593 }
1594 
1595 
1596 void
1597 YQPackageSelector::pkgAllowVendorChangeChanged( bool on )
1598 {
1599  zypp::getZYpp()->resolver()->setAllowVendorChange( on );
1601 }
1602 
1603 
1604 
1605 void
1606 YQPackageSelector::installSubPkgs( const QString & suffix )
1607 {
1608  // Find all matching packages and put them into a QMap
1609 
1610  QMap<QString, ZyppSel> subPkgs;
1611 
1612  for ( ZyppPoolIterator it = zyppPkgBegin();
1613  it != zyppPkgEnd();
1614  ++it )
1615  {
1616  QString name = (*it)->name().c_str();
1617 
1618  if ( name.endsWith( suffix ) || name.endsWith( suffix + "-32bit" ) )
1619  {
1620  subPkgs[ name ] = *it;
1621 
1622  yuiDebug() << "Found subpackage: " << name << std::endl;
1623  }
1624  }
1625 
1626 
1627  // Now go through all packages and look if there is a corresponding subpackage in the QMap
1628 
1629  for ( ZyppPoolIterator it = zyppPkgBegin();
1630  it != zyppPkgEnd();
1631  ++it )
1632  {
1633  QString name = (*it)->name().c_str();
1634 
1635  if ( subPkgs.contains( name + suffix ) )
1636  {
1637  QString subPkgName( name + suffix );
1638  ZyppSel subPkg = subPkgs[ subPkgName ];
1639 
1640  switch ( (*it)->status() )
1641  {
1642  case S_AutoDel:
1643  case S_NoInst:
1644  case S_Protected:
1645  case S_Taboo:
1646  case S_Del:
1647  // Don't install the subpackage
1648  yuiMilestone() << "Ignoring unwanted subpackage " << subPkgName << std::endl;
1649  break;
1650 
1651  case S_AutoInstall:
1652  case S_Install:
1653  case S_KeepInstalled:
1654 
1655  // Install the subpackage, but don't try to update it
1656 
1657  if ( ! subPkg->installedObj() )
1658  {
1659  subPkg->setStatus( S_Install );
1660  yuiMilestone() << "Installing subpackage " << subPkgName << std::endl;
1661  }
1662  break;
1663 
1664 
1665  case S_Update:
1666  case S_AutoUpdate:
1667 
1668  // Install or update the subpackage
1669 
1670  if ( ! subPkg->installedObj() )
1671  {
1672  subPkg->setStatus( S_Install );
1673  yuiMilestone() << "Installing subpackage " << subPkgName << std::endl;
1674  }
1675  else
1676  {
1677  subPkg->setStatus( S_Update );
1678  yuiMilestone() << "Updating subpackage " << subPkgName << std::endl;
1679  }
1680  break;
1681 
1682  // Intentionally omitting 'default' branch so the compiler can
1683  // catch unhandled enum states
1684  }
1685  }
1686  }
1687 
1688 
1689  if ( _filters && _statusFilterView )
1690  {
1691  _filters->showPage( _statusFilterView );
1692  _statusFilterView->filter();
1693  }
1694 
1696  _( "Added Subpackages:" ),
1697  QRegExp( ".*" + suffix + "$" ),
1698  _( "&OK" ),
1699  QString::null, // rejectButtonLabel
1700  YQPkgChangesDialog::FilterAutomatic,
1701  YQPkgChangesDialog::OptionNone ); // showIfEmpty
1702 }
1703 
1704 void
1706 {
1707  QString settingsName = "YQPackageSelector";
1708  if ( onlineUpdateMode() ) settingsName = "YQOnlineUpdate";
1709  if ( updateMode() ) settingsName = "YQSystemUpdate";
1710 
1711  QSettings settings( QSettings::UserScope, SETTINGS_DIR, settingsName );
1712 
1713  _autoDependenciesAction->setChecked( settings.value("Options/AutocheckDependencies",
1714  AUTO_CHECK_DEPENDENCIES_DEFAULT ).toBool() ) ;
1715 
1716  _showDevelAction->setChecked(settings.value("Options/showDevelPackages", true).toBool());
1717  pkgExcludeDevelChanged(_showDevelAction->isChecked());
1718 
1719  _showDebugAction->setChecked(settings.value("Options/showDebugPackages", true).toBool());
1720  pkgExcludeDebugChanged(_showDebugAction->isChecked());
1721 
1722  _verifySystemModeAction->setChecked( settings.value("Options/systemVerificationMode",
1723  zypp::getZYpp()->resolver()->systemVerification() ).toBool() );
1724  pkgVerifySytemModeChanged ( _verifySystemModeAction->isChecked() );
1725 
1726  _ignoreAlreadyRecommendAction->setChecked(
1727  settings.value("Options/IgnoreRecommendedPackagesForAlreadyInstalledPackages",
1728  zypp::getZYpp()->resolver()->ignoreAlreadyRecommended() ).toBool() );
1729  pkgIgnoreAlreadyRecommendedChanged(_ignoreAlreadyRecommendAction->isChecked());
1730 
1731 
1732  _cleanDepsOnRemoveAction->setChecked( settings.value("Options/CleanupWhenDeletingPackages",
1733  zypp::getZYpp()->resolver()->cleandepsOnRemove()).toBool() );
1734  pkgCleanDepsOnRemoveChanged(_cleanDepsOnRemoveAction->isChecked());
1735 
1736  _allowVendorChangeAction->setChecked( settings.value("Options/AllowVendorChange",
1737  zypp::getZYpp()->resolver()->allowVendorChange() ).toBool() );
1738  pkgAllowVendorChangeChanged(_allowVendorChangeAction->isChecked());
1739 
1740 
1741 
1742 }
1743 
1744 void
1746 {
1747  QString settingsName = "YQPackageSelector";
1748  if ( onlineUpdateMode() ) settingsName = "YQOnlineUpdate";
1749  if ( updateMode() ) settingsName = "YQSystemUpdate";
1750 
1751  QSettings settings( QSettings::UserScope, SETTINGS_DIR, settingsName );
1752 
1753  settings.setValue("Options/AutocheckDependencies", _autoDependenciesAction->isChecked() );
1754  settings.setValue("Options/showDevelPackages", _showDevelAction->isChecked() );
1755  settings.setValue("Options/showDebugPackages", _showDebugAction->isChecked() );
1756  settings.setValue("Options/systemVerificationMode", _verifySystemModeAction->isChecked() );
1757  settings.setValue("Options/IgnoreRecommendedPackagesForAlreadyInstalledPackages", _ignoreAlreadyRecommendAction->isChecked() );
1758  settings.setValue("Options/CleanupWhenDeletingPackages", _cleanDepsOnRemoveAction->isChecked() );
1759  settings.setValue("Options/AllowVendorChange", _allowVendorChangeAction->isChecked() );
1760 
1761 }
1762 
1763 #include "YQPackageSelector.moc"
Display the description of a ZyppObj derived object along with its name and summary.
void showPage(QWidget *page)
QWidget * rightPane() const
int globalSetPkgStatus(ZyppStatus newStatus, bool force, bool countOnly)
Definition: YQPkgList.cc:675
RPM group tags filter view: Display the RPM group tags tree and emit signals if any group tag is sele...
void connectFilter(QWidget *filter, QWidget *pkgList, bool hasUpdateSignal=true)
void addPage(const QString &pageLabel, QWidget *pageContent, const QString &internalName)
static int countEnabledRepositories()
YQPkgDiskUsageList * diskUsageList() const
Filter view for packages that made problems during update.
static bool haveInstalledPkgs()
Definition: YQPkgList.cc:178
void importSelectable(ZyppSel selectable, bool isWanted, const char *kind)
static void showHistoryDialog()
void enable(bool enable=true)
Display a list of zypp::Patch objects and ( below ) details about the currently selected patch...
void slotRepoUpgradeLabelLinkClicked(const QString &link)
Display a pkg&#39;s file list.
static std::string iconPath(const std::string &name, int size)
Display a list of zypp::Package objects.
Definition: YQPkgList.h:54
Display a list of zypp::Pattern objects.
Filter view for searching within packages.
Display technical details (very much like &#39;rpm -qi&#39;) for a ZYPP object - the installed instance...
void clear()
Definition: YQPkgList.cc:432
void applyExcludeRules()
Filter view for packages that made problems during update.
Package version selector: Display a list of available versions from all the different installation so...
static void showProductDialog()
Display a list of zypp::Selection objects.
Definition: YQPkgLangList.h:52
static bool showChangesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null, Filters f=FilterAutomatic, Options o=OptionAutoAcceptIfEmpty)
virtual QMenu * addAllInListSubMenu(QMenu *menu)
virtual QMenu * addAllInListSubMenu(QMenu *menu)
Definition: YQPkgList.cc:501
YQPkgPatchList * patchList() const
void installSubPkgs(const QString &suffix)
Display technical details ( very much like &#39;rpm -qi&#39; ) for a zypp::Package object - the installed ins...
void pkgExcludeDebugChanged(bool on)
Display a pkg&#39;s file list.
zypp::Repository selectedRepo() const