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 )
45 addColumn( "" ); _statusCol = numCol++;
46 // _statusCol = numCol;
47 addColumn( _( "Package" ) ); _nameCol = numCol++;
49 addColumn( _( "Summary" ) ); _summaryCol = numCol++;
50 addColumn( _( "Size" ) ); _sizeCol = numCol++;
52 if ( haveInstalledPkgs() )
54 addColumn( _( "Avail. Ver." ) ); _versionCol = numCol++;
55 addColumn( _( "Inst. Ver." ) ); _instVersionCol = numCol++;
59 addColumn( _( "Version" ) ); _versionCol = numCol++;
63 #if SOURCE_RPM_DISABLED
64 #warning Selecting source RPMs disabled!
66 addColumn( _( "Source" ) ); _srpmStatusCol = numCol++;
70 setSorting( nameCol() );
71 setColumnAlignment( sizeCol(), Qt::AlignRight );
72 setAllColumnsShowFocus( true );
76 createSourceRpmContextMenu();
80 YQPkgList::~YQPkgList()
86 void YQPkgList::addPkgItem( ZyppSel selectable,
89 addPkgItem( selectable, zyppPkg, false );
93 void YQPkgList::addPkgItemDimmed( ZyppSel selectable,
96 addPkgItem( selectable, zyppPkg, true );
101 YQPkgList::addPkgItem( ZyppSel selectable,
107 y2error( "NULL zypp::ui::Selectable!" );
111 YQPkgListItem * item = new YQPkgListItem( this, selectable, zyppPkg );
114 item->setDimmed( dimmed );
115 applyExcludeRules( item );
120 YQPkgList::haveInstalledPkgs()
122 for ( ZyppPoolIterator it = zyppPkgBegin();
126 if ( (*it)->installedObj() )
135 YQPkgList::pkgObjClicked( int button,
136 QTreeWidgetItem * listViewItem,
140 if ( col == srpmStatusCol() )
142 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
146 if ( button == Qt::LeftButton )
148 if ( editable() && item->editable() )
149 item->toggleSourceRpmStatus();
152 else if ( button == Qt::RightButton )
154 if ( editable() && item->editable() )
156 updateActions( item );
158 if ( _sourceRpmContextMenu )
159 _sourceRpmContextMenu->popup( pos );
167 YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
172 YQPkgList::sizeHint() const
174 return QSize( 600, 350 );
179 YQPkgList::createSourceRpmContextMenu()
181 _sourceRpmContextMenu = new Q3PopupMenu( this );
183 actionInstallSourceRpm->addTo( _sourceRpmContextMenu );
184 actionDontInstallSourceRpm->addTo( _sourceRpmContextMenu );
186 Q3PopupMenu * submenu = new Q3PopupMenu( _sourceRpmContextMenu );
187 Q_CHECK_PTR( submenu );
188 _sourceRpmContextMenu->insertItem( _( "&All in This List" ), submenu );
190 actionInstallListSourceRpms->addTo( submenu );
191 actionDontInstallListSourceRpms->addTo( submenu );
196 YQPkgList::setInstallCurrentSourceRpm( bool installSourceRpm,
197 bool selectNextItem )
200 QTreeWidgetItem * listViewItem = selectedItem();
202 if ( ! listViewItem )
205 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
209 item->setInstallSourceRpm( installSourceRpm );
211 if ( selectNextItem && item->nextSibling() )
213 item->setSelected( false ); // doesn't emit signals
214 setSelected( item->nextSibling(), true ); // emits signals
222 YQPkgList::setInstallListSourceRpms( bool installSourceRpm )
228 QTreeWidgetItem * listViewItem = firstChild();
230 while ( listViewItem )
232 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
234 if ( item && item->editable() )
236 item->setInstallSourceRpm( installSourceRpm );
239 listViewItem = listViewItem->nextSibling();
247 YQPkgList::createNotInstalledContextMenu()
249 _notInstalledContextMenu = new Q3PopupMenu( this );
250 Q_CHECK_PTR( _notInstalledContextMenu );
252 actionSetCurrentInstall->addTo( _notInstalledContextMenu );
253 actionSetCurrentDontInstall->addTo( _notInstalledContextMenu );
254 actionSetCurrentTaboo->addTo( _notInstalledContextMenu );
256 addAllInListSubMenu( _notInstalledContextMenu );
259 _notInstalledContextMenu->insertSeparator();
260 _notInstalledContextMenu->insertItem( _( "Export This List to &Text File..." ),
261 this, SLOT( askExportList() ) );
266 YQPkgList::createInstalledContextMenu()
268 _installedContextMenu = new Q3PopupMenu( this );
269 Q_CHECK_PTR( _installedContextMenu );
271 actionSetCurrentKeepInstalled->addTo( _installedContextMenu );
272 actionSetCurrentDelete->addTo( _installedContextMenu );
273 actionSetCurrentUpdate->addTo( _installedContextMenu );
274 actionSetCurrentProtected->addTo( _installedContextMenu );
276 addAllInListSubMenu( _installedContextMenu );
278 _installedContextMenu->insertSeparator();
279 _installedContextMenu->insertItem( _( "Export This List to &Text File..." ),
280 this, SLOT( askExportList() ) );
285 YQPkgList::addAllInListSubMenu( Q3PopupMenu * menu )
287 Q3PopupMenu * submenu = new Q3PopupMenu( menu );
288 Q_CHECK_PTR( submenu );
290 actionSetListInstall->addTo( submenu );
291 actionSetListDontInstall->addTo( submenu );
292 actionSetListKeepInstalled->addTo( submenu );
293 actionSetListDelete->addTo( submenu );
294 actionSetListUpdate->addTo( submenu );
295 actionSetListUpdateForce->addTo( submenu );
296 actionSetListTaboo->addTo( submenu );
297 actionSetListProtected->addTo( submenu );
299 menu->insertItem( _( "&All in This List" ), submenu );
306 YQPkgList::createActions()
308 actionInstallSourceRpm = createAction( _( "&Install Source" ),
309 statusIcon( S_Install, true ),
310 statusIcon( S_Install, false ) );
312 actionDontInstallSourceRpm = createAction( _( "Do &Not Install Source" ),
313 statusIcon( S_NoInst, true ),
314 statusIcon( S_NoInst, false ) );
316 actionInstallListSourceRpms = createAction( _( "&Install All Available Sources" ),
317 statusIcon( S_Install, true ),
318 statusIcon( S_Install, false ),
319 QString::null, // key
322 actionDontInstallListSourceRpms = createAction( _( "Do &Not Install Any Sources" ),
323 statusIcon( S_NoInst, true ),
324 statusIcon( S_NoInst, false ),
325 QString::null, // key
328 connect( actionInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setInstallCurrentSourceRpm() ) );
329 connect( actionDontInstallSourceRpm, SIGNAL( activated() ), this, SLOT( setDontInstallCurrentSourceRpm() ) );
331 connect( actionInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setInstallListSourceRpms() ) );
332 connect( actionDontInstallListSourceRpms, SIGNAL( activated() ), this, SLOT( setDontInstallListSourceRpms() ) );
337 YQPkgList::updateActions( YQPkgObjListItem * pkgObjListItem )
339 YQPkgObjList::updateActions( pkgObjListItem );
341 YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (pkgObjListItem);
345 actionInstallSourceRpm->setEnabled( item->hasSourceRpm() );
346 actionDontInstallSourceRpm->setEnabled( item->hasSourceRpm() );
350 actionInstallSourceRpm->setEnabled( false );
351 actionDontInstallSourceRpm->setEnabled( false );
357 YQPkgList::askExportList() const
359 QString filename = YQUI::ui()->askForSaveFileName( "pkglist.txt", // startsWith
361 _( "Export Package List" ) );
362 if ( ! filename.isEmpty() )
363 exportList( filename, true );
368 YQPkgList::exportList( const QString filename, bool interactive ) const
372 FILE * file = fopen( (const char *) filename, "w" );
376 y2error( "Can't open file %s", (const char *) filename );
382 QMessageBox::warning( 0, // parent
383 _( "Error" ), // caption
384 _( "Cannot open file %1" ).arg( filename ),
385 QMessageBox::Ok | QMessageBox::Default, // button0
386 QMessageBox::NoButton, // button1
387 QMessageBox::NoButton ); // button2
397 // Format the header line with QString::sprintf() because plain stdio
398 // fprintf() is not UTF-8 aware - it will count multi-byte characters
399 // wrong, so the formatting will be broken.
402 header.sprintf( "# %-18s %-30s | %10s | %-16s | %-16s\n\n",
403 (const char *) _( "Status" ).utf8(),
404 (const char *) _( "Package" ).utf8(),
405 (const char *) _( "Size" ).utf8(),
406 (const char *) _( "Avail. Ver." ).utf8(),
407 (const char *) _( "Inst. Ver." ).utf8()
409 fputs( (const char *) header.utf8(), file );
417 const QTreeWidgetItem * item = firstChild();
421 const YQPkgListItem * pkg = dynamic_cast<const YQPkgListItem *> (item);
425 QString candVersion = pkg->text( versionCol() );
426 QString instVersion = pkg->text( instVersionCol() );
428 if ( candVersion.isEmpty() ) candVersion = "---";
429 if ( instVersion.isEmpty() ) instVersion = "---";
431 QString status = "[" + statusText( pkg->status() ) + "]";
432 fprintf( file, "%-20s %-30s | %10s | %-16s | %-16s\n",
433 (const char *) status.utf8(),
434 (const char *) pkg->text( nameCol() ),
435 (const char *) pkg->text( sizeCol() ),
436 (const char *) candVersion,
437 (const char *) instVersion
441 item = item->nextSibling();
453 YQPkgList::globalSetPkgStatus( ZyppStatus newStatus, bool force, bool countOnly )
455 YQUI::ui()->busyCursor();
456 int changedCount = 0;
458 for ( ZyppPoolIterator it = zyppPkgBegin();
462 ZyppSel selectable = *it;
463 ZyppStatus oldStatus = selectable->status();
465 if ( newStatus != oldStatus )
467 bool doChange = false;
471 case S_KeepInstalled:
475 doChange = selectable->hasInstalledObj();
483 doChange = selectable->hasInstalledObj();
485 else // don't force - update only if useful (if candidate is newer)
487 const ZyppObj candidate = selectable->candidateObj();
488 const ZyppObj installed = selectable->installedObj();
490 if ( candidate && installed )
492 doChange = ( installed->edition() < candidate->edition() );
501 doChange = ! selectable->hasInstalledObj();
508 selectable->set_status( newStatus );
511 // y2milestone( "Updating %s", selectable->name().c_str() );
516 if ( changedCount > 0 && ! countOnly )
518 emit updateItemStates();
519 emit updatePackages();
520 emit statusChanged();
523 YQUI::ui()->normalCursor();
533 YQPkgListItem::YQPkgListItem( YQPkgList * pkgList,
536 : YQPkgObjListItem( pkgList, selectable, zyppPkg )
537 , _pkgList( pkgList )
538 , _zyppPkg( zyppPkg )
542 _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
548 YQPkgListItem::~YQPkgListItem()
555 YQPkgListItem::updateData()
557 YQPkgObjListItem::updateData();
563 YQPkgListItem::hasSourceRpm() const
565 if ( ! selectable() )
569 return selectable()->providesSources();
577 YQPkgListItem::installSourceRpm() const
579 if ( ! selectable() )
583 if ( ! selectable()->providesSources() )
586 return selectable()->source_install();
594 YQPkgListItem::setSourceRpmIcon()
596 if ( srpmStatusCol() < 0 )
601 if ( hasSourceRpm() )
604 if ( editable() && _pkgObjList->editable() )
606 icon = installSourceRpm() ?
607 YQIconPool::pkgInstall() :
608 YQIconPool::pkgNoInst();
612 icon = installSourceRpm() ?
613 YQIconPool::disabledPkgInstall() :
614 YQIconPool::disabledPkgNoInst();
618 setPixmap( srpmStatusCol(), icon );
624 YQPkgListItem::setInstallSourceRpm( bool installSourceRpm )
626 if ( hasSourceRpm() )
630 selectable()->set_source_install( installSourceRpm );
639 YQPkgListItem::toggleSourceRpmStatus()
641 setInstallSourceRpm( ! installSourceRpm() );
646 YQPkgListItem::toolTip( int col )
649 QString name = _zyppObj->name().c_str();
651 if ( col == statusCol() )
653 text = YQPkgObjListItem::toolTip( col );
655 else if ( col == srpmStatusCol() )
657 text = name + "\n\n";
659 if ( hasSourceRpm() )
661 text += installSourceRpm() ?
662 _( "Install Sources" ) :
663 _( "Do Not Install Sources" );
667 text += _( "No Sources Available" );
672 text = name + "\n\n";
677 if ( selectable()->hasInstalledObj() )
679 installed = selectable()->installedObj()->edition().asString().c_str();
681 installed += selectable()->installedObj()->arch().asString().c_str();
682 installed = _( "Installed Version: %1" ).arg( installed );
685 if ( selectable()->hasCandidateObj() )
687 candidate = selectable()->candidateObj()->edition().asString().c_str();
689 candidate += selectable()->candidateObj()->arch().asString().c_str();
692 if ( selectable()->hasInstalledObj() )
694 text += installed + "\n";
696 if ( selectable()->hasCandidateObj() )
698 // Translators: This is the relation between two versions of one package
699 // if both versions are the same, e.g., both "1.2.3-42", "1.2.3-42"
700 QString relation = _( "same" );
702 if ( _candidateIsNewer ) relation = _( "newer" );
703 if ( _installedIsNewer ) relation = _( "older" );
705 // Translators: %1 is the version, %2 is one of "newer", "older", "same"
706 text += _( "Available Version: %1 (%2)" ).arg( candidate ).arg( relation );
710 text += _( "Not available for installation" );
713 else // not installed
725 * Comparison function used for sorting the list.
732 YQPkgListItem::compare( QTreeWidgetItem * otherListViewItem,
734 bool ascending ) const
736 if ( col == srpmStatusCol() )
738 YQPkgListItem * other = dynamic_cast<YQPkgListItem *> (otherListViewItem);
742 int thisPoints = ( this->hasSourceRpm() ? 1 : 0 ) + ( this->installSourceRpm() ? 1 : 0 );
743 int otherPoints = ( other->hasSourceRpm() ? 1 : 0 ) + ( other->installSourceRpm() ? 1 : 0 );
745 // Intentionally inverting order: Pkgs with source RPMs are more interesting than without.
746 if ( thisPoints > otherPoints ) return -1;
747 if ( thisPoints < otherPoints ) return 1;
752 // Fallback: Use parent class method
753 return YQPkgObjListItem::compare( otherListViewItem, col, ascending );
758 YQPkgListItem::paintCell( QPainter * painter,
759 const QColorGroup & colorGroup,
765 if ( isDimmed() && ! YQUI::ui()->usingVisionImpairedPalette() )
767 QColorGroup cg = colorGroup;
768 cg.setColor( QColorGroup::Text, QColor( 0xA0, 0xA0, 0xA0 ) );
770 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
774 if ( installedIsNewer() )
776 QColorGroup cg = colorGroup;
778 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
780 if ( column == instVersionCol() )
781 cg.setColor( QColorGroup::Base, QColor( 0xFF, 0x30, 0x30 ) ); // Background
783 cg.setColor( QColorGroup::Text, QColor( 0xFF, 0, 0 ) ); // Foreground
786 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
788 else if ( candidateIsNewer() )
790 QColorGroup cg = colorGroup;
792 if ( ! YQUI::ui()->usingVisionImpairedPalette() )
794 cg.setColor( QColorGroup::Text, QColor( 0, 0, 0xC0 ) ); // Foreground
796 if ( column == versionCol() )
797 cg.setColor( QColorGroup::Base, QColor( 0xF0, 0xF0, 0xF0 ) ); // Background
800 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
804 QTreeWidgetItem::paintCell( painter, colorGroup, column, width, alignment );
812 #include "YQPkgList.moc"