libyui-qt-pkg  2.42.13
 All Classes Functions Variables Enumerations
YQPkgPatchList.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: YQPkgPatchList.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 
45 #include <QPainter>
46 #include <QItemDelegate>
47 #include <QMenu>
48 #include <QAction>
49 #include <QEvent>
50 #include <QHeaderView>
51 #include <zypp/base/Logger.h>
52 #include <set>
53 
54 #include "YQi18n.h"
55 #include "utf8.h"
56 
57 #include "YQPkgPatchList.h"
58 #include "YQPkgTextDialog.h"
59 #include "YQIconPool.h"
60 
61 using std::list;
62 using std::endl;
63 using std::set;
64 
65 class YQPkgPatchItemDelegate : public QItemDelegate
66 {
67  YQPkgPatchList *_view;
68 public:
69  YQPkgPatchItemDelegate( YQPkgPatchList *parent ) : QItemDelegate( parent ), _view( parent ) {
70  }
71 
72  virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
73  {
74  painter->save();
75  //QColor background = option.palette.color(QPalette::Window);
76 
77  YQPkgPatchCategoryItem *citem = dynamic_cast<YQPkgPatchCategoryItem *>(_view->itemFromIndex(index));
78  // special painting for category items
79  if ( citem )
80  {
81  QFont f = painter->font();
82  f.setWeight(QFont::Bold);
83  QFontMetrics fm(f);
84  f.setPixelSize( (int) ( fm.height() * 1.05 ) );
85  citem->setFont(_view->summaryCol(), f);
86 
87  painter->fillRect(option.rect, option.palette.color(QPalette::AlternateBase));
88  QItemDelegate::paint(painter, option, index);
89  painter->restore();
90  return;
91  }
92 
93  YQPkgPatchListItem *item = dynamic_cast<YQPkgPatchListItem *>(_view->itemFromIndex(index));
94  if ( item )
95  {
96  painter->restore();
97  QItemDelegate::paint(painter, option, index);
98  }
99  }
100 };
101 
102 
104  : YQPkgObjList( parent )
105 {
106  yuiDebug() << "Creating patch list" << endl;
107 
108  _filterCriteria = RelevantPatches;
109 
110  int numCol = 0;
111 
112  QStringList headers;
113 
114  headers << ""; _statusCol = numCol++;
115  //headers << _( "Patch" ); _nameCol = numCol++;
116  headers << _( "Summary" ); _summaryCol = numCol++;
117  //headers << _( "Category" ); _categoryCol = numCol++;
118  //headers << _( "Size" ); _sizeCol = numCol++;
119  //headers << _( "Version" ); _versionCol = numCol++;
120 
121  // Can use the same colum for "broken" and "satisfied":
122  // Both states are mutually exclusive
123 
124  _satisfiedIconCol = -42;
125  _brokenIconCol = -42;
126 
127  setHeaderLabels(headers);
128  setIndentation(0);
129 
130  header()->setResizeMode(_statusCol, QHeaderView::ResizeToContents);
131  //header()->setResizeMode(_versionCol, QHeaderView::ResizeToContents);
132  //header()->setResizeMode(_categoryCol, QHeaderView::ResizeToContents);
133  header()->setResizeMode(_summaryCol, QHeaderView::Stretch);
134 
135 
136  setItemDelegateForColumn( _summaryCol, new YQPkgPatchItemDelegate( this ) );
137  setItemDelegateForColumn( _statusCol, new YQPkgPatchItemDelegate( this ) );
138 
139  setAllColumnsShowFocus( true );
140  //FIXME setColumnAlignment( sizeCol(), Qt::AlignRight );
141 
142  connect( this, SIGNAL( currentItemChanged ( QTreeWidgetItem *, QTreeWidgetItem* ) ),
143  this, SLOT ( filter() ) );
144 
145  //sortItems( categoryCol(), Qt::AscendingOrder );
146  setSortingEnabled( true );
147 
148  fillList();
149 
150  yuiDebug() << "Creating patch list done" << endl;
151 }
152 
153 
155 {
156  // NOP
157 }
158 
159 
160 void
162 {
163  // Delayed initialization after widget is fully created etc.
164 
165  // Only now send currentItemChanged() signal so attached details views also
166  // display something if their showDetailsIfVisible() slot is connected to
167  // currentItemChanged() signals.
168  selectSomething();
169 }
170 
172 YQPkgPatchList::category( YQPkgPatchCategory category )
173 {
174  YQPkgPatchCategoryItem * cat = _categories[ category ];
175 
176  if ( ! cat )
177  {
178  yuiDebug() << "New patch category \""<< category << "\"" << endl;
179 
180  cat = new YQPkgPatchCategoryItem( category, this );
181  Q_CHECK_PTR( cat );
182  _categories.insert( category, cat );
183  }
184 
185  return cat;
186 }
187 
188 void
189 YQPkgPatchList::setFilterCriteria( FilterCriteria filterCriteria )
190 {
191  _filterCriteria = filterCriteria;
192 }
193 
194 void
196 {
197  // wee need to do a full solve in order
198  // to get the satisfied status correctly
199 
200  _categories.clear();
201 
202  clear();
203  yuiDebug() << "Filling patch list" << endl;
204 
205  for ( ZyppPoolIterator it = zyppPatchesBegin();
206  it != zyppPatchesEnd();
207  ++it )
208  {
209  ZyppSel selectable = *it;
210  ZyppPatch zyppPatch = tryCastToZyppPatch( selectable->theObj() );
211 
212  if ( zyppPatch )
213  {
214  bool displayPatch = false;
215 
216  switch ( _filterCriteria )
217  {
218  case RelevantPatches: // needed + broken + satisfied (but not installed)
219 
220  // only shows patches relevant to the system
221  if ( selectable->hasCandidateObj() &&
222  selectable->candidateObj().isRelevant() )
223  {
224  // and only those that are needed
225  if ( ! selectable->candidateObj().isSatisfied() ||
226  // may be it is satisfied because is preselected
227  selectable->candidateObj().status().isToBeInstalled() )
228  displayPatch = true;
229  else
230  yuiDebug() << "Patch " << zyppPatch->ident()
231  << " is already satisfied"
232  << endl;
233 
234  }
235  else
236  yuiDebug() << "Patch " << zyppPatch->ident()
237  << " is not relevant to the system"
238  << endl;
239  break;
240  case RelevantAndInstalledPatches: // patches we dont need
241 
242  // only shows patches relevant to the system
243  if ( ( selectable->hasCandidateObj() ) &&
244  ( ! selectable->candidateObj().isRelevant()
245  || ( selectable->candidateObj().isSatisfied() &&
246  ! selectable->candidateObj().status().isToBeInstalled() ) ) )
247  {
248  // now we show satisfied patches too
249  displayPatch = true;
250  }
251  break;
252  case AllPatches:
253  displayPatch = true;
254  break;
255 
256  // Intentionally omitting "default" so the compiler
257  // can catch unhandled enum values
258  default:
259  yuiDebug() << "unknown patch filter" << endl;
260 
261  }
262 
263  if ( displayPatch )
264  {
265  yuiDebug() << "Displaying patch " << zyppPatch->name()
266  << " - " << zyppPatch->summary()
267  << endl;
268  addPatchItem( *it, zyppPatch);
269  }
270  }
271  else
272  {
273  yuiError() << "Found non-patch selectable" << endl;
274  }
275  }
276 
277  yuiDebug() << "Patch list filled" << endl;
278  resizeColumnToContents(_statusCol);
279  //resizeColumnToContents(_nameCol);
280  //resizeColumnToContents(_categoryCol);
281 }
282 
283 
284 
285 void
286 YQPkgPatchList::message( const QString & text )
287 {
288  QY2ListViewItem * item = new QY2ListViewItem( this );
289  Q_CHECK_PTR( item );
290 
291  item->setText( 1, text );
292  item->setBackgroundColor( 0, QColor( 0xE0, 0xE0, 0xF8 ) );
293 }
294 
295 void
297 {
298  if ( isVisible() )
299  filter();
300 }
301 
302 
303 void
305 {
306  emit filterStart();
307 
308  if ( selection() )
309  {
310  ZyppPatch patch = selection()->zyppPatch();
311 
312  if ( patch )
313  {
314  zypp::Patch::Contents contents(patch->contents());
315  yuiMilestone() << contents << endl;
316 
317  for ( zypp::Patch::Contents::Selectable_iterator it = contents.selectableBegin();
318  it != contents.selectableEnd();
319  ++it )
320  {
321  ZyppPkg zyppPkg = tryCastToZyppPkg( (*it)->theObj() );
322  if ( zyppPkg )
323  {
324  emit filterMatch( *it, zyppPkg );
325  }
326  }
327  }
328  else
329  {
330  yuiMilestone() << "patch is bogus" << endl;
331  }
332 
333  }
334  else
335  yuiWarning() << "selection empty" << endl;
336 
337  emit filterFinished();
338 }
339 
340 
341 void
342 YQPkgPatchList::addPatchItem( ZyppSel selectable,
343  ZyppPatch zyppPatch )
344 {
345  if ( ! selectable || ! zyppPatch )
346  {
347  yuiError() << "NULL ZyppSel!" << endl;
348  return;
349  }
350 
351  YQPkgPatchCategory ncat = YQPkgPatchCategoryItem::patchCategory(zyppPatch->category());
352 
353  YQPkgPatchCategoryItem * cat = category(ncat);
354  YQPkgPatchListItem * item = 0;
355 
356  if ( cat )
357  {
358  item = new YQPkgPatchListItem( this, cat, selectable, zyppPatch );
359  }
360  else
361  {
362  item = new YQPkgPatchListItem( this, selectable, zyppPatch );
363  }
364 
365  if (item)
366  applyExcludeRules( item );
367 
368 }
369 
370 
373 {
374  QTreeWidgetItem * item = currentItem();
375 
376  if ( ! item )
377  return 0;
378 
379  return dynamic_cast<YQPkgPatchListItem *> (item);
380 }
381 
382 
383 
384 void
386 {
387  _notInstalledContextMenu = new QMenu( this );
388  Q_CHECK_PTR( _notInstalledContextMenu );
389 
390  _notInstalledContextMenu->addAction(actionSetCurrentInstall);
391  _notInstalledContextMenu->addAction(actionSetCurrentDontInstall);
392  _notInstalledContextMenu->addAction(actionSetCurrentTaboo);
393 
394  addAllInListSubMenu( _notInstalledContextMenu );
395 }
396 
397 
398 void
400 {
401  _installedContextMenu = new QMenu( this );
402  Q_CHECK_PTR( _installedContextMenu );
403 
404  _installedContextMenu->addAction(actionSetCurrentKeepInstalled);
405 
406 #if ENABLE_DELETING_PATCHES
407  _installedContextMenu->addAction(actionSetCurrentDelete);
408 #endif
409 
410  _installedContextMenu->addAction(actionSetCurrentUpdate);
411  _installedContextMenu->addAction(actionSetCurrentUpdateForce);
412  _installedContextMenu->addAction(actionSetCurrentProtected);
413 
414  addAllInListSubMenu( _installedContextMenu );
415 }
416 
417 
418 QMenu *
420 {
421  QMenu * submenu = new QMenu( menu );
422  Q_CHECK_PTR( submenu );
423 
424  submenu->addAction(actionSetListInstall);
425  submenu->addAction(actionSetListDontInstall);
426  submenu->addAction(actionSetListKeepInstalled);
427 
428 #if ENABLE_DELETING_PATCHES
429  submenu->addAction(actionSetListDelete);
430 #endif
431 
432  submenu->addAction(actionSetListUpdate);
433  submenu->addAction(actionSetListUpdateForce);
434  submenu->addAction(actionSetListTaboo);
435  submenu->addAction(actionSetListProtected);
436 
437  QAction *action = menu->addMenu(submenu);
438  action->setText(_( "&All in This List" ));
439 
440  return submenu;
441 }
442 
443 
444 void
445 YQPkgPatchList::keyPressEvent( QKeyEvent * event )
446 {
447  if ( event )
448  {
449 #if ! ENABLE_DELETING_PATCHES
450  if ( event->ascii() == '-' )
451  {
452  QTreeWidgetItem * selectedListViewItem = currentItem();
453 
454  if ( selectedListViewItem )
455  {
456  YQPkgPatchListItem * item = dynamic_cast<YQPkgPatchListItem *> (selectedListViewItem);
457 
458  if ( item && item->selectable()->hasInstalledObj() )
459  {
460  yuiWarning() << "Deleting patches is not supported" << endl;
461  return;
462  }
463  }
464  }
465 #endif
466  }
467 
469 }
470 
471 
473  YQPkgPatchCategoryItem * parentCategory,
474  ZyppSel selectable,
475  ZyppPatch zyppPatch )
476  : YQPkgObjListItem( patchList, parentCategory, selectable, zyppPatch )
477  , _patchList( patchList )
478  , _zyppPatch( zyppPatch )
479 {
480 
481  init();
482 }
483 
485  ZyppSel selectable,
486  ZyppPatch zyppPatch )
487  : YQPkgObjListItem( patchList, selectable, zyppPatch )
488  , _patchList( patchList )
489  , _zyppPatch( zyppPatch )
490 {
491  init();
492 
493 }
494 
495 void YQPkgPatchListItem::init()
496 {
497  setStatusIcon();
498 
499  if ( summaryCol() > -1 && _zyppPatch->summary().empty() )
500  setText( summaryCol(), _zyppPatch->name() ); // use name as fallback
501 }
502 
503 
505 {
506  // NOP
507 }
508 
509 void
511 {
513 
514  if ( status() == S_Del ) // Can't delete patches
515  setStatus( S_KeepInstalled );
516 }
517 
518 
519 QString
521 {
522  QString text;
523 
524  if ( col == statusCol() )
525  {
526  text = YQPkgObjListItem::toolTip( col );
527  }
528  else
529  {
530  if ( ( col == brokenIconCol() && isBroken() ) ||
531  ( col == satisfiedIconCol() && isSatisfied() ) )
532  {
533  text = YQPkgObjListItem::toolTip( col );
534  }
535  else
536  {
537  text = fromUTF8( zyppPatch()->category() );
538 
539  if ( ! text.isEmpty() )
540  text += "\n";
541 
542  text += fromUTF8( zyppPatch()->downloadSize().asString().c_str() );
543  }
544  }
545 
546  return text;
547 }
548 
549 
550 void
552 {
554 }
555 
556 
557 bool YQPkgPatchListItem::operator< ( const QTreeWidgetItem & otherListViewItem ) const
558 {
559  const YQPkgPatchListItem * other = dynamic_cast<const YQPkgPatchListItem *> (&otherListViewItem);
560  if ( other )
561  {
562  return ( this->text(_patchList->summaryCol()) < other->text( _patchList->summaryCol()) );
563  }
564  return YQPkgObjListItem::operator<( otherListViewItem );
565 }
566 
568  YQPkgPatchList * patchList )
569  : QY2ListViewItem( patchList )
570  , _patchList( patchList )
571 {
572 
573  _category = category;
574 
575 
576  if ( _patchList->categoryCol() > -1 )
577  setText( _patchList->summaryCol(), YQPkgPatchCategoryItem::asString( _category ) );
578 
579 
580  //setText( _patchList->summaryCol(), "Category" );
581 
582  setExpanded( true );
583  setTreeIcon();
584 }
585 
586 
587 YQPkgPatchCategory
588 YQPkgPatchCategoryItem::patchCategory( const string & category )
589 {
590  return patchCategory( fromUTF8( category ) );
591 }
592 
593 
594 YQPkgPatchCategory
596 {
597  category = category.toLower();
598 
599  if ( category == "yast" ) return YQPkgYaSTPatch;
600  if ( category == "security" ) return YQPkgSecurityPatch;
601  if ( category == "recommended" ) return YQPkgRecommendedPatch;
602  if ( category == "optional" ) return YQPkgOptionalPatch;
603  if ( category == "document" ) return YQPkgDocumentPatch;
604 
605  yuiWarning() << "Unknown patch category \"" << category << "\"" << endl;
606  return YQPkgUnknownPatchCategory;
607 }
608 
609 
610 QString
611 YQPkgPatchCategoryItem::asString( YQPkgPatchCategory category )
612 {
613  switch ( category )
614  {
615  // Translators: These are patch categories
616  case YQPkgYaSTPatch: return _( "YaST" );
617  case YQPkgSecurityPatch: return _( "security" );
618  case YQPkgRecommendedPatch: return _( "recommended" );
619  case YQPkgOptionalPatch: return _( "optional" );
620  case YQPkgDocumentPatch: return _( "document" );
621  case YQPkgUnknownPatchCategory: return "";
622  }
623 
624  return "";
625 }
626 
627 
629 {
630  // NOP
631 }
632 
633 void
635 {
636  if ( ! _firstPatch )
637  {
638  _firstPatch = patch;
639  }
640  else
641  {
642  //if ( _firstPatch->order().compare( pattern->order() ) < 0 )
643  // _firstPatch = pattern;
644  }
645 }
646 
647 
648 void
649 YQPkgPatchCategoryItem::setExpanded( bool open )
650 {
651  QTreeWidgetItem::setExpanded( open );
652  setTreeIcon();
653 }
654 
655 
656 void
658 {
659  setIcon( _patchList->iconCol(),
660  isExpanded() ?
661  YQIconPool::treeMinus() :
662  YQIconPool::treePlus() );
663 
664 }
665 
666 
667 bool YQPkgPatchCategoryItem::operator< ( const QTreeWidgetItem & otherListViewItem ) const
668 {
669  const YQPkgPatchCategoryItem * otherCategoryItem = dynamic_cast<const YQPkgPatchCategoryItem *>(&otherListViewItem);
670 
671  return category() > otherCategoryItem->category();
672  return QTreeWidgetItem::operator<( otherListViewItem );
673 }
674 
675 
676 
677 #include "YQPkgPatchList.moc"
ZyppSel selectable() const
Definition: YQPkgObjList.h:466
Abstract base class to display a list of zypp::ResObjects. Handles most generic stuff like setting st...
Definition: YQPkgObjList.h:68
virtual bool operator<(const QTreeWidgetItem &other) const
void setText(int column, const string text)
Display a list of zypp::Patch objects.
virtual void polish()
virtual void applyChanges()
ZyppPatch zyppPatch() const
virtual ~YQPkgPatchListItem()
virtual void clear()
YQPkgPatchListItem * selection() const
virtual void keyPressEvent(QKeyEvent *ev)
virtual void cycleStatus()
virtual void setStatus(ZyppStatus newStatus, bool sendSignals=true)
YQPkgPatchCategory category() const
void filterMatch(ZyppSel selectable, ZyppPkg pkg)
YQPkgPatchList(QWidget *parent)
virtual bool operator<(const QTreeWidgetItem &other) const
YQPkgPatchCategoryItem(YQPkgPatchCategory category, YQPkgPatchList *patternList)
virtual void createInstalledContextMenu()
virtual void message(const QString &text)
static QString asString(YQPkgPatchCategory category)
void applyExcludeRules()
virtual void createNotInstalledContextMenu()
virtual ~YQPkgPatchList()
bool isBroken() const
void currentItemChanged(ZyppSel selectable)
FilterCriteria filterCriteria() const
virtual QMenu * addAllInListSubMenu(QMenu *menu)
void filterFinished()
bool isSatisfied() const
int categoryCol() const
void filterStart()
static YQPkgPatchCategory patchCategory(QString category)
void addPatchItem(ZyppSel selectable, ZyppPatch zyppPatch)
void addPatch(ZyppPatch patch)
virtual QString toolTip(int column)
virtual bool operator<(const QTreeWidgetItem &other) const
void solveResolvableCollections()
virtual QString toolTip(int column)
virtual void keyPressEvent(QKeyEvent *ev)
virtual ZyppStatus status() const
void setFilterCriteria(FilterCriteria filterCriteria)
YQPkgPatchListItem(YQPkgPatchList *patchList, ZyppSel selectable, ZyppPatch zyppPatch)
YQPkgPatchCategoryItem * category(YQPkgPatchCategory category)
virtual void setStatusIcon()
virtual void cycleStatus()