42 #define YUILogComponent "qt-pkg"
45 #include <QHeaderView>
54 #include "YQPkgObjList.h"
55 #include "YQPkgTextDialog.h"
57 #include "YQIconPool.h"
60 #include "zypp/ZYppFactory.h"
67 #define VERBOSE_EXCLUDE_RULES 0
68 #define EXTRA_SOLVE_COLLECTIONS 0
72 : QY2ListView( parent )
74 , _installedContextMenu(0)
75 , _notInstalledContextMenu(0)
76 , actionSetCurrentInstall(0)
77 , actionSetCurrentDontInstall(0)
78 , actionSetCurrentKeepInstalled(0)
79 , actionSetCurrentDelete(0)
80 , actionSetCurrentUpdate(0)
81 , actionSetCurrentUpdateForce(0)
82 , actionSetCurrentTaboo(0)
83 , actionSetCurrentProtected(0)
84 , actionSetListInstall(0)
85 , actionSetListDontInstall(0)
86 , actionSetListKeepInstalled(0)
87 , actionSetListDelete(0)
88 , actionSetListUpdate(0)
89 , actionSetListUpdateForce(0)
90 , actionSetListTaboo(0)
91 , actionSetListProtected(0)
101 _instVersionCol = -42;
104 _brokenIconCol = -42;
105 _satisfiedIconCol = -42;
106 _excludedItemsCount = 0;
111 connect(
this, SIGNAL( columnClicked (
int, QTreeWidgetItem *,
int,
const QPoint & ) ),
112 this, SLOT (
pkgObjClicked (
int, QTreeWidgetItem *,
int,
const QPoint & ) ) );
114 connect(
this, SIGNAL( columnDoubleClicked (
int, QTreeWidgetItem *,
int,
const QPoint & ) ),
115 this, SLOT (
pkgObjClicked (
int, QTreeWidgetItem *,
int,
const QPoint & ) ) );
120 connect(
this, SIGNAL(customContextMenuRequested(
const QPoint &)),
123 setIconSize( QSize( 16, 16 ) );
125 setContextMenuPolicy(Qt::CustomContextMenu);
140 yuiError() <<
"Null zypp::ui::Selectable!" << endl;
151 const QString & summary,
154 QY2ListViewItem * item =
new QY2ListViewItem(
this, QString() );
158 if ( nameCol() >= 0 && ! name.isEmpty() ) item->setText( nameCol(), name );
159 if ( summaryCol() >= 0 && ! summary.isEmpty() ) item->setText( summaryCol(), summary );
160 if ( sizeCol() >= 0 && size > 0L )
162 QString sizeStr = size.form().c_str();
163 item->setText( sizeCol(), sizeStr );
171 QTreeWidgetItem * listViewItem,
180 if ( button == Qt::LeftButton )
182 if ( col == statusCol() )
207 _excludedItemsCount = 0;
209 QY2ListView::clear();
216 QPixmap icon = YQIconPool::pkgNoInst();
222 case S_Del: icon = YQIconPool::pkgDel();
break;
223 case S_Install: icon = YQIconPool::pkgInstall();
break;
224 case S_KeepInstalled: icon = YQIconPool::pkgKeepInstalled();
break;
225 case S_NoInst: icon = YQIconPool::pkgNoInst();
break;
226 case S_Protected: icon = YQIconPool::pkgProtected();
break;
227 case S_Taboo: icon = YQIconPool::pkgTaboo();
break;
228 case S_Update: icon = YQIconPool::pkgUpdate();
break;
230 case S_AutoDel: icon = YQIconPool::pkgAutoDel();
break;
231 case S_AutoInstall: icon = YQIconPool::pkgAutoInstall();
break;
232 case S_AutoUpdate: icon = YQIconPool::pkgAutoUpdate();
break;
242 case S_Del: icon = YQIconPool::disabledPkgDel();
break;
243 case S_Install: icon = YQIconPool::disabledPkgInstall();
break;
244 case S_KeepInstalled: icon = YQIconPool::disabledPkgKeepInstalled();
break;
245 case S_NoInst: icon = YQIconPool::disabledPkgNoInst();
break;
246 case S_Protected: icon = YQIconPool::disabledPkgProtected();
break;
247 case S_Taboo: icon = YQIconPool::disabledPkgTaboo();
break;
248 case S_Update: icon = YQIconPool::disabledPkgUpdate();
break;
250 case S_AutoDel: icon = YQIconPool::disabledPkgAutoDel();
break;
251 case S_AutoInstall: icon = YQIconPool::disabledPkgAutoInstall();
break;
252 case S_AutoUpdate: icon = YQIconPool::disabledPkgAutoUpdate();
break;
268 case S_AutoDel:
return _(
"Autodelete" );
269 case S_AutoInstall:
return _(
"Autoinstall" );
270 case S_AutoUpdate:
return _(
"Autoupdate" );
271 case S_Del:
return _(
"Delete" );
272 case S_Install:
return _(
"Install" );
273 case S_KeepInstalled:
return _(
"Keep" );
274 case S_NoInst:
return _(
"Do Not Install" );
275 case S_Protected:
return _(
"Protected -- Do Not Modify" );
276 case S_Taboo:
return _(
"Taboo -- Never Install" );
277 case S_Update:
return _(
"Update" );
287 QTreeWidgetItem * listViewItem = currentItem();
289 if ( ! listViewItem )
296 if ( newStatus != item->
status() )
314 if ( doSelectNextItem )
325 YQUI::ui()->busyCursor();
326 QTreeWidgetItemIterator it(
this );
334 if ( newStatus == S_Update )
359 emit updateItemStates();
362 YQUI::ui()->normalCursor();
370 QTreeWidgetItemIterator it(
this);
371 QTreeWidgetItem * item;
373 while ( (item = *it) != NULL )
378 setCurrentItem( *it );
387 actionSetCurrentInstall =
createAction( S_Install,
"[+]" );
388 actionSetCurrentDontInstall =
createAction( S_NoInst,
"[-]" );
389 actionSetCurrentKeepInstalled =
createAction( S_KeepInstalled,
"[<], [-]" );
391 actionSetCurrentUpdate =
createAction( S_Update,
"[>], [+]" );
393 actionSetCurrentUpdateForce =
createAction( _(
"Update unconditionally" ),
402 actionSetCurrentProtected =
createAction( S_Protected,
"[*]" );
404 actionSetListInstall =
createAction( S_Install,
"",
true );
405 actionSetListDontInstall =
createAction( S_NoInst,
"",
true );
406 actionSetListKeepInstalled =
createAction( S_KeepInstalled,
"",
true );
408 actionSetListProtected =
createAction( S_Protected,
"",
true );
410 actionSetListUpdate =
createAction( _(
"Update if newer version available" ),
416 actionSetListUpdateForce =
createAction( _(
"Update unconditionally" ),
424 connect( actionSetCurrentInstall, &QAction::triggered,
this, &YQPkgObjList::setCurrentInstall );
425 connect( actionSetCurrentDontInstall, &QAction::triggered,
this, &YQPkgObjList::setCurrentDontInstall );
426 connect( actionSetCurrentKeepInstalled, &QAction::triggered,
this, &YQPkgObjList::setCurrentKeepInstalled );
427 connect( actionSetCurrentDelete, &QAction::triggered,
this, &YQPkgObjList::setCurrentDelete );
428 connect( actionSetCurrentUpdate, &QAction::triggered,
this, &YQPkgObjList::setCurrentUpdate );
429 connect( actionSetCurrentUpdateForce, &QAction::triggered,
this, &YQPkgObjList::setCurrentUpdateForce );
430 connect( actionSetCurrentTaboo, &QAction::triggered,
this, &YQPkgObjList::setCurrentTaboo );
431 connect( actionSetCurrentProtected, &QAction::triggered,
this, &YQPkgObjList::setCurrentProtected );
432 connect( actionSetListInstall, &QAction::triggered,
this, &YQPkgObjList::setListInstall );
433 connect( actionSetListDontInstall, &QAction::triggered,
this, &YQPkgObjList::setListDontInstall );
434 connect( actionSetListKeepInstalled, &QAction::triggered,
this, &YQPkgObjList::setListKeepInstalled );
435 connect( actionSetListDelete, &QAction::triggered,
this, &YQPkgObjList::setListDelete );
436 connect( actionSetListUpdate, &QAction::triggered,
this, &YQPkgObjList::setListUpdate );
437 connect( actionSetListUpdateForce, &QAction::triggered,
this, &YQPkgObjList::setListUpdateForce );
438 connect( actionSetListTaboo, &QAction::triggered,
this, &YQPkgObjList::setListTaboo );
439 connect( actionSetListProtected, &QAction::triggered,
this, &YQPkgObjList::setListProtected );
457 const QPixmap & icon,
458 const QPixmap & insensitiveIcon,
462 QString label = text;
464 if ( ! key.isEmpty() )
468 QIcon iconSet ( icon );
470 if ( ! insensitiveIcon.isNull() )
472 iconSet.addPixmap( insensitiveIcon,
476 QAction * action =
new QAction( label,
478 Q_CHECK_PTR( action );
479 action->setEnabled( enabled );
480 action->setIcon( iconSet );
489 _notInstalledContextMenu =
new QMenu(
this );
490 Q_CHECK_PTR( _notInstalledContextMenu );
492 _notInstalledContextMenu->addAction( actionSetCurrentInstall );
493 _notInstalledContextMenu->addAction( actionSetCurrentDontInstall );
494 _notInstalledContextMenu->addAction( actionSetCurrentTaboo );
503 _installedContextMenu =
new QMenu(
this );
504 Q_CHECK_PTR( _installedContextMenu );
506 _installedContextMenu->addAction( actionSetCurrentKeepInstalled );
507 _installedContextMenu->addAction( actionSetCurrentDelete );
508 _installedContextMenu->addAction( actionSetCurrentUpdate );
509 _installedContextMenu->addAction( actionSetCurrentUpdateForce );
518 QMenu * submenu =
new QMenu( menu );
519 Q_CHECK_PTR( submenu );
521 submenu->addAction( actionSetListInstall );
522 submenu->addAction( actionSetListDontInstall );
523 submenu->addAction( actionSetListKeepInstalled );
524 submenu->addAction( actionSetListDelete );
525 submenu->addAction( actionSetListUpdate );
526 submenu->addAction( actionSetListUpdateForce );
527 submenu->addAction( actionSetListTaboo );
529 QAction *action = menu->addMenu( submenu );
530 action->setText( _(
"&All in This List" ) );
539 if ( ! _notInstalledContextMenu )
542 return _notInstalledContextMenu;
549 if ( ! _installedContextMenu )
552 return _installedContextMenu;
560 item = dynamic_cast<YQPkgObjListItem *> ( currentItem() );
566 if ( selectable->hasInstalledObj() )
568 actionSetCurrentInstall->setEnabled(
false );
569 actionSetCurrentDontInstall->setEnabled(
false );
570 actionSetCurrentTaboo->setEnabled(
false );
571 actionSetCurrentProtected->setEnabled(
true );
573 actionSetCurrentKeepInstalled->setEnabled(
true );
574 actionSetCurrentDelete->setEnabled(
true );
575 actionSetCurrentUpdate->setEnabled( selectable->hasCandidateObj() );
576 actionSetCurrentUpdateForce->setEnabled( selectable->hasCandidateObj() );
580 actionSetCurrentInstall->setEnabled( selectable->hasCandidateObj() );
581 actionSetCurrentDontInstall->setEnabled(
true );
582 actionSetCurrentTaboo->setEnabled(
true );
583 actionSetCurrentProtected->setEnabled(
false );
585 actionSetCurrentKeepInstalled->setEnabled(
false );
586 actionSetCurrentDelete->setEnabled(
false );
587 actionSetCurrentUpdate->setEnabled(
false );
588 actionSetCurrentUpdateForce->setEnabled(
false );
593 actionSetCurrentInstall->setEnabled(
false );
594 actionSetCurrentDontInstall->setEnabled(
false );
595 actionSetCurrentTaboo->setEnabled(
false );
597 actionSetCurrentKeepInstalled->setEnabled(
false );
598 actionSetCurrentDelete->setEnabled(
false );
599 actionSetCurrentUpdate->setEnabled(
false );
600 actionSetCurrentUpdateForce->setEnabled(
false );
601 actionSetCurrentProtected->setEnabled(
false );
612 Qt::KeyboardModifiers special_combo = ( Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier );
614 if ( ( event->modifiers() & special_combo ) == special_combo )
616 if ( event->key() == Qt::Key_Q )
619 yuiMilestone() <<
"Debug mode: " << _debug << endl;
623 QTreeWidgetItem * selectedListViewItem = currentItem();
625 if ( selectedListViewItem )
627 YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> (selectedListViewItem);
634 installed = item->
selectable()->hasInstalledObj();
638 ZyppStatus status = item->
status();
640 switch( event->key() )
651 ZyppStatus newStatus = S_KeepInstalled;
654 newStatus = S_Update;
675 case Qt::Key_Asterisk:
682 case Qt::Key_Greater:
691 if ( status == S_Update ||
692 status == S_AutoUpdate )
703 item->toggleDebugIsBroken();
713 item->toggleDebugIsSatisfied();
722 QY2ListView::keyPressEvent( event );
729 QY2ListViewItem * item =
new QY2ListViewItem(
this );
732 item->setText( nameCol() >= 0 ? nameCol() : 0, text );
739 _excludeRules.push_back( rule );
746 _excludedItemsCount = 0;
748 QTreeWidgetItemIterator listView_it(
this );
750 while ( *listView_it )
752 QTreeWidgetItem * current_item = *listView_it;
767 if ( _excludedItemsCount > 0 )
769 yuiMilestone() << _excludedItemsCount <<
" packages excluded" << endl;
771 for ( ExcludeRuleList::iterator rule_it = _excludeRules.begin();
772 rule_it != _excludeRules.end();
779 yuiMilestone() <<
"Active exclude rule: \""
780 << rule->
regexp().pattern() <<
"\""
796 #if VERBOSE_EXCLUDE_RULES
800 for ( ExcludeRuleList::iterator rule_it = _excludeRules.begin();
801 rule_it != _excludeRules.end() && !
exclude;
806 if ( rule->
match( item ) )
809 #if VERBOSE_EXCLUDE_RULES
820 _excludedItemsCount++;
822 #if VERBOSE_EXCLUDE_RULES
825 yuiDebug() <<
"Rule \"" << matchingRule->
regexp().pattern()
826 <<
"\" matches: Excluding " << item->
zyppObj()->name()
831 yuiDebug() <<
"Un-excluding " << item->
zyppObj()->name() << endl;
847 QTreeWidgetItem * parentItem = item->parent();
850 parentItem->setHidden(
exclude );
861 : QY2ListViewItem( pkgObjList )
862 , _pkgObjList( pkgObjList )
863 , _selectable( selectable )
864 , _zyppObj( zyppObj )
873 QY2ListViewItem * parent,
876 : QY2ListViewItem( parent )
877 , _pkgObjList( pkgObjList )
878 , _selectable( selectable )
879 , _zyppObj( zyppObj )
888 : QY2ListViewItem( pkgObjList )
889 , _pkgObjList( pkgObjList )
907 if ( _zyppObj == 0 && _selectable )
908 _zyppObj = _selectable->theObj();
910 _debugIsBroken =
false;
911 _debugIsSatisfied =
false;
912 _candidateIsNewer =
false;
913 _installedIsNewer =
false;
915 const ZyppObj candidate =
selectable()->candidateObj();
916 const ZyppObj installed =
selectable()->installedObj();
918 if ( candidate && installed )
920 if ( candidate->edition() < installed->edition() )
921 _installedIsNewer =
true;
922 else if ( installed->edition() < candidate->edition() )
923 _candidateIsNewer =
true;
926 if ( installed && ! candidate )
927 _installedIsNewer =
true;
930 if ( summaryCol() >= 0 )
setText( summaryCol(),
zyppObj()->summary() );
932 if ( sizeCol() >= 0 )
934 zypp::ByteCount size =
zyppObj()->installSize();
937 setText( sizeCol(), size.asString() );
940 if ( versionCol() == instVersionCol() )
942 if ( versionCol() >= 0 )
953 if ( candidate && installed->edition() != candidate->edition() )
957 .arg( installed->edition().c_str() )
958 .arg( candidate->edition().c_str() ) );
962 setText( versionCol(), installed->edition() );
969 setText( versionCol(), QString(
"(%1)" ).arg( candidate->edition().c_str() ) );
974 if ( _installedIsNewer )
975 setForeground( versionCol(), Qt::red);
976 else if ( _candidateIsNewer )
977 setForeground( versionCol(), Qt::blue);
982 if ( instVersionCol() >= 0 )
986 setText( instVersionCol(), installed->edition() );
988 if ( _installedIsNewer )
989 setForeground( instVersionCol(), Qt::red);
990 else if ( _candidateIsNewer )
991 setForeground( instVersionCol(), Qt::blue);
995 if ( versionCol() >= 0 )
1002 else if ( candidate )
1004 setText( versionCol(), candidate->edition() );
1006 if ( _installedIsNewer )
1007 setForeground( versionCol(), Qt::red);
1008 else if ( _candidateIsNewer )
1009 setForeground( versionCol(), Qt::blue);
1028 QTreeWidgetItem::setText( column, fromUTF8( text.c_str() ) );
1035 setText( column, edition.asString() );
1044 yuiError() <<
"No selectable" << endl;
1055 zypp::ResStatus::TransactByValue modifiedBy =
selectable()->modifiedBy();
1057 return ( modifiedBy == zypp::ResStatus::APPL_LOW ||
1058 modifiedBy == zypp::ResStatus::APPL_HIGH );
1066 ZyppStatus oldStatus =
selectable()->status();
1075 _pkgObjList->updateItemStates();
1087 zypp::getZYpp()->resolver()->resolvePool();
1102 if ( statusCol() >= 0 )
1109 if ( brokenIconCol() >= 0 )
1112 setIcon( brokenIconCol(), QPixmap() );
1115 if ( satisfiedIconCol() >= 0 )
1121 setIcon( satisfiedIconCol(),
isSatisfied() ? YQIconPool::pkgSatisfied() : QPixmap() );
1124 if ( brokenIconCol() >= 0 )
1131 setIcon( brokenIconCol(), YQIconPool::warningSign() );
1133 yuiWarning() <<
"Broken object: " << _selectable->theObj()->name()
1134 <<
" - " << _selectable->theObj()->summary()
1144 if ( _debugIsSatisfied )
1147 if ( _selectable->hasInstalledObj() )
1150 return _selectable->candidateObj().isSatisfied();
1156 if ( _debugIsBroken )
1159 if ( ! _selectable->hasInstalledObj() )
1164 case S_KeepInstalled:
1167 return _selectable->installedObj().isBroken();
1181 yuiError() <<
"Expected uninstalled zyppObj" << endl;
1185 yuiError() <<
"Should never get here" << endl;
1193 if ( ! _editable || ! _pkgObjList->
editable() )
1196 ZyppStatus oldStatus =
status();
1197 ZyppStatus newStatus = oldStatus;
1199 switch ( oldStatus )
1202 newStatus = S_NoInst;
1206 newStatus =
selectable()->hasCandidateObj() ?
1207 S_KeepInstalled: S_NoInst;
1211 newStatus =
selectable()->hasInstalledObj() ?
1212 S_KeepInstalled : S_NoInst;
1215 case S_KeepInstalled:
1216 newStatus =
selectable()->hasCandidateObj() ?
1225 newStatus = S_KeepInstalled;
1230 newStatus = S_KeepInstalled;
1236 newStatus = S_Install;
1240 yuiWarning() <<
"No candidate for " <<
selectable()->theObj()->name() << endl;
1241 newStatus = S_NoInst;
1248 newStatus = S_NoInst;
1252 if ( oldStatus != newStatus )
1284 text =
selectable()->candidateObj()->insnotify();
1291 text =
selectable()->candidateObj()->delnotify();
1297 if ( ! text.empty() )
1299 yuiDebug() <<
"Showing notify text" << endl;
1323 switch ( sel->status() )
1330 if ( sel->hasLicenceConfirmed() )
1333 if ( sel->candidateObj() )
1334 licenseText = sel->candidateObj()->licenseToConfirm();
1337 default:
return true;
1340 if ( licenseText.empty() )
1343 yuiDebug() <<
"Showing license agreement for " << sel->name() << endl;
1350 yuiMilestone() <<
"User confirmed license agreement for " << sel->name() << endl;
1351 sel->setLicenceConfirmed(
true );
1358 switch ( sel->status() )
1363 yuiWarning() <<
"User rejected license agreement for " << sel->name()
1364 <<
" - setting to TABOO"
1367 sel->setStatus( S_Taboo );
1374 yuiWarning() <<
"User rejected license agreement for " << sel->name()
1375 <<
" - setting to PROTECTED"
1378 sel->setStatus( S_Protected );
1394 if ( col == statusCol() )
1406 tip +=
"\n" + _(
"(by a software selection)" );
1408 tip +=
"\n" + _(
"(by dependencies)" );
1419 if ( col == brokenIconCol() )
1424 return _(
"Dependencies broken" );
1429 if ( col == satisfiedIconCol() )
1434 return _(
"All dependencies satisfied" );
1444 const YQPkgObjListItem * other = dynamic_cast<const YQPkgObjListItem *> (&otherListViewItem);
1445 int col = treeWidget()->sortColumn();
1449 if ( col == nameCol() )
1451 return ( strcasecmp( this->
zyppObj()->name().c_str(), other->
zyppObj()->name().c_str() ) < 0 );
1453 if ( col == summaryCol() )
1456 return ( strcoll( this->
zyppObj()->summary().c_str(), other->
zyppObj()->summary().c_str() ) < 0 );
1458 if ( col == sizeCol() )
1462 return ( this->
zyppObj()->installSize() < other->
zyppObj()->installSize() );
1464 else if ( col == statusCol() )
1477 else if ( col == instVersionCol() ||
1478 col == versionCol() )
1493 if (thisPoints == otherPoints )
1494 return ( QString (this->
zyppObj()->edition().c_str() ) <
1495 QString (other->
zyppObj()->edition().c_str() ) );
1497 return ( thisPoints < otherPoints );
1502 return QY2ListViewItem::operator<( otherListViewItem );
1513 if (
selectable()->hasInstalledObj() ) points += 10;
1514 if (
selectable()->hasCandidateObj() ) points += 1;
1527 const QRegExp & regexp,
1543 #if VERBOSE_EXCLUDE_RULES
1544 yuiDebug() << ( enable ?
"Enabling" :
"Disabling" )
1545 <<
" exclude rule " << _regexp.pattern()
1571 QString text = item->text( _column );
1573 if ( text.isEmpty() )
1576 return _regexp.exactMatch( text );
1582 YQPkgObjListItem * item = dynamic_cast<YQPkgObjListItem *> ( currentItem() );
1591 QMenu * contextMenu =
1596 contextMenu->popup( viewport()->mapToGlobal( pos ) );