]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgObjList.h
compile some more
[duncan/yast2-qt4.git] / src / pkg / YQPkgObjList.h
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPkgObjList.h
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19
20 #ifndef YQPkgObjList_h
21 #define YQPkgObjList_h
22
23 #include <qpixmap.h>
24 #include <qregexp.h>
25 //Added by qt3to4:
26 #include <q3popupmenu.h>
27 #include <qevent.h>
28 #include <map>
29 #include <list>
30 #include <QY2ListView.h>
31 #include "YQZypp.h"
32 #include <zypp/Edition.h>
33 #include <FSize.h>
34
35 class YQPkgObjListItem;
36 class Q3Action;
37 class Q3PopupMenu;
38 using std::string;
39 using std::list;
40
41
42 /**
43  * @short Abstract base class to display a list of zypp::ResObjects.
44  * Handles most generic stuff like setting status etc.
45  **/
46 class YQPkgObjList : public QY2ListView
47 {
48     Q_OBJECT
49
50 protected:
51     /**
52      * Constructor. Does not add any QListView columns!
53      **/
54     YQPkgObjList( QWidget * parent );
55
56     /**
57      * Destructor
58      **/
59     virtual ~YQPkgObjList();
60
61     // avoiding warning about virtuals
62     using QTreeView::selectionChanged;
63
64 public:
65
66     // Column numbers
67
68     int statusCol()             const   { return _statusCol;            }
69     int nameCol()               const   { return _nameCol;              }
70     int summaryCol()            const   { return _summaryCol;           }
71     int sizeCol()               const   { return _sizeCol;              }
72     int versionCol()            const   { return _versionCol;           }
73     int instVersionCol()        const   { return _instVersionCol;       }
74     int brokenIconCol()         const   { return _brokenIconCol;        }
75     int satisfiedIconCol()      const   { return _satisfiedIconCol;     }
76
77     /**
78      * Return whether or not items in this list are generally editable,
79      * i.e. the user can change their status. Note that individual items can be
80      * set to non-editable even if the list is generally editable.
81      * Lists are editable by default.
82      **/
83     bool editable() const { return _editable; }
84
85     /**
86      * Set the list's editable status.
87      **/
88     void setEditable( bool editable = true ) { _editable = editable; }
89
90     /**
91      * Sets the currently selected item's status.
92      * Automatically selects the next item if 'selectNextItem' is 'true'.
93      **/
94     void setCurrentStatus( ZyppStatus   newStatus,
95                            bool                 selectNextItem = false );
96
97     /**
98      * Sets the status of all (toplevel) list items to 'newStatus', if possible.
99      * Only one single statusChanged() signal is emitted.
100      *
101      * 'force' overrides sensible defaults like setting only zypp::ResObjects to
102      * 'update' that really come with a newer version.
103      **/
104     void setAllItemStatus( ZyppStatus newStatus, bool force = false );
105
106     /**
107      * Add a submenu "All in this list..." to 'menu'.
108      * Returns the newly created submenu.
109      **/
110     virtual Q3PopupMenu * addAllInListSubMenu( Q3PopupMenu * menu );
111
112     /**
113      * Returns the suitable icon for a zypp::ResObject status - the regular
114      * icon if 'enabled' is 'true' or the insensitive icon if 'enabled' is
115      * 'false.  'bySelection' is relevant only for auto-states: This uses the
116      * icon for 'auto-by-selection" rather than the default auto-icon.
117      **/
118     virtual QPixmap statusIcon( ZyppStatus status,
119                                 bool            enabled     = true,
120                                 bool            bySelection = false );
121
122     /**
123      * Returns a short (one line) descriptive text for a zypp::ResObject status.
124      **/
125     virtual QString statusText( ZyppStatus status ) const;
126
127
128     class ExcludeRule;
129
130     /**
131      * Add an exclude rule to this list.
132      **/
133     void addExcludeRule( YQPkgObjList::ExcludeRule * rule );
134
135     /**
136      * Apply all exclude rules of this list to all items,
137      * including those that are currently excluded.
138      **/
139     void applyExcludeRules();
140
141     /**
142      * Apply all exclude rules of this list to one item.
143      **/
144     void applyExcludeRules( QTreeWidgetItem * );
145
146     /**
147      * Exclude or include an item, i.e. remove it from the visible items
148      * and add it to the internal exclude list or vice versa.
149      **/
150     void exclude( YQPkgObjListItem * item, bool exclude );
151
152
153 public slots:
154
155     /**
156      * Add a zypp::ResObject to the list. Connect a filter's filterMatch()
157      * signal to this slot. Remember to connect filterStart() to clear()
158      * (inherited from QListView).
159      *
160      * 'zyppObj' has to be one of the objects of 'selectable'. If it is 0,
161      * selectable->theObject() will be used.
162      *
163      * Intentionally NOT named addItem() so the calling class cannot confuse
164      * this method with overlaid methods of the same name that were simply
165      * forgotten to implement!
166      **/
167     void addPkgObjItem( ZyppSel selectable,
168                         ZyppObj zyppObj = 0 );
169
170     /**
171      * Add a purely passive list item that has a name and optional summary and
172      * size.
173      **/
174     void addPassiveItem( const QString & name,
175                          const QString & summary = QString::null,
176                          FSize           size    = -1 );
177
178     /**
179      * Dispatcher slot for mouse click: cycle status depending on column.
180      **/
181     virtual void pkgObjClicked( int             button,
182                                 QTreeWidgetItem * item,
183                                 int             col,
184                                 const QPoint &  pos );
185
186     /**
187      * Reimplemented from QY2ListView:
188      * Emit selectionChanged() signal after clearing the list.
189      **/
190     virtual void clear();
191
192     /**
193      * Update the internal actions for the currently selected item ( if any ).
194      * This only calls updateActions( YQPkgObjListItem * ) with the currently
195      * selected item as argument, so there is normally no need to reimplement
196      * this method, too, if the other one is reimplemented.
197      **/
198     virtual void updateActions( YQPkgObjListItem * item = 0);
199
200     /**
201      * Emit an updatePackages() signal.
202      **/
203     void sendUpdatePackages() { emit updatePackages(); }
204
205     /**
206      * Select the next item, i.e. move the selection one item further down the
207      * list.
208      **/
209     void selectNextItem();
210
211     /**
212      * Emit a statusChanged() signal for the specified zypp::ResObject.
213      **/
214     void sendStatusChanged() { emit statusChanged(); }
215
216     /**
217      * Display a one-line message in the list.
218      **/
219     virtual void message( const QString & text );
220
221     /**
222      * Write statistics about excluded items to the log, if there are any.
223      **/
224     void logExcludeStatistics();
225     
226
227     // Direct access to some states for menu actions
228
229     void setCurrentInstall()       { setCurrentStatus( S_Install        ); }
230     void setCurrentDontInstall()   { setCurrentStatus( S_NoInst         ); }
231     void setCurrentKeepInstalled() { setCurrentStatus( S_KeepInstalled  ); }
232     void setCurrentDelete()        { setCurrentStatus( S_Del            ); }
233     void setCurrentUpdate()        { setCurrentStatus( S_Update         ); }
234     void setCurrentTaboo()         { setCurrentStatus( S_Taboo          ); }
235     void setCurrentProtected()     { setCurrentStatus( S_Protected      ); }
236
237     void setListInstall()          { setAllItemStatus( S_Install        ); }
238     void setListDontInstall()      { setAllItemStatus( S_NoInst         ); }
239     void setListKeepInstalled()    { setAllItemStatus( S_KeepInstalled  ); }
240     void setListDelete()           { setAllItemStatus( S_Del            ); }
241     void setListUpdate()           { setAllItemStatus( S_Update         ); }
242     void setListUpdateForce()      { setAllItemStatus( S_Update, true   ); }
243     void setListTaboo()            { setAllItemStatus( S_Taboo          ); }
244     void setListProtected()        { setAllItemStatus( S_Protected      ); }
245
246
247 protected slots:
248
249     /**
250      * Dispatcher slot for selection change - internal only.
251      **/
252     virtual void selectionChangedInternal( QTreeWidgetItem * item );
253
254 signals:
255
256
257     /**
258      * Emitted when a zypp::ui::Selectable is selected.
259      * May be called with a null poiner if no zypp::ResObject is selected.
260      **/
261     void selectionChanged( ZyppSel selectable );
262
263     /**
264      * Emitted when the status of a zypp::ResObject is changed.
265      **/
266     void statusChanged();
267
268     /**
269      * Emitted when it's time to update displayed package information,
270      * e.g., package states.
271      **/
272     void updatePackages();
273
274
275 protected:
276
277     /**
278      * Event handler for keyboard input.
279      * Only very special keys are processed here.
280      *
281      * Reimplemented from QListView / QWidget.
282      **/
283     virtual void keyPressEvent( QKeyEvent * ev );
284
285     /**
286      * Returns the context menu for items that are not installed.
287      * Creates the menu upon the first call.
288      **/
289     virtual Q3PopupMenu * installedContextMenu();
290
291     /**
292      * Returns the context menu for items that are installed.
293      * Creates the menu upon the first call.
294      **/
295     virtual Q3PopupMenu * notInstalledContextMenu();
296
297     /**
298      * Create the context menu for items that are not installed.
299      **/
300     virtual void createNotInstalledContextMenu();
301
302     /**
303      * Create the context menu for installed items.
304      **/
305     virtual void createInstalledContextMenu();
306
307     /**
308      * Create the actions for the context menus.
309      * Note: This is intentionally not virtual!
310      **/
311     void createActions();
312
313     /**
314      * Create an action based on a zypp::ResObject status - automatically
315      * retrieve the corresponding status icons (both sensitive and insensitive)
316      * and text.  'key' is only a descriptive text, no true accelerator.
317      **/
318     Q3Action * createAction( ZyppStatus         status,
319                             const QString &     key     = QString::null,
320                             bool                enabled = false );
321
322     /**
323      * Low-level: Create an action.
324      * 'key' is only a descriptive text, no true accelerator.
325      **/
326     Q3Action * createAction( const QString &    text,
327                             const QPixmap &     icon            = QPixmap(),
328                             const QPixmap &     insensitiveIcon = QPixmap(),
329                             const QString &     key             = QString::null,
330                             bool                enabled         = false );
331
332     class ExcludedItems;
333
334     // Data members
335
336     int         _statusCol;
337     int         _nameCol;
338     int         _summaryCol;
339     int         _sizeCol;
340     int         _versionCol;
341     int         _instVersionCol;
342     int         _brokenIconCol;
343     int         _satisfiedIconCol;
344     bool        _editable;
345     bool        _debug;
346
347     typedef list<ExcludeRule *> ExcludeRuleList;
348     
349     ExcludeRuleList     _excludeRules;
350     ExcludedItems *     _excludedItems;
351
352     Q3PopupMenu *       _installedContextMenu;
353     Q3PopupMenu *       _notInstalledContextMenu;
354
355
356 public:
357
358     Q3Action *          actionSetCurrentInstall;
359     Q3Action *          actionSetCurrentDontInstall;
360     Q3Action *          actionSetCurrentKeepInstalled;
361     Q3Action *          actionSetCurrentDelete;
362     Q3Action *          actionSetCurrentUpdate;
363     Q3Action *          actionSetCurrentTaboo;
364     Q3Action *          actionSetCurrentProtected;
365
366     Q3Action *          actionSetListInstall;
367     Q3Action *          actionSetListDontInstall;
368     Q3Action *          actionSetListKeepInstalled;
369     Q3Action *          actionSetListDelete;
370     Q3Action *          actionSetListUpdate;
371     Q3Action *          actionSetListUpdateForce;
372     Q3Action *          actionSetListTaboo;
373     Q3Action *          actionSetListProtected;
374
375
376 public:
377
378 };
379
380
381
382 class YQPkgObjListItem: public QY2ListViewItem
383 {
384 public:
385
386     /**
387      * Constructor for root items: Creates a YQPkgObjList item that corresponds
388      * to the ZYPP selectable that 'selectable' refers to. 'zyppObj' has to be
389      * one object of 'selectable'.  If it is 0, selectable->theObject() will be
390      * used.
391      **/
392     YQPkgObjListItem( YQPkgObjList *    pkgObjList,
393                       ZyppSel           selectable,
394                       ZyppObj           zyppObj = 0 );
395
396 protected:
397     /**
398      * Constructor for non-root items.
399      **/
400     YQPkgObjListItem( YQPkgObjList *    pkgObjList,
401                       QY2ListViewItem * parent,
402                       ZyppSel           selectable,
403                       ZyppObj           zyppObj = 0 );
404
405 public:
406
407     /**
408      * Destructor
409      **/
410     virtual ~YQPkgObjListItem();
411
412     /**
413      * Returns the original selectable within the package manager backend.
414      **/
415     ZyppSel selectable() const { return _selectable; }
416
417     /**
418      * Returns the original object within the package manager backend.
419      **/
420     ZyppObj zyppObj() const { return _zyppObj; }
421
422     /**
423      * Return whether or not this items is editable, i.e. the user can change
424      * its status. This requires the corresponding list to be editable, too.
425      * Items are editable by default.
426      **/
427     bool editable() const { return _editable; }
428
429     /**
430      * Set this item's editable status.
431      **/
432     void setEditable( bool editable = true ) { _editable = editable; }
433
434     /**
435      * Returns the (binary RPM) package status
436      **/
437     ZyppStatus status() const;
438
439     /**
440      * Returns 'true' if this selectable's status is set by a selection
441      * (rather than by the user or by the dependency solver).
442      **/
443     bool bySelection() const;
444
445     /**
446      * Set the (binary RPM) package status.
447      *
448      * If 'sendSignals' is 'true' (default), the parent list will be requested
449      * to send update signals. List operations might want to use this for
450      * optimizations to send the signals only once after all changes are done.
451      **/
452     virtual void setStatus( ZyppStatus newStatus, bool sendSignals = true );
453
454     /**
455      * Set a status icon according to the package's status.
456      **/
457     virtual void setStatusIcon();
458
459     /**
460      * Update this item's status.
461      * Triggered by QY2ListView::updateAllItemStates().
462      * Overwritten from QY2ListViewItem.
463      **/
464     virtual void updateStatus();
465
466     /**
467      * Cycle the package status to the next valid value.
468      **/
469     virtual void cycleStatus();
470
471     /**
472      * Check if the candidate is newer than the installed version.
473      **/
474     bool candidateIsNewer() const { return _candidateIsNewer; }
475
476     /**
477      * Check if the installed version is newer than the candidate.
478      **/
479     bool installedIsNewer() const { return _installedIsNewer; }
480
481     /**
482      * Check if this item is satisfied, even though it is not installed.
483      * This is useful for package collections, e.g., patterns and patches:
484      * 'true' is returned if all requirements are fulfilled, but the object
485      * itself is not installed.
486      **/
487     bool isSatisfied() const;
488
489     /**
490      * Check if this item is "broken": If it is installed, but any of its
491      * dependencies are no longer satisfied.
492      * This is useful for package collections, e.g., patterns and patches.
493      **/
494     bool isBroken() const;
495
496     /**
497      * Display this item's notify text (if there is any) that corresponds to
498      * the specified status (S_Install, S_Del) in a pop-up window.
499      **/
500     void showNotifyTexts( ZyppStatus status );
501
502     /**
503      * Display a selectable's license agreement (if there is any) that
504      * corresponds to its current status (S_Install, S_Update) in a pop-up
505      * window.
506      *
507      * Returns 'true' if the user agreed to that license , 'false' otherwise.
508      * The item's status may have changed to S_Taboo, S_Proteced or S_Del if
509      * the user disagreed with the license.
510      **/
511     static bool showLicenseAgreement( ZyppSel sel );
512
513     /**
514      * Display this item's license agreement (if there is any) that corresponds
515      * to its current status (S_Install, S_Update) in a pop-up window.
516      **/
517     bool showLicenseAgreement();
518
519     /**
520      * Comparison function used for sorting the list.
521      * Returns:
522      * -1 if this <  other
523      *  0 if this == other
524      * +1 if this >  other
525      *
526      * Reimplemented from QListViewItem
527      **/
528     virtual int compare( QTreeWidgetItem *      other,
529                          int                    col,
530                          bool                   ascending ) const;
531
532     /**
533      * Calculate a numerical value to compare versions, based on version
534      * relations:
535      *
536      * - Installed newer than candidate (red)
537      * - Candidate newer than installed (blue) - worthwhile updating
538      * - Installed
539      * - Not installed, but candidate available
540      **/
541     int versionPoints() const;
542
543     /**
544      * Update this item's data completely.
545      * Triggered by QY2ListView::updateAllItemData().
546      *
547      * Reimplemented from QY2ListViewItem.
548      **/
549     virtual void updateData();
550
551     /**
552      * Returns a tool tip text for a specific column of this item.
553      * 'column' is -1 if the mouse pointer is in the tree indentation area.
554      *
555      * Reimplemented from QY2ListViewItem.
556      **/
557     virtual QString toolTip( int column );
558
559     /**
560      * Returns 'true' if this item is excluded.
561      **/
562     bool isExcluded() const { return _excluded; }
563
564     /**
565      * Set this item's exclude flag.
566      * Note that this is just a marker. It is the caller's responsibility
567      * to add or remove it from exclude lists etc.
568      **/
569     void setExcluded( bool exclude = true );
570
571
572     // Handle Debug isBroken and isSatisfied flags
573
574     bool debugIsBroken()    const               { return _debugIsBroken;                }
575     bool debugIsSatisfied() const               { return _debugIsSatisfied;             }
576     void setDebugIsBroken   ( bool val = true ) { _debugIsBroken = val;                 }
577     void setDebugIsSatisfied( bool val = true ) { _debugIsSatisfied = val;              }
578     void toggleDebugIsBroken()                  { _debugIsBroken = ! _debugIsBroken;    }
579     void toggleDebugIsSatisfied()               { _debugIsSatisfied = ! _debugIsSatisfied; }
580
581
582     // Columns
583
584     int statusCol()             const   { return _pkgObjList->statusCol();      }
585     int nameCol()               const   { return _pkgObjList->nameCol();        }
586     int summaryCol()            const   { return _pkgObjList->summaryCol();     }
587     int sizeCol()               const   { return _pkgObjList->sizeCol();        }
588     int versionCol()            const   { return _pkgObjList->versionCol();     }
589     int instVersionCol()        const   { return _pkgObjList->instVersionCol(); }
590     int brokenIconCol()         const   { return _pkgObjList->brokenIconCol();  }
591     int satisfiedIconCol()      const   { return _pkgObjList->satisfiedIconCol(); }
592
593
594 protected:
595
596     /**
597      * Initialize internal data and set fields accordingly.
598      **/
599     void init();
600
601     /**
602      * Apply changes hook. This is called each time the user changes the status
603      * of a list item manually (if the old status is different from the new
604      * one). Insert code to propagate changes to other objects here, for
605      * example to trigger a "small" solver run (Resolver::transactObjKind()
606      * etc.).
607      *
608      * This default implementation does nothing.
609      **/
610     virtual void applyChanges() {}
611
612     /**
613      * Do a "small" solver run for all "resolvable collections", i.e., for
614      * selections, patterns, languages, patches.
615      **/
616     void solveResolvableCollections();
617
618     /**
619      * Set a column text via STL string.
620      * ( QListViewItem::setText() expects a QString! )
621      **/
622     void setText( int column, const string text );
623
624     /**
625      * Re-declare ordinary setText() method so the compiler doesn't get
626      * confused which one to use.
627      **/
628     void setText( int column, const QString & text )
629         { QTreeWidgetItem::setText( column, text ); }
630
631     /**
632      * Set a column text via Edition.
633      **/
634     void setText( int column, const zypp::Edition & edition );
635
636
637     //
638     // Data members
639     //
640
641     YQPkgObjList *      _pkgObjList;
642     ZyppSel             _selectable;
643     ZyppObj             _zyppObj;
644     bool                _editable:1;
645     bool                _candidateIsNewer:1;
646     bool                _installedIsNewer:1;
647
648     bool                _debugIsBroken:1;
649     bool                _debugIsSatisfied:1;
650     bool                _excluded:1;
651 };
652
653
654
655 class YQPkgObjList::ExcludeRule
656 {
657 public:
658
659     /**
660      * Constructor: Creates a new exclude rule with a regular expression
661      * to check against the text of the specified column of each list
662      * entry.
663      *
664      * The parent YQPkgObjList will assume ownership of this exclude rule
665      * and destroy it when the parent is destroyed.
666      **/
667     ExcludeRule( YQPkgObjList *         parent,
668                  const QRegExp &        regexp,
669                  int                    column = 0 );
670
671     
672     // Intentionally omitting virtual destructor:
673     // No allocated objects, no other virtual methods,
674     // no need to have a vtable for each instance of this class.
675     //
676     // virtual ~ExcludeRule();
677
678     /**
679      * Enable or disable this exclude rule.
680      * New exclude rules are enabled by default.
681      **/
682     void enable( bool enable = true );
683
684     /**
685      * Returns 'true' if this exclude rule is enabled,
686      * 'false' otherwise.
687      **/
688     bool isEnabled() const { return _enabled; }
689
690     /**
691      * Change the regular expression after creation.
692      **/
693     void setRegexp( const QRegExp & regexp );
694
695     /**
696      * Returns the regexp.
697      **/
698     QRegExp regexp() const { return _regexp; };
699
700     /**
701      * Change the column number to check against after creation.
702      **/
703     void setColumn( int column = 0 );
704
705     /**
706      * Returns the column number.
707      **/
708     int column() const { return _column; }
709
710     /**
711      * Returns this exclude rule's parent YQPkgObjList.
712      **/
713     YQPkgObjList * parent() const { return _parent; }
714
715     /**
716      * Check a list item against this exclude rule. 
717      * Returns 'true' if the item matches this exclude rule,
718      * i.e. if it should be excluded.
719      **/
720     bool match( QTreeWidgetItem * item );
721
722 private:
723
724     YQPkgObjList *      _parent;
725     QRegExp             _regexp;
726     int                 _column;
727     bool                _enabled;
728 };
729
730
731 class YQPkgObjList::ExcludedItems
732 {
733 public:
734
735     typedef std::map <QTreeWidgetItem *, QTreeWidgetItem *> ItemMap;
736     typedef std::pair<QTreeWidgetItem *, QTreeWidgetItem *> ItemPair;
737     typedef ItemMap::iterator                           iterator;
738
739     /**
740      * Constructor
741      **/
742     ExcludedItems( YQPkgObjList * parent );
743
744     /**
745      * Destructor
746      **/
747     virtual ~ExcludedItems();
748
749     /**
750      * Add a list item to the excluded items and transfer ownership to this
751      * class.
752      *
753      * oldParent is the previous parent item of this item
754      * or 0 if it was a root item.
755      **/
756     void add( QTreeWidgetItem * item, QTreeWidgetItem * oldParent );
757
758     /**
759      * Remove a list item from the excluded items and transfer ownership back
760      * to the caller.
761      **/
762     void remove( QTreeWidgetItem * item );
763
764     /**
765      * Clear the excluded items. Delete all items still excluded.
766      **/
767     void clear();
768
769     /**
770      * Returns 'true' if the specified item is in the excluded items.
771      **/
772     bool contains( QTreeWidgetItem * item );
773
774     /**
775      * Returns the old parent of this item so it can be reparented
776      * or 0 if it was a root item.
777      **/
778     QTreeWidgetItem * oldParentItem( QTreeWidgetItem * item );
779
780     /**
781      * Returns the number of items
782      **/
783     int size() const { return (int) _excludeMap.size(); }
784
785     /**
786      * Returns an iterator that points to the first excluded item.
787      **/
788     iterator begin() { return _excludeMap.begin(); }
789
790     /**
791      * Returns an iterator that points after the last excluded item.
792      **/
793     iterator end()   { return _excludeMap.end(); }
794
795 private:
796     void updateActions();
797
798     ItemMap             _excludeMap;
799     YQPkgObjList *      _pkgObjList;
800 };
801
802
803 #endif // ifndef YQPkgObjList_h