47 #define YUILogComponent "qt-pkg" 52 #include <QMessageBox> 56 #include <QHeaderView> 57 #include <QFontMetrics> 61 #include "YQPkgList.h" 64 #include "YQIconPool.h" 65 #include "YQApplication.h" 67 #define SINGLE_VERSION_COL 1 79 QString versionHeaderText;
80 QString instVersionHeaderText;
83 headers <<
""; _statusCol = numCol++;
84 headers << _(
"Package" ); _nameCol = numCol++;
85 headers << _(
"Summary" ); _summaryCol = numCol++;
89 #if SINGLE_VERSION_COL 90 versionHeaderText = _(
"Installed (Available)");
91 headers << versionHeaderText; _instVersionCol = numCol++;
92 _versionCol = _instVersionCol;
94 versionHeaderText = _(
"Avail. Ver." );
95 headers << versionHeaderText; _versionCol = numCol++;
97 instVersionHeaderText = _(
"Inst. Ver." );
98 headers << instVersionHeaderText; _instVersionCol = numCol++;
103 versionHeaderText = _(
"Version" );
104 headers << versionHeaderText; _versionCol = numCol++;
108 headers << _(
"Size" ); _sizeCol = numCol++;
110 setHeaderLabels( headers );
112 header()->setSortIndicatorShown(
true );
113 header()->setSectionsClickable(
true );
115 sortByColumn( statusCol(), Qt::AscendingOrder );
116 setAllColumnsShowFocus(
true );
117 setIconSize( QSize( 22, 16 ) );
119 header()->setSectionResizeMode( QHeaderView::Interactive );
126 connect ( header(), SIGNAL( sectionClicked (
int) ),
127 this, SLOT( sortByColumn (
int) ) );
158 scheduleDelayedItemsLayout();
162 yuiError() <<
"NULL zypp::ui::Selectable!" << std::endl;
180 for ( ZyppPoolIterator it = zyppPkgBegin();
184 if ( (*it)->installedObj() )
194 QTreeWidgetItem * listViewItem,
198 if ( col == srpmStatusCol() )
204 if ( button == Qt::LeftButton )
210 else if ( button == Qt::RightButton )
216 if ( _sourceRpmContextMenu )
217 _sourceRpmContextMenu->popup( pos );
232 return QSize( 600, 350 );
239 _sourceRpmContextMenu =
new QMenu(
this );
241 _sourceRpmContextMenu->addAction(actionInstallSourceRpm);
242 _sourceRpmContextMenu->addAction(actionDontInstallSourceRpm);
244 QMenu * submenu =
new QMenu( _sourceRpmContextMenu );
245 Q_CHECK_PTR( submenu );
246 QAction *action = _sourceRpmContextMenu->addMenu( submenu );
247 action->setText(_(
"&All in This List" ));
249 submenu->addAction(actionInstallListSourceRpms);
250 submenu->addAction(actionDontInstallListSourceRpms);
255 YQPkgList::setInstallCurrentSourceRpm(
bool installSourceRpm,
259 QTreeWidgetItem * listViewItem = selectedItem();
261 if ( ! listViewItem )
270 if ( selectNextItem && item->nextSibling() )
272 item->setSelected(
false );
273 setSelected( item->nextSibling(), true );
281 YQPkgList::setInstallListSourceRpms(
bool installSourceRpm )
287 QTreeWidgetItem * listViewItem = firstChild();
289 while ( listViewItem )
298 listViewItem = listViewItem->nextSibling();
307 _optimalColWidth_statusIcon = 0;
308 _optimalColWidth_name = 0;
309 _optimalColWidth_summary = 0;
310 _optimalColWidth_version = 0;
311 _optimalColWidth_instVersion = 0;
312 _optimalColWidth_size = 0;
321 QFontMetrics fm( this->font() );
322 const ZyppObj candidate = selectable->candidateObj();
323 const ZyppObj installed = selectable->installedObj();
325 _optimalColWidth_statusIcon = 28;
327 qstr = QString::fromUtf8( zyppPkg->name().c_str() );
328 qstr_width = fm.boundingRect( qstr ).width() + 8;
329 if (qstr_width > _optimalColWidth_name)
330 _optimalColWidth_name = qstr_width;
332 qstr = QString::fromUtf8( zyppPkg->summary().c_str() );
333 qstr_width = fm.boundingRect( qstr ).width() + 8;
334 if (qstr_width > _optimalColWidth_summary)
335 _optimalColWidth_summary = qstr_width;
337 if ( instVersionCol() == versionCol() )
340 qstr = QString::fromUtf8( installed->edition().c_str() );
343 if (candidate && (!installed || (candidate->edition() != installed->edition())))
347 qstr +=
"(" + QString::fromUtf8( candidate->edition().c_str() ) +
")";
349 qstr_width = fm.boundingRect( qstr ).width() + 8;
350 if (qstr_width > _optimalColWidth_version)
351 _optimalColWidth_version = qstr_width;
357 qstr = QString::fromUtf8( candidate->edition().c_str() );
358 qstr_width = fm.boundingRect( qstr ).width() + 8;
359 if (qstr_width > _optimalColWidth_version)
360 _optimalColWidth_version = qstr_width;
364 qstr = QString::fromUtf8( installed->edition().c_str() );
365 qstr_width = fm.boundingRect( qstr ).width() + 8;
366 if (qstr_width > _optimalColWidth_instVersion)
367 _optimalColWidth_instVersion = qstr_width;
371 qstr = QString::fromUtf8( zyppPkg->installSize().asString().c_str() );
372 qstr_width = fm.boundingRect( qstr ).width() + 8;
373 if (qstr_width > _optimalColWidth_size)
374 _optimalColWidth_size = qstr_width;
381 int visibleSpace = 0;
382 int optimalWidthsSum = 0;
384 int statusIconColWidth = _optimalColWidth_statusIcon;
386 if (statusIconColWidth == 0)
387 statusIconColWidth = 28;
388 optimalWidthsSum = _optimalColWidth_statusIcon + _optimalColWidth_name + _optimalColWidth_summary + _optimalColWidth_version + _optimalColWidth_size;
389 if ( instVersionCol() != versionCol() )
391 optimalWidthsSum += _optimalColWidth_instVersion;
395 visibleSpace = this->viewport()->width();
396 if (visibleSpace < 0)
return;
397 if (optimalWidthsSum >= visibleSpace)
401 int reducedSummaryWidth = visibleSpace - optimalWidthsSum + _optimalColWidth_summary;
402 if (reducedSummaryWidth < 100)
403 reducedSummaryWidth = 100;
405 this->setColumnWidth( statusCol(), statusIconColWidth );
406 this->setColumnWidth( nameCol(), _optimalColWidth_name );
407 this->setColumnWidth( summaryCol(), reducedSummaryWidth);
408 this->setColumnWidth( versionCol(), _optimalColWidth_version );
409 if ( instVersionCol() != versionCol() )
410 this->setColumnWidth( instVersionCol(), _optimalColWidth_instVersion );
411 this->setColumnWidth( sizeCol(), _optimalColWidth_size);
417 int addSpace = (visibleSpace - optimalWidthsSum) / numOptCol;
418 int addSpaceR = (visibleSpace - optimalWidthsSum) % numOptCol;
420 this->setColumnWidth( statusCol(), statusIconColWidth );
421 this->setColumnWidth( nameCol(), _optimalColWidth_name + addSpace );
422 this->setColumnWidth( summaryCol(), _optimalColWidth_summary + addSpace );
423 this->setColumnWidth( versionCol(), _optimalColWidth_version + addSpace );
424 if ( instVersionCol() != versionCol() )
425 this->setColumnWidth( instVersionCol(), _optimalColWidth_instVersion + addSpace );
426 this->setColumnWidth( sizeCol(), _optimalColWidth_size + addSpace + addSpaceR );
443 int col = sortColumn();
444 Qt::SortOrder order = header()->sortIndicatorOrder();
445 sortByColumn(col, order);
452 if (event->size().width() !=
event->oldSize().width())
463 _notInstalledContextMenu =
new QMenu(
this );
464 Q_CHECK_PTR( _notInstalledContextMenu );
466 _notInstalledContextMenu->addAction(actionSetCurrentInstall);
467 _notInstalledContextMenu->addAction(actionSetCurrentDontInstall);
468 _notInstalledContextMenu->addAction(actionSetCurrentTaboo);
472 _notInstalledContextMenu->addSeparator();
473 _notInstalledContextMenu->addAction( _(
"Export This List to &Text File..." ),
481 _installedContextMenu =
new QMenu(
this );
482 Q_CHECK_PTR( _installedContextMenu );
484 _installedContextMenu->addAction(actionSetCurrentKeepInstalled);
485 _installedContextMenu->addAction(actionSetCurrentDelete);
486 _installedContextMenu->addAction(actionSetCurrentUpdate);
487 _installedContextMenu->addAction(actionSetCurrentUpdateForce);
488 _installedContextMenu->addAction(actionSetCurrentProtected);
492 _installedContextMenu->addSeparator();
493 _installedContextMenu->addAction( _(
"Export This List to &Text File..." ),
501 QMenu * submenu =
new QMenu( menu );
502 Q_CHECK_PTR( submenu );
504 submenu->addAction(actionSetListInstall);
505 submenu->addAction(actionSetListDontInstall);
506 submenu->addAction(actionSetListKeepInstalled);
507 submenu->addAction(actionSetListDelete);
508 submenu->addAction(actionSetListDelete);
509 submenu->addAction(actionSetListUpdate);
510 submenu->addAction(actionSetListUpdateForce);
511 submenu->addAction(actionSetListTaboo);
512 submenu->addAction(actionSetListProtected);
514 QAction *action = menu->addMenu( submenu );
515 action->setText(_(
"&All in This List" ));
524 actionInstallSourceRpm =
createAction( _(
"&Install Source" ),
528 actionDontInstallSourceRpm =
createAction( _(
"Do &Not Install Source" ),
532 actionInstallListSourceRpms =
createAction( _(
"&Install All Available Sources" ),
538 actionDontInstallListSourceRpms =
createAction( _(
"Do &Not Install Any Sources" ),
544 connect( actionInstallSourceRpm, &QAction::triggered,
545 this,
static_cast<void (
YQPkgList::*)()
>(&YQPkgList::setInstallCurrentSourceRpm) );
546 connect( actionDontInstallSourceRpm, &QAction::triggered,
547 this, &YQPkgList::setDontInstallCurrentSourceRpm );
548 connect( actionInstallListSourceRpms, &QAction::triggered,
549 this,
static_cast<void (
YQPkgList::*)()
>(&YQPkgList::setInstallListSourceRpms) );
550 connect( actionDontInstallListSourceRpms, &QAction::triggered,
551 this, &YQPkgList::setDontInstallListSourceRpms );
564 actionInstallSourceRpm->setEnabled( item->
hasSourceRpm() );
565 actionDontInstallSourceRpm->setEnabled( item->
hasSourceRpm() );
569 actionInstallSourceRpm->setEnabled(
false );
570 actionDontInstallSourceRpm->setEnabled(
false );
578 QString filename = YQApplication::askForSaveFileName(
"pkglist.txt",
580 _(
"Export Package List" ) );
581 if ( ! filename.isEmpty() )
591 QFile file(filename);
592 file.open(QIODevice::WriteOnly);
594 if ( file.error() != QFile::NoError )
596 yuiError() <<
"Can't open file " << filename << std::endl;
602 QMessageBox::warning( 0,
604 _(
"Cannot open file %1" ).arg( filename ),
605 QMessageBox::Ok | QMessageBox::Default,
606 QMessageBox::NoButton,
607 QMessageBox::NoButton );
622 header.sprintf(
"# %-18s %-30s | %-40s | %-25s | %10s\n\n",
623 (
const char *) _(
"Status" ).toUtf8(),
624 (
const char *) _(
"Package" ).toUtf8(),
625 (
const char *) _(
"Summary" ).toUtf8(),
626 (
const char *) _(
"Installed (Available)" ).toUtf8(),
627 (
const char *) _(
"Size" ).toUtf8()
629 file.write(header.toUtf8());
634 QTreeWidgetItemIterator it((QTreeWidget*)
this);
638 const QTreeWidgetItem* item(*it);
643 QString version = pkg->text( versionCol() );
644 if ( version.isEmpty() ) version =
"---";
646 QString summary = pkg->text( summaryCol() );
647 if ( summary.isEmpty() ) summary =
"---";
648 if ( summary.size() > 40 )
650 summary.truncate(40-3);
656 format.sprintf(
"%-20s %-30s | %-40s | %-25s | %10s\n",
657 (
const char*) status.toUtf8(),
658 (
const char*) pkg->text( nameCol() ).toUtf8(),
659 (
const char*) summary.toUtf8(),
660 (
const char*) version.toUtf8(),
661 (
const char*) pkg->text( sizeCol() ).toUtf8()
663 file.write(format.toUtf8());
678 YQUI::ui()->busyCursor();
679 int changedCount = 0;
681 for ( ZyppPoolIterator it = zyppPkgBegin();
685 ZyppSel selectable = *it;
686 ZyppStatus oldStatus = selectable->status();
688 if ( newStatus != oldStatus )
690 bool doChange =
false;
694 case S_KeepInstalled:
698 doChange = !selectable->installedEmpty();
706 doChange = !selectable->installedEmpty();
710 const ZyppObj candidate = selectable->candidateObj();
711 const ZyppObj installed = selectable->installedObj();
713 if ( candidate && installed )
715 doChange = ( installed->edition() < candidate->edition() );
724 doChange = selectable->installedEmpty();
730 if ( ! countOnly && oldStatus != S_Protected )
731 selectable->setStatus( newStatus );
739 if ( changedCount > 0 && ! countOnly )
741 emit updateItemStates();
746 YQUI::ui()->normalCursor();
760 , _pkgList( pkgList )
761 , _zyppPkg( zyppPkg )
765 _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
769 setTextAlignment( sizeCol(), Qt::AlignRight );
821 if ( srpmStatusCol() < 0 )
832 YQIconPool::pkgInstall() :
833 YQIconPool::pkgNoInst();
838 YQIconPool::disabledPkgInstall() :
839 YQIconPool::disabledPkgNoInst();
842 setData( srpmStatusCol(), Qt::DecorationRole, icon );
853 selectable()->set_source_install( installSourceRpm );
872 QString name = _zyppObj->name().c_str();
874 if ( col == statusCol() )
878 else if ( col == srpmStatusCol() )
880 text = name +
"\n\n";
885 _(
"Install Sources" ) :
886 _(
"Do Not Install Sources" );
890 text += _(
"No Sources Available" );
895 text = name +
"\n\n";
902 installed =
selectable()->installedObj()->edition().asString().c_str();
904 installed +=
selectable()->installedObj()->arch().asString().c_str();
905 installed = _(
"Installed Version: %1" ).arg( installed );
910 candidate =
selectable()->candidateObj()->edition().asString().c_str();
912 candidate +=
selectable()->candidateObj()->arch().asString().c_str();
917 text += installed +
"\n";
923 QString relation = _(
"same" );
925 if ( _candidateIsNewer ) relation = _(
"newer" );
926 if ( _installedIsNewer ) relation = _(
"older" );
929 text += _(
"Available Version: %1 (%2)" ).arg( candidate ).arg( relation );
933 text += _(
"Not available for installation" );
951 int col = treeWidget()->sortColumn();
952 if ( col == srpmStatusCol() )
960 return ( thisPoints < otherPoints );
968 #include "YQPkgList.moc" ZyppSel selectable() const
Returns the original selectable within the package manager backend.
Abstract base class to display a list of zypp::ResObjects.
void statusChanged()
Emitted when the status of a zypp::ResObject is changed.
void addPkgItem(ZyppSel selectable, ZyppPkg zyppPkg)
Add a pkg to the list.
int globalSetPkgStatus(ZyppStatus newStatus, bool force, bool countOnly)
Set the status of all packages in the pool to a new value.
void toggleSourceRpmStatus()
Cycle the source package status to the next valid value.
virtual QPixmap statusIcon(ZyppStatus status, bool enabled=true, bool bySelection=false)
Returns the suitable icon for a zypp::ResObject status - the regular icon if 'enabled' is 'true' or t...
virtual void createInstalledContextMenu()
Create the context menu for installed items.
void resetOptimalColumnWidthValues()
Resets the optimal column width values.
virtual void pkgObjClicked(int button, QTreeWidgetItem *item, int col, const QPoint &pos)
Dispatcher slot for mouse click: Take care of source RPM status.
virtual bool operator<(const QTreeWidgetItem &other) const
sorting function
YQPkgListItem(YQPkgList *pkgList, ZyppSel selectable, ZyppPkg zyppPkg)
Constructor.
virtual void updateActions(YQPkgObjListItem *item)
Update the internal actions: What actions are available for 'item'?
static bool haveInstalledPkgs()
Returns 'true' if there are any installed packages.
virtual void updateData()
Update this item's data completely.
virtual void clear()
Reimplemented from QY2ListView: Emit currentItemChanged() signal after clearing the list...
void optimizeColumnWidths()
Optimizes the column widths depending on content and the available horizontal space.
void addPkgItemDimmed(ZyppSel selectable, ZyppPkg zyppPkg)
Add a pkg to the list, but display it dimmed (grey text foreground rather than normal black)...
QAction * createAction(ZyppStatus status, const QString &key=QString::null, bool enabled=false)
Create an action based on a zypp::ResObject status - automatically retrieve the corresponding status ...
virtual void pkgObjClicked(int button, QTreeWidgetItem *item, int col, const QPoint &pos)
Dispatcher slot for mouse click: cycle status depending on column.
virtual void updateActions(YQPkgObjListItem *item=0)
Update the internal actions for the currently selected item ( if any ).
bool editable() const
Return whether or not items in this list are generally editable, i.e.
void selectNextItem()
Select the next item, i.e.
bool hasSourceRpm() const
Returns whether or not a source RPM is available for this package.
void updatePackages()
Emitted when it's time to update displayed package information, e.g., package states.
virtual QSize sizeHint() const
Reimplemented from QListView / QWidget: Reserve a reasonable amount of space.
virtual bool operator<(const QTreeWidgetItem &other) const
sorting function
Display a list of zypp::Package objects.
virtual void updateData()
Update this item's data completely.
virtual void createNotInstalledContextMenu()
Create the context menu for items that are not installed.
void setSourceRpmIcon()
Set the suitable icon for the source RPM status.
void resort()
Sort the tree widget again according to the column selected and its current sort order.
YQPkgList(QWidget *parent)
Constructor.
void exportList(const QString filename, bool interactive) const
Save the pkg list to a file.
void clear()
Clears the tree-widgets content, resets the optimal column width values.
void setDimmed(bool d=true)
Set the 'dimmed' flag.
void applyExcludeRules()
Apply all exclude rules of this list to all items, including those that are currently excluded...
virtual QString statusText(ZyppStatus status) const
Returns a short (one line) descriptive text for a zypp::ResObject status.
void askExportList() const
Ask for a file name and save the current pkg list to file.
virtual QString toolTip(int column)
Returns a tool tip text for a specific column of this item.
void updateOptimalColumnWidthValues(ZyppSel selectable, ZyppPkg zyppPkg)
Set and save optimal column widths depending on content only There is currently no way to get the opt...
virtual QMenu * addAllInListSubMenu(QMenu *menu)
Add a submenu "All in this list..." to 'menu'.
void setInstallSourceRpm(bool installSourceRpm)
Set the source RPM status.
void createActions()
Create ( additional ) actions for the context menus.
virtual QString toolTip(int column)
Returns a tool tip text for a specific column of this item.
void createSourceRpmContextMenu()
Create context menu for source RPMs.
bool installSourceRpm() const
Returns the source RPM package status: Should the source RPM be installed?
virtual ZyppStatus status() const
Returns the (binary RPM) package status.
void resizeEvent(QResizeEvent *event)
Handler for resize events.
virtual ~YQPkgListItem()
Destructor.
virtual ~YQPkgList()
Destructor.
bool editable() const
Return whether or not this items is editable, i.e.