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