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 )
48 headers << ""; _statusCol = numCol++;
49 // _statusCol = numCol;
50 headers << _( "Package" ); _nameCol = numCol++;
52 headers << _( "Summary" ); _summaryCol = numCol++;
53 headers << _( "Size" ); _sizeCol = numCol++;
55 if ( haveInstalledPkgs() )
57 headers << _( "Avail. Ver." ); _versionCol = numCol++;
58 headers << _( "Inst. Ver." ); _instVersionCol = numCol++;
62 headers << _( "Version" ); _versionCol = numCol++;
66 #if SOURCE_RPM_DISABLED
67 #warning Selecting source RPMs disabled!
69 headers << _( "Source" ); _srpmStatusCol = numCol++;
71 setHeaderLabels(headers);
73 //FIXME sort( nameCol() );
74 //FIXME setColumnAlignment( sizeCol(), Qt::AlignRight );
75 setAllColumnsShowFocus( true );
79 createSourceRpmContextMenu();
83 YQPkgList::~YQPkgList()
89 void YQPkgList::addPkgItem( ZyppSel selectable,
92 addPkgItem( selectable, zyppPkg, false );
96 void YQPkgList::addPkgItemDimmed( ZyppSel selectable,
99 addPkgItem( selectable, zyppPkg, true );
104 YQPkgList::addPkgItem( ZyppSel selectable,
110 y2error( "NULL zypp::ui::Selectable!" );
114 YQPkgListItem * item = new YQPkgListItem( this, selectable, zyppPkg );
117 item->setDimmed( dimmed );
118 applyExcludeRules( item );
123 YQPkgList::haveInstalledPkgs()
125 for ( ZyppPoolIterator it = zyppPkgBegin();
129 if ( (*it)->installedObj() )
138 YQPkgList::pkgObjClicked( int button,
139 QTreeWidgetItem * listViewItem,
143 if ( col == srpmStatusCol() )
145 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
149 if ( button == Qt::LeftButton )
151 if ( editable() && item->editable() )
152 item->toggleSourceRpmStatus();
155 else if ( button == Qt::RightButton )
157 if ( editable() && item->editable() )
159 updateActions( item );
161 if ( _sourceRpmContextMenu )
162 _sourceRpmContextMenu->popup( pos );
170 YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
175 YQPkgList::sizeHint() const
177 return QSize( 600, 350 );
182 YQPkgList::createSourceRpmContextMenu()
184 _sourceRpmContextMenu = new QMenu( this );
186 _sourceRpmContextMenu->addAction(actionInstallSourceRpm);
187 _sourceRpmContextMenu->addAction(actionDontInstallSourceRpm);
189 QMenu * submenu = new QMenu( _sourceRpmContextMenu );
190 Q_CHECK_PTR( submenu );
191 QAction *action = _sourceRpmContextMenu->addMenu( submenu );
192 action->setText(_( "&All in This List" ));
194 submenu->addAction(actionInstallListSourceRpms);
195 submenu->addAction(actionDontInstallListSourceRpms);
200 YQPkgList::setInstallCurrentSourceRpm( bool installSourceRpm,
201 bool selectNextItem )
204 QTreeWidgetItem * listViewItem = selectedItem();
206 if ( ! listViewItem )
209 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
213 item->setInstallSourceRpm( installSourceRpm );
215 if ( selectNextItem && item->nextSibling() )
217 item->setSelected( false ); // doesn't emit signals
218 setSelected( item->nextSibling(), true ); // emits signals
226 YQPkgList::setInstallListSourceRpms( bool installSourceRpm )
232 QTreeWidgetItem * listViewItem = firstChild();
234 while ( listViewItem )
236 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
238 if ( item && item->editable() )
240 item->setInstallSourceRpm( installSourceRpm );
243 listViewItem = listViewItem->nextSibling();
251 YQPkgList::createNotInstalledContextMenu()
253 _notInstalledContextMenu = new QMenu( this );
254 Q_CHECK_PTR( _notInstalledContextMenu );
256 _notInstalledContextMenu->addAction(actionSetCurrentInstall);
257 _notInstalledContextMenu->addAction(actionSetCurrentDontInstall);
258 _notInstalledContextMenu->addAction(actionSetCurrentTaboo);
260 addAllInListSubMenu( _notInstalledContextMenu );
263 _notInstalledContextMenu->addSeparator();
264 _notInstalledContextMenu->addAction( _( "Export This List to &Text File..." ),
265 this, SLOT( askExportList() ) );
270 YQPkgList::createInstalledContextMenu()
272 _installedContextMenu = new QMenu( this );
273 Q_CHECK_PTR( _installedContextMenu );
275 _installedContextMenu->addAction(actionSetCurrentKeepInstalled);
276 _installedContextMenu->addAction(actionSetCurrentDelete);
277 _installedContextMenu->addAction(actionSetCurrentUpdate);
278 _installedContextMenu->addAction(actionSetCurrentProtected);
280 addAllInListSubMenu( _installedContextMenu );
282 _installedContextMenu->addSeparator();
283 _installedContextMenu->addAction( _( "Export This List to &Text File..." ),
284 this, SLOT( askExportList() ) );
289 YQPkgList::addAllInListSubMenu( QMenu * menu )
291 QMenu * submenu = new QMenu( menu );
292 Q_CHECK_PTR( submenu );
294 submenu->addAction(actionSetListInstall);
295 submenu->addAction(actionSetListDontInstall);
296 submenu->addAction(actionSetListKeepInstalled);
297 submenu->addAction(actionSetListDelete);
298 submenu->addAction(actionSetListDelete);
299 submenu->addAction(actionSetListUpdate);
300 submenu->addAction(actionSetListUpdateForce);
301 submenu->addAction(actionSetListTaboo);
302 submenu->addAction(actionSetListProtected);
304 QAction *action = menu->addMenu( submenu );
305 action->setText(_( "&All in This List" ));
312 YQPkgList::createActions()
314 actionInstallSourceRpm = createAction( _( "&Install Source" ),
315 statusIcon( S_Install, true ),
316 statusIcon( S_Install, false ) );
318 actionDontInstallSourceRpm = createAction( _( "Do &Not Install Source" ),
319 statusIcon( S_NoInst, true ),
320 statusIcon( S_NoInst, false ) );
322 actionInstallListSourceRpms = createAction( _( "&Install All Available Sources" ),
323 statusIcon( S_Install, true ),
324 statusIcon( S_Install, false ),
325 QString::null, // key
328 actionDontInstallListSourceRpms = createAction( _( "Do &Not Install Any Sources" ),
329 statusIcon( S_NoInst, true ),
330 statusIcon( S_NoInst, false ),
331 QString::null, // key
334 connect( actionInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setInstallCurrentSourceRpm() ) );
335 connect( actionDontInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setDontInstallCurrentSourceRpm() ) );
337 connect( actionInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setInstallListSourceRpms() ) );
338 connect( actionDontInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setDontInstallListSourceRpms() ) );
343 YQPkgList::updateActions( YQPkgObjListItem * pkgObjListItem )
345 YQPkgObjList::updateActions( pkgObjListItem );
347 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (pkgObjListItem);
351 actionInstallSourceRpm->setEnabled( item->hasSourceRpm() );
352 actionDontInstallSourceRpm->setEnabled( item->hasSourceRpm() );
356 actionInstallSourceRpm->setEnabled( false );
357 actionDontInstallSourceRpm->setEnabled( false );
363 YQPkgList::askExportList() const
365 QString filename = YQUI::ui()->askForSaveFileName( "pkglist.txt", // startsWith
367 _( "Export Package List" ) );
368 if ( ! filename.isEmpty() )
369 exportList( filename, true );
374 YQPkgList::exportList( const QString filename, bool interactive ) const
378 QFile file(filename);
379 file.open(QIODevice::WriteOnly);
381 if ( file.error() != QFile::NoError )
383 y2error( "Can't open file %s", qPrintable(filename) );
389 QMessageBox::warning( 0, // parent
390 _( "Error" ), // caption
391 _( "Cannot open file %1" ).arg( filename ),
392 QMessageBox::Ok | QMessageBox::Default, // button0
393 QMessageBox::NoButton, // button1
394 QMessageBox::NoButton ); // button2
404 // Format the header line with QString::sprintf() because plain stdio
405 // fprintf() is not UTF-8 aware - it will count multi-byte characters
406 // wrong, so the formatting will be broken.
409 header.sprintf( "# %-18s %-30s | %10s | %-16s | %-16s\n\n",
410 (const char *) _( "Status" ).toUtf8(),
411 (const char *) _( "Package" ).toUtf8(),
412 (const char *) _( "Size" ).toUtf8(),
413 (const char *) _( "Avail. Ver." ).toUtf8(),
414 (const char *) _( "Inst. Ver." ).toUtf8()
416 file.write(header.toUtf8());
424 const QTreeWidgetItem * item = firstChild();
428 const YQPkgListItem * pkg = dynamic_cast<const YQPkgListItem *> (item);
432 QString candVersion = pkg->text( versionCol() );
433 QString instVersion = pkg->text( instVersionCol() );
435 if ( candVersion.isEmpty() ) candVersion = "---";
436 if ( instVersion.isEmpty() ) instVersion = "---";
438 QString status = "[" + statusText( pkg->status() ) + "]";
440 format.sprintf("%-20s %-30s | %10s | %-16s | %-16s\n",
441 (const char *) status.toUtf8(),
442 (const char *) pkg->text( nameCol() ),
443 (const char *) pkg->text( sizeCol() ),
444 (const char *) candVersion,
445 (const char *) instVersion
447 file.write(format.toUtf8());
450 item = item->nextSibling();
462 YQPkgList::globalSetPkgStatus( ZyppStatus newStatus, bool force, bool countOnly )
464 YQUI::ui()->busyCursor();
465 int changedCount = 0;
467 for ( ZyppPoolIterator it = zyppPkgBegin();
471 ZyppSel selectable = *it;
472 ZyppStatus oldStatus = selectable->status();
474 if ( newStatus != oldStatus )
476 bool doChange = false;
480 case S_KeepInstalled:
484 doChange = selectable->hasInstalledObj();
492 doChange = selectable->hasInstalledObj();
494 else // don't force - update only if useful (if candidate is newer)
496 const ZyppObj candidate = selectable->candidateObj();
497 const ZyppObj installed = selectable->installedObj();
499 if ( candidate && installed )
501 doChange = ( installed->edition() < candidate->edition() );
510 doChange = ! selectable->hasInstalledObj();
517 selectable->set_status( newStatus );
520 // y2milestone( "Updating %s", selectable->name().c_str() );
525 if ( changedCount > 0 && ! countOnly )
527 emit updateItemStates();
528 emit updatePackages();
529 emit statusChanged();
532 YQUI::ui()->normalCursor();
542 YQPkgListItem::YQPkgListItem( YQPkgList * pkgList,
545 : YQPkgObjListItem( pkgList, selectable, zyppPkg )
546 , _pkgList( pkgList )
547 , _zyppPkg( zyppPkg )
551 _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
557 YQPkgListItem::~YQPkgListItem()
564 YQPkgListItem::updateData()
566 YQPkgObjListItem::updateData();
572 YQPkgListItem::hasSourceRpm() const
574 if ( ! selectable() )
578 return selectable()->providesSources();
586 YQPkgListItem::installSourceRpm() const
588 if ( ! selectable() )
592 if ( ! selectable()->providesSources() )
595 return selectable()->source_install();
603 YQPkgListItem::setSourceRpmIcon()
605 if ( srpmStatusCol() < 0 )
610 if ( hasSourceRpm() )
613 if ( editable() && _pkgObjList->editable() )
615 icon = installSourceRpm() ?
616 YQIconPool::pkgInstall() :
617 YQIconPool::pkgNoInst();
621 icon = installSourceRpm() ?
622 YQIconPool::disabledPkgInstall() :
623 YQIconPool::disabledPkgNoInst();
626 setData( srpmStatusCol(), Qt::DecorationRole, 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
731 bool YQPkgListItem::operator< ( const QTreeWidgetItem & otherListViewItem ) const
733 int col = treeWidget()->sortColumn();
734 if ( col == srpmStatusCol() )
736 const YQPkgListItem * other = dynamic_cast<const YQPkgListItem *> (&otherListViewItem);
740 int thisPoints = ( this->hasSourceRpm() ? 1 : 0 ) + ( this->installSourceRpm() ? 1 : 0 );
741 int otherPoints = ( other->hasSourceRpm() ? 1 : 0 ) + ( other->installSourceRpm() ? 1 : 0 );
743 // Intentionally inverting order: Pkgs with source RPMs are more interesting than without.
744 return ( thisPoints < otherPoints );
748 // Fallback: Use parent class method
749 return YQPkgObjListItem::operator<( otherListViewItem );
754 YQPkgListItem::paintCell( QPainter * painter,
755 const QColorGroup & colorGroup,
761 if ( isDimmed() && ! YQUI::ui()->usingVisionImpairedPalette() )
763 QColorGroup cg = colorGroup;
764 cg.setColor( QColorGroup::Text, QColor( 0xA0, 0xA0, 0xA0 ) );
766 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
770 if ( installedIsNewer() )
772 QColorGroup cg = colorGroup;
774 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
776 if ( column == instVersionCol() )
777 cg.setColor( QColorGroup::Base, QColor( 0xFF, 0x30, 0x30 ) ); // Background
779 cg.setColor( QColorGroup::Text, QColor( 0xFF, 0, 0 ) ); // Foreground
782 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
784 else if ( candidateIsNewer() )
786 QColorGroup cg = colorGroup;
788 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
790 cg.setColor( QColorGroup::Text, QColor( 0, 0, 0xC0 ) ); // Foreground
792 if ( column == versionCol() )
793 cg.setColor( QColorGroup::Base, QColor( 0xF0, 0xF0, 0xF0 ) ); // Background
796 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
800 QTreeWidgetItem::paintCell( painter, colorGroup, column, width, alignment );
808 #include "YQPkgList.moc"