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>
27 #include <q3popupmenu.h>
28 #include <qmessagebox.h>
32 #include "YQPkgList.h"
35 #include "YQIconPool.h"
38 YQPkgList::YQPkgList( QWidget * parent )
39 : YQPkgObjList( parent )
44 addColumn( "" ); _statusCol = numCol++;
45 // _statusCol = numCol;
46 addColumn( _( "Package" ) ); _nameCol = numCol++;
48 addColumn( _( "Summary" ) ); _summaryCol = numCol++;
49 addColumn( _( "Size" ) ); _sizeCol = numCol++;
51 if ( haveInstalledPkgs() )
53 addColumn( _( "Avail. Ver." ) ); _versionCol = numCol++;
54 addColumn( _( "Inst. Ver." ) ); _instVersionCol = numCol++;
58 addColumn( _( "Version" ) ); _versionCol = numCol++;
62 #if SOURCE_RPM_DISABLED
63 #warning Selecting source RPMs disabled!
65 addColumn( _( "Source" ) ); _srpmStatusCol = numCol++;
69 setSorting( nameCol() );
70 setColumnAlignment( sizeCol(), Qt::AlignRight );
71 setAllColumnsShowFocus( true );
74 createSourceRpmContextMenu();
78 YQPkgList::~YQPkgList()
84 void YQPkgList::addPkgItem( ZyppSel selectable,
87 addPkgItem( selectable, zyppPkg, false );
91 void YQPkgList::addPkgItemDimmed( ZyppSel selectable,
94 addPkgItem( selectable, zyppPkg, true );
99 YQPkgList::addPkgItem( ZyppSel selectable,
105 y2error( "NULL zypp::ui::Selectable!" );
109 YQPkgListItem * item = new YQPkgListItem( this, selectable, zyppPkg );
112 item->setDimmed( dimmed );
113 applyExcludeRules( item );
118 YQPkgList::haveInstalledPkgs()
120 for ( ZyppPoolIterator it = zyppPkgBegin();
124 if ( (*it)->installedObj() )
133 YQPkgList::pkgObjClicked( int button,
134 QTreeWidgetItem * listViewItem,
138 if ( col == srpmStatusCol() )
140 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
144 if ( button == Qt::LeftButton )
146 if ( editable() && item->editable() )
147 item->toggleSourceRpmStatus();
150 else if ( button == Qt::RightButton )
152 if ( editable() && item->editable() )
154 updateActions( item );
156 if ( _sourceRpmContextMenu )
157 _sourceRpmContextMenu->popup( pos );
165 YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
170 YQPkgList::sizeHint() const
172 return QSize( 600, 350 );
177 YQPkgList::createSourceRpmContextMenu()
179 _sourceRpmContextMenu = new Q3PopupMenu( this );
181 actionInstallSourceRpm->addTo( _sourceRpmContextMenu );
182 actionDontInstallSourceRpm->addTo( _sourceRpmContextMenu );
184 Q3PopupMenu * submenu = new Q3PopupMenu( _sourceRpmContextMenu );
185 Q_CHECK_PTR( submenu );
186 _sourceRpmContextMenu->insertItem( _( "&All in This List" ), submenu );
188 actionInstallListSourceRpms->addTo( submenu );
189 actionDontInstallListSourceRpms->addTo( submenu );
194 YQPkgList::setInstallCurrentSourceRpm( bool installSourceRpm,
195 bool selectNextItem )
197 QTreeWidgetItem * listViewItem = selectedItem();
199 if ( ! listViewItem )
202 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
206 item->setInstallSourceRpm( installSourceRpm );
208 if ( selectNextItem && item->nextSibling() )
210 item->setSelected( false ); // doesn't emit signals
211 setSelected( item->nextSibling(), true ); // emits signals
218 YQPkgList::setInstallListSourceRpms( bool installSourceRpm )
223 QTreeWidgetItem * listViewItem = firstChild();
225 while ( listViewItem )
227 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
229 if ( item && item->editable() )
231 item->setInstallSourceRpm( installSourceRpm );
234 listViewItem = listViewItem->nextSibling();
241 YQPkgList::createNotInstalledContextMenu()
243 _notInstalledContextMenu = new Q3PopupMenu( this );
244 Q_CHECK_PTR( _notInstalledContextMenu );
246 actionSetCurrentInstall->addTo( _notInstalledContextMenu );
247 actionSetCurrentDontInstall->addTo( _notInstalledContextMenu );
248 actionSetCurrentTaboo->addTo( _notInstalledContextMenu );
250 addAllInListSubMenu( _notInstalledContextMenu );
253 _notInstalledContextMenu->insertSeparator();
254 _notInstalledContextMenu->insertItem( _( "Export This List to &Text File..." ),
255 this, SLOT( askExportList() ) );
260 YQPkgList::createInstalledContextMenu()
262 _installedContextMenu = new Q3PopupMenu( this );
263 Q_CHECK_PTR( _installedContextMenu );
265 actionSetCurrentKeepInstalled->addTo( _installedContextMenu );
266 actionSetCurrentDelete->addTo( _installedContextMenu );
267 actionSetCurrentUpdate->addTo( _installedContextMenu );
268 actionSetCurrentProtected->addTo( _installedContextMenu );
270 addAllInListSubMenu( _installedContextMenu );
272 _installedContextMenu->insertSeparator();
273 _installedContextMenu->insertItem( _( "Export This List to &Text File..." ),
274 this, SLOT( askExportList() ) );
279 YQPkgList::addAllInListSubMenu( Q3PopupMenu * menu )
281 Q3PopupMenu * submenu = new Q3PopupMenu( menu );
282 Q_CHECK_PTR( submenu );
284 actionSetListInstall->addTo( submenu );
285 actionSetListDontInstall->addTo( submenu );
286 actionSetListKeepInstalled->addTo( submenu );
287 actionSetListDelete->addTo( submenu );
288 actionSetListUpdate->addTo( submenu );
289 actionSetListUpdateForce->addTo( submenu );
290 actionSetListTaboo->addTo( submenu );
291 actionSetListProtected->addTo( submenu );
293 menu->insertItem( _( "&All in This List" ), submenu );
300 YQPkgList::createActions()
302 actionInstallSourceRpm = createAction( _( "&Install Source" ),
303 statusIcon( S_Install, true ),
304 statusIcon( S_Install, false ) );
306 actionDontInstallSourceRpm = createAction( _( "Do &Not Install Source" ),
307 statusIcon( S_NoInst, true ),
308 statusIcon( S_NoInst, false ) );
310 actionInstallListSourceRpms = createAction( _( "&Install All Available Sources" ),
311 statusIcon( S_Install, true ),
312 statusIcon( S_Install, false ),
313 QString::null, // key
316 actionDontInstallListSourceRpms = createAction( _( "Do &Not Install Any Sources" ),
317 statusIcon( S_NoInst, true ),
318 statusIcon( S_NoInst, false ),
319 QString::null, // key
322 connect( actionInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setInstallCurrentSourceRpm() ) );
323 connect( actionDontInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setDontInstallCurrentSourceRpm() ) );
325 connect( actionInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setInstallListSourceRpms() ) );
326 connect( actionDontInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setDontInstallListSourceRpms() ) );
331 YQPkgList::updateActions( YQPkgObjListItem * pkgObjListItem )
333 YQPkgObjList::updateActions( pkgObjListItem );
335 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (pkgObjListItem);
339 actionInstallSourceRpm->setEnabled( item->hasSourceRpm() );
340 actionDontInstallSourceRpm->setEnabled( item->hasSourceRpm() );
344 actionInstallSourceRpm->setEnabled( false );
345 actionDontInstallSourceRpm->setEnabled( false );
351 YQPkgList::askExportList() const
353 QString filename = YQUI::ui()->askForSaveFileName( "pkglist.txt", // startsWith
355 _( "Export Package List" ) );
356 if ( ! filename.isEmpty() )
357 exportList( filename, true );
362 YQPkgList::exportList( const QString filename, bool interactive ) const
366 FILE * file = fopen( (const char *) filename, "w" );
370 y2error( "Can't open file %s", (const char *) filename );
376 QMessageBox::warning( 0, // parent
377 _( "Error" ), // caption
378 _( "Cannot open file %1" ).arg( filename ),
379 QMessageBox::Ok | QMessageBox::Default, // button0
380 QMessageBox::NoButton, // button1
381 QMessageBox::NoButton ); // button2
391 // Format the header line with QString::sprintf() because plain stdio
392 // fprintf() is not UTF-8 aware - it will count multi-byte characters
393 // wrong, so the formatting will be broken.
396 header.sprintf( "# %-18s %-30s | %10s | %-16s | %-16s\n\n",
397 (const char *) _( "Status" ).utf8(),
398 (const char *) _( "Package" ).utf8(),
399 (const char *) _( "Size" ).utf8(),
400 (const char *) _( "Avail. Ver." ).utf8(),
401 (const char *) _( "Inst. Ver." ).utf8()
403 fputs( (const char *) header.utf8(), file );
410 const QTreeWidgetItem * item = firstChild();
414 const YQPkgListItem * pkg = dynamic_cast<const YQPkgListItem *> (item);
418 QString candVersion = pkg->text( versionCol() );
419 QString instVersion = pkg->text( instVersionCol() );
421 if ( candVersion.isEmpty() ) candVersion = "---";
422 if ( instVersion.isEmpty() ) instVersion = "---";
424 QString status = "[" + statusText( pkg->status() ) + "]";
425 fprintf( file, "%-20s %-30s | %10s | %-16s | %-16s\n",
426 (const char *) status.utf8(),
427 (const char *) pkg->text( nameCol() ),
428 (const char *) pkg->text( sizeCol() ),
429 (const char *) candVersion,
430 (const char *) instVersion
434 item = item->nextSibling();
446 YQPkgList::globalSetPkgStatus( ZyppStatus newStatus, bool force, bool countOnly )
448 YQUI::ui()->busyCursor();
449 int changedCount = 0;
451 for ( ZyppPoolIterator it = zyppPkgBegin();
455 ZyppSel selectable = *it;
456 ZyppStatus oldStatus = selectable->status();
458 if ( newStatus != oldStatus )
460 bool doChange = false;
464 case S_KeepInstalled:
468 doChange = selectable->hasInstalledObj();
476 doChange = selectable->hasInstalledObj();
478 else // don't force - update only if useful (if candidate is newer)
480 const ZyppObj candidate = selectable->candidateObj();
481 const ZyppObj installed = selectable->installedObj();
483 if ( candidate && installed )
485 doChange = ( installed->edition() < candidate->edition() );
494 doChange = ! selectable->hasInstalledObj();
501 selectable->set_status( newStatus );
504 // y2milestone( "Updating %s", selectable->name().c_str() );
509 if ( changedCount > 0 && ! countOnly )
511 emit updateItemStates();
512 emit updatePackages();
513 emit statusChanged();
516 YQUI::ui()->normalCursor();
526 YQPkgListItem::YQPkgListItem( YQPkgList * pkgList,
529 : YQPkgObjListItem( pkgList, selectable, zyppPkg )
530 , _pkgList( pkgList )
531 , _zyppPkg( zyppPkg )
535 _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
541 YQPkgListItem::~YQPkgListItem()
548 YQPkgListItem::updateData()
550 YQPkgObjListItem::updateData();
556 YQPkgListItem::hasSourceRpm() const
558 if ( ! selectable() )
562 return selectable()->providesSources();
570 YQPkgListItem::installSourceRpm() const
572 if ( ! selectable() )
576 if ( ! selectable()->providesSources() )
579 return selectable()->source_install();
587 YQPkgListItem::setSourceRpmIcon()
589 if ( srpmStatusCol() < 0 )
594 if ( hasSourceRpm() )
597 if ( editable() && _pkgObjList->editable() )
599 icon = installSourceRpm() ?
600 YQIconPool::pkgInstall() :
601 YQIconPool::pkgNoInst();
605 icon = installSourceRpm() ?
606 YQIconPool::disabledPkgInstall() :
607 YQIconPool::disabledPkgNoInst();
611 setPixmap( srpmStatusCol(), icon );
616 YQPkgListItem::setInstallSourceRpm( bool installSourceRpm )
618 if ( hasSourceRpm() )
622 selectable()->set_source_install( installSourceRpm );
631 YQPkgListItem::toggleSourceRpmStatus()
633 setInstallSourceRpm( ! installSourceRpm() );
638 YQPkgListItem::toolTip( int col )
641 QString name = _zyppObj->name().c_str();
643 if ( col == statusCol() )
645 text = YQPkgObjListItem::toolTip( col );
647 else if ( col == srpmStatusCol() )
649 text = name + "\n\n";
651 if ( hasSourceRpm() )
653 text += installSourceRpm() ?
654 _( "Install Sources" ) :
655 _( "Do Not Install Sources" );
659 text += _( "No Sources Available" );
664 text = name + "\n\n";
669 if ( selectable()->hasInstalledObj() )
671 installed = selectable()->installedObj()->edition().asString().c_str();
673 installed += selectable()->installedObj()->arch().asString().c_str();
674 installed = _( "Installed Version: %1" ).arg( installed );
677 if ( selectable()->hasCandidateObj() )
679 candidate = selectable()->candidateObj()->edition().asString().c_str();
681 candidate += selectable()->candidateObj()->arch().asString().c_str();
684 if ( selectable()->hasInstalledObj() )
686 text += installed + "\n";
688 if ( selectable()->hasCandidateObj() )
690 // Translators: This is the relation between two versions of one package
691 // if both versions are the same, e.g., both "1.2.3-42", "1.2.3-42"
692 QString relation = _( "same" );
694 if ( _candidateIsNewer ) relation = _( "newer" );
695 if ( _installedIsNewer ) relation = _( "older" );
697 // Translators: %1 is the version, %2 is one of "newer", "older", "same"
698 text += _( "Available Version: %1 (%2)" ).arg( candidate ).arg( relation );
702 text += _( "Not available for installation" );
705 else // not installed
717 * Comparison function used for sorting the list.
724 YQPkgListItem::compare( QTreeWidgetItem * otherListViewItem,
726 bool ascending ) const
728 if ( col == srpmStatusCol() )
730 YQPkgListItem * other = dynamic_cast<YQPkgListItem *> (otherListViewItem);
734 int thisPoints = ( this->hasSourceRpm() ? 1 : 0 ) + ( this->installSourceRpm() ? 1 : 0 );
735 int otherPoints = ( other->hasSourceRpm() ? 1 : 0 ) + ( other->installSourceRpm() ? 1 : 0 );
737 // Intentionally inverting order: Pkgs with source RPMs are more interesting than without.
738 if ( thisPoints > otherPoints ) return -1;
739 if ( thisPoints < otherPoints ) return 1;
744 // Fallback: Use parent class method
745 return YQPkgObjListItem::compare( otherListViewItem, col, ascending );
750 YQPkgListItem::paintCell( QPainter * painter,
751 const QColorGroup & colorGroup,
756 if ( isDimmed() && ! YQUI::ui()->usingVisionImpairedPalette() )
758 QColorGroup cg = colorGroup;
759 cg.setColor( QColorGroup::Text, QColor( 0xA0, 0xA0, 0xA0 ) );
761 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
765 if ( installedIsNewer() )
767 QColorGroup cg = colorGroup;
769 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
771 if ( column == instVersionCol() )
772 cg.setColor( QColorGroup::Base, QColor( 0xFF, 0x30, 0x30 ) ); // Background
774 cg.setColor( QColorGroup::Text, QColor( 0xFF, 0, 0 ) ); // Foreground
777 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
779 else if ( candidateIsNewer() )
781 QColorGroup cg = colorGroup;
783 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
785 cg.setColor( QColorGroup::Text, QColor( 0, 0, 0xC0 ) ); // Foreground
787 if ( column == versionCol() )
788 cg.setColor( QColorGroup::Base, QColor( 0xF0, 0xF0, 0xF0 ) ); // Background
791 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
795 QTreeWidgetItem::paintCell( painter, colorGroup, column, width, alignment );
802 #include "YQPkgList.moc"