]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPackageSelectorBase.cc
restart qt4 porting
[duncan/yast2-qt4.git] / src / pkg / YQPackageSelectorBase.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPackageSelectorBase.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   Textdomain "packages-qt"
18
19 /-*/
20
21 #include <qmessagebox.h>
22
23 #define y2log_component "qt-pkg"
24 #include <ycp/y2log.h>
25
26 #include <qaction.h>
27 #include "QY2LayoutUtils.h"
28
29 #include "YQPackageSelectorBase.h"
30 #include "YQPkgChangesDialog.h"
31 #include "YQPkgConflictDialog.h"
32 #include "YQPkgDiskUsageList.h"
33 #include "YQPkgDiskUsageWarningDialog.h"
34 #include "YQPkgTextDialog.h"
35 #include "YQPkgObjList.h"
36
37 #include "YQDialog.h"
38 #include "utf8.h"
39 #include "YQApplication.h"
40 #include "YQUI.h"
41 #include "YEvent.h"
42 #include "YQi18n.h"
43
44
45 using std::max;
46 using std::string;
47
48
49 YQPackageSelectorBase::YQPackageSelectorBase( YWidget * parent,
50                                               long      modeFlags )
51     : QVBox( (QWidget *) parent->widgetRep() )
52     , YPackageSelector( parent, modeFlags )
53 {
54     setWidgetRep( this );
55
56     _showChangesDialog          = false;
57     _pkgConflictDialog          = 0;
58     _diskUsageList              = 0;
59     _pkgConflictDialog          = 0;
60
61     YQUI::setTextdomain( "packages-qt" );
62     setFont( YQUI::yqApp()->currentFont() );
63     YQUI::ui()->blockWmClose(); // Automatically undone after UI::RunPkgSelection()
64
65     _pkgConflictDialog = new YQPkgConflictDialog( this );
66     CHECK_PTR( _pkgConflictDialog );
67
68     QString label = _( "Reset &Ignored Dependency Conflicts" );
69     _actionResetIgnoredDependencyProblems = new QAction( label,                 // text
70                                                          label,                 // menu text
71                                                          (QKeySequence) 0,      // accel
72                                                          this );                // parent
73     CHECK_PTR( _actionResetIgnoredDependencyProblems );
74
75     connect( _actionResetIgnoredDependencyProblems, SIGNAL( activated() ),
76              this,                                  SLOT  ( resetIgnoredDependencyProblems() ) );
77
78     zyppPool().saveState<zypp::Package  >();
79     zyppPool().saveState<zypp::Pattern  >();
80     zyppPool().saveState<zypp::Selection>();
81     zyppPool().saveState<zypp::Language >();
82     zyppPool().saveState<zypp::Patch    >();
83
84
85     //
86     // Handle WM_CLOSE like "Cancel"
87     //
88
89     connect( YQUI::ui(),        SIGNAL( wmClose() ),
90              this,              SLOT  ( reject()   ) );
91
92     y2milestone( "PackageSelectorBase init done" );
93 }
94
95
96 YQPackageSelectorBase::~YQPackageSelectorBase()
97 {
98     y2milestone( "Destroying PackageSelector" );
99 }
100
101
102 int
103 YQPackageSelectorBase::resolveDependencies()
104 {
105     if ( ! _pkgConflictDialog )
106     {
107         y2error( "No package conflict dialog existing" );
108         return QDialog::Accepted;
109     }
110
111
112     YQUI::ui()->busyCursor();
113     emit resolvingStarted();
114
115     int result = _pkgConflictDialog->solveAndShowConflicts();
116
117     emit resolvingFinished();
118     YQUI::ui()->normalCursor();
119
120     return result;
121 }
122
123
124 int
125 YQPackageSelectorBase::verifySystem()
126 {
127     if ( ! _pkgConflictDialog )
128     {
129         y2error( "No package conflict dialog existing" );
130         return QDialog::Accepted;
131     }
132
133
134     YQUI::ui()->busyCursor();
135     int result = _pkgConflictDialog->verifySystem();
136     YQUI::ui()->normalCursor();
137     
138     if ( result == QDialog::Accepted )
139     {
140         QMessageBox::information( this, "",
141                                   _( "System dependencies verify OK." ),
142                                   QMessageBox::Ok );
143     }
144
145     return result;
146 }
147
148
149 int
150 YQPackageSelectorBase::checkDiskUsage()
151 {
152     if ( ! _diskUsageList )
153     {
154         return QDialog::Accepted;
155     }
156
157     if ( ! _diskUsageList->overflowWarning.inRange() )
158         return QDialog::Accepted;
159
160     QString msg =
161         // Translators: RichText ( HTML-like ) format
162         "<p><b>" + _( "Error: Out of disk space!" ) + "</b></p>"
163         + _( "<p>"
164              "You can choose to install anyway if you know what you are doing, "
165              "but you risk getting a corrupted system that requires manual repairs. "
166              "If you are not absolutely sure how to handle such a case, "
167              "press <b>Cancel</b> now and deselect some packages."
168              "</p>" );
169
170     return YQPkgDiskUsageWarningDialog::diskUsageWarning( msg,
171                                                           100, _( "C&ontinue Anyway" ), _( "&Cancel" ) );
172
173 }
174
175
176
177 void
178 YQPackageSelectorBase::showAutoPkgList()
179 {
180     resolveDependencies();
181
182     // Show which packages are installed/deleted automatically
183     QString msg =
184         "<p><b>"
185         // Dialog header
186         + _( "Automatic Changes" )
187         + "</b></p>"
188         // Detailed explanation ( automatic word wrap! )
189         + "<p>"
190         + _( "In addition to your manual selections, the following packages"
191              " have been changed to resolve dependencies:" )
192         + "<p>";
193
194     YQPkgChangesDialog::showChangesDialog( msg,
195                                            _( "&OK" ),
196                                            QString::null,       // rejectButtonLabel
197                                            true );              // showIfEmpty
198 }
199
200
201
202 void
203 YQPackageSelectorBase::reject()
204 {
205     bool changes =
206         zyppPool().diffState<zypp::Package  >() ||
207         zyppPool().diffState<zypp::Pattern  >() ||
208         zyppPool().diffState<zypp::Selection>() ||
209         zyppPool().diffState<zypp::Language >() ||
210         zyppPool().diffState<zypp::Patch    >();
211
212     if ( changes )
213     {
214         if ( zyppPool().diffState<zypp::Package>() )
215             y2milestone( "diffState() reports changed packages" );
216
217         if ( zyppPool().diffState<zypp::Pattern>() )
218             y2milestone( "diffState() reports changed patterns" );
219
220         if ( zyppPool().diffState<zypp::Selection>() )
221             y2milestone( "diffState() reports changed selections" );
222
223         if ( zyppPool().diffState<zypp::Language>() )
224             y2milestone( "diffState() reports changed languages" );
225
226         if ( zyppPool().diffState<zypp::Patch>() )
227             y2milestone( "diffState() reports changed patches" );
228     }
229
230     if ( ! changes ||
231          ( QMessageBox::warning( this, "",
232                                  _( "Abandon all changes?" ),
233                                  _( "&OK" ), _( "&Cancel" ), "",
234                                  1, // defaultButtonNumber (from 0)
235                                  1 ) // escapeButtonNumber
236            == 0 )       // Proceed upon button #0 ( OK )
237          )
238     {
239         zyppPool().restoreState<zypp::Package  >();
240         zyppPool().restoreState<zypp::Pattern  >();
241         zyppPool().restoreState<zypp::Selection>();
242         zyppPool().restoreState<zypp::Language >();
243         zyppPool().restoreState<zypp::Patch    >();
244
245         y2milestone( "Closing PackageSelector with \"Cancel\"" );
246         YQUI::ui()->sendEvent( new YCancelEvent() );
247     }
248 }
249
250
251 void
252 YQPackageSelectorBase::accept()
253 {
254     bool confirmedAllLicenses;
255
256     do
257     {
258         // Force final dependency resolving
259         if ( resolveDependencies() == QDialog::Rejected )
260             return;
261
262         confirmedAllLicenses = showPendingLicenseAgreements();
263
264     } while ( ! confirmedAllLicenses ); // Some packages will be set to S_TABOO - need another solver run
265
266     if ( _showChangesDialog )
267     {
268         // Show which packages are installed/deleted automatically
269         QString msg =
270             "<p><b>"
271             // Dialog header
272             + _( "Automatic Changes" )
273             + "</b></p>"
274             // Detailed explanation ( automatic word wrap! )
275             + "<p>"
276             + _( "In addition to your manual selections, the following packages"
277                  " have been changed to resolve dependencies:" )
278             + "<p>";
279
280         if ( YQPkgChangesDialog::showChangesDialog( msg, _( "C&ontinue" ), _( "&Cancel" ) )
281              == QDialog::Rejected )
282             return;
283     }
284
285     // Check disk usage
286     if ( checkDiskUsage() == QDialog::Rejected )
287         return;
288
289     y2milestone( "Closing PackageSelector with \"Accept\"" );
290     YQUI::ui()->sendEvent( new YMenuEvent( YCPSymbol( "accept" ) ) );
291 }
292
293
294 bool
295 YQPackageSelectorBase::showPendingLicenseAgreements()
296 {
297     y2milestone( "Showing all pending license agreements" );
298
299     bool allConfirmed = true;
300
301     if ( onlineUpdateMode() )
302         allConfirmed = showPendingLicenseAgreements( zyppPatchesBegin(), zyppPatchesEnd() );
303
304     allConfirmed = showPendingLicenseAgreements( zyppPkgBegin(), zyppPkgEnd() ) && allConfirmed;
305
306     return allConfirmed;
307 }
308
309
310 bool
311 YQPackageSelectorBase::showPendingLicenseAgreements( ZyppPoolIterator begin, ZyppPoolIterator end )
312 {
313     bool allConfirmed = true;
314     
315     for ( ZyppPoolIterator it = begin; it != end; ++it )
316     {
317         ZyppSel sel = (*it);
318
319         switch ( sel->status() )
320         {
321             case S_Install:
322             case S_AutoInstall:
323             case S_Update:
324             case S_AutoUpdate:
325
326                 if ( sel->candidateObj() )
327                 {
328                     string licenseText = sel->candidateObj()->licenseToConfirm();
329
330                     if ( ! licenseText.empty() )
331                     {
332                         y2milestone( "Resolvable %s has a license agreement", sel->name().c_str() );
333
334                         if( ! sel->hasLicenceConfirmed() )
335                         {
336                             y2debug( "Showing license agreement for resolvable %s", sel->name().c_str() );
337                             allConfirmed = YQPkgObjListItem::showLicenseAgreement( sel ) && allConfirmed;
338                         }
339                         else
340                         {
341                             y2milestone( "Resolvable %s's  license is already confirmed", sel->name().c_str() );
342                         }
343                     }
344                 }
345                 break;
346
347             default:
348                 break;
349         }
350     }
351
352     return allConfirmed;
353 }
354
355
356 void
357 YQPackageSelectorBase::notImplemented()
358 {
359     QMessageBox::information( this, "",
360                               _( "Not implemented yet. Sorry." ),
361                               QMessageBox::Ok );
362 }
363
364
365 void
366 YQPackageSelectorBase::resetIgnoredDependencyProblems()
367 {
368     YQPkgConflictDialog::resetIgnoredDependencyProblems();
369 }
370
371
372 void
373 YQPackageSelectorBase::keyPressEvent( QKeyEvent * event )
374 {
375     if ( event )
376     {
377         unsigned special_combo = ( Qt::ControlButton | Qt::ShiftButton | Qt::AltButton );
378
379         if ( ( event->state() & special_combo ) == special_combo )
380         {
381             if ( event->key() == Qt::Key_A )
382             {
383                 showAutoPkgList();
384                 event->accept();
385                 return;
386             }
387         }
388         else if ( event->key() == Qt::Key_F5 )  // No matter if Ctrl/Alt/Shift pressed
389         {
390             YQUI::ui()->easterEgg();
391             return;
392         }
393     }
394
395     QWidget::keyPressEvent( event );
396 }
397
398
399 int YQPackageSelectorBase::preferredWidth()
400 {
401     return max( 640, sizeHint().width() );
402 }
403
404
405 int YQPackageSelectorBase::preferredHeight()
406 {
407     return max( 480, sizeHint().height() );
408 }
409
410
411 void
412 YQPackageSelectorBase::setSize( int newWidth, int newHeight )
413 {
414     resize( newWidth, newHeight );
415 }
416
417
418 void
419 YQPackageSelectorBase::setEnabling( bool enabled )
420 {
421     QWidget::setEnabled( enabled );
422 }
423
424
425 bool
426 YQPackageSelectorBase::setKeyboardFocus()
427 {
428     setFocus();
429
430     return true;
431 }
432
433
434 #include "YQPackageSelectorBase.moc"