1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
21 #define SOURCE_RPM_DISABLED 0
23 #define y2log_component "qt-pkg"
24 #include <ycp/y2log.h>
28 #include <QMessageBox>
33 #include "YQPkgList.h"
36 #include "YQIconPool.h"
39 YQPkgList::YQPkgList( QWidget * parent )
40 : YQPkgObjList( parent )
46 addColumn( "" ); _statusCol = numCol++;
47 // _statusCol = numCol;
48 addColumn( _( "Package" ) ); _nameCol = numCol++;
50 addColumn( _( "Summary" ) ); _summaryCol = numCol++;
51 addColumn( _( "Size" ) ); _sizeCol = numCol++;
53 if ( haveInstalledPkgs() )
55 addColumn( _( "Avail. Ver." ) ); _versionCol = numCol++;
56 addColumn( _( "Inst. Ver." ) ); _instVersionCol = numCol++;
60 addColumn( _( "Version" ) ); _versionCol = numCol++;
64 #if SOURCE_RPM_DISABLED
65 #warning Selecting source RPMs disabled!
67 addColumn( _( "Source" ) ); _srpmStatusCol = numCol++;
71 setSorting( nameCol() );
72 setColumnAlignment( sizeCol(), Qt::AlignRight );
73 setAllColumnsShowFocus( true );
77 createSourceRpmContextMenu();
81 YQPkgList::~YQPkgList()
87 void YQPkgList::addPkgItem( ZyppSel selectable,
90 addPkgItem( selectable, zyppPkg, false );
94 void YQPkgList::addPkgItemDimmed( ZyppSel selectable,
97 addPkgItem( selectable, zyppPkg, true );
102 YQPkgList::addPkgItem( ZyppSel selectable,
108 y2error( "NULL zypp::ui::Selectable!" );
112 YQPkgListItem * item = new YQPkgListItem( this, selectable, zyppPkg );
115 item->setDimmed( dimmed );
116 applyExcludeRules( item );
121 YQPkgList::haveInstalledPkgs()
123 for ( ZyppPoolIterator it = zyppPkgBegin();
127 if ( (*it)->installedObj() )
136 YQPkgList::pkgObjClicked( int button,
137 QTreeWidgetItem * listViewItem,
141 if ( col == srpmStatusCol() )
143 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
147 if ( button == Qt::LeftButton )
149 if ( editable() && item->editable() )
150 item->toggleSourceRpmStatus();
153 else if ( button == Qt::RightButton )
155 if ( editable() && item->editable() )
157 updateActions( item );
159 if ( _sourceRpmContextMenu )
160 _sourceRpmContextMenu->popup( pos );
168 YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
173 YQPkgList::sizeHint() const
175 return QSize( 600, 350 );
180 YQPkgList::createSourceRpmContextMenu()
182 _sourceRpmContextMenu = new QMenu( this );
184 _sourceRpmContextMenu->addAction(actionInstallSourceRpm);
185 _sourceRpmContextMenu->addAction(actionDontInstallSourceRpm);
187 QMenu * submenu = new QMenu( _sourceRpmContextMenu );
188 Q_CHECK_PTR( submenu );
189 QAction *action = _sourceRpmContextMenu->addMenu( submenu );
190 action->setText(_( "&All in This List" ));
192 submenu->addAction(actionInstallListSourceRpms);
193 submenu->addAction(actionDontInstallListSourceRpms);
198 YQPkgList::setInstallCurrentSourceRpm( bool installSourceRpm,
199 bool selectNextItem )
202 QTreeWidgetItem * listViewItem = selectedItem();
204 if ( ! listViewItem )
207 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
211 item->setInstallSourceRpm( installSourceRpm );
213 if ( selectNextItem && item->nextSibling() )
215 item->setSelected( false ); // doesn't emit signals
216 setSelected( item->nextSibling(), true ); // emits signals
224 YQPkgList::setInstallListSourceRpms( bool installSourceRpm )
230 QTreeWidgetItem * listViewItem = firstChild();
232 while ( listViewItem )
234 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
236 if ( item && item->editable() )
238 item->setInstallSourceRpm( installSourceRpm );
241 listViewItem = listViewItem->nextSibling();
249 YQPkgList::createNotInstalledContextMenu()
251 _notInstalledContextMenu = new QMenu( this );
252 Q_CHECK_PTR( _notInstalledContextMenu );
254 _notInstalledContextMenu->addAction(actionSetCurrentInstall);
255 _notInstalledContextMenu->addAction(actionSetCurrentDontInstall);
256 _notInstalledContextMenu->addAction(actionSetCurrentTaboo);
258 addAllInListSubMenu( _notInstalledContextMenu );
261 _notInstalledContextMenu->addSeparator();
262 _notInstalledContextMenu->addAction( _( "Export This List to &Text File..." ),
263 this, SLOT( askExportList() ) );
268 YQPkgList::createInstalledContextMenu()
270 _installedContextMenu = new QMenu( this );
271 Q_CHECK_PTR( _installedContextMenu );
273 _installedContextMenu->addAction(actionSetCurrentKeepInstalled);
274 _installedContextMenu->addAction(actionSetCurrentDelete);
275 _installedContextMenu->addAction(actionSetCurrentUpdate);
276 _installedContextMenu->addAction(actionSetCurrentProtected);
278 addAllInListSubMenu( _installedContextMenu );
280 _installedContextMenu->addSeparator();
281 _installedContextMenu->addAction( _( "Export This List to &Text File..." ),
282 this, SLOT( askExportList() ) );
287 YQPkgList::addAllInListSubMenu( QMenu * menu )
289 QMenu * submenu = new QMenu( menu );
290 Q_CHECK_PTR( submenu );
292 submenu->addAction(actionSetListInstall);
293 submenu->addAction(actionSetListDontInstall);
294 submenu->addAction(actionSetListKeepInstalled);
295 submenu->addAction(actionSetListDelete);
296 submenu->addAction(actionSetListDelete);
297 submenu->addAction(actionSetListUpdate);
298 submenu->addAction(actionSetListUpdateForce);
299 submenu->addAction(actionSetListTaboo);
300 submenu->addAction(actionSetListProtected);
302 QAction *action = menu->addMenu( submenu );
303 action->setText(_( "&All in This List" ));
310 YQPkgList::createActions()
312 actionInstallSourceRpm = createAction( _( "&Install Source" ),
313 statusIcon( S_Install, true ),
314 statusIcon( S_Install, false ) );
316 actionDontInstallSourceRpm = createAction( _( "Do &Not Install Source" ),
317 statusIcon( S_NoInst, true ),
318 statusIcon( S_NoInst, false ) );
320 actionInstallListSourceRpms = createAction( _( "&Install All Available Sources" ),
321 statusIcon( S_Install, true ),
322 statusIcon( S_Install, false ),
323 QString::null, // key
326 actionDontInstallListSourceRpms = createAction( _( "Do &Not Install Any Sources" ),
327 statusIcon( S_NoInst, true ),
328 statusIcon( S_NoInst, false ),
329 QString::null, // key
332 connect( actionInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setInstallCurrentSourceRpm() ) );
333 connect( actionDontInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setDontInstallCurrentSourceRpm() ) );
335 connect( actionInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setInstallListSourceRpms() ) );
336 connect( actionDontInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setDontInstallListSourceRpms() ) );
341 YQPkgList::updateActions( YQPkgObjListItem * pkgObjListItem )
343 YQPkgObjList::updateActions( pkgObjListItem );
345 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (pkgObjListItem);
349 actionInstallSourceRpm->setEnabled( item->hasSourceRpm() );
350 actionDontInstallSourceRpm->setEnabled( item->hasSourceRpm() );
354 actionInstallSourceRpm->setEnabled( false );
355 actionDontInstallSourceRpm->setEnabled( false );
361 YQPkgList::askExportList() const
363 QString filename = YQUI::ui()->askForSaveFileName( "pkglist.txt", // startsWith
365 _( "Export Package List" ) );
366 if ( ! filename.isEmpty() )
367 exportList( filename, true );
372 YQPkgList::exportList( const QString filename, bool interactive ) const
376 QFile file(filename);
377 file.open(QIODevice::WriteOnly);
379 if ( file.error() != QFile::NoError )
381 y2error( "Can't open file %s", qPrintable(filename) );
387 QMessageBox::warning( 0, // parent
388 _( "Error" ), // caption
389 _( "Cannot open file %1" ).arg( filename ),
390 QMessageBox::Ok | QMessageBox::Default, // button0
391 QMessageBox::NoButton, // button1
392 QMessageBox::NoButton ); // button2
402 // Format the header line with QString::sprintf() because plain stdio
403 // fprintf() is not UTF-8 aware - it will count multi-byte characters
404 // wrong, so the formatting will be broken.
407 header.sprintf( "# %-18s %-30s | %10s | %-16s | %-16s\n\n",
408 (const char *) _( "Status" ).toUtf8(),
409 (const char *) _( "Package" ).toUtf8(),
410 (const char *) _( "Size" ).toUtf8(),
411 (const char *) _( "Avail. Ver." ).toUtf8(),
412 (const char *) _( "Inst. Ver." ).toUtf8()
414 file.write(header.toUtf8());
422 const QTreeWidgetItem * item = firstChild();
426 const YQPkgListItem * pkg = dynamic_cast<const YQPkgListItem *> (item);
430 QString candVersion = pkg->text( versionCol() );
431 QString instVersion = pkg->text( instVersionCol() );
433 if ( candVersion.isEmpty() ) candVersion = "---";
434 if ( instVersion.isEmpty() ) instVersion = "---";
436 QString status = "[" + statusText( pkg->status() ) + "]";
438 format.sprintf("%-20s %-30s | %10s | %-16s | %-16s\n",
439 (const char *) status.toUtf8(),
440 (const char *) pkg->text( nameCol() ),
441 (const char *) pkg->text( sizeCol() ),
442 (const char *) candVersion,
443 (const char *) instVersion
445 file.write(format.toUtf8());
448 item = item->nextSibling();
460 YQPkgList::globalSetPkgStatus( ZyppStatus newStatus, bool force, bool countOnly )
462 YQUI::ui()->busyCursor();
463 int changedCount = 0;
465 for ( ZyppPoolIterator it = zyppPkgBegin();
469 ZyppSel selectable = *it;
470 ZyppStatus oldStatus = selectable->status();
472 if ( newStatus != oldStatus )
474 bool doChange = false;
478 case S_KeepInstalled:
482 doChange = selectable->hasInstalledObj();
490 doChange = selectable->hasInstalledObj();
492 else // don't force - update only if useful (if candidate is newer)
494 const ZyppObj candidate = selectable->candidateObj();
495 const ZyppObj installed = selectable->installedObj();
497 if ( candidate && installed )
499 doChange = ( installed->edition() < candidate->edition() );
508 doChange = ! selectable->hasInstalledObj();
515 selectable->set_status( newStatus );
518 // y2milestone( "Updating %s", selectable->name().c_str() );
523 if ( changedCount > 0 && ! countOnly )
525 emit updateItemStates();
526 emit updatePackages();
527 emit statusChanged();
530 YQUI::ui()->normalCursor();
540 YQPkgListItem::YQPkgListItem( YQPkgList * pkgList,
543 : YQPkgObjListItem( pkgList, selectable, zyppPkg )
544 , _pkgList( pkgList )
545 , _zyppPkg( zyppPkg )
549 _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
555 YQPkgListItem::~YQPkgListItem()
562 YQPkgListItem::updateData()
564 YQPkgObjListItem::updateData();
570 YQPkgListItem::hasSourceRpm() const
572 if ( ! selectable() )
576 return selectable()->providesSources();
584 YQPkgListItem::installSourceRpm() const
586 if ( ! selectable() )
590 if ( ! selectable()->providesSources() )
593 return selectable()->source_install();
601 YQPkgListItem::setSourceRpmIcon()
603 if ( srpmStatusCol() < 0 )
608 if ( hasSourceRpm() )
611 if ( editable() && _pkgObjList->editable() )
613 icon = installSourceRpm() ?
614 YQIconPool::pkgInstall() :
615 YQIconPool::pkgNoInst();
619 icon = installSourceRpm() ?
620 YQIconPool::disabledPkgInstall() :
621 YQIconPool::disabledPkgNoInst();
625 setPixmap( srpmStatusCol(), icon );
631 YQPkgListItem::setInstallSourceRpm( bool installSourceRpm )
633 if ( hasSourceRpm() )
637 selectable()->set_source_install( installSourceRpm );
646 YQPkgListItem::toggleSourceRpmStatus()
648 setInstallSourceRpm( ! installSourceRpm() );
653 YQPkgListItem::toolTip( int col )
656 QString name = _zyppObj->name().c_str();
658 if ( col == statusCol() )
660 text = YQPkgObjListItem::toolTip( col );
662 else if ( col == srpmStatusCol() )
664 text = name + "\n\n";
666 if ( hasSourceRpm() )
668 text += installSourceRpm() ?
669 _( "Install Sources" ) :
670 _( "Do Not Install Sources" );
674 text += _( "No Sources Available" );
679 text = name + "\n\n";
684 if ( selectable()->hasInstalledObj() )
686 installed = selectable()->installedObj()->edition().asString().c_str();
688 installed += selectable()->installedObj()->arch().asString().c_str();
689 installed = _( "Installed Version: %1" ).arg( installed );
692 if ( selectable()->hasCandidateObj() )
694 candidate = selectable()->candidateObj()->edition().asString().c_str();
696 candidate += selectable()->candidateObj()->arch().asString().c_str();
699 if ( selectable()->hasInstalledObj() )
701 text += installed + "\n";
703 if ( selectable()->hasCandidateObj() )
705 // Translators: This is the relation between two versions of one package
706 // if both versions are the same, e.g., both "1.2.3-42", "1.2.3-42"
707 QString relation = _( "same" );
709 if ( _candidateIsNewer ) relation = _( "newer" );
710 if ( _installedIsNewer ) relation = _( "older" );
712 // Translators: %1 is the version, %2 is one of "newer", "older", "same"
713 text += _( "Available Version: %1 (%2)" ).arg( candidate ).arg( relation );
717 text += _( "Not available for installation" );
720 else // not installed
732 * Comparison function used for sorting the list.
739 YQPkgListItem::compare( QTreeWidgetItem * otherListViewItem,
741 bool ascending ) const
743 if ( col == srpmStatusCol() )
745 YQPkgListItem * other = dynamic_cast<YQPkgListItem *> (otherListViewItem);
749 int thisPoints = ( this->hasSourceRpm() ? 1 : 0 ) + ( this->installSourceRpm() ? 1 : 0 );
750 int otherPoints = ( other->hasSourceRpm() ? 1 : 0 ) + ( other->installSourceRpm() ? 1 : 0 );
752 // Intentionally inverting order: Pkgs with source RPMs are more interesting than without.
753 if ( thisPoints > otherPoints ) return -1;
754 if ( thisPoints < otherPoints ) return 1;
759 // Fallback: Use parent class method
760 return YQPkgObjListItem::compare( otherListViewItem, col, ascending );
765 YQPkgListItem::paintCell( QPainter * painter,
766 const QColorGroup & colorGroup,
772 if ( isDimmed() && ! YQUI::ui()->usingVisionImpairedPalette() )
774 QColorGroup cg = colorGroup;
775 cg.setColor( QColorGroup::Text, QColor( 0xA0, 0xA0, 0xA0 ) );
777 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
781 if ( installedIsNewer() )
783 QColorGroup cg = colorGroup;
785 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
787 if ( column == instVersionCol() )
788 cg.setColor( QColorGroup::Base, QColor( 0xFF, 0x30, 0x30 ) ); // Background
790 cg.setColor( QColorGroup::Text, QColor( 0xFF, 0, 0 ) ); // Foreground
793 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
795 else if ( candidateIsNewer() )
797 QColorGroup cg = colorGroup;
799 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
801 cg.setColor( QColorGroup::Text, QColor( 0, 0, 0xC0 ) ); // Foreground
803 if ( column == versionCol() )
804 cg.setColor( QColorGroup::Base, QColor( 0xF0, 0xF0, 0xF0 ) ); // Background
807 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
811 QTreeWidgetItem::paintCell( painter, colorGroup, column, width, alignment );
819 #include "YQPkgList.moc"