merging mod-ui changes from trunk
[duncan/yast2-qt4.git] / src / YQWizard.h
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                    (c) SuSE Linux AG |
11 \----------------------------------------------------------------------/
12
13   File:       YQWizard.h
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19
20 #ifndef YQWizard_h
21 #define YQWizard_h
22
23 #include <q3vbox.h>
24 #include <qpixmap.h>
25 #include <q3ptrlist.h>
26 #include <qstringlist.h>
27 #include <q3dict.h>
28 #include "QY2ListView.h"
29 //Added by qt3to4:
30 #include <q3gridlayout.h>
31 #include <qlabel.h>
32 #include <q3popupmenu.h>
33 #include <qevent.h>
34 #include <YWizard.h>
35 #include "YQWizardButton.h"
36
37 #include <string>
38 #include <vector>
39
40 class Q3GridLayout;
41 class QFrame;
42 class QLabel;
43 class QMenuBar;
44 class Q3PopupMenu;
45 class QPushButton;
46 class QSpacerItem;
47 class Q3TextBrowser;
48 class QToolButton;
49 class Q3WidgetStack;
50 class YReplacePoint;
51
52 class YQAlignment;
53 class YQReplacePoint;
54 class QY2ListView;
55
56
57 class YQWizard : public QFrame, public YWizard
58 {
59     Q_OBJECT
60
61 protected:
62     class Step;
63     class TreeItem;
64
65 public:
66     /**
67      * Constructor.
68      **/
69     YQWizard( YWidget *         parent,
70               const string &    backButtonLabel,
71               const string &    abortButtonLabel,
72               const string &    nextButtonLabel,
73               YWizardMode       wizardMode = YWizardMode_Standard );
74
75     /**
76      * Destructor.
77      **/
78     virtual ~YQWizard();
79
80     /**
81      * Returns a descriptive label of this dialog instance for debugging.
82      *
83      * Reimplemented from YWidget.
84      **/
85     virtual string debugLabel();
86
87     enum Direction { Forward, Backward };
88
89     /**
90      * Returns the current direction of wizard operations - going forward or
91      * going backward. This can be used to maintain a consistent direction when
92      * assigning default buttons to a dialog.
93      **/
94     Direction direction() const { return _direction; }
95
96     //
97     // Wizard basics
98     //
99
100     /**
101      * Return internal widgets.
102      *
103      * Implemented from YWizard.
104      **/
105     virtual YQWizardButton * backButton()  const { return _backButton;  }
106     virtual YQWizardButton * abortButton() const { return _abortButton; }
107     virtual YQWizardButton * nextButton()  const { return _nextButton;  }
108
109     virtual YReplacePoint * contentsReplacePoint() const { return _contentsReplacePoint; }
110
111     /**
112      * Set the label of one of the wizard buttons (backButton(), abortButton(),
113      * nextButton() ) if that button is non-null. 
114      *
115      * Implemented from YWizard.
116      **/
117     virtual void setButtonLabel( YPushButton * button, const string & newLabel );
118     
119     /**
120      * Set the help text.
121      *
122      * Implemented from YWizard.
123      **/
124     virtual void setHelpText( const string & helpText );
125
126     /**
127      * Set the dialog icon. An empty icon name clears the current icon.
128      *
129      * Implemented from YWizard.
130      **/
131     virtual void setDialogIcon( const string & iconName );
132
133     /**
134      * Set the dialog heading.
135      *
136      * Implemented from YWizard.
137      **/
138     virtual void setDialogHeading( const string & headingText );
139
140
141     //
142     // Steps handling
143     //
144
145     /**
146      * Add a step for the steps panel on the side bar.
147      * This only adds the step to the internal list of steps.
148      * The display is only updated upon calling updateSteps().
149      *
150      * Implemented from YWizard.
151      **/
152     virtual void addStep( const string & text, const string & id );
153
154     /**
155      * Add a step heading for the steps panel on the side bar.
156      * This only adds the heading to the internal list of steps.
157      * The display is only updated upon calling updateSteps().
158      *
159      * Implemented from YWizard.
160      **/
161     virtual void addStepHeading( const string & text );
162
163     /**
164      * Delete all steps and step headings from the internal lists.
165      * The display is only updated upon calling updateSteps().
166      *
167      * Implemented from YWizard.
168      **/
169     virtual void deleteSteps();
170
171     /**
172      * Set the current step. This also triggers updateSteps() if necessary.
173      *
174      * Implemented from YWizard.
175      **/
176     virtual void setCurrentStep( const string & id );
177
178     /**
179      * Update the steps display: Reflect the internal steps and heading lists
180      * in the layout.
181      *
182      * Implemented from YWizard.
183      **/
184     virtual void updateSteps();
185
186
187     //
188     // Tree handling
189     //
190
191     /**
192      * Add a tree item. If "parentID" is an empty string, it will be a root
193      * item. 'text' is the text that will be displayed in the tree, 'id' the ID
194      * with which this newly created item can be referenced - and that will be
195      * returned when the user clicks on a tree item.
196      *
197      * Implemented from YWizard.
198      **/
199     virtual void addTreeItem( const string & parentID,
200                               const string & text,
201                               const string & id );
202
203     /**
204      * Select the tree item with the specified ID, if such an item exists.
205      *
206      * Implemented from YWizard.
207      **/
208     virtual void selectTreeItem( const string & id );
209
210     /**
211      * Returns the current tree selection or an empty string if nothing is
212      * selected or there is no tree.
213      *
214      * Implemented from YWizard.
215      **/
216     virtual string currentTreeSelection();
217
218     /**
219      * Delete all tree items.
220      *
221      * Implemented from YWizard.
222      **/
223     virtual void deleteTreeItems();
224
225
226     //
227     // Menu handling
228     //
229
230     /**
231      * Add a menu to the menu bar. If the menu bar is not visible yet, it will
232      * be made visible. 'text' is the user-visible text for the menu bar
233      * (including keyboard shortcuts marked with '&'), 'id' is the menu ID for
234      * later addMenuEntry() etc. calls.
235      *
236      * Implemented from YWizard.
237      **/
238     virtual void addMenu( const string & text,
239                           const string & id );
240
241     /**
242      * Add a submenu to the menu with ID 'parentMenuID'.
243      *
244      * Implemented from YWizard.
245      **/
246     virtual void addSubMenu( const string & parentMenuID,
247                              const string & text,
248                              const string & id );
249
250     /**
251      * Add a menu entry to the menu with ID 'parentMenuID'. 'id' is what will
252      * be returned by UI::UserInput() etc. when a user activates this menu entry.
253      *
254      * Implemented from YWizard.
255      **/
256     virtual void addMenuEntry( const string & parentMenuID,
257                                const string & text,
258                                const string & id );
259
260     /**
261      * Add a menu separator to a menu.
262      *
263      * Implemented from YWizard.
264      **/
265     virtual void addMenuSeparator( const string & parentMenuID );
266
267     /**
268      * Delete all menus and hide the menu bar.
269      *
270      * Implemented from YWizard.
271      **/
272     virtual void deleteMenus();
273
274
275     //
276     // Misc
277     //
278
279     /**
280      * Show a "Release Notes" button above the "Help" button in the steps panel
281      * with the specified label that will return the specified id to
282      * UI::UserInput() when clicked.
283      *
284      * The button (or the wizard) will assume ownership of the id and delete it
285      * in the destructor.
286      *
287      * Implemented from YWizard.
288      **/
289     virtual void showReleaseNotesButton( const string & label,
290                                          const string & id );
291
292     /**
293      * Hide an existing "Release Notes" button.
294      *
295      * Implemented from YWizard.
296      **/
297     virtual void hideReleaseNotesButton();
298
299     /**
300      * Retranslate internal buttons that are not accessible from the outside:
301      * - [Help]
302      * - [Steps]
303      * - [Tree]
304      *
305      * Implemented from YWizard.
306      **/
307     virtual void retranslateInternalButtons();
308
309     /**
310      * Event filter.
311      *
312      * Reimplemented from QWidget.
313      **/
314     virtual bool eventFilter( QObject * obj, QEvent * ev );
315
316     //
317     // Geometry management
318     //
319
320     /**
321      * Preferred width of the widget.
322      *
323      * Reimplemented from YWidget.
324      **/
325     virtual int preferredWidth();
326
327     /**
328      * Preferred height of the widget.
329      *
330      * Reimplemented from YWidget.
331      **/
332     virtual int preferredHeight();
333
334     /**
335      * Set the new size of the widget.
336      *
337      * Reimplemented from YWidget.
338      **/
339     virtual void setSize( int newWidth, int newHeight );
340
341
342 signals:
343
344     /**
345      * Emitted when the "Back" or "Cancel" button is clicked.
346      **/
347     void backClicked();
348
349     /**
350      * Emitted when the "Abort" button is clicked.
351      **/
352     void abortClicked();
353
354     /**
355      * Emitted when the "Next" or "OK" button is clicked.
356      *
357      * Notice: As long as this signal is connected, the wizard will no longer
358      * send button events to the UI. Rather, the connected QObject has to take
359      * care to propagate those events.
360      * This is used in YQPatternSelector, for example.
361      **/
362     void nextClicked();
363
364
365 public slots:
366
367     /**
368      * Adapt the size of the client area (the ReplacePoint(`id(`contents)) to
369      * fit in its current space.
370      **/
371     void resizeClientArea();
372
373     /**
374      * Show the current help text.
375      *
376      * This is useful only if it is obscured by any wizard steps, but it can
377      * safely be called at any time.
378      **/
379     void showHelp();
380
381     /**
382      * Show the current wizard steps, if there are any. If there are none,
383      * nothing happens.
384      **/
385     void showSteps();
386
387     /**
388      * Show the current selection tree in the side panel, if there is any. If
389      * there is none, nothing happens.
390      **/
391     void showTree();
392
393     /**
394      * Set a widget's background pixmap to a gradient pixmap and set the
395      * widget's height (fixed) to that pixmap's height.
396      **/
397     static void setGradient( QWidget * widget, const QPixmap & pixmap );
398
399     /**
400      * Set a widget's background to the lower portion (the bottom
401      * 'croppedHeight' pixels) of a pixmap and set the widget's height (fixed)
402      * to that 'croppedHeight'.
403      **/
404     static void setBottomCroppedGradient( QWidget * widget,
405                                           const QPixmap & pixmap,
406                                           int croppedHeight );
407
408     /**
409      * Bottom-crop a pixmap: Return a pixmap with the bottom 'croppedHeight'
410      * pixels.
411      **/
412     static QPixmap bottomCropPixmap( const QPixmap & pixmap, int croppedHeight );
413
414     /**
415      * Return the color of pixel( x, y ) of a pixmap.
416      * If pixmap is null defaultColor is returned.
417      * This is a _very_ expensive operation!
418      **/
419     static QColor pixelColor( const QPixmap & pixmap, int x, int y, const QColor & defaultColor );
420
421
422 protected slots:
423
424     /**
425      * Internal notification that the "Back" button has been clicked.
426      **/
427     void slotBackClicked();
428
429     /**
430      * Internal notification that the "Abort" button has been clicked.
431      **/
432     void slotAbortClicked();
433
434     /**
435      * Internal notification that the "Next" button has been clicked.
436      **/
437     void slotNextClicked();
438
439     /**
440      * Propagate button clicked event of release notes button to the
441      * application.
442      **/
443     void releaseNotesClicked();
444
445     /**
446      * Internal notification that [Space] or [Return] has been pressed on a
447      * tree item.
448      * If the item has an ID, that ID will be returned to UI::UserInput().
449      **/
450     void sendTreeEvent( Q3ListViewItem * item );
451
452     /**
453      * Internal notification that the tree selection has changed.
454      *
455      * If the currently selected item has an ID, that ID will be returned to
456      * UI::UserInput().
457      **/
458     void treeSelectionChanged();
459
460     /**
461      * Internal notification that a menu item with numeric ID 'numID' has been
462      * activated.
463      **/
464     void sendMenuEvent( int numID );
465
466
467 protected:
468
469     // Layout functions
470
471     void layoutTitleBar         ( QWidget * parent );
472     void layoutSideBar          ( QWidget * parent );
473     void layoutSideBarButtonBox ( QWidget * parent, QPushButton * button );
474     void layoutStepsPanel();
475     void layoutHelpPanel();
476     void layoutTreePanel();
477     void layoutWorkArea ( QFrame * parentHBox );
478     void layoutClientArea( QWidget * parent );
479     void layoutButtonBox( QWidget * parent );
480
481
482     /**
483      * Load gradient pixmaps
484      **/
485     void loadGradientPixmaps();
486
487     /**
488      * Load step status icons
489      **/
490     void loadStepsIcons();
491
492     /**
493      * Destroy the button box's buttons
494      **/
495     void destroyButtons();
496
497     /**
498      * Update all step - use appropriate icons and colors
499      **/
500     void updateStepStates();
501
502     /**
503      * Add a (left or right) margin of the specified width to a widget,
504      * consisting of a fixed height top gradient , a flexible center part (in
505      * the gradient center color) and a fixed height bottom gradient.
506      *
507      * The bottom gradient widget is returned as a reference for other
508      * background pixmaps.
509      **/
510     void addGradientColumn( QWidget * parent, int width = 8 );
511
512     /**
513      * Send a wizard event with the specified ID.
514      **/
515     void sendEvent( const string & id );
516
517     /**
518      * Returns 'true' if the application is running on a high-color display,
519      * i.e., on an X visual with more than 8 bit depth.
520      **/
521     bool highColorDisplay() const;
522
523     /**
524      * Notification that a signal is being connected.
525      *
526      * Reimplemented from QObject.
527      **/
528     void connectNotify ( const char * signal );
529
530     /**
531      * Notification that a signal is being disconnected.
532      *
533      * Reimplemented from QObject.
534      **/
535     void disconnectNotify ( const char * signal );
536
537     /**
538      * Set a button's label.
539      **/
540     void setButtonLabel( YQWizardButton * button, const QString & newLabel );
541
542     /**
543      * Enable or disable a button.
544      **/
545     void enableButton( YQWizardButton * button, bool enabled );
546
547     /**
548      * Set the keyboard focus to a button.
549      **/
550     void setButtonFocus( YQWizardButton * button );
551
552     /**
553      * Set text color and status icon for one wizard step
554      **/
555     void setStepStatus( YQWizard::Step * step, const QPixmap & icon, const QColor & color );
556
557     /**
558      * Find a step with the specified ID. Returns 0 if there is no such step.
559      **/
560     YQWizard::Step * findStep( const QString & id );
561
562     /**
563      * Find a tree item with the specified ID. Tree items without IDs cannot be
564      * found at all.
565      * Returns the item or 0 if no such item found.
566      **/
567     YQWizard::TreeItem * findTreeItem( const string & id );
568
569
570     //
571     // Data members
572     //
573
574     string      _backButtonLabel;
575     string      _abortButtonLabel;
576     string      _nextButtonLabel;
577     
578     bool        _stepsEnabled;
579     bool        _treeEnabled;
580     bool        _protectNextButton;
581     bool        _stepsDirty;
582     bool        _sendButtonEvents;
583     Direction   _direction;
584
585     QPixmap     _titleBarGradientPixmap;
586     QPixmap     _topGradientPixmap;
587     QColor      _gradientCenterColor;
588     QColor      _gradientTopColor;
589     QPixmap     _bottomGradientPixmap;
590
591     QPixmap     _stepCurrentIcon;
592     QPixmap     _stepToDoIcon;
593     QPixmap     _stepDoneIcon;
594
595     QColor      _stepCurrentColor;
596     QColor      _stepToDoColor;
597     QColor      _stepDoneColor;
598
599     QString     _currentStepID;
600
601
602     Q3WidgetStack *     _sideBar;
603     Q3VBox *                _stepsPanel;
604     Q3VBox *                    _stepsBox;
605     Q3GridLayout *                  _stepsGrid;
606     QPushButton *               _releaseNotesButton;
607     string                          _releaseNotesButtonId;
608     QPushButton *               _helpButton;
609     Q3HBox *                _helpPanel;
610     Q3TextBrowser *             _helpBrowser;
611     QPushButton *               _stepsButton;
612     QPushButton *               _treeButton;
613     Q3HBox *                _treePanel;
614     QY2ListView *               _tree;
615
616     Q3VBox *            _clientArea;
617     QWidget *               _menuBarBox;
618     QMenuBar *                  _menuBar;
619     QLabel *                _dialogIcon;
620     QLabel *                _dialogHeading;
621     YQAlignment *           _contents;
622     YQWizardButton *        _backButton;
623     QSpacerItem *           _backButtonSpacer;
624     YQWizardButton *        _abortButton;
625     YQWizardButton *        _nextButton;
626     YReplacePoint *     _contentsReplacePoint;
627
628     Q3PtrList<YQWizard::Step>   _stepsList;
629     Q3Dict<YQWizard::Step>      _stepsIDs;
630     Q3Dict<YQWizard::TreeItem>  _treeIDs;
631     Q3Dict<Q3PopupMenu>         _menuIDs;
632     vector<string>              _menuEntryIDs;
633
634
635 protected:
636
637     /**
638      * Helper class to represent a wizard step internally
639      **/
640     class Step
641     {
642     public:
643
644         Step( const QString & name = "", const QString & id = "" )
645             : _name( name )
646             , _statusLabel( 0 )
647             , _nameLabel(0)
648             , _enabled( true )
649             , _idList( id )
650         {}
651
652         /**
653          * Destructor. Intentionally not deleting the widgets.
654          **/
655         virtual ~Step() {}
656
657         virtual bool isHeading() const { return false; }
658
659         QString  name()         const { return _name;           }
660         QLabel * statusLabel()  const { return _statusLabel;    }
661         QLabel * nameLabel()    const { return _nameLabel;      }
662         bool     isEnabled()    const { return _enabled;        }
663         const QStringList & id() const { return _idList;        }
664         void addID( const QString & id ) { _idList.append( id ); }
665         virtual bool hasID( const QString & id ) { return _idList.find( id ) != _idList.end(); }
666
667         void setStatusLabel( QLabel * label )   { _statusLabel = label; }
668         void setNameLabel  ( QLabel * label )   { _nameLabel   = label; }
669         void setEnabled( bool enabled )         { _enabled = enabled; }
670
671     protected:
672
673         QString         _name;
674         QLabel *        _statusLabel;
675         QLabel *        _nameLabel;
676         bool            _enabled;
677         QStringList     _idList;
678     };
679
680
681     /**
682      * Helper class to represent a wizard step heading internally
683      **/
684     class StepHeading: public Step
685     {
686     public:
687
688         StepHeading( const QString & name = "" )
689             : Step( name, "" )
690             {}
691
692         virtual ~StepHeading() {}
693         virtual bool isHeading() const { return true; }
694         virtual bool hasID( const QString & id ) { return false; }
695     };
696
697
698     /**
699      * Helper class for wizard tree item
700      **/
701     class TreeItem: public QY2ListViewItem
702     {
703     public:
704         TreeItem( QY2ListView *         parent,
705                   const QString &       text,
706                   const QString &       id )
707             : QY2ListViewItem( parent, text )
708             , _id( id )
709             {}
710
711         TreeItem( YQWizard::TreeItem *  parent,
712                   const QString &       text,
713                   const QString &       id )
714             : QY2ListViewItem( parent, text )
715             , _id( id )
716             {}
717
718         virtual QString text(int index) const { return Q3ListViewItem::text(index); } 
719         QString text() const { return Q3ListViewItem::text(0); }
720         QString id()   const { return _id; }
721
722     private:
723         QString _id;
724     };
725
726 }; // class YQWizard
727
728
729
730 #endif // YQWizard_h