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