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