libyui-qt-pkg  2.47.5
YQPkgVersionsView.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: YQPkgVersionsView.cc
35 
36  Author: Stefan Hundhammer <sh@suse.de>
37 
38  Textdomain "qt-pkg"
39 
40 /-*/
41 
42 #define YUILogComponent "qt-pkg"
43 
44 #include <YQZypp.h>
45 #include <zypp/Repository.h>
46 #include "YUILog.h"
47 #include <QTabWidget>
48 #include <QRegExp>
49 #include <QHeaderView>
50 #include <QStylePainter>
51 #include <QStyleOptionButton>
52 #include <QMessageBox>
53 #include <QApplication>
54 
55 
56 #include "YQPkgVersionsView.h"
57 #include "YQPkgRepoList.h"
58 #include "YQIconPool.h"
59 #include "YQSignalBlocker.h"
60 #include "YQi18n.h"
61 #include "utf8.h"
62 
63 using std::endl;
64 
65 
67  : QScrollArea( parent )
68  , _buttonGroup( 0 )
69  , _layout( 0 )
70 {
71  _selectable = 0;
72  _isMixedMultiVersion = false;
73  _parentTab = dynamic_cast<QTabWidget *> (parent);
74 
75  if ( _parentTab )
76  {
77  connect( _parentTab, SIGNAL( currentChanged( int ) ),
78  this, SLOT ( reload ( int ) ) );
79  }
80 }
81 
82 
84 {
85  // NOP
86 }
87 
88 
89 void
90 YQPkgVersionsView::reload( int newCurrent )
91 {
92  if ( _parentTab && _parentTab->widget( newCurrent ) == this )
93  showDetailsIfVisible( _selectable );
94 }
95 
96 
97 void
99 {
100  _selectable = selectable;
101  _isMixedMultiVersion = isMixedMultiVersion( selectable );
102 
103  if ( _parentTab ) // Is this view embedded into a tab widget?
104  {
105  if ( _parentTab->currentWidget() == this ) // Is this page the topmost?
107  }
108  else // No tab parent - simply show data unconditionally.
109  {
111  }
112 }
113 
114 
115 void
116 YQPkgVersionsView::showDetails( ZyppSel selectable )
117 {
118  _selectable = selectable;
119  _isMixedMultiVersion = isMixedMultiVersion( selectable );
120  QWidget * content = widget();
121  delete content; // This recursively deletes all child widgets and qobjects
122 
123  content = new QWidget( this );
124  _buttonGroup = new QButtonGroup( content );
125  _layout = new QVBoxLayout( content );
126  content->setLayout( _layout );
127 
128  if ( ! selectable )
129  {
130  setWidget( content ); // Prevent mem leak
131  return;
132  }
133 
134  QLabel * pkgNameLabel = new QLabel( this );
135 
136  if ( ! selectable->theObj() )
137  return;
138 
139  _layout->addWidget( pkgNameLabel );
140 
141  QFont font = pkgNameLabel->font();
142  font.setBold( true );
143 
144  QFontMetrics fm( font) ;
145  font.setPixelSize( (int) ( fm.height() * 1.1 ) );
146 
147  pkgNameLabel->setFont( font );
148  pkgNameLabel->setText( fromUTF8(selectable->theObj()->name().c_str()) );
149 
150  if ( selectable->multiversionInstall() ) // at least one (!) PoolItem is multiversion
151  {
152  //
153  // Find installed and available objects (for multiversion view)
154  //
155  {
156  zypp::ui::Selectable::picklist_iterator it = selectable->picklistBegin();
157 
158  while ( it != selectable->picklistEnd() )
159  {
160  YQPkgMultiVersion * version = new YQPkgMultiVersion( this, selectable, *it );
161 
162  _layout->addWidget( version );
163 
164  connect( version, SIGNAL( statusChanged() ),
165  this, SIGNAL( statusChanged() ) );
166 
167  connect( this, SIGNAL( statusChanged() ),
168  version, SLOT ( update() ) );
169 
170  ++it;
171  }
172 
173  }
174  }
175  else
176  {
177  //
178  // Fill installed objects
179  //
180  {
181  zypp::ui::Selectable::installed_iterator it = selectable->installedBegin();
182 
183  while ( it != selectable->installedEnd() )
184  {
185  // Cache this, it's somewhat expensive
186  bool retracted = installedIsRetracted( selectable, *it );
187  QString text;
188 
189  if ( retracted )
190  {
191  text = _( "%1-%2 [RETRACTED] from vendor %3 (installed)" )
192  .arg( fromUTF8( (*it)->edition().asString().c_str() ) )
193  .arg( fromUTF8( (*it)->arch().asString().c_str() ) )
194  .arg( fromUTF8( (*it)->vendor().c_str() ) ) ;
195 
196  }
197  else
198  {
199  text = _( "%1-%2 from vendor %3 (installed)" )
200  .arg( fromUTF8( (*it)->edition().asString().c_str() ) )
201  .arg( fromUTF8( (*it)->arch().asString().c_str() ) )
202  .arg( fromUTF8( (*it)->vendor().c_str() ) ) ;
203  }
204 
205  QWidget * installedVersion = new QWidget( this );
206  QHBoxLayout * instLayout = new QHBoxLayout( installedVersion );
207  instLayout->setContentsMargins( 0, 0, 0, 0 );
208 
209  QLabel * icon = new QLabel( installedVersion );
210  icon->setPixmap( YQIconPool::pkgSatisfied() );
211  instLayout->addWidget( icon );
212 
213  QLabel * textLabel = new QLabel( text, installedVersion );
214  instLayout->addWidget( textLabel );
215  instLayout->addStretch();
216 
217  if ( retracted )
218  setRetractedColor( textLabel );
219 
220  _layout->addWidget( installedVersion );
221 
222  ++it;
223  }
224  }
225 
226 
227  //
228  // Fill available objects
229  //
230 
231  {
232  zypp::ui::Selectable::available_iterator it = selectable->availableBegin();
233 
234  while ( it != selectable->availableEnd() )
235  {
236  YQPkgVersion *radioButton = new YQPkgVersion( this, selectable, *it );
237 
238  connect( radioButton, SIGNAL( clicked( bool ) ),
239  this, SLOT ( checkForChangedCandidate() ) );
240 
241  _buttonGroup->addButton( radioButton );
242  _layout->addWidget( radioButton );
243 
244  if ( ! _buttonGroup->checkedButton() &&
245  selectable->hasCandidateObj() &&
246  selectable->candidateObj()->edition() == (*it)->edition() &&
247  selectable->candidateObj()->arch() == (*it)->arch() )
248  {
249  radioButton->setChecked( true );
250  }
251 
252  ++it;
253  }
254  }
255  }
256 
257  _layout->addStretch();
258 
259  // This really needs to wait until this point, or the content will never
260  // get its correct size and become visible.
261 
262  setWidget( content );
263  content->show();
264 }
265 
266 
267 void YQPkgVersionsView::setRetractedColor( QWidget * widget )
268 {
269  QPalette pal = widget->palette();
270  pal.setColor( QPalette::WindowText, Qt::red );
271  widget->setPalette( pal );
272 }
273 
274 
275 bool YQPkgVersionsView::installedIsRetracted( ZyppSel selectable, ZyppObj installed )
276 {
277  zypp::ui::Selectable::available_iterator it = selectable->availableBegin();
278 
279  while ( it != selectable->availableEnd() )
280  {
281  if ( (*it)->isRetracted() )
282  {
283  if ( installed->edition() == (*it)->edition() &&
284  installed->arch() == (*it)->arch() &&
285  installed->vendor() == (*it)->vendor() )
286  {
287  return true;
288  }
289  }
290 
291  ++it;
292  }
293 
294  return false;
295 }
296 
297 
298 void
300 {
301  QListIterator<QAbstractButton*> it( _buttonGroup->buttons() );
302 
303  while ( it.hasNext() )
304  {
305  YQPkgVersion * versionItem = dynamic_cast<YQPkgVersion *> (it.next());
306 
307  if ( versionItem && versionItem->isChecked() )
308  {
309  ZyppObj newCandidate = versionItem->zyppObj();
310 
311  if ( _selectable && *newCandidate != _selectable->candidateObj() )
312  {
313  yuiMilestone() << "Candidate changed" << endl;
314 
315  // Change status of selectable
316 
317  ZyppStatus status = _selectable->status();
318 
319  if ( !_selectable->installedEmpty() &&
320  _selectable->installedObj()->arch() == newCandidate->arch() &&
321  _selectable->installedObj()->edition() == newCandidate->edition() )
322  {
323  // Switch back to the original instance -
324  // the version that was previously installed
325  status = S_KeepInstalled;
326  }
327  else
328  {
329  switch ( status )
330  {
331  case S_KeepInstalled:
332  case S_Protected:
333  case S_AutoDel:
334  case S_AutoUpdate:
335  case S_Del:
336  case S_Update:
337 
338  status = S_Update;
339  break;
340 
341  case S_NoInst:
342  case S_Taboo:
343  case S_Install:
344  case S_AutoInstall:
345  status = S_Install;
346  break;
347  }
348  }
349 
350  _selectable->setStatus( status );
351 
352 
353  // Set candidate
354 
355  _selectable->setCandidate( newCandidate );
356  emit candidateChanged( newCandidate );
357  return;
358  }
359  }
360  }
361 }
362 
363 
364 QSize
366 {
367  return QSize( 0, 0 );
368 }
369 
370 
371 bool
373 {
374  ZyppPoolItem poolItem = newSelected->zyppPoolItem();
375  Q_CHECK_PTR( poolItem );
376 
377  bool multiVersion = poolItem->multiversionInstall();
378 
379  yuiMilestone() << "Selected: "
380  << ( multiVersion ? "Multiversion " : "Non-Multiversion " )
381  << newSelected->text()
382  << endl;
383 
384  if ( anyMultiVersionToInstall( !multiVersion ) )
385  {
386  yuiMilestone() << "Multiversion and non-multiversion conflict!" << endl;
387  bool forceContinue = mixedMultiVersionPopup( multiVersion );
388 
389  if ( forceContinue )
390  {
391  _selectable->setPickStatus( poolItem, S_Install );
392  emit statusChanged(); // update status icons for all versions
393  }
394  else
395  {
396  // Nothing to do here: The status of this item was not changed yet;
397  // simply leave it like it was.
398  }
399 
400  return true; // handled here
401  }
402  else
403  {
404  return false; // Not handled here
405  }
406 }
407 
408 
409 bool
411 {
412  // Translators: Popup dialog text. Try to keep the lines about the same length.
413  QString msg = _( "You are trying to install multiversion-capable\n"
414  "and non-multiversion-capable versions of this\n"
415  "package at the same time." );
416  msg += "\n\n";
417 
418  if ( multiversion )
419  {
420  msg +=
421  _( "This version is multiversion-capable.\n"
422  "\n"
423  "Press \"Continue\" to install this version\n"
424  "and unselect the non-multiversion-capable version,\n"
425  "\"Cancel\" to unselect this version and keep the other one." );
426  }
427  else
428  {
429  msg +=
430  _( "This version is not multiversion-capable.\n"
431  "\n"
432  "Press \"Continue\" to install only this version\n"
433  "and unselect all other versions,\n"
434  "\"Cancel\" to unselect this version and keep the other ones." );
435  }
436 
437  // Dialog heading
438  QString heading = _( "Incompatible Package Versions" );
439 
440  int buttonNo = QMessageBox::question( 0, // parent
441  heading,
442  msg,
443  _( "C&ontinue" ), // button #0
444  _( "&Cancel" ) ); // button #1
445  yuiMilestone() << "User hit " << (buttonNo == 0 ? "[Continue]" : "[Cancel]" ) << endl;
446 
447  return buttonNo == 0;
448 }
449 
450 
451 
452 bool
454 {
455  if ( ! _selectable )
456  return false;
457 
458  zypp::ui::Selectable::available_iterator it = _selectable->availableBegin();
459 
460  while ( it != _selectable->availableEnd() )
461  {
462  if ( it->multiversionInstall() == multiversion )
463  {
464  switch ( _selectable->pickStatus( *it ) )
465  {
466  case S_Install:
467  case S_AutoInstall:
468  yuiMilestone() << "Found " << ( multiversion ? "multiversion" : "non-multiversion" )
469  << " to install" << endl;
470  return true;
471 
472  default:
473  break;
474  }
475  }
476 
477  ++it;
478  }
479 
480  yuiMilestone() << "No " << ( multiversion ? "multiversion" : "non-multiversion" )
481  << " to install" << endl;
482  return false;
483 }
484 
485 
486 void
488 {
489  if ( ! _selectable )
490  return;
491 
492  zypp::ui::Selectable::available_iterator it = _selectable->availableBegin();
493 
494  while ( it != _selectable->availableEnd() )
495  {
496  if ( it->multiversionInstall() )
497  {
498  switch ( _selectable->pickStatus( *it ) )
499  {
500  case S_Install:
501  case S_AutoInstall:
502  _selectable->setPickStatus( *it, S_NoInst );
503  yuiMilestone() << "Unselecting " << *it << endl;
504  break;
505 
506  default:
507  break;
508  }
509  }
510 
511  ++it;
512  }
513 }
514 
515 
516 bool
518 {
519  if ( ! selectable )
520  return false;
521 
522  zypp::ui::Selectable::available_iterator it = selectable->availableBegin();
523 
524  if ( it == selectable->availableEnd() )
525  return false;
526 
527  bool multiversion = it->multiversionInstall();
528 
529  while ( it != selectable->availableEnd() )
530  {
531  if ( it->multiversionInstall() != multiversion )
532  {
533  yuiMilestone() << "Mixed multiversion" << endl;
534  return true;
535  }
536 
537  ++it;
538  }
539 
540  return false;
541 }
542 
543 
544 
545 
546 
547 
548 YQPkgVersion::YQPkgVersion( QWidget * parent,
549  ZyppSel selectable,
550  ZyppObj zyppObj )
551  : QRadioButton( parent )
552  , _selectable( selectable )
553  , _zyppObj( zyppObj )
554 {
555  if ( zyppObj->isRetracted() )
556  {
557  // Translators: %1 is a package version, %2 the package architecture,
558  // %3 describes the repository where it comes from,
559  // %4 is the repository's priority
560  // %5 is the vendor of the package
561  // Examples:
562  // 2.5.23-i568 from Packman with priority 100 and vendor openSUSE
563  // 3.17.4-i386 from openSUSE-11.1 update repository with priority 20 and vendor openSUSE
564  // ^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^
565  // %1 %2 %3 %4 %5
566  setText( _( "%1-%2 [RETRACTED] from %3 with priority %4 and vendor %5" )
567  .arg( fromUTF8( zyppObj->edition().asString().c_str() ) )
568  .arg( fromUTF8( zyppObj->arch().asString().c_str() ) )
569  .arg( fromUTF8( zyppObj->repository().info().name().c_str() ) )
570  .arg( zyppObj->repository().info().priority() )
571  .arg( fromUTF8( zyppObj->vendor().c_str() ) ) );
572 
574  }
575  else
576  {
577  // Translators: %1 is a package version, %2 the package architecture,
578  // %3 describes the repository where it comes from,
579  // %4 is the repository's priority
580  // %5 is the vendor of the package
581  // Examples:
582  // 2.5.23-i568 from Packman with priority 100 and vendor openSUSE
583  // 3.17.4-i386 from openSUSE-11.1 update repository with priority 20 and vendor openSUSE
584  // ^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^
585  // %1 %2 %3 %4 %5
586  setText( _( "%1-%2 from %3 with priority %4 and vendor %5" )
587  .arg( fromUTF8( zyppObj->edition().asString().c_str() ) )
588  .arg( fromUTF8( zyppObj->arch().asString().c_str() ) )
589  .arg( fromUTF8( zyppObj->repository().info().name().c_str() ) )
590  .arg( zyppObj->repository().info().priority() )
591  .arg( fromUTF8( zyppObj->vendor().c_str() ) ) );
592  }
593 }
594 
595 
597 {
598  // NOP
599 }
600 
601 
602 QString
604 {
605  QString tip;
606 
607  if ( *zyppObj() == selectable()->installedObj() )
608  tip = _( "This version is installed in your system." );
609 
610  return tip;
611 }
612 
613 
614 
615 
617  ZyppSel selectable,
618  ZyppPoolItem zyppPoolItem )
619  : QCheckBox( parent )
620  , _parent( parent )
621  , _selectable( selectable )
622  , _zyppPoolItem( zyppPoolItem )
623 {
624  setText (_( "%1-%2 from %3 with priority %4 and vendor %5" )
625  .arg( fromUTF8( zyppPoolItem->edition().asString().c_str() ) )
626  .arg( fromUTF8( zyppPoolItem->arch().asString().c_str() ) )
627  .arg( fromUTF8( zyppPoolItem->repository().info().name().c_str() ) )
628  .arg( zyppPoolItem->repository().info().priority() )
629  .arg( fromUTF8( zyppPoolItem->vendor().c_str() ) ));
630 
631  connect( this, SIGNAL( toggled( bool) ),
632  this, SLOT ( slotIconClicked() ) );
633 }
634 
635 
637 {
638  // NOP
639 }
640 
641 
642 void YQPkgMultiVersion::slotIconClicked()
643 {
644  {
645  YQSignalBlocker sigBlocker( this ); // prevent checkmark, we draw the status icons ourselves
646  setChecked( false );
647  }
648  cycleStatus();
649 }
650 
651 
653 {
654  ZyppStatus oldStatus = _selectable->pickStatus( _zyppPoolItem );
655  ZyppStatus newStatus = oldStatus;
656 
657  switch ( oldStatus )
658  {
659  case S_Install:
660  case S_AutoInstall:
661  case S_Protected:
662  newStatus = S_NoInst;
663  break;
664 
665  case S_KeepInstalled:
666  case S_Update:
667  case S_AutoUpdate:
668  newStatus = S_Del;
669  break;
670 
671 
672  case S_Del:
673  case S_AutoDel:
674  newStatus = S_KeepInstalled;
675  break;
676 
677  case S_NoInst:
678  case S_Taboo:
679  newStatus = S_Install;
680  break;
681  }
682 
683  bool handled = false;
684 
685  if ( _parent->isMixedMultiVersion() &&
686  newStatus == S_Install &&
687  oldStatus != newStatus )
688  {
689  handled = _parent->handleMixedMultiVersion( this );
690  }
691 
692  if ( ! handled )
693  setStatus( newStatus );
694 
695  yuiMilestone() << "oldStatus: " << oldStatus << endl;
696  ZyppStatus actualStatus = _selectable->pickStatus( _zyppPoolItem );
697 
698  if ( actualStatus != newStatus )
699  yuiWarning() << "FAILED to set new status: " << newStatus
700  << " actual Status: " << actualStatus << endl;
701  else
702  yuiMilestone() << "newStatus:" << newStatus << endl;
703 
704  if ( oldStatus != actualStatus )
705  {
706  update();
707  emit statusChanged();
708  }
709 }
710 
711 
712 void YQPkgMultiVersion::setStatus( ZyppStatus newStatus )
713 {
714  yuiMilestone() << "Setting pick status to " << newStatus << endl;
715  _selectable->setPickStatus( _zyppPoolItem, newStatus );
716 }
717 
718 
719 void YQPkgMultiVersion::paintEvent(QPaintEvent *)
720 {
721  // draw the usual checkbox
722  QStylePainter p( this );
723  QStyleOptionButton opt;
724  initStyleOption( &opt );
725  p.drawControl( QStyle::CE_CheckBox, opt );
726 
727 
728  // calculate position and draw the status icon
729  QRect elementRect = style()->subElementRect ( QStyle::SE_CheckBoxIndicator, &opt );
730  QPixmap icon = statusIcon( _selectable->pickStatus( _zyppPoolItem ) );
731 
732  QPoint start = elementRect.center() - icon.rect().center();
733  QRect rect = QRect( start.x(), start.y(), icon.width(), icon.height() );
734 
735  p.drawItemPixmap( rect, 0, icon );
736 }
737 
738 
739 QPixmap YQPkgMultiVersion::statusIcon( ZyppStatus status )
740 {
741  QPixmap icon = YQIconPool::pkgNoInst();
742 
743  switch ( status )
744  {
745  case S_Del: icon = YQIconPool::pkgDel(); break;
746  case S_Install: icon = YQIconPool::pkgInstall(); break;
747  case S_KeepInstalled: icon = YQIconPool::pkgKeepInstalled(); break;
748  case S_NoInst: icon = QPixmap(); break;
749  case S_Protected: icon = YQIconPool::pkgProtected(); break;
750  case S_Taboo: icon = YQIconPool::pkgTaboo(); break;
751  case S_Update: icon = YQIconPool::pkgUpdate(); break;
752 
753  case S_AutoDel: icon = YQIconPool::pkgAutoDel(); break;
754  case S_AutoInstall: icon = YQIconPool::pkgAutoInstall(); break;
755  case S_AutoUpdate: icon = YQIconPool::pkgAutoUpdate(); break;
756 
757  // Intentionally omitting 'default' branch so the compiler can
758  // catch unhandled enum states
759  }
760  return icon;
761 }
762 
763 
764 
static void setRetractedColor(QWidget *widget)
Set the colors of a widget for a retracted zyppObj.
ZyppPoolItem zyppPoolItem() const
Returns the original ZYPP object.
ZyppObj zyppObj() const
Returns the original ZYPP object.
virtual QString toolTip(int column)
Returns a tool tip text for a specific column of this item.
bool isMixedMultiVersion() const
Return the cached value for the current selectable.
YQPkgMultiVersion(YQPkgVersionsView *parent, ZyppSel selectable, ZyppPoolItem zyppPoolItem)
Constructor.
YQPkgVersion(QWidget *parent, ZyppSel selectable, ZyppObj zyppObj)
Constructor.
void showDetailsIfVisible(ZyppSel selectable)
Show details for the specified package.
virtual ~YQPkgVersion()
Destructor.
virtual ~YQPkgMultiVersion()
Destructor.
YQPkgVersionsView(QWidget *parent)
Constructor.
Package version selector: Display a list of available versions from all the different installation so...
virtual QSize minimumSizeHint() const
Returns the minimum size required for this widget.
ZyppSel selectable() const
Return the selectable of this details view.
void paintEvent(QPaintEvent *)
Paints checkboxes with status icons instead of a checkmark.
void checkForChangedCandidate()
Check for changed candidates.
bool anyMultiVersionToInstall(bool multiversion) const
Check if any package version is marked for installation where its &#39;multiversion&#39; flag is set to &#39;mult...
bool mixedMultiVersionPopup(bool multiversion) const
Ask user if he really wants to install incompatible package versions.
void unselectAllMultiVersion()
Unselect all multiversion package versions.
void candidateChanged(ZyppObj newCandidate)
Emitted when the user changes the candidate.
virtual ~YQPkgVersionsView()
Destructor.
bool handleMixedMultiVersion(YQPkgMultiVersion *newSelected)
Negotiate between multiversion and non-multiversion packages if there are both kinds in that selectab...
ZyppSel selectable() const
Returns the original ZYPP selectable.
void statusChanged()
Emitted when the status of this package version is changed.
void cycleStatus()
Cycle the package status to the next valid value.
static bool installedIsRetracted(ZyppSel selectable, ZyppObj installed)
Return &#39;true&#39; if &#39;installed&#39; is retraced, i.e.
static bool isMixedMultiVersion(ZyppSel selectable)
Return &#39;true&#39; if &#39;selectable&#39; has mixed multiversion flags, &#39;false&#39; if all its pool items are of the ...
void statusChanged()
Emitted when the status of any package changed.
void reload(int newCurrent)
Show data for the current package.
void showDetails(ZyppSel selectable)
Show details for the specified package.