libyui-qt-pkg  2.42.13
 All Classes Functions Variables Enumerations
YQPackageSelectorBase.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: YQPackageSelectorBase.cc
35 
36  Author: Stefan Hundhammer <sh@suse.de>
37 
38  Textdomain "qt-pkg"
39 
40 /-*/
41 
42 #include <QMessageBox>
43 #include <QKeyEvent>
44 
45 #define YUILogComponent "qt-pkg"
46 #include "YUILog.h"
47 
48 #include <QAction>
49 #include <QVBoxLayout>
50 #include <QHBoxLayout>
51 #include "QY2LayoutUtils.h"
52 
53 #include "YQPackageSelectorBase.h"
54 #include "YQPkgChangesDialog.h"
55 #include "YQPkgConflictDialog.h"
56 #include "YQPkgDiskUsageList.h"
57 #include "YQPkgDiskUsageWarningDialog.h"
58 #include "YQPkgTextDialog.h"
59 #include "YQPkgObjList.h"
60 
61 #include "YQDialog.h"
62 #include "utf8.h"
63 #include "YQApplication.h"
64 #include "YQUI.h"
65 #include "YEvent.h"
66 #include "YQi18n.h"
67 #include "QY2Styler.h"
68 
69 using std::max;
70 using std::string;
71 
72 
73 
75  long modeFlags )
76  : QFrame( (QWidget *) parent->widgetRep() )
77  , YPackageSelector( parent, modeFlags )
78 {
79  setWidgetRep( this );
80 
81  _wmCloseHandler = 0;
82  _showChangesDialog = false;
83  _pkgConflictDialog = 0;
84  _diskUsageList = 0;
85  _pkgConflictDialog = 0;
86 
87  YQUI::setTextdomain( "qt-pkg" );
88  setFont( YQUI::yqApp()->currentFont() );
89 
90  _pkgConflictDialog = new YQPkgConflictDialog( this );
91  Q_CHECK_PTR( _pkgConflictDialog );
92 
93  QString label = _( "Reset &Ignored Dependency Conflicts" );
94  _actionResetIgnoredDependencyProblems = new QAction( label, this);
95  _actionResetIgnoredDependencyProblems->setShortcut((QKeySequence) 0);
96  //_actionResetIgnoredDependencyProblems->setMenuRole(QAction::TextHeuristicRole);
97  Q_CHECK_PTR( _actionResetIgnoredDependencyProblems );
98 
99  connect( _actionResetIgnoredDependencyProblems, SIGNAL( activated() ),
100  this, SLOT ( resetIgnoredDependencyProblems() ) );
101 
102  zyppPool().saveState<zypp::Package >();
103  zyppPool().saveState<zypp::Pattern >();
104  zyppPool().saveState<zypp::Patch >();
105 
106  _wmCloseHandler = new YQPkgSelWmCloseHandler( this );
107 
108  QY2Styler::styler()->registerWidget( this );
109 
110  yuiMilestone() << "PackageSelectorBase init done" << std::endl;
111 }
112 
113 
115 {
116  yuiMilestone() << "Destroying PackageSelector" << std::endl;
117 
118  QY2Styler::styler()->unregisterWidget( this );
119 
120  if ( _wmCloseHandler )
121  delete _wmCloseHandler;
122 }
123 
124 
125 int
127 {
128  if ( ! _pkgConflictDialog )
129  {
130  yuiError() << "No package conflict dialog existing" << std::endl;
131  return QDialog::Accepted;
132  }
133 
134 
135  YQUI::ui()->busyCursor();
136  emit resolvingStarted();
137 
138  int result = _pkgConflictDialog->solveAndShowConflicts();
139 
140  emit resolvingFinished();
141  YQUI::ui()->normalCursor();
142 
143  return result;
144 }
145 
146 
147 int
149 {
150  if ( ! _pkgConflictDialog )
151  {
152  yuiError() << "No package conflict dialog existing" << std::endl;
153  return QDialog::Accepted;
154  }
155 
156 
157  YQUI::ui()->busyCursor();
158  int result = _pkgConflictDialog->verifySystem();
159  YQUI::ui()->normalCursor();
160 
161  if ( result == QDialog::Accepted )
162  {
163  QMessageBox::information( this, "",
164  _( "System dependencies verify OK." ),
165  QMessageBox::Ok );
166  }
167 
168  return result;
169 }
170 
171 
172 int
174 {
175  if ( ! _diskUsageList )
176  {
177  return QDialog::Accepted;
178  }
179 
180  if ( ! _diskUsageList->overflowWarning.inRange() )
181  return QDialog::Accepted;
182 
183  QString msg =
184  // Translators: RichText ( HTML-like ) format
185  "<p><b>" + _( "Error: Out of disk space!" ) + "</b></p>"
186  + _( "<p>"
187  "You can choose to install anyway if you know what you are doing, "
188  "but you risk getting a corrupted system that requires manual repairs. "
189  "If you are not absolutely sure how to handle such a case, "
190  "press <b>Cancel</b> now and deselect some packages."
191  "</p>" );
192 
194  100, _( "C&ontinue Anyway" ), _( "&Cancel" ) );
195 }
196 
197 
198 
199 void
201 {
203 
204  // Show which packages are installed/deleted
205  QString msg =
206  // Detailed explanation ( automatic word wrap! )
207  + "<p>"
208  + _( "The following items will be changed:"
209  " " )
210  + "<p>";
211 
213  msg,
214  _( "&OK" ),
215  QString::null, // rejectButtonLabel
216  YQPkgChangesDialog::FilterAutomatic,
217  YQPkgChangesDialog::OptionNone ); // showIfEmpty
218 }
219 
220 
221 
222 bool
224 {
225  bool changes =
226  zyppPool().diffState<zypp::Package >() ||
227  zyppPool().diffState<zypp::Pattern >() ||
228  zyppPool().diffState<zypp::Patch >();
229 
230  if ( changes )
231  {
232  if ( zyppPool().diffState<zypp::Package>() )
233  yuiMilestone() << "diffState() reports changed packages" << std::endl;
234 
235  if ( zyppPool().diffState<zypp::Pattern>() )
236  yuiMilestone() << "diffState() reports changed patterns" << std::endl;
237 
238  if ( zyppPool().diffState<zypp::Patch>() )
239  yuiMilestone() << "diffState() reports changed patches" << std::endl;
240  }
241 
242  bool confirm = false;
243 
244  if ( changes )
245  {
246  int result =
247  QMessageBox::warning( this, "",
248  _( "Abandon all changes?" ),
249  _( "&Abandon" ), _( "&Cancel" ), "",
250  1, // defaultButtonNumber (from 0)
251  1 ); // escapeButtonNumber
252 
253  confirm = ( result == 0 );
254  }
255 
256  if ( ! changes || confirm )
257  {
258  zyppPool().restoreState<zypp::Package >();
259  zyppPool().restoreState<zypp::Pattern >();
260  zyppPool().restoreState<zypp::Patch >();
261 
262  yuiMilestone() << "Closing PackageSelector with \"Cancel\"" << std::endl;
263  YQUI::ui()->sendEvent( new YCancelEvent() );
264 
265  return true; // Really reject
266  }
267  else
268  {
269  yuiMilestone() << "Returning to package selector" << std::endl;
270 
271  return false; // User changed his mind - don't reject
272  }
273 }
274 
275 
276 void
278 {
279  bool confirmedAllLicenses;
280 
281  do
282  {
283  // Force final dependency resolving
284  if ( resolveDependencies() == QDialog::Rejected )
285  return;
286 
287  confirmedAllLicenses = showPendingLicenseAgreements();
288 
289  } while ( ! confirmedAllLicenses ); // Some packages will be set to S_TABOO - need another solver run
290 
291  if ( _showChangesDialog )
292  {
293  // Show which packages are installed/deleted automatically
294  QString msg =
295  "<p><b>"
296  // Dialog header
297  + _( "Automatic Changes" )
298  + "</b></p>"
299  // Detailed explanation ( automatic word wrap! )
300  + "<p>"
301  + _( "In addition to your manual selections, the following packages"
302  " have been changed to resolve dependencies:" )
303  + "<p>";
304 
305  if ( YQPkgChangesDialog::showChangesDialog( this, msg, _( "C&ontinue" ), _( "&Cancel" ), YQPkgChangesDialog::FilterAutomatic, YQPkgChangesDialog::OptionAutoAcceptIfEmpty )
306  == QDialog::Rejected )
307  return;
308  }
309 
310  if ( confirmUnsupported() )
311  {
312  yuiMilestone() << "Confirm unsupported packages enabled." << std::endl;
313  // Show which packages are unsupported
314 
315  QString msg =
316  "<p><b>"
317  // Dialog header
318  + _( "Unsupported Packages" )
319  + "</b></p>"
320  // Detailed explanation ( automatic word wrap! )
321  + "<p>"
322  + _( "Please realize that the following selected software is either unsupported or"
323  " requires an additional customer contract for support." )
324  + "<p>";
325 
326  if ( YQPkgUnsupportedPackagesDialog::showUnsupportedPackagesDialog( this, msg, _( "C&ontinue" ), _( "&Cancel" ), YQPkgChangesDialog::FilterUser, YQPkgChangesDialog::OptionAutoAcceptIfEmpty )
327  == QDialog::Rejected )
328  return;
329  }
330 
331 
332  // Check disk usage
333  if ( checkDiskUsage() == QDialog::Rejected )
334  return;
335 
336  yuiMilestone() << "Closing PackageSelector with \"Accept\"" << std::endl;
337  YQUI::ui()->sendEvent( new YMenuEvent( "accept" ) );
338 }
339 
340 void
342 {
343  yuiMilestone() << "Closing PackageSelector with \"RepoManager\"" << std::endl;
344  YQUI::ui()->sendEvent( new YMenuEvent( "repo_mgr" ) );
345 }
346 
347 void
349 {
350  yuiMilestone() << "Closing PackageSelector with \"OnlineUpdateConfiguration\"" << std::endl;
351  YQUI::ui()->sendEvent( new YMenuEvent( "online_update_configuration" ) );
352 }
353 
354 bool
356 {
357  yuiMilestone() << "Showing all pending license agreements" << std::endl;
358 
359  bool allConfirmed = true;
360 
361  if ( onlineUpdateMode() )
362  allConfirmed = showPendingLicenseAgreements( zyppPatchesBegin(), zyppPatchesEnd() );
363 
364  allConfirmed = showPendingLicenseAgreements( zyppPkgBegin(), zyppPkgEnd() ) && allConfirmed;
365 
366  return allConfirmed;
367 }
368 
369 
370 bool
371 YQPackageSelectorBase::showPendingLicenseAgreements( ZyppPoolIterator begin, ZyppPoolIterator end )
372 {
373  bool allConfirmed = true;
374 
375  for ( ZyppPoolIterator it = begin; it != end; ++it )
376  {
377  ZyppSel sel = (*it);
378 
379  switch ( sel->status() )
380  {
381  case S_Install:
382  case S_AutoInstall:
383  case S_Update:
384  case S_AutoUpdate:
385 
386  if ( sel->candidateObj() )
387  {
388  string licenseText = sel->candidateObj()->licenseToConfirm();
389 
390  if ( ! licenseText.empty() )
391  {
392  yuiMilestone() << "Resolvable " << sel->name() << " has a license agreement" << std::endl;
393 
394  if( ! sel->hasLicenceConfirmed() )
395  {
396  yuiDebug() << "Showing license agreement for resolvable " << sel->name() << std::endl;
397  allConfirmed = YQPkgObjListItem::showLicenseAgreement( sel ) && allConfirmed;
398  }
399  else
400  {
401  yuiMilestone() << "Resolvable " << sel->name()
402  << "'s license is already confirmed" << std::endl;
403  }
404  }
405  }
406  break;
407 
408  default:
409  break;
410  }
411  }
412 
413  return allConfirmed;
414 }
415 
416 
417 void
419 {
420  QMessageBox::information( this, "",
421  _( "Not implemented yet. Sorry." ),
422  QMessageBox::Ok );
423 }
424 
425 
426 void
428 {
430 }
431 
432 
433 void
435 {
436  if ( event )
437  {
438  Qt::KeyboardModifiers special_combo = ( Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier );
439 
440  if ( ( event->modifiers() & special_combo ) == special_combo )
441  {
442  if ( event->key() == Qt::Key_A )
443  {
444  showAutoPkgList();
445  event->accept();
446  return;
447  }
448  }
449  }
450 
451  QWidget::keyPressEvent( event );
452 }
453 
454 
456 {
457  return max( 640, sizeHint().width() );
458 }
459 
460 
462 {
463  return max( 480, sizeHint().height() );
464 }
465 
466 
467 void
468 YQPackageSelectorBase::setSize( int newWidth, int newHeight )
469 {
470  resize( newWidth, newHeight );
471 }
472 
473 
474 void
476 {
477  QWidget::setEnabled( enabled );
478 }
479 
480 
481 bool
483 {
484  setFocus();
485 
486  return true;
487 }
488 
489 
490 YEvent *
492 {
493  if ( event && event->eventType() == YEvent::CancelEvent // WM_CLOSE
494  && ! _inReject ) // prevent recursion
495  {
496  // Handle WM_CLOSE like "Cancel"
497  yuiMilestone() << "Caught WM_CLOSE from package selector dialog" << std::endl;
498 
499  YUI::app()->normalCursor();
500  YUI_CHECK_WIDGET( _pkgSel );
501 
502  _inReject = true; // reject() might send a CancelEvent, too
503  bool reallyReject = _pkgSel->reject();
504  _inReject = false;
505 
506  if ( ! reallyReject )
507  {
508  event = 0; // Stop processing this event
509  yuiMilestone() << "User changed his mind - discarding CancelEvent" << std::endl;
510  }
511  }
512 
513  return event; // Don't stop processing this event
514 }
515 
516 
517 #include "YQPackageSelectorBase.moc"
YQPkgWarningRangeNotifier overflowWarning
virtual void setEnabling(bool enabled)
bool showLicenseAgreement()
virtual YEvent * filter(YEvent *event)
static bool diskUsageWarning(const QString &message, int thresholdPercent, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null)
static bool showChangesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null, Filters f=FilterAutomatic, Options o=OptionAutoAcceptIfEmpty)
static void resetIgnoredDependencyProblems()
virtual void setSize(int newWidth, int newHeight)
virtual void keyPressEvent(QKeyEvent *ev)
YQPackageSelectorBase(YWidget *parent, long modeFlags=0)
Dialog that takes care of dependency checking and resolving conflicts.
static bool showUnsupportedPackagesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null, Filters f=FilterAutomatic, Options o=OptionAutoAcceptIfEmpty)