libyui-qt-pkg  2.44.7
 All Classes Functions Variables Enumerations
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 <QApplication>
53 
54 
55 #include "YQPkgVersionsView.h"
56 #include "YQPkgRepoList.h"
57 #include "YQIconPool.h"
58 #include "YQi18n.h"
59 #include "utf8.h"
60 
61 #define ICONOFFSET 3 // the status icons have an asymmetrical transparent border
62 
63 using std::endl;
64 
65 YQPkgVersionsView::YQPkgVersionsView( QWidget * parent, bool userCanSwitch )
66  : QScrollArea( parent )
67  , _content(0)
68  , _layout(0)
69 {
70  _selectable = 0;
71  _parentTab = dynamic_cast<QTabWidget *> (parent);
72  _userCanSwitch = userCanSwitch;
73 
74  _buttons = new QButtonGroup(this);
75 
76  if ( _parentTab )
77  {
78  connect( _parentTab, &QTabWidget::currentChanged,
80  }
81 }
82 
83 
85 {
86  // NOP
87 }
88 
89 
90 void
91 YQPkgVersionsView::reload( int newCurrent )
92 {
93  if ( _parentTab && _parentTab->widget( newCurrent ) == this )
94  showDetailsIfVisible( _selectable );
95 }
96 
97 
98 void
99 YQPkgVersionsView::slotRefreshDetails( )
100 {
101  emit multiversionSelectionChanged( );
102 }
103 
104 
105 void
107 {
108  _selectable = selectable;
109 
110  yuiMilestone() << "showDetailsIfVis" << endl;
111 
112  if ( _parentTab ) // Is this view embedded into a tab widget?
113  {
114  if ( _parentTab->currentWidget() == this ) // Is this page the topmost?
115  showDetails( selectable );
116  }
117  else // No tab parent - simply show data unconditionally.
118  {
119  showDetails( selectable );
120  }
121 }
122 
123 
124 void
125 YQPkgVersionsView::showDetails( ZyppSel selectable )
126 {
127  yuiMilestone() << "showDetails" << endl;
128 
129  _selectable = selectable;
130 
131  if ( ! selectable )
132  {
133  // Delete all installed items
134  qDeleteAll( _installed );
135  _installed.clear();
136 
137  _content = new QWidget( this );
138  setWidget( _content );
139  _content->show();
140  return;
141  }
142 
143  // old widget is autodestroyed by setWidget later
144  _content = new QWidget( this );
145  _layout = new QVBoxLayout( _content );
146  _content->setLayout( _layout );
147 
148  QLabel * pkgNameLabel = new QLabel( this );
149 
150  if ( ! selectable->theObj() )
151  return;
152 
153  _layout->addWidget( pkgNameLabel );
154 
155  QFont font = pkgNameLabel->font();
156  font.setBold( true );
157 
158  QFontMetrics fm( font) ;
159  font.setPixelSize( (int) ( fm.height() * 1.1 ) );
160 
161  pkgNameLabel->setFont( font );
162  pkgNameLabel->setText( fromUTF8(selectable->theObj()->name().c_str()) );
163 
164  // New scope
165  {
166  QListIterator<QAbstractButton*> it( _buttons->buttons() );
167 
168  while ( it.hasNext() )
169  {
170  delete it.next();
171  }
172  }
173 
174  // Delete all installed items
175  qDeleteAll( _installed );
176  _installed.clear();
177 
178  if ( selectable->multiversionInstall() )
179  {
180  //
181  // Find installed and available objects ( for multiversion view )
182  //
183  {
184  zypp::ui::Selectable::picklist_iterator it = selectable->picklistBegin();
185 
186 
187  while ( it != selectable->picklistEnd() )
188  {
189  YQPkgMultiVersion * version = new YQPkgMultiVersion( this, selectable, *it, _userCanSwitch );
190 
191  _installed.push_back( version );
192  _layout->addWidget( version );
193 
194  connect (version, SIGNAL(statusChanged()), this, SLOT(slotRefreshDetails()));
195  connect (this, SIGNAL(multiversionSelectionChanged()), version, SLOT(update()));
196 
197  ++it;
198  }
199  }
200  }
201  else
202  {
203  //
204  // Fill installed objects
205  //
206  {
207  zypp::ui::Selectable::installed_iterator it = selectable->installedBegin();
208 
209  while ( it != selectable->installedEnd() )
210  {
211  QString text = _( "%1-%2 from vendor %3 (installed)" )
212  .arg( fromUTF8( (*it)->edition().asString().c_str() ) )
213  .arg( fromUTF8( (*it)->arch().asString().c_str() ) )
214  .arg( fromUTF8( (*it)->vendor().c_str() ) ) ;
215 
216  QWidget * installedVersion = new QWidget( this );
217  QHBoxLayout * instLayout = new QHBoxLayout( installedVersion );
218  instLayout->setContentsMargins( 0, 0, 0, 0 );
219 
220  QLabel * icon = new QLabel( installedVersion );
221  icon->setPixmap( YQIconPool::pkgSatisfied() );
222  instLayout->addWidget( icon );
223 
224  QLabel * textLabel = new QLabel( text, installedVersion );
225  instLayout->addWidget( textLabel );
226  instLayout->addStretch();
227 
228  _installed.push_back( installedVersion );
229  _layout->addWidget( installedVersion );
230 
231  ++it;
232  }
233  }
234 
235 
236  //
237  // Fill available objects
238  //
239 
240  {
241  zypp::ui::Selectable::available_iterator it = selectable->availableBegin();
242 
243  while ( it != selectable->availableEnd() )
244  {
245  QRadioButton *radioButton = new YQPkgVersion( this, selectable, *it, _userCanSwitch );
246  connect( radioButton, SIGNAL( clicked( bool ) ), SLOT( checkForChangedCandidate() ) );
247 
248  _buttons->addButton( radioButton );
249  _layout->addWidget( radioButton );
250 
251 
252  if ( selectable->hasCandidateObj() &&
253  selectable->candidateObj()->edition() == (*it)->edition() &&
254  selectable->candidateObj()->arch() == (*it)->arch() )
255  {
256  radioButton->setChecked(true);
257  }
258 
259  ++it;
260  }
261  }
262  }
263 
264  _layout->addStretch();
265  setWidget( _content );
266  _content->show();
267 }
268 
269 
270 void
272 {
273  QListIterator<QAbstractButton*> it( _buttons->buttons() );
274 
275  while ( it.hasNext() )
276  {
277  YQPkgVersion * versionItem = dynamic_cast<YQPkgVersion *> (it.next());
278 
279  if ( versionItem && versionItem->isChecked() )
280  {
281  ZyppObj newCandidate = versionItem->zyppObj();
282 
283  if ( _selectable && newCandidate != _selectable->candidateObj() )
284  {
285  yuiMilestone() << "Candidate changed" << endl;
286 
287  // Change status of selectable
288 
289  ZyppStatus status = _selectable->status();
290 
291  if ( !_selectable->installedEmpty() &&
292  _selectable->installedObj()->arch() == newCandidate->arch() &&
293  _selectable->installedObj()->edition() == newCandidate->edition() )
294  {
295  // Switch back to the original instance -
296  // the version that was previously installed
297  status = S_KeepInstalled;
298  }
299  else
300  {
301  switch ( status )
302  {
303  case S_KeepInstalled:
304  case S_Protected:
305  case S_AutoDel:
306  case S_AutoUpdate:
307  case S_Del:
308  case S_Update:
309 
310  status = S_Update;
311  break;
312 
313  case S_NoInst:
314  case S_Taboo:
315  case S_Install:
316  case S_AutoInstall:
317  status = S_Install;
318  break;
319  }
320  }
321 
322  _selectable->setStatus( status );
323 
324 
325  // Set candidate
326 
327  _selectable->setCandidate( newCandidate );
328  emit candidateChanged( newCandidate );
329  return;
330  }
331  }
332 
333  }
334 }
335 
336 
337 QSize
339 {
340  return QSize( 0, 0 );
341 }
342 
343 
344 
345 
346 
347 
348 YQPkgVersion::YQPkgVersion( QWidget * parent,
349  ZyppSel selectable,
350  ZyppObj zyppObj,
351  bool enabled )
352  : QRadioButton( parent )
353  , _selectable( selectable )
354  , _zyppObj( zyppObj )
355 {
356  // Translators: %1 is a package version, %2 the package architecture,
357  // %3 describes the repository where it comes from,
358  // %4 is the repository's priority
359  // %5 is the vendor of the package
360  // Examples:
361  // 2.5.23-i568 from Packman with priority 100 and vendor openSUSE
362  // 3.17.4-i386 from openSUSE-11.1 update repository with priority 20 and vendor openSUSE
363  // ^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^
364  // %1 %2 %3 %4 %5
365  setText( _( "%1-%2 from %3 with priority %4 and vendor %5" )
366  .arg( fromUTF8( zyppObj->edition().asString().c_str() ) )
367  .arg( fromUTF8( zyppObj->arch().asString().c_str() ) )
368  .arg( fromUTF8( zyppObj->repository().info().name().c_str() ) )
369  .arg( zyppObj->repository().info().priority() )
370  .arg( fromUTF8( zyppObj->vendor().c_str() ) ) );
371 }
372 
373 
375 {
376  // NOP
377 }
378 
379 
380 QString
382 {
383  QString tip;
384 
385  if ( zyppObj() == selectable()->installedObj() )
386  tip = _( "This version is installed in your system." );
387 
388  return tip;
389 }
390 
391 
392 
393 
395  ZyppSel selectable,
396  ZyppPoolItem zyppPoolItem,
397  bool enabled )
398  : QCheckBox( parent )
399  , _selectable( selectable )
400  , _zyppPoolItem( zyppPoolItem )
401 {
402  setText (_( "%1-%2 from %3 with priority %4 and vendor %5" )
403  .arg( fromUTF8( zyppPoolItem->edition().asString().c_str() ) )
404  .arg( fromUTF8( zyppPoolItem->arch().asString().c_str() ) )
405  .arg( fromUTF8( zyppPoolItem->repository().info().name().c_str() ) )
406  .arg( zyppPoolItem->repository().info().priority() )
407  .arg( fromUTF8( zyppPoolItem->vendor().c_str() ) ));
408 
409 
410  connect( this, SIGNAL (toggled(bool)), this, SLOT( slotIconClicked()));
411 }
412 
413 
415 {
416  // NOP
417 }
418 
419 
420 void YQPkgMultiVersion::slotIconClicked()
421 {
422  // prevent checkmark, we draw the status icons ourselves
423  bool oldBlock = blockSignals( true );
424  setChecked( false );
425  blockSignals( oldBlock );
426  cycleStatus();
427 }
428 
429 
431 {
432 
433  ZyppStatus oldStatus = _selectable->pickStatus( _zyppPoolItem );
434  ZyppStatus newStatus = oldStatus;
435 
436  switch ( oldStatus )
437  {
438  case S_Install:
439  newStatus = S_NoInst;
440  break;
441 
442  case S_Protected:
443  newStatus = _selectable->identicalAvailable( _zyppPoolItem ) ?
444  S_KeepInstalled: S_NoInst;
445  break;
446 
447  case S_Taboo:
448  newStatus = _selectable->identicalInstalled( _zyppPoolItem ) ?
449  S_KeepInstalled : S_NoInst;
450  break;
451 
452  case S_KeepInstalled:
453  newStatus = _selectable->identicalAvailable( _zyppPoolItem ) ?
454  S_Update : S_Del;
455  break;
456 
457  case S_Update:
458  newStatus = S_Del;
459  break;
460 
461  case S_AutoUpdate:
462  newStatus = S_KeepInstalled;
463  break;
464 
465  case S_Del:
466  case S_AutoDel:
467  newStatus = S_KeepInstalled;
468  break;
469 
470  case S_NoInst:
471  if ( _selectable->identicalAvailable( _zyppPoolItem ) )
472  {
473  newStatus = S_Install;
474  }
475  else
476  {
477  yuiWarning() << "No candidate for " << _selectable->theObj()->name() << endl;
478  newStatus = S_NoInst;
479  }
480  break;
481 
482  case S_AutoInstall:
483  // this used to be taboo before, but now ZYpp supports
484  // saving weak locks (unselected packages)
485  newStatus = S_NoInst;
486  break;
487  }
488 
489 
490  setStatus( newStatus );
491  yuiMilestone() << "oldStatus:" << oldStatus << endl;
492  yuiMilestone() << "newStatus:" << newStatus << endl;
493 
494 }
495 
496 
497 void YQPkgMultiVersion::setStatus( ZyppStatus newStatus )
498 {
499  _selectable->setPickStatus( _zyppPoolItem, newStatus );
500 
501  emit statusChanged();
502  update();
503 }
504 
505 
506 void YQPkgMultiVersion::paintEvent(QPaintEvent *)
507 {
508  // draw the usual checkbox
509  QStylePainter p(this);
510  QStyleOptionButton opt;
511  initStyleOption(&opt);
512  p.drawControl(QStyle::CE_CheckBox, opt);
513 
514 
515  // calculate position and draw the status icon
516  QRect elementRect = style()->subElementRect ( QStyle::SE_CheckBoxIndicator, &opt);
517  QPixmap icon = statusIcon( _selectable->pickStatus(_zyppPoolItem) );
518 
519  QPoint start = elementRect.center() - icon.rect().center();
520  QRect rect = QRect(start.x() - ICONOFFSET, start.y(), icon.width(), icon.height());
521 
522  p.drawItemPixmap( rect, 0, icon );
523 }
524 
525 
526 QPixmap YQPkgMultiVersion::statusIcon( ZyppStatus status )
527 {
528  QPixmap icon = YQIconPool::pkgNoInst();
529 
530  switch ( status )
531  {
532  case S_Del: icon = YQIconPool::pkgDel(); break;
533  case S_Install: icon = YQIconPool::pkgInstall(); break;
534  case S_KeepInstalled: icon = YQIconPool::pkgKeepInstalled(); break;
535  case S_NoInst: icon = QPixmap(); break;
536  case S_Protected: icon = YQIconPool::pkgProtected(); break;
537  case S_Taboo: icon = YQIconPool::pkgTaboo(); break;
538  case S_Update: icon = YQIconPool::pkgUpdate(); break;
539 
540  case S_AutoDel: icon = YQIconPool::pkgAutoDel(); break;
541  case S_AutoInstall: icon = YQIconPool::pkgAutoInstall(); break;
542  case S_AutoUpdate: icon = YQIconPool::pkgAutoUpdate(); break;
543 
544  // Intentionally omitting 'default' branch so the compiler can
545  // catch unhandled enum states
546  }
547  return icon;
548 }
549 
550 
551 
552 #include "YQPkgVersionsView.moc"
virtual QSize minimumSizeHint() const
Returns the minimum size required for this widget.
virtual QString toolTip(int column)
Returns a tool tip text for a specific column of this item.
YQPkgMultiVersion(QWidget *parent, ZyppSel selectable, ZyppPoolItem zyppPoolItem, bool enabled=true)
Constructor.
YQPkgVersion(QWidget *parent, ZyppSel selectable, ZyppObj zyppObj, bool enabled=true)
Constructor.
void showDetailsIfVisible(ZyppSel selectable)
Show details for the specified package.
virtual ~YQPkgVersion()
Destructor.
YQPkgVersionsView(QWidget *parent, bool userCanSwitchVersions)
Constructor.
virtual ~YQPkgMultiVersion()
Destructor.
ZyppSel selectable() const
Returns the original ZYPP selectable.
void paintEvent(QPaintEvent *)
Paints checkboxes with status icons instead of a checkmark.
void checkForChangedCandidate()
Check for changed candidates.
void candidateChanged(ZyppObj newCandidate)
Emitted when the user changes the.
ZyppObj zyppObj() const
Returns the original ZYPP object.
virtual ~YQPkgVersionsView()
Destructor.
void cycleStatus()
Cycle the package status to the next valid value.
void reload(int newCurrent)
Show data for the last package.
void showDetails(ZyppSel selectable)
Show details for the specified package.