libyui-qt-pkg  2.45.15
YQPkgObjList.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: YQPkgObjList.cc
35 
36  Author: Stefan Hundhammer <sh@suse.de>
37 
38  Textdomain "qt-pkg"
39 
40 /-*/
41 
42 #define YUILogComponent "qt-pkg"
43 #include "YUILog.h"
44 #include <QPixmap>
45 #include <QHeaderView>
46 #include <QMenu>
47 #include <QAction>
48 #include <QDebug>
49 #include <QKeyEvent>
50 
51 #include "utf8.h"
52 
53 #include "YDialog.h"
54 #include "YQPkgObjList.h"
55 #include "YQPkgTextDialog.h"
56 #include "YQi18n.h"
57 #include "YQIconPool.h"
58 #include "YQUI.h"
59 
60 #include "zypp/ZYppFactory.h"
61 
62 using std::endl;
63 using std::list;
64 using std::string;
65 
66 
67 #define VERBOSE_EXCLUDE_RULES 0
68 #define EXTRA_SOLVE_COLLECTIONS 0
69 
70 
71 YQPkgObjList::YQPkgObjList( QWidget * parent )
72  : QY2ListView( parent )
73  , _editable( true )
74  , _installedContextMenu(0)
75  , _notInstalledContextMenu(0)
76  , actionSetCurrentInstall(0)
77  , actionSetCurrentDontInstall(0)
78  , actionSetCurrentKeepInstalled(0)
79  , actionSetCurrentDelete(0)
80  , actionSetCurrentUpdate(0)
81  , actionSetCurrentUpdateForce(0)
82  , actionSetCurrentTaboo(0)
83  , actionSetCurrentProtected(0)
84  , actionShowCurrentSolverInfo(0)
85  , actionSetListInstall(0)
86  , actionSetListDontInstall(0)
87  , actionSetListKeepInstalled(0)
88  , actionSetListDelete(0)
89  , actionSetListUpdate(0)
90  , actionSetListUpdateForce(0)
91  , actionSetListTaboo(0)
92  , actionSetListProtected(0)
93 {
94  // This class does not add any columns. This is the main reason why this is
95  // an abstract base class: It doesn't know which columns are desired and in
96  // what order.
97 
98  _iconCol = -42;
99  _statusCol = -42;
100  _nameCol = -42;
101  _versionCol = -42;
102  _instVersionCol = -42;
103  _summaryCol = -42;
104  _sizeCol = -42;
105  _brokenIconCol = -42;
106  _satisfiedIconCol = -42;
107  _debug = false;
108 
109  _excludedItems = new YQPkgObjList::ExcludedItems( this );
110 
111  createActions();
112 
113  connect( this, SIGNAL( columnClicked ( int, QTreeWidgetItem *, int, const QPoint & ) ),
114  this, SLOT ( pkgObjClicked ( int, QTreeWidgetItem *, int, const QPoint & ) ) );
115 
116  connect( this, SIGNAL( columnDoubleClicked ( int, QTreeWidgetItem *, int, const QPoint & ) ),
117  this, SLOT ( pkgObjClicked ( int, QTreeWidgetItem *, int, const QPoint & ) ) );
118 
119  connect( this, SIGNAL( currentItemChanged ( QTreeWidgetItem *, QTreeWidgetItem * ) ),
120  this, SLOT ( currentItemChangedInternal( QTreeWidgetItem * ) ) );
121 
122  connect( this, SIGNAL(customContextMenuRequested(const QPoint &)),
123  this, SLOT (slotCustomContextMenu(const QPoint&)));
124 
125  setIconSize( QSize( 22, 16 ) );
126 
127  setContextMenuPolicy(Qt::CustomContextMenu);
128 
129 }
130 
131 
132 
133 
135 {
136  if ( _excludedItems )
137  delete _excludedItems;
138 }
139 
140 
141 void
142 YQPkgObjList::addPkgObjItem( ZyppSel selectable, ZyppObj zyppObj )
143 {
144  if ( ! selectable )
145  {
146  yuiError() << "Null zypp::ui::Selectable!" << endl;
147  return;
148  }
149 
150  YQPkgObjListItem * item = new YQPkgObjListItem( this, selectable, zyppObj );
151  applyExcludeRules( item );
152 }
153 
154 
155 void
156 YQPkgObjList::addPassiveItem( const QString & name,
157  const QString & summary,
158  FSize size )
159 {
160  QY2ListViewItem * item = new QY2ListViewItem( this, QString::null );
161 
162  if ( item )
163  {
164  if ( nameCol() >= 0 && ! name.isEmpty() ) item->setText( nameCol(), name );
165  if ( summaryCol() >= 0 && ! summary.isEmpty() ) item->setText( summaryCol(), summary );
166  if ( sizeCol() >= 0 && size > 0L )
167  {
168  QString sizeStr = size.form().c_str();
169  item->setText( sizeCol(), sizeStr );
170  }
171  }
172 }
173 
174 
175 void
177  QTreeWidgetItem * listViewItem,
178  int col,
179  const QPoint & pos )
180 {
181  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (listViewItem);
182 
183  if ( item )
184  {
185  //y2internal("CLICKED: %s", item->zyppObj()->name().c_str());
186  if ( button == Qt::LeftButton )
187  {
188  if ( col == statusCol() )
189  // || col == nameCol() )
190  {
191  if ( editable() && item->editable() )
192  item->cycleStatus();
193  }
194  }
195  // context menus are handled in slotCustomContextMenu()
196  }
197 }
198 
199 
200 void
201 YQPkgObjList::currentItemChangedInternal( QTreeWidgetItem * listViewItem )
202 {
203  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (listViewItem);
204 
205  emit currentItemChanged( item ? item->selectable() : ZyppSel() );
206 }
207 
208 
209 void
211 {
212  emit currentItemChanged( ZyppSel() );
213 
214  _excludedItems->clear();
215  QY2ListView::clear();
216 }
217 
218 
219 QPixmap
220 YQPkgObjList::statusIcon( ZyppStatus status, bool enabled, bool bySelection )
221 {
222  QPixmap icon = YQIconPool::pkgNoInst();
223 
224  if ( enabled )
225  {
226  switch ( status )
227  {
228  case S_Del: icon = YQIconPool::pkgDel(); break;
229  case S_Install: icon = YQIconPool::pkgInstall(); break;
230  case S_KeepInstalled: icon = YQIconPool::pkgKeepInstalled(); break;
231  case S_NoInst: icon = YQIconPool::pkgNoInst(); break;
232  case S_Protected: icon = YQIconPool::pkgProtected(); break;
233  case S_Taboo: icon = YQIconPool::pkgTaboo(); break;
234  case S_Update: icon = YQIconPool::pkgUpdate(); break;
235 
236  case S_AutoDel: icon = YQIconPool::pkgAutoDel(); break;
237  case S_AutoInstall: icon = YQIconPool::pkgAutoInstall(); break;
238  case S_AutoUpdate: icon = YQIconPool::pkgAutoUpdate(); break;
239 
240  // Intentionally omitting 'default' branch so the compiler can
241  // catch unhandled enum states
242  }
243  }
244  else
245  {
246  switch ( status )
247  {
248  case S_Del: icon = YQIconPool::disabledPkgDel(); break;
249  case S_Install: icon = YQIconPool::disabledPkgInstall(); break;
250  case S_KeepInstalled: icon = YQIconPool::disabledPkgKeepInstalled(); break;
251  case S_NoInst: icon = YQIconPool::disabledPkgNoInst(); break;
252  case S_Protected: icon = YQIconPool::disabledPkgProtected(); break;
253  case S_Taboo: icon = YQIconPool::disabledPkgTaboo(); break;
254  case S_Update: icon = YQIconPool::disabledPkgUpdate(); break;
255 
256  case S_AutoDel: icon = YQIconPool::disabledPkgAutoDel(); break;
257  case S_AutoInstall: icon = YQIconPool::disabledPkgAutoInstall(); break;
258  case S_AutoUpdate: icon = YQIconPool::disabledPkgAutoUpdate(); break;
259 
260  // Intentionally omitting 'default' branch so the compiler can
261  // catch unhandled enum states
262  }
263  }
264 
265  return icon;
266 }
267 
268 
269 QString
270 YQPkgObjList::statusText( ZyppStatus status ) const
271 {
272  switch ( status )
273  {
274  case S_AutoDel: return _( "Autodelete" );
275  case S_AutoInstall: return _( "Autoinstall" );
276  case S_AutoUpdate: return _( "Autoupdate" );
277  case S_Del: return _( "Delete" );
278  case S_Install: return _( "Install" );
279  case S_KeepInstalled: return _( "Keep" );
280  case S_NoInst: return _( "Do Not Install" );
281  case S_Protected: return _( "Protected -- Do Not Modify" );
282  case S_Taboo: return _( "Taboo -- Never Install" );
283  case S_Update: return _( "Update" );
284  }
285 
286  return QString::null;
287 }
288 
289 
290 void
291 YQPkgObjList::setCurrentStatus( ZyppStatus newStatus, bool doSelectNextItem, bool ifNewerOnly )
292 {
293  QTreeWidgetItem * listViewItem = currentItem();
294 
295  if ( ! listViewItem )
296  return;
297 
298  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (listViewItem);
299 
300  if ( item && item->editable() && _editable && ( item->candidateIsNewer() || !ifNewerOnly ) )
301  {
302  if ( newStatus != item->status() )
303  {
304  item->setStatus( newStatus );
305 
306  if ( item->showLicenseAgreement() )
307  {
308  item->showNotifyTexts( newStatus );
309  }
310  else // License not confirmed?
311  {
312  // Status is now S_Taboo or S_Del - update status icon
313  item->setStatusIcon();
314  }
315 
316  emit statusChanged();
317  }
318  }
319 
320  if ( doSelectNextItem )
321  selectNextItem();
322 }
323 
324 
325 void
327 {
328  QTreeWidgetItem * listViewItem = currentItem();
329 
330  if ( ! listViewItem )
331  return;
332 
333  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (listViewItem);
334 
335  if ( item )
336  {
337  _plugin.createZyppSolverDialog(item->zyppObj()->poolItem());
338  }
339 }
340 
341 
342 void
343 YQPkgObjList::setAllItemStatus( ZyppStatus newStatus, bool force )
344 {
345  if ( ! _editable )
346  return;
347 
348  YQUI::ui()->busyCursor();
349  QTreeWidgetItemIterator it( this );
350 
351  while ( *it )
352  {
353  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (*it);
354 
355  if ( item && item->editable() && newStatus != item->status() )
356  {
357  if ( newStatus == S_Update )
358  {
359  if ( force )
360  {
361  item->setStatus( newStatus,
362  false ); // sendSignals
363  }
364  else
365  {
366  if ( item->selectable()->installedObj() && item->status() != S_Protected && item->selectable()->updateCandidateObj() )
367  {
368  item->selectable()->setOnSystem( item->selectable()->updateCandidateObj() );
369  }
370  }
371  }
372  else
373  {
374  item->setStatus( newStatus,
375  false ); // sendSignals
376  }
377  }
378 
379  ++it;
380  }
381 
382  emit updateItemStates();
383  emit updatePackages();
384 
385  YQUI::ui()->normalCursor();
386  emit statusChanged();
387 }
388 
389 
390 void
392 {
393  QTreeWidgetItemIterator it(this);
394  QTreeWidgetItem * item;
395 
396  while ( (item = *it) != NULL )
397  {
398  ++it;
399  //item->setSelected( false ); // Doesn't emit signals
400  scrollToItem( *it ); // Scroll if necessary
401  setCurrentItem( *it ); // Emits signals
402 
403  }
404 }
405 
406 
407 void
409 {
410  actionSetCurrentInstall = createAction( S_Install, "[+]" );
411  actionSetCurrentDontInstall = createAction( S_NoInst, "[-]" );
412  actionSetCurrentKeepInstalled = createAction( S_KeepInstalled, "[<], [-]" );
413  actionSetCurrentDelete = createAction( S_Del, "[-]" );
414  actionSetCurrentUpdate = createAction( S_Update, "[>], [+]" );
415  actionSetCurrentUpdateForce = createAction( _( "Update unconditionally" ), statusIcon( S_Update, true ) ,statusIcon( S_Update, false ) , "", true ) ;
416 
417 
418 
419  actionSetCurrentTaboo = createAction( S_Taboo, "[!]" );
420  actionSetCurrentProtected = createAction( S_Protected, "[*]" );
421 
422  actionShowCurrentSolverInfo = createAction( _( "Show solver information" ));
423 
424  actionSetListInstall = createAction( S_Install, "", true );
425  actionSetListDontInstall = createAction( S_NoInst, "", true );
426  actionSetListKeepInstalled = createAction( S_KeepInstalled, "", true );
427  actionSetListDelete = createAction( S_Del, "", true );
428  actionSetListProtected = createAction( S_Protected, "", true );
429 
430  actionSetListUpdate = createAction( _( "Update if newer version available" ),
431  statusIcon( S_Update, true ),
432  statusIcon( S_Update, false ),
433  "",
434  true );
435 
436  actionSetListUpdateForce = createAction( _( "Update unconditionally" ),
437  statusIcon( S_Update, true ),
438  statusIcon( S_Update, false ),
439  "",
440  true );
441 
442  actionSetListTaboo = createAction( S_Taboo, "", true );
443 
444  connect( actionSetCurrentInstall, &QAction::triggered, this, &YQPkgObjList::setCurrentInstall );
445  connect( actionSetCurrentDontInstall, &QAction::triggered, this, &YQPkgObjList::setCurrentDontInstall );
446  connect( actionSetCurrentKeepInstalled, &QAction::triggered, this, &YQPkgObjList::setCurrentKeepInstalled );
447  connect( actionSetCurrentDelete, &QAction::triggered, this, &YQPkgObjList::setCurrentDelete );
448  connect( actionSetCurrentUpdate, &QAction::triggered, this, &YQPkgObjList::setCurrentUpdate );
449  connect( actionSetCurrentUpdateForce, &QAction::triggered, this, &YQPkgObjList::setCurrentUpdateForce );
450  connect( actionSetCurrentTaboo, &QAction::triggered, this, &YQPkgObjList::setCurrentTaboo );
451  connect( actionSetCurrentProtected, &QAction::triggered, this, &YQPkgObjList::setCurrentProtected );
452  connect( actionShowCurrentSolverInfo, &QAction::triggered, this, &YQPkgObjList::showCurrentSolverInfo );
453  connect( actionSetListInstall, &QAction::triggered, this, &YQPkgObjList::setListInstall );
454  connect( actionSetListDontInstall, &QAction::triggered, this, &YQPkgObjList::setListDontInstall );
455  connect( actionSetListKeepInstalled, &QAction::triggered, this, &YQPkgObjList::setListKeepInstalled );
456  connect( actionSetListDelete, &QAction::triggered, this, &YQPkgObjList::setListDelete );
457  connect( actionSetListUpdate, &QAction::triggered, this, &YQPkgObjList::setListUpdate );
458  connect( actionSetListUpdateForce, &QAction::triggered, this, &YQPkgObjList::setListUpdateForce );
459  connect( actionSetListTaboo, &QAction::triggered, this, &YQPkgObjList::setListTaboo );
460  connect( actionSetListProtected, &QAction::triggered, this, &YQPkgObjList::setListProtected );
461 
462  // if the solver info plugin did not success to load (which is, the package
463  // of the plugin is not installed or was not included in the media
464  //
465  // it will show up a popup when called, however, if we are in installation
466  // (that is, target is not / or there is no target at all,
467  // the user will have no chance of installing
468  // the plugin package, therefore we disable the action.
469  //
470  zypp::Target_Ptr target = zypp::getZYpp()->getTarget();
471  if ( ! target || ( target->root() != "/" ) )
472  {
473  // there is no target or the target is mounted out of root
474  // which means install or update
475  // if the plugin did not load
476  if ( ! _plugin.success() )
477  {
478  // grey out the option
479  yuiMilestone() << "Disabling solver info plugin: not available and no target or target is not /" << endl;
480  actionShowCurrentSolverInfo->setVisible(false);
481  }
482  else
483  {
484  yuiMilestone() << "target not available or target or target is not /. Solver info plugin available anyway." << endl;
485  }
486  }
487 }
488 
489 
490 
491 QAction *
492 YQPkgObjList::createAction( ZyppStatus status, const QString & key, bool enabled )
493 {
494  return createAction( statusText( status ),
495  statusIcon( status, true ),
496  statusIcon( status, false ),
497  key,
498  enabled );
499 }
500 
501 
502 QAction *
503 YQPkgObjList::createAction( const QString & text,
504  const QPixmap & icon,
505  const QPixmap & insensitiveIcon,
506  const QString & key,
507  bool enabled )
508 {
509  QString label = text;
510 
511  if ( ! key.isEmpty() )
512  label += "\t" + key;
513 
514 
515  QIcon iconSet ( icon );
516 
517  if ( ! insensitiveIcon.isNull() )
518  {
519  iconSet.addPixmap( insensitiveIcon,
520  QIcon::Disabled );
521  }
522 
523  QAction * action = new QAction( label, // text
524  this ); // parent
525  Q_CHECK_PTR( action );
526  action->setEnabled( enabled );
527  action->setIcon( iconSet );
528 
529  return action;
530 }
531 
532 
533 void
535 {
536  _notInstalledContextMenu = new QMenu( this );
537  Q_CHECK_PTR( _notInstalledContextMenu );
538 
539  _notInstalledContextMenu->addAction( actionSetCurrentInstall );
540  _notInstalledContextMenu->addAction( actionSetCurrentDontInstall );
541  _notInstalledContextMenu->addAction( actionSetCurrentTaboo );
542  _notInstalledContextMenu->addAction( actionShowCurrentSolverInfo );
543 
544  addAllInListSubMenu( _notInstalledContextMenu );
545 }
546 
547 
548 void
550 {
551  _installedContextMenu = new QMenu( this );
552  Q_CHECK_PTR( _installedContextMenu );
553 
554  _installedContextMenu->addAction( actionSetCurrentKeepInstalled );
555  _installedContextMenu->addAction( actionSetCurrentDelete );
556  _installedContextMenu->addAction( actionSetCurrentUpdate );
557  _installedContextMenu->addAction( actionSetCurrentUpdateForce );
558  _installedContextMenu->addAction( actionShowCurrentSolverInfo );
559 
560  addAllInListSubMenu( _installedContextMenu );
561 }
562 
563 
564 QMenu *
566 {
567  QMenu * submenu = new QMenu( menu );
568  Q_CHECK_PTR( submenu );
569 
570  submenu->addAction( actionSetListInstall );
571  submenu->addAction( actionSetListDontInstall );
572  submenu->addAction( actionSetListKeepInstalled );
573  submenu->addAction( actionSetListDelete );
574  submenu->addAction( actionSetListUpdate );
575  submenu->addAction( actionSetListUpdateForce );
576  submenu->addAction( actionSetListTaboo );
577 
578  QAction *action = menu->addMenu( submenu );
579  action->setText( _( "&All in This List" ) );
580 
581  return submenu;
582 }
583 
584 
585 QMenu *
587 {
588  if ( ! _notInstalledContextMenu )
590 
591  return _notInstalledContextMenu;
592 }
593 
594 
595 QMenu *
597 {
598  if ( ! _installedContextMenu )
600 
601  return _installedContextMenu;
602 }
603 
604 
605 void
607 {
608  if ( !item)
609  item = dynamic_cast<YQPkgObjListItem *> ( currentItem() );
610 
611  if ( item )
612  {
613  ZyppSel selectable = item->selectable();
614 
615  if ( selectable->hasInstalledObj() )
616  {
617  actionSetCurrentInstall->setEnabled( false );
618  actionSetCurrentDontInstall->setEnabled( false );
619  actionSetCurrentTaboo->setEnabled( false );
620  actionSetCurrentProtected->setEnabled( true );
621 
622  actionSetCurrentKeepInstalled->setEnabled( true );
623  actionSetCurrentDelete->setEnabled( true );
624  actionSetCurrentUpdate->setEnabled( selectable->hasCandidateObj() );
625  actionSetCurrentUpdateForce->setEnabled( selectable->hasCandidateObj() );
626  }
627  else
628  {
629  actionSetCurrentInstall->setEnabled( selectable->hasCandidateObj() );
630  actionSetCurrentDontInstall->setEnabled( true );
631  actionSetCurrentTaboo->setEnabled( true );
632  actionSetCurrentProtected->setEnabled( false );
633 
634  actionSetCurrentKeepInstalled->setEnabled( false );
635  actionSetCurrentDelete->setEnabled( false );
636  actionSetCurrentUpdate->setEnabled( false );
637  actionSetCurrentUpdateForce->setEnabled( false );
638  }
639  actionShowCurrentSolverInfo->setEnabled( true );
640  }
641  else // ! item
642  {
643  actionSetCurrentInstall->setEnabled( false );
644  actionSetCurrentDontInstall->setEnabled( false );
645  actionSetCurrentTaboo->setEnabled( false );
646 
647  actionSetCurrentKeepInstalled->setEnabled( false );
648  actionSetCurrentDelete->setEnabled( false );
649  actionSetCurrentUpdate->setEnabled( false );
650  actionSetCurrentUpdateForce->setEnabled( false );
651  actionSetCurrentProtected->setEnabled( false );
652 
653  actionShowCurrentSolverInfo->setEnabled( false );
654 
655  }
656 }
657 
658 
659 void
660 YQPkgObjList::keyPressEvent( QKeyEvent * event )
661 {
662  if ( event )
663  {
664  Qt::KeyboardModifiers special_combo = ( Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier );
665 
666  if ( ( event->modifiers() & special_combo ) == special_combo )
667  {
668  if ( event->key() == Qt::Key_Q )
669  {
670  _debug= ! _debug;
671  yuiMilestone() << "Debug mode: " << _debug << endl;
672  }
673 
674  }
675  QTreeWidgetItem * selectedListViewItem = currentItem();
676 
677  if ( selectedListViewItem )
678  {
679  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (selectedListViewItem);
680 
681  if ( item )
682  {
683  bool installed;
684 
685  if ( item->selectable() )
686  installed = item->selectable()->hasInstalledObj();
687  else
688  installed = false;
689 
690  ZyppStatus status = item->status();
691 
692  switch( event->key() )
693  {
694  case Qt::Key_Space: // Cycle
695  item->cycleStatus();
696  event->accept();
697  return;
698 
699  case Qt::Key_Plus: // Grab everything - install or update
700 
701  if ( installed )
702  {
703  ZyppStatus newStatus = S_KeepInstalled;
704 
705  if ( item->candidateIsNewer() )
706  newStatus = S_Update;
707 
708  setCurrentStatus( newStatus );
709  }
710  else
711  setCurrentStatus( S_Install );
712  event->accept();
713  return;
714 
715  case Qt::Key_Minus: // Get rid of everything - don't install or delete
716  setCurrentStatus( installed ? S_Del : S_NoInst );
717  event->accept();
718  return;
719 
720  case Qt::Key_Exclam: // Taboo
721 
722  if ( ! installed )
723  setCurrentStatus( S_Taboo );
724  event->accept();
725  return;
726 
727  case Qt::Key_Asterisk: // Protected
728 
729  if ( installed )
730  setCurrentStatus( S_Protected );
731  event->accept();
732  return;
733 
734  case Qt::Key_Greater: // Update what is worth to be updated
735 
736  if ( installed && item->candidateIsNewer() )
737  setCurrentStatus( S_Update );
738  event->accept();
739  return;
740 
741  case Qt::Key_Less: // Revert update
742 
743  if ( status == S_Update ||
744  status == S_AutoUpdate )
745  {
746  setCurrentStatus( S_KeepInstalled );
747  }
748  event->accept();
749  return;
750 
751  case Qt::Key_B: // Toggle debugIsBroken flag
752 
753  if ( _debug )
754  {
755  item->toggleDebugIsBroken();
756  item->setStatusIcon();
757  }
758  event->accept();
759  break;
760 
761  case Qt::Key_S: // Toggle debugIsSatisfied flag
762 
763  if ( _debug )
764  {
765  item->toggleDebugIsSatisfied();
766  item->setStatusIcon();
767  }
768  event->accept();
769  break;
770  }
771  }
772  }
773  }
774  QY2ListView::keyPressEvent( event );
775 }
776 
777 
778 void
779 YQPkgObjList::message( const QString & text )
780 {
781  QY2ListViewItem * item = new QY2ListViewItem( this );
782  Q_CHECK_PTR( item );
783 
784  item->setText( nameCol() >= 0 ? nameCol() : 0, text );
785 }
786 
787 
788 void
790 {
791  _excludeRules.push_back( rule );
792 }
793 
794 
795 void
797 {
798  // yuiDebug() << "Applying exclude rules" << endl;
799  QTreeWidgetItemIterator listView_it( this );
800 
801  while ( *listView_it )
802  {
803  QTreeWidgetItem * current_item = *listView_it;
804 
805  // Advance iterator now so it remains valid even if there are changes
806  // to the QListView, e.g., if the current item is excluded and thus
807  // removed from the QListView
808  ++listView_it;
809 
810  applyExcludeRules( current_item );
811  }
812 
813  ExcludedItems::iterator excluded_it = _excludedItems->begin();
814 
815  while ( excluded_it != _excludedItems->end() )
816  {
817  QTreeWidgetItem * current_item = (*excluded_it).first;
818 
819  // Advance iterator now so it remains valid even if there are changes
820  // to the excluded items, e.g., if the current item is un-excluded and thus
821  // removed from the excluded items
822  ++excluded_it;
823 
824  applyExcludeRules( current_item );
825  }
826 
828 }
829 
830 
831 void
833 {
834  if ( _excludedItems->size() > 0 )
835  {
836  yuiMilestone() << _excludedItems->size() << " packages excluded" << endl;
837 
838  for ( ExcludeRuleList::iterator rule_it = _excludeRules.begin();
839  rule_it != _excludeRules.end();
840  ++rule_it )
841  {
842  ExcludeRule * rule = *rule_it;
843 
844  if ( rule->isEnabled() )
845  {
846  yuiMilestone() << "Active exclude rule: \""
847  << rule->regexp().pattern() << "\""
848  << endl;
849  }
850  }
851  }
852 }
853 
854 void
855 YQPkgObjList::applyExcludeRules( QTreeWidgetItem * listViewItem )
856 {
857  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *>( listViewItem );
858 
859  if ( item )
860  {
861  bool exclude = false;
862 #if VERBOSE_EXCLUDE_RULES
863  ExcludeRule * matchingRule = 0;
864 #endif
865 
866  for ( ExcludeRuleList::iterator rule_it = _excludeRules.begin();
867  rule_it != _excludeRules.end() && ! exclude;
868  ++rule_it )
869  {
870  ExcludeRule * rule = *rule_it;
871 
872  if ( rule->match( item ) )
873  {
874  exclude = true;
875 #if VERBOSE_EXCLUDE_RULES
876  matchingRule = rule;
877 #endif
878  }
879  }
880 
881  if ( exclude != item->isExcluded() ) // change exclude status?
882  {
883  this->exclude( item, exclude );
884 
885 #if VERBOSE_EXCLUDE_RULES
886  if ( exclude )
887  {
888  yuiDebug() << "Rule \"" << matchingRule->regexp().pattern()
889  << "\" matches: Excluding " << item->zyppObj()->name()
890  << endl;
891  }
892  else
893  {
894  yuiDebug() << "Un-excluding " << item->zyppObj()->name() << endl;
895  }
896 #endif
897  }
898  }
899 }
900 
901 
902 void
904 {
905  if ( exclude == item->isExcluded() )
906  return;
907 
908  item->setExcluded( exclude );
909 
910  QTreeWidgetItem * parentItem = item->parent();
911 
912  if ( parentItem )
913  parentItem->setHidden(exclude);
914  else
915  item->setHidden(exclude);
916 
917  _excludedItems->add( item, parentItem );
918 }
919 
920 
921 
922 
924  ZyppSel selectable,
925  ZyppObj zyppObj )
926  : QY2ListViewItem( pkgObjList )
927  , _pkgObjList( pkgObjList )
928  , _selectable( selectable )
929  , _zyppObj( zyppObj )
930  , _editable( true )
931  , _excluded( false )
932 {
933  init();
934 }
935 
936 
938  QY2ListViewItem * parent,
939  ZyppSel selectable,
940  ZyppObj zyppObj )
941  : QY2ListViewItem( parent )
942  , _pkgObjList( pkgObjList )
943  , _selectable( selectable )
944  , _zyppObj( zyppObj )
945  , _editable( true )
946  , _excluded( false )
947 {
948  init();
949 }
950 
951 
953  : QY2ListViewItem( pkgObjList )
954  , _pkgObjList( pkgObjList )
955  , _selectable( 0 )
956  , _zyppObj( 0 )
957  , _editable( true )
958  , _excluded( false )
959 {
960 }
961 
962 
964 {
965  // NOP
966 }
967 
968 
969 void
971 {
972  if ( _zyppObj == 0 && _selectable )
973  _zyppObj = _selectable->theObj();
974 
975  _debugIsBroken = false;
976  _debugIsSatisfied = false;
977  _candidateIsNewer = false;
978  _installedIsNewer = false;
979 
980  const ZyppObj candidate = selectable()->candidateObj();
981  const ZyppObj installed = selectable()->installedObj();
982 
983  if ( candidate && installed )
984  {
985  if ( candidate->edition() < installed->edition() )
986  _installedIsNewer = true;
987  else if ( installed->edition() < candidate->edition() )
988  _candidateIsNewer = true;
989  }
990 
991  if ( installed && ! candidate )
992  _installedIsNewer = true;
993 
994  if ( nameCol() >= 0 ) setText( nameCol(), zyppObj()->name() );
995  if ( summaryCol() >= 0 ) setText( summaryCol(), zyppObj()->summary() );
996 
997  if ( sizeCol() >= 0 )
998  {
999  zypp::ByteCount size = zyppObj()->installSize();
1000 
1001  if ( size > 0L )
1002  setText( sizeCol(), size.asString() );
1003  }
1004 
1005  if ( versionCol() == instVersionCol() ) // Display both versions in the same column: 1.2.3 (1.2.4)
1006  {
1007  if ( versionCol() >= 0 )
1008  {
1009  if ( installed )
1010  {
1011  if ( zyppObj() != installed &&
1012  zyppObj() != candidate )
1013  {
1014  setText( versionCol(), QString().sprintf( "%s", zyppObj()->edition().c_str() ) );
1015  }
1016  else
1017  {
1018  if ( candidate && installed->edition() != candidate->edition() )
1019  {
1020  setText( versionCol(),
1021  QString().sprintf( "%s (%s)",
1022  installed->edition().c_str(),
1023  candidate->edition().c_str() ) );
1024  }
1025  else // no candidate or both versions are the same anyway
1026  {
1027  setText( versionCol(),
1028  QString().sprintf( "%s", installed->edition().c_str() ) );
1029  }
1030  }
1031  }
1032  else
1033  {
1034  if ( candidate )
1035  setText( versionCol(), QString().sprintf( "(%s)", candidate->edition().c_str() ) );
1036  else
1037  setText( versionCol(), zyppObj()->edition() );
1038  }
1039 
1040  if ( _installedIsNewer )
1041  setTextColor( versionCol(), Qt::red);
1042  else if ( _candidateIsNewer )
1043  setTextColor( versionCol(), Qt::blue);
1044  }
1045  }
1046  else // separate columns for installed and available versions
1047  {
1048  if ( instVersionCol() >= 0 )
1049  {
1050  if ( installed )
1051  {
1052  setText( instVersionCol(), installed->edition() );
1053 
1054  if ( _installedIsNewer )
1055  setTextColor( instVersionCol(), Qt::red);
1056  else if ( _candidateIsNewer )
1057  setTextColor( instVersionCol(), Qt::blue);
1058  }
1059  }
1060 
1061  if ( versionCol() >= 0 )
1062  {
1063  if ( zyppObj() != installed &&
1064  zyppObj() != candidate )
1065  {
1066  setText( versionCol(), zyppObj()->edition() );
1067  }
1068  else if ( candidate )
1069  {
1070  setText( versionCol(), candidate->edition() );
1071 
1072  if ( _installedIsNewer )
1073  setTextColor( versionCol(), Qt::red);
1074  else if ( _candidateIsNewer )
1075  setTextColor( versionCol(), Qt::blue);
1076  }
1077  }
1078  }
1079 
1080  setStatusIcon();
1081 }
1082 
1083 
1084 void
1086 {
1087  init();
1088 }
1089 
1090 
1091 void
1092 YQPkgObjListItem::setText( int column, const string text )
1093 {
1094  QTreeWidgetItem::setText( column, fromUTF8( text.c_str() ) );
1095 }
1096 
1097 
1098 void
1099 YQPkgObjListItem::setText( int column, const zypp::Edition & edition )
1100 {
1101  setText( column, edition.asString() );
1102 }
1103 
1104 
1105 ZyppStatus
1107 {
1108  if ( ! selectable() )
1109  {
1110  yuiError() << "No selectable" << endl;
1111  return S_NoInst;
1112  }
1113 
1114  return selectable()->status();
1115 }
1116 
1117 
1118 bool
1120 {
1121  zypp::ResStatus::TransactByValue modifiedBy = selectable()->modifiedBy();
1122 
1123  return ( modifiedBy == zypp::ResStatus::APPL_LOW ||
1124  modifiedBy == zypp::ResStatus::APPL_HIGH );
1125 }
1126 
1127 
1128 
1129 void
1130 YQPkgObjListItem::setStatus( ZyppStatus newStatus, bool sendSignals )
1131 {
1132  ZyppStatus oldStatus = selectable()->status();
1133  selectable()->setStatus( newStatus );
1134 
1135  if ( oldStatus != selectable()->status() )
1136  {
1137  applyChanges();
1138 
1139  if ( sendSignals )
1140  {
1141  _pkgObjList->updateItemStates();
1142  _pkgObjList->sendUpdatePackages();
1143  }
1144  }
1145 
1146  setStatusIcon();
1147 }
1148 
1149 
1150 void
1152 {
1153  zypp::getZYpp()->resolver()->resolvePool();
1154 }
1155 
1156 
1157 
1158 void
1160 {
1161  setStatusIcon();
1162 }
1163 
1164 
1165 void
1167 {
1168  if ( statusCol() >= 0 )
1169  {
1170  bool enabled = editable() && _pkgObjList->editable();
1171  setIcon( statusCol(), _pkgObjList->statusIcon( status(), enabled, bySelection() ) );
1172  }
1173 
1174 
1175  if ( brokenIconCol() >= 0 )
1176  {
1177  // Reset this icon now - it might be the same column as satisfiedIconCol()
1178  setIcon( brokenIconCol(), QPixmap() );
1179  }
1180 
1181  if ( satisfiedIconCol() >= 0 )
1182  {
1183  // Set special icon for zyppObjs that are not marked as installed,
1184  // but satisfied anyway (e.g. for patches or patterns where the user
1185  // selected all required packages manually)
1186 
1187  setIcon( satisfiedIconCol(), isSatisfied() ? YQIconPool::pkgSatisfied() : QPixmap() );
1188  }
1189 
1190  if ( brokenIconCol() >= 0 )
1191  {
1192  // Set special icon for zyppObjs that are installed, but broken
1193  // (dependencies no longer satisfied, e.g. for patches or patterns)
1194 
1195  if ( isBroken() )
1196  {
1197  setIcon( brokenIconCol(), YQIconPool::warningSign() );
1198 
1199  yuiWarning() << "Broken object: " << _selectable->theObj()->name()
1200  << " - " << _selectable->theObj()->summary()
1201  << endl;
1202  }
1203  }
1204 }
1205 
1206 
1207 bool
1209 {
1210  if ( _debugIsSatisfied )
1211  return true;
1212 
1213  if ( _selectable->hasInstalledObj() )
1214  return false;
1215 
1216  return _selectable->candidateObj().isSatisfied();
1217 }
1218 
1219 
1221 {
1222  if ( _debugIsBroken )
1223  return true;
1224 
1225  if ( ! _selectable->hasInstalledObj() )
1226  return false; // can't be broken if not installed
1227 
1228  switch ( status() )
1229  {
1230  case S_KeepInstalled:
1231  case S_Protected:
1232 
1233  return _selectable->installedObj().isBroken();
1234 
1235  case S_Update: // will be fixed by updating
1236  case S_AutoUpdate:
1237  case S_Del: // will no longer be relevant after deleting
1238  case S_AutoDel:
1239 
1240  return false;
1241 
1242  case S_NoInst: // should not happen - no installed obj
1243  case S_Install:
1244  case S_AutoInstall:
1245  case S_Taboo:
1246 
1247  yuiError() << "Expected uninstalled zyppObj" << endl;
1248  return false;
1249  }
1250 
1251  yuiError() << "Should never get here" << endl;
1252  return false;
1253 }
1254 
1255 
1256 void
1258 {
1259  if ( ! _editable || ! _pkgObjList->editable() )
1260  return;
1261 
1262  ZyppStatus oldStatus = status();
1263  ZyppStatus newStatus = oldStatus;
1264 
1265  switch ( oldStatus )
1266  {
1267  case S_Install:
1268  newStatus = S_NoInst;
1269  break;
1270 
1271  case S_Protected:
1272  newStatus = selectable()->hasCandidateObj() ?
1273  S_KeepInstalled: S_NoInst;
1274  break;
1275 
1276  case S_Taboo:
1277  newStatus = selectable()->hasInstalledObj() ?
1278  S_KeepInstalled : S_NoInst;
1279  break;
1280 
1281  case S_KeepInstalled:
1282  newStatus = selectable()->hasCandidateObj() ?
1283  S_Update : S_Del;
1284  break;
1285 
1286  case S_Update:
1287  newStatus = S_Del;
1288  break;
1289 
1290  case S_AutoUpdate:
1291  newStatus = S_KeepInstalled;
1292  break;
1293 
1294  case S_Del:
1295  case S_AutoDel:
1296  newStatus = S_KeepInstalled;
1297  break;
1298 
1299  case S_NoInst:
1300  if ( selectable()->hasCandidateObj() )
1301  {
1302  newStatus = S_Install;
1303  }
1304  else
1305  {
1306  yuiWarning() << "No candidate for " << selectable()->theObj()->name() << endl;
1307  newStatus = S_NoInst;
1308  }
1309  break;
1310 
1311  case S_AutoInstall:
1312  // this used to be taboo before, but now ZYpp supports
1313  // saving weak locks (unselected packages)
1314  newStatus = S_NoInst;
1315  break;
1316  }
1317 
1318  if ( oldStatus != newStatus )
1319  {
1320  setStatus( newStatus );
1321 
1322  if ( showLicenseAgreement() )
1323  {
1324  showNotifyTexts( newStatus );
1325  }
1326  else // License not confirmed?
1327  {
1328  // Status is now S_Taboo or S_Del - update status icon
1329  setStatusIcon();
1330  }
1331 
1332  _pkgObjList->sendStatusChanged();
1333  }
1334 }
1335 
1336 
1337 void
1339 {
1340  // just return if no selectable
1341  if ( ! selectable() )
1342  return;
1343 
1344  string text;
1345 
1346  switch ( status )
1347  {
1348  case S_Install:
1349  if ( selectable()->hasCandidateObj() )
1350  text = selectable()->candidateObj()->insnotify();
1351  break;
1352 
1353  case S_NoInst:
1354  case S_Del:
1355  case S_Taboo:
1356  if ( selectable()->hasCandidateObj() )
1357  text = selectable()->candidateObj()->delnotify();
1358  break;
1359 
1360  default: break;
1361  }
1362 
1363  if ( ! text.empty() )
1364  {
1365  yuiDebug() << "Showing notify text" << endl;
1366  YQPkgTextDialog::showText( _pkgObjList, selectable(), text );
1367  }
1368 }
1369 
1370 
1371 bool
1373 {
1374  return showLicenseAgreement( selectable() );
1375 }
1376 
1377 
1378 bool
1380 {
1381  // if we have a subclass with no selectable
1382  // confirming the license should be just always
1383  // true
1384  if ( ! sel )
1385  return true;
1386 
1387  string licenseText;
1388 
1389  switch ( sel->status() )
1390  {
1391  case S_Install:
1392  case S_AutoInstall:
1393  case S_Update:
1394  case S_AutoUpdate:
1395 
1396  if ( sel->hasLicenceConfirmed() )
1397  return true;
1398 
1399  if ( sel->candidateObj() )
1400  licenseText = sel->candidateObj()->licenseToConfirm();
1401  break;
1402 
1403  default: return true;
1404  }
1405 
1406  if ( licenseText.empty() )
1407  return true;
1408 
1409  yuiDebug() << "Showing license agreement for " << sel->name() << endl;
1410 
1411  bool confirmed = YQPkgTextDialog::confirmText( (QWidget *) YDialog::currentDialog()->widgetRep(),
1412  sel, licenseText );
1413 
1414  if ( confirmed )
1415  {
1416  yuiMilestone() << "User confirmed license agreement for " << sel->name() << endl;
1417  sel->setLicenceConfirmed( true );
1418  }
1419  else
1420  {
1421  // The user rejected the license agreement -
1422  // make sure the package gets unselected.
1423 
1424  switch ( sel->status() )
1425  {
1426  case S_Install:
1427  case S_AutoInstall:
1428 
1429  yuiWarning() << "User rejected license agreement for " << sel->name()
1430  << " - setting to TABOO"
1431  << endl;
1432 
1433  sel->setStatus( S_Taboo );
1434  break;
1435 
1436 
1437  case S_Update:
1438  case S_AutoUpdate:
1439 
1440  yuiWarning() << "User rejected license agreement for " << sel->name()
1441  << " - setting to PROTECTED"
1442  << endl;
1443 
1444  sel->setStatus( S_Protected );
1445  // S_Keep wouldn't be good enough: The next solver run might
1446  // set it to S_AutoUpdate again
1447  break;
1448 
1449  default: break;
1450  }
1451  }
1452 
1453  return confirmed;
1454 }
1455 
1456 
1457 QString
1459 {
1460  if ( col == statusCol() )
1461  {
1462  QString tip = _pkgObjList->statusText( status() );
1463 
1464  switch ( status() )
1465  {
1466  case S_AutoDel:
1467  case S_AutoInstall:
1468  case S_AutoUpdate:
1469 
1470  if ( bySelection() )
1471  // Translators: Additional hint what caused an auto-status
1472  tip += "\n" + _( "(by a software selection)" );
1473  else
1474  tip += "\n" + _( "(by dependencies)" );
1475 
1476  break;
1477 
1478  default:
1479  break;
1480  }
1481 
1482  return tip;
1483  }
1484 
1485  if ( col == brokenIconCol() )
1486  {
1487  if ( isBroken() )
1488  // Translators: tool tip for patches / patterns that are installed,
1489  // but whose dependencies are broken (no longer satisfied)
1490  return _( "Dependencies broken" );
1491  }
1492 
1493  // don't use "else if" here, it might be the same colum as another one!
1494 
1495  if ( col == satisfiedIconCol() )
1496  {
1497  if ( isSatisfied() )
1498  // Translators: tool tip for patches / patterns that are not installed,
1499  // but whose dependencies are satisfied
1500  return _( "All dependencies satisfied" );
1501  }
1502 
1503  return QString::null;
1504 }
1505 
1506 
1507 
1508 bool YQPkgObjListItem::operator<( const QTreeWidgetItem & otherListViewItem ) const
1509 {
1510  const YQPkgObjListItem * other = dynamic_cast<const YQPkgObjListItem *> (&otherListViewItem);
1511  int col = treeWidget()->sortColumn();
1512 
1513  if ( other )
1514  {
1515  if ( col == nameCol() )
1516  {
1517  return ( strcasecmp( this->zyppObj()->name().c_str(), other->zyppObj()->name().c_str() ) < 0 );
1518  }
1519  if ( col == summaryCol() )
1520  {
1521  // locale aware sort
1522  return ( strcoll( this->zyppObj()->summary().c_str(), other->zyppObj()->summary().c_str() ) < 0 );
1523  }
1524  if ( col == sizeCol() )
1525  {
1526  // Numeric sort by size
1527 
1528  return ( this->zyppObj()->installSize() < other->zyppObj()->installSize() );
1529  }
1530  else if ( col == statusCol() )
1531  {
1532  // Sorting by status depends on the numeric value of the
1533  // ZyppStatus enum, thus it is important to insert new
1534  // package states there where they make most sense. We want to show
1535  // dangerous or noteworthy states first - e.g., "taboo" which should
1536  // seldeom occur, but when it does, it is important.
1537 
1538  bool b = ( this->status() < other->status() );
1539  if ( !b && this->status() == other->status() )
1540  b = this->zyppObj()->name() < other->zyppObj()->name();
1541  return b;
1542  }
1543  else if ( col == instVersionCol() ||
1544  col == versionCol() )
1545  {
1546  // Sorting by version numbers doesn't make too much sense, so let's
1547  // sort by package relation:
1548  // - Installed newer than candidate (red)
1549  // - Candidate newer than installed (blue) - worthwhile updating
1550  // - Installed
1551  // - Not installed, but candidate available
1552  //
1553  // Within these categories, sort versions by ASCII - OK, it's
1554  // pretty random, but predictable.
1555 
1556  int thisPoints = this->versionPoints();
1557  int otherPoints = other->versionPoints();
1558 
1559  if (thisPoints == otherPoints )
1560  return ( QString (this->zyppObj()->edition().c_str() ) <
1561  QString (other->zyppObj()->edition().c_str() ) );
1562  else
1563  return ( thisPoints < otherPoints );
1564  }
1565  }
1566 
1567  // Fallback: Use parent class method
1568  return QY2ListViewItem::operator<( otherListViewItem );
1569 }
1570 
1571 
1572 int
1574 {
1575  int points = 0;
1576 
1577  if ( installedIsNewer() ) points += 1000;
1578  if ( candidateIsNewer() ) points += 100;
1579  if ( selectable()->hasInstalledObj() ) points += 10;
1580  if ( selectable()->hasCandidateObj() ) points += 1;
1581 
1582  return points;
1583 }
1584 
1585 
1586 void
1588 {
1589  _excluded = excl;
1590 }
1591 
1593  const QRegExp & regexp,
1594  int column )
1595  : _parent( parent )
1596  , _regexp( regexp )
1597  , _column( column )
1598  , _enabled( true )
1599 {
1600  _parent->addExcludeRule( this );
1601 }
1602 
1603 
1604 void
1606 {
1607  _enabled = enable;
1608 
1609 #if VERBOSE_EXCLUDE_RULES
1610  yuiDebug() << ( enable ? "Enabling" : "Disabling" )
1611  << " exclude rule " << _regexp.pattern()
1612  << endl;
1613 #endif
1614 }
1615 
1616 
1617 void
1618 YQPkgObjList::ExcludeRule::setRegexp( const QRegExp & regexp )
1619 {
1620  _regexp = regexp;
1621 }
1622 
1623 
1624 void
1626 {
1627  _column = column;
1628 }
1629 
1630 
1631 bool
1632 YQPkgObjList::ExcludeRule::match( QTreeWidgetItem * item )
1633 {
1634  if ( ! _enabled )
1635  return false;
1636 
1637  QString text = item->text( _column );
1638 
1639  if ( text.isEmpty() )
1640  return false;
1641 
1642  return _regexp.exactMatch( text );
1643 }
1644 
1645 
1646 
1647 
1648 
1649 
1651  : _pkgObjList( parent )
1652 {
1653 }
1654 
1655 
1657 {
1658  clear();
1659 }
1660 
1661 
1662 void YQPkgObjList::ExcludedItems::add( QTreeWidgetItem * item, QTreeWidgetItem * oldParent )
1663 {
1664  _excludeMap.insert( ItemPair( item, oldParent ) );
1665 }
1666 
1667 
1668 void YQPkgObjList::ExcludedItems::remove( QTreeWidgetItem * item )
1669 {
1670  ItemMap::iterator it = _excludeMap.find( item );
1671 
1672  if ( it != _excludeMap.end() )
1673  {
1674  _excludeMap.erase( it );
1675  }
1676 }
1677 
1678 
1680 {
1681  for ( ItemMap::iterator it = _excludeMap.begin();
1682  it != _excludeMap.end();
1683  ++it )
1684  {
1685  delete it->first;
1686  }
1687 
1688  _excludeMap.clear();
1689 }
1690 
1691 
1692 bool YQPkgObjList::ExcludedItems::contains( QTreeWidgetItem * item )
1693 {
1694  return ( _excludeMap.find( item ) != _excludeMap.end() );
1695 }
1696 
1698 {
1699  YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> ( currentItem() );
1700 
1701  if ( item && editable() && item->editable() )
1702  {
1703  updateActions( item );
1704 
1705  if ( ! item->selectable() )
1706  return;
1707 
1708  QMenu * contextMenu =
1709  ! item->selectable()->installedEmpty() ?
1711 
1712  if ( contextMenu )
1713  contextMenu->popup( viewport()->mapToGlobal( pos ) );
1714  }
1715 }
1716 
1717 
1718 QTreeWidgetItem * YQPkgObjList::ExcludedItems::oldParentItem( QTreeWidgetItem * item )
1719 {
1720  ItemMap::iterator it = _excludeMap.find( item );
1721 
1722  if ( it == _excludeMap.end() )
1723  return 0;
1724 
1725  return it->second;
1726 }
1727 
1728 
1729 
1730 #include "YQPkgObjList.moc"
bool installedIsNewer() const
Check if the installed version is newer than the candidate.
Definition: YQPkgObjList.h:531
bool candidateIsNewer() const
Check if the candidate is newer than the installed version.
Definition: YQPkgObjList.h:526
bool isExcluded() const
Returns &#39;true&#39; if this item is excluded.
Definition: YQPkgObjList.h:606
Abstract base class to display a list of zypp::ResObjects.
Definition: YQPkgObjList.h:68
void statusChanged()
Emitted when the status of a zypp::ResObject is changed.
void setText(int column, const string text)
Set a column text via STL string.
void setExcluded(bool exclude=true)
Set this item&#39;s exclude flag.
virtual QPixmap statusIcon(ZyppStatus status, bool enabled=true, bool bySelection=false)
Returns the suitable icon for a zypp::ResObject status - the regular icon if &#39;enabled&#39; is &#39;true&#39; or t...
void addPkgObjItem(ZyppSel selectable, ZyppObj zyppObj=0)
Add a zypp::ResObject to the list.
YQPkgObjListItem(YQPkgObjList *pkgObjList, ZyppSel selectable, ZyppObj zyppObj=0)
Constructor for root items: Creates a YQPkgObjList item that corresponds to the ZYPP selectable that ...
virtual bool operator<(const QTreeWidgetItem &other) const
sorting function
void addExcludeRule(YQPkgObjList::ExcludeRule *rule)
Add an exclude rule to this list.
virtual void createInstalledContextMenu()
Create the context menu for installed items.
virtual QString statusText(ZyppStatus status) const
Returns a short (one line) descriptive text for a zypp::ResObject status.
void setAllItemStatus(ZyppStatus newStatus, bool force=false)
Sets the status of all (toplevel) list items to &#39;newStatus&#39;, if possible.
virtual QMenu * notInstalledContextMenu()
Returns the context menu for items that are installed.
bool showLicenseAgreement()
Display this item&#39;s license agreement (if there is any) that corresponds to its current status (S_Ins...
iterator begin()
Returns an iterator that points to the first excluded item.
Definition: YQPkgObjList.h:834
virtual void updateData()
Update this item&#39;s data completely.
virtual void clear()
Reimplemented from QY2ListView: Emit currentItemChanged() signal after clearing the list...
void setColumn(int column=0)
Change the column number to check against after creation.
virtual void message(const QString &text)
Display a one-line message in the list.
static bool confirmText(QWidget *parent, const QString &text, const QString &acceptButtonLabel, const QString &rejectButtonLabel)
Let the user confirm a text.
virtual void updateStatus()
Update this item&#39;s status.
void addPassiveItem(const QString &name, const QString &summary=QString::null, FSize size=-1)
Add a purely passive list item that has a name and optional summary and size.
ExcludeRule(YQPkgObjList *parent, const QRegExp &regexp, int column=0)
Constructor: Creates a new exclude rule with a regular expression to check against the text of the sp...
void createActions()
Create the actions for the context menus.
virtual void setStatus(ZyppStatus newStatus, bool sendSignals=true)
Set the (binary RPM) package status.
QRegExp regexp() const
Returns the regexp.
Definition: YQPkgObjList.h:744
QAction * createAction(ZyppStatus status, const QString &key=QString::null, bool enabled=false)
Create an action based on a zypp::ResObject status - automatically retrieve the corresponding status ...
virtual void pkgObjClicked(int button, QTreeWidgetItem *item, int col, const QPoint &pos)
Dispatcher slot for mouse click: cycle status depending on column.
void enable(bool enable=true)
Enable or disable this exclude rule.
void logExcludeStatistics()
Write statistics about excluded items to the log, if there are any.
virtual void currentItemChangedInternal(QTreeWidgetItem *item)
Dispatcher slot for selection change - internal only.
bool isBroken() const
Check if this item is "broken": If it is installed, but any of its dependencies are no longer satisfi...
bool editable() const
Return whether or not this items is editable, i.e.
Definition: YQPkgObjList.h:478
virtual void updateActions(YQPkgObjListItem *item=0)
Update the internal actions for the currently selected item ( if any ).
void showSolverInfo()
Show solver information about the current selected item.
void sendStatusChanged()
Emit a statusChanged() signal for the specified zypp::ResObject.
Definition: YQPkgObjList.h:248
void exclude(YQPkgObjListItem *item, bool exclude)
Exclude or include an item, i.e.
void selectNextItem()
Select the next item, i.e.
virtual bool createZyppSolverDialog(const zypp::PoolItem item)
Create and show a QZyppDialog widget.
void updatePackages()
Emitted when it&#39;s time to update displayed package information, e.g., package states.
iterator end()
Returns an iterator that points after the last excluded item.
Definition: YQPkgObjList.h:839
virtual ZyppStatus status() const
Returns the (binary RPM) package status.
bool match(QTreeWidgetItem *item)
Check a list item against this exclude rule.
static void showText(QWidget *parent, const QString &text)
Show a text and wait until the user confirmed with &#39;OK&#39;.
bool editable() const
Return whether or not items in this list are generally editable, i.e.
Definition: YQPkgObjList.h:110
void clear()
Clear the excluded items.
ExcludedItems(YQPkgObjList *parent)
Constructor.
virtual void applyChanges()
Apply changes hook.
Definition: YQPkgObjList.h:655
void applyExcludeRules()
Apply all exclude rules of this list to all items, including those that are currently excluded...
bool contains(QTreeWidgetItem *item)
Returns &#39;true&#39; if the specified item is in the excluded items.
void setRegexp(const QRegExp &regexp)
Change the regular expression after creation.
QTreeWidgetItem * oldParentItem(QTreeWidgetItem *item)
Returns the old parent of this item so it can be reparented or 0 if it was a root item...
int size() const
Returns the number of items.
Definition: YQPkgObjList.h:829
virtual QMenu * addAllInListSubMenu(QMenu *menu)
Add a submenu "All in this list..." to &#39;menu&#39;.
ZyppSel selectable() const
Returns the original selectable within the package manager backend.
Definition: YQPkgObjList.h:466
bool isSatisfied() const
Check if this item is satisfied, even though it is not installed.
void currentItemChanged(ZyppSel selectable)
Emitted when a zypp::ui::Selectable is selected.
void slotCustomContextMenu(const QPoint &pos)
slot that shows context menu when requested
void setCurrentStatus(ZyppStatus newStatus, bool selectNextItem=false, bool ifNewerOnly=false)
Sets the currently selected item&#39;s status.
void sendUpdatePackages()
Emit an updatePackages() signal.
Definition: YQPkgObjList.h:237
virtual void createNotInstalledContextMenu()
Create the context menu for items that are not installed.
virtual QMenu * installedContextMenu()
Returns the context menu for items that are not installed.
virtual bool bySelection() const
Returns &#39;true&#39; if this selectable&#39;s status is set by a selection (rather than by the user or by the d...
bool isEnabled() const
Returns &#39;true&#39; if this exclude rule is enabled, &#39;false&#39; otherwise.
Definition: YQPkgObjList.h:734
virtual QString toolTip(int column)
Returns a tool tip text for a specific column of this item.
void solveResolvableCollections()
Do a "small" solver run for all "resolvable collections", i.e., for selections, patterns, languages, patches.
virtual ~YQPkgObjList()
Destructor.
void showNotifyTexts(ZyppStatus status)
Display this item&#39;s notify text (if there is any) that corresponds to the specified status (S_Install...
virtual void keyPressEvent(QKeyEvent *ev)
Event handler for keyboard input.
YQPkgObjList(QWidget *parent)
Constructor.
Definition: YQPkgObjList.cc:71
virtual ~ExcludedItems()
Destructor.
static bool showLicenseAgreement(ZyppSel sel)
Display a selectable&#39;s license agreement (if there is any) that corresponds to its current status (S_...
void add(QTreeWidgetItem *item, QTreeWidgetItem *oldParent)
Add a list item to the excluded items and transfer ownership to this class.
int versionPoints() const
Calculate a numerical value to compare versions, based on version relations:
virtual ~YQPkgObjListItem()
Destructor.
virtual void setStatusIcon()
Set a status icon according to the package&#39;s status.
ZyppObj zyppObj() const
Returns the original object within the package manager backend.
Definition: YQPkgObjList.h:471
virtual void cycleStatus()
Cycle the package status to the next valid value.
void init()
Initialize internal data and set fields accordingly.
void remove(QTreeWidgetItem *item)
Remove a list item from the excluded items and transfer ownership back to the caller.