1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
23 #define SOURCE_RPM_DISABLED 0
25 #define y2log_component "qt-pkg"
26 #include <ycp/y2log.h>
30 #include <QMessageBox>
34 #include "YQPkgList.h"
37 #include "YQIconPool.h"
40 YQPkgList::YQPkgList( QWidget * parent )
41 : YQPkgObjList( parent )
47 addColumn( "" ); _statusCol = numCol++;
48 // _statusCol = numCol;
49 addColumn( _( "Package" ) ); _nameCol = numCol++;
51 addColumn( _( "Summary" ) ); _summaryCol = numCol++;
52 addColumn( _( "Size" ) ); _sizeCol = numCol++;
54 if ( haveInstalledPkgs() )
56 addColumn( _( "Avail. Ver." ) ); _versionCol = numCol++;
57 addColumn( _( "Inst. Ver." ) ); _instVersionCol = numCol++;
61 addColumn( _( "Version" ) ); _versionCol = numCol++;
65 #if SOURCE_RPM_DISABLED
66 #warning Selecting source RPMs disabled!
68 addColumn( _( "Source" ) ); _srpmStatusCol = numCol++;
72 setSorting( nameCol() );
73 setColumnAlignment( sizeCol(), Qt::AlignRight );
74 setAllColumnsShowFocus( true );
78 createSourceRpmContextMenu();
82 YQPkgList::~YQPkgList()
88 void YQPkgList::addPkgItem( ZyppSel selectable,
91 addPkgItem( selectable, zyppPkg, false );
95 void YQPkgList::addPkgItemDimmed( ZyppSel selectable,
98 addPkgItem( selectable, zyppPkg, true );
103 YQPkgList::addPkgItem( ZyppSel selectable,
109 y2error( "NULL zypp::ui::Selectable!" );
113 YQPkgListItem * item = new YQPkgListItem( this, selectable, zyppPkg );
116 item->setDimmed( dimmed );
117 applyExcludeRules( item );
122 YQPkgList::haveInstalledPkgs()
124 for ( ZyppPoolIterator it = zyppPkgBegin();
128 if ( (*it)->installedObj() )
137 YQPkgList::pkgObjClicked( int button,
138 QTreeWidgetItem * listViewItem,
142 if ( col == srpmStatusCol() )
144 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
148 if ( button == Qt::LeftButton )
150 if ( editable() && item->editable() )
151 item->toggleSourceRpmStatus();
154 else if ( button == Qt::RightButton )
156 if ( editable() && item->editable() )
158 updateActions( item );
160 if ( _sourceRpmContextMenu )
161 _sourceRpmContextMenu->popup( pos );
169 YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
174 YQPkgList::sizeHint() const
176 return QSize( 600, 350 );
181 YQPkgList::createSourceRpmContextMenu()
183 _sourceRpmContextMenu = new QMenu( this );
185 actionInstallSourceRpm->addTo( _sourceRpmContextMenu );
186 actionDontInstallSourceRpm->addTo( _sourceRpmContextMenu );
188 QMenu * submenu = new QMenu( _sourceRpmContextMenu );
189 Q_CHECK_PTR( submenu );
190 _sourceRpmContextMenu->insertItem( _( "&All in This List" ), submenu );
192 actionInstallListSourceRpms->addTo( submenu );
193 actionDontInstallListSourceRpms->addTo( submenu );
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 actionSetCurrentInstall->addTo( _notInstalledContextMenu );
255 actionSetCurrentDontInstall->addTo( _notInstalledContextMenu );
256 actionSetCurrentTaboo->addTo( _notInstalledContextMenu );
258 addAllInListSubMenu( _notInstalledContextMenu );
261 _notInstalledContextMenu->insertSeparator();
262 _notInstalledContextMenu->insertItem( _( "Export This List to &Text File..." ),
263 this, SLOT( askExportList() ) );
268 YQPkgList::createInstalledContextMenu()
270 _installedContextMenu = new QMenu( this );
271 Q_CHECK_PTR( _installedContextMenu );
273 actionSetCurrentKeepInstalled->addTo( _installedContextMenu );
274 actionSetCurrentDelete->addTo( _installedContextMenu );
275 actionSetCurrentUpdate->addTo( _installedContextMenu );
276 actionSetCurrentProtected->addTo( _installedContextMenu );
278 addAllInListSubMenu( _installedContextMenu );
280 _installedContextMenu->insertSeparator();
281 _installedContextMenu->insertItem( _( "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 actionSetListInstall->addTo( submenu );
293 actionSetListDontInstall->addTo( submenu );
294 actionSetListKeepInstalled->addTo( submenu );
295 actionSetListDelete->addTo( submenu );
296 actionSetListUpdate->addTo( submenu );
297 actionSetListUpdateForce->addTo( submenu );
298 actionSetListTaboo->addTo( submenu );
299 actionSetListProtected->addTo( submenu );
301 menu->insertItem( _( "&All in This List" ), submenu );
308 YQPkgList::createActions()
310 actionInstallSourceRpm = createAction( _( "&Install Source" ),
311 statusIcon( S_Install, true ),
312 statusIcon( S_Install, false ) );
314 actionDontInstallSourceRpm = createAction( _( "Do &Not Install Source" ),
315 statusIcon( S_NoInst, true ),
316 statusIcon( S_NoInst, false ) );
318 actionInstallListSourceRpms = createAction( _( "&Install All Available Sources" ),
319 statusIcon( S_Install, true ),
320 statusIcon( S_Install, false ),
321 QString::null, // key
324 actionDontInstallListSourceRpms = createAction( _( "Do &Not Install Any Sources" ),
325 statusIcon( S_NoInst, true ),
326 statusIcon( S_NoInst, false ),
327 QString::null, // key
330 connect( actionInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setInstallCurrentSourceRpm() ) );
331 connect( actionDontInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setDontInstallCurrentSourceRpm() ) );
333 connect( actionInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setInstallListSourceRpms() ) );
334 connect( actionDontInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setDontInstallListSourceRpms() ) );
339 YQPkgList::updateActions( YQPkgObjListItem * pkgObjListItem )
341 YQPkgObjList::updateActions( pkgObjListItem );
343 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (pkgObjListItem);
347 actionInstallSourceRpm->setEnabled( item->hasSourceRpm() );
348 actionDontInstallSourceRpm->setEnabled( item->hasSourceRpm() );
352 actionInstallSourceRpm->setEnabled( false );
353 actionDontInstallSourceRpm->setEnabled( false );
359 YQPkgList::askExportList() const
361 QString filename = YQUI::ui()->askForSaveFileName( "pkglist.txt", // startsWith
363 _( "Export Package List" ) );
364 if ( ! filename.isEmpty() )
365 exportList( filename, true );
370 YQPkgList::exportList( const QString filename, bool interactive ) const
374 FILE * file = fopen( (const char *) filename, "w" );
378 y2error( "Can't open file %s", (const char *) filename );
384 QMessageBox::warning( 0, // parent
385 _( "Error" ), // caption
386 _( "Cannot open file %1" ).arg( filename ),
387 QMessageBox::Ok | QMessageBox::Default, // button0
388 QMessageBox::NoButton, // button1
389 QMessageBox::NoButton ); // button2
399 // Format the header line with QString::sprintf() because plain stdio
400 // fprintf() is not UTF-8 aware - it will count multi-byte characters
401 // wrong, so the formatting will be broken.
404 header.sprintf( "# %-18s %-30s | %10s | %-16s | %-16s\n\n",
405 (const char *) _( "Status" ).utf8(),
406 (const char *) _( "Package" ).utf8(),
407 (const char *) _( "Size" ).utf8(),
408 (const char *) _( "Avail. Ver." ).utf8(),
409 (const char *) _( "Inst. Ver." ).utf8()
411 fputs( (const char *) header.utf8(), file );
419 const QTreeWidgetItem * item = firstChild();
423 const YQPkgListItem * pkg = dynamic_cast<const YQPkgListItem *> (item);
427 QString candVersion = pkg->text( versionCol() );
428 QString instVersion = pkg->text( instVersionCol() );
430 if ( candVersion.isEmpty() ) candVersion = "---";
431 if ( instVersion.isEmpty() ) instVersion = "---";
433 QString status = "[" + statusText( pkg->status() ) + "]";
434 fprintf( file, "%-20s %-30s | %10s | %-16s | %-16s\n",
435 (const char *) status.utf8(),
436 (const char *) pkg->text( nameCol() ),
437 (const char *) pkg->text( sizeCol() ),
438 (const char *) candVersion,
439 (const char *) instVersion
443 item = item->nextSibling();
455 YQPkgList::globalSetPkgStatus( ZyppStatus newStatus, bool force, bool countOnly )
457 YQUI::ui()->busyCursor();
458 int changedCount = 0;
460 for ( ZyppPoolIterator it = zyppPkgBegin();
464 ZyppSel selectable = *it;
465 ZyppStatus oldStatus = selectable->status();
467 if ( newStatus != oldStatus )
469 bool doChange = false;
473 case S_KeepInstalled:
477 doChange = selectable->hasInstalledObj();
485 doChange = selectable->hasInstalledObj();
487 else // don't force - update only if useful (if candidate is newer)
489 const ZyppObj candidate = selectable->candidateObj();
490 const ZyppObj installed = selectable->installedObj();
492 if ( candidate && installed )
494 doChange = ( installed->edition() < candidate->edition() );
503 doChange = ! selectable->hasInstalledObj();
510 selectable->set_status( newStatus );
513 // y2milestone( "Updating %s", selectable->name().c_str() );
518 if ( changedCount > 0 && ! countOnly )
520 emit updateItemStates();
521 emit updatePackages();
522 emit statusChanged();
525 YQUI::ui()->normalCursor();
535 YQPkgListItem::YQPkgListItem( YQPkgList * pkgList,
538 : YQPkgObjListItem( pkgList, selectable, zyppPkg )
539 , _pkgList( pkgList )
540 , _zyppPkg( zyppPkg )
544 _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
550 YQPkgListItem::~YQPkgListItem()
557 YQPkgListItem::updateData()
559 YQPkgObjListItem::updateData();
565 YQPkgListItem::hasSourceRpm() const
567 if ( ! selectable() )
571 return selectable()->providesSources();
579 YQPkgListItem::installSourceRpm() const
581 if ( ! selectable() )
585 if ( ! selectable()->providesSources() )
588 return selectable()->source_install();
596 YQPkgListItem::setSourceRpmIcon()
598 if ( srpmStatusCol() < 0 )
603 if ( hasSourceRpm() )
606 if ( editable() && _pkgObjList->editable() )
608 icon = installSourceRpm() ?
609 YQIconPool::pkgInstall() :
610 YQIconPool::pkgNoInst();
614 icon = installSourceRpm() ?
615 YQIconPool::disabledPkgInstall() :
616 YQIconPool::disabledPkgNoInst();
620 setPixmap( srpmStatusCol(), icon );
626 YQPkgListItem::setInstallSourceRpm( bool installSourceRpm )
628 if ( hasSourceRpm() )
632 selectable()->set_source_install( installSourceRpm );
641 YQPkgListItem::toggleSourceRpmStatus()
643 setInstallSourceRpm( ! installSourceRpm() );
648 YQPkgListItem::toolTip( int col )
651 QString name = _zyppObj->name().c_str();
653 if ( col == statusCol() )
655 text = YQPkgObjListItem::toolTip( col );
657 else if ( col == srpmStatusCol() )
659 text = name + "\n\n";
661 if ( hasSourceRpm() )
663 text += installSourceRpm() ?
664 _( "Install Sources" ) :
665 _( "Do Not Install Sources" );
669 text += _( "No Sources Available" );
674 text = name + "\n\n";
679 if ( selectable()->hasInstalledObj() )
681 installed = selectable()->installedObj()->edition().asString().c_str();
683 installed += selectable()->installedObj()->arch().asString().c_str();
684 installed = _( "Installed Version: %1" ).arg( installed );
687 if ( selectable()->hasCandidateObj() )
689 candidate = selectable()->candidateObj()->edition().asString().c_str();
691 candidate += selectable()->candidateObj()->arch().asString().c_str();
694 if ( selectable()->hasInstalledObj() )
696 text += installed + "\n";
698 if ( selectable()->hasCandidateObj() )
700 // Translators: This is the relation between two versions of one package
701 // if both versions are the same, e.g., both "1.2.3-42", "1.2.3-42"
702 QString relation = _( "same" );
704 if ( _candidateIsNewer ) relation = _( "newer" );
705 if ( _installedIsNewer ) relation = _( "older" );
707 // Translators: %1 is the version, %2 is one of "newer", "older", "same"
708 text += _( "Available Version: %1 (%2)" ).arg( candidate ).arg( relation );
712 text += _( "Not available for installation" );
715 else // not installed
727 * Comparison function used for sorting the list.
734 YQPkgListItem::compare( QTreeWidgetItem * otherListViewItem,
736 bool ascending ) const
738 if ( col == srpmStatusCol() )
740 YQPkgListItem * other = dynamic_cast<YQPkgListItem *> (otherListViewItem);
744 int thisPoints = ( this->hasSourceRpm() ? 1 : 0 ) + ( this->installSourceRpm() ? 1 : 0 );
745 int otherPoints = ( other->hasSourceRpm() ? 1 : 0 ) + ( other->installSourceRpm() ? 1 : 0 );
747 // Intentionally inverting order: Pkgs with source RPMs are more interesting than without.
748 if ( thisPoints > otherPoints ) return -1;
749 if ( thisPoints < otherPoints ) return 1;
754 // Fallback: Use parent class method
755 return YQPkgObjListItem::compare( otherListViewItem, col, ascending );
760 YQPkgListItem::paintCell( QPainter * painter,
761 const QColorGroup & colorGroup,
767 if ( isDimmed() && ! YQUI::ui()->usingVisionImpairedPalette() )
769 QColorGroup cg = colorGroup;
770 cg.setColor( QColorGroup::Text, QColor( 0xA0, 0xA0, 0xA0 ) );
772 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
776 if ( installedIsNewer() )
778 QColorGroup cg = colorGroup;
780 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
782 if ( column == instVersionCol() )
783 cg.setColor( QColorGroup::Base, QColor( 0xFF, 0x30, 0x30 ) ); // Background
785 cg.setColor( QColorGroup::Text, QColor( 0xFF, 0, 0 ) ); // Foreground
788 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
790 else if ( candidateIsNewer() )
792 QColorGroup cg = colorGroup;
794 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
796 cg.setColor( QColorGroup::Text, QColor( 0, 0, 0xC0 ) ); // Foreground
798 if ( column == versionCol() )
799 cg.setColor( QColorGroup::Base, QColor( 0xF0, 0xF0, 0xF0 ) ); // Background
802 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
806 QTreeWidgetItem::paintCell( painter, colorGroup, column, width, alignment );
814 #include "YQPkgList.moc"