libyui  3.10.0
YDialog.h
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YDialog.h
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 
26 #ifndef YDialog_h
27 #define YDialog_h
28 
29 #include "YSingleChildContainerWidget.h"
30 #include <stack>
31 #include <map>
32 
33 class YShortcutManager;
34 class YPushButton;
35 class YDialogPrivate;
36 class YEvent;
37 class YEventFilter;
38 
39 // See YTypes.h for enum YDialogType and enum YDialogColorMode
40 
41 
42 /**
43  * A window in the desktop environment.
44  * A YPopupDialog always has a dedicated window
45  * but YMainDialog may be stacked in a single window.
46  **/
48 {
49 protected:
50  /**
51  * Constructor.
52  *
53  * 'dialogType' is one of YMainDialog or YPopupDialog.
54  *
55  * 'colorMode' can be set to YDialogWarnColor to use very bright "warning"
56  * colors or YDialogInfoColor to use more prominent, yet not quite as
57  * bright as "warning" colors. Use both only very rarely.
58  **/
60  YDialogColorMode colorMode = YDialogNormalColor );
61 
62  /**
63  * Destructor.
64  * Don't delete a dialog directly, use YDialog::deleteTopmostDialog()
65  * or YDialog::destroy().
66  **/
67  virtual ~YDialog();
68 
69 public:
70  /**
71  * Return a descriptive name of this widget class for logging,
72  * debugging etc.
73  **/
74  virtual const char * widgetClass() const { return "YDialog"; }
75 
76  /**
77  * Open a newly created dialog: Finalize it and make it visible
78  * on the screen.
79  *
80  * Applications should call this once after all children are created.
81  * If the application doesn't do this, it will be done automatically upon
82  * the next call of YDialog::waitForEvent() (or related). This is OK if
83  * YDialog::waitForEvent() is called immediately after creating the dialog
84  * anyway. If it is not, the application might appear sluggish to the user.
85  *
86  * Derived classes are free to reimplement this, but they should call this
87  * base class method in the new implementation.
88  **/
89  void open();
90 
91  /**
92  * Return 'true' if open() has already been called for this dialog.
93  **/
94  bool isOpen() const;
95 
96  /**
97  * Wait for a user event. In most cases, this means waiting until the user
98  * has clicked on a button in this dialog. If any widget has its 'notify'
99  * flag set (`opt(`notify) in YCP, setNotify( true ) in C++), an action on
100  * such a widget will also make waitForEvent() return.
101  *
102  * If the specified timeout elapses without any user event, a YTimeoutEvent
103  * will be returned. 0 means no timeout (wait forever).
104  *
105  * If open() has not been called for this dialog until now,
106  * it is called now.
107  *
108  * The dialog retains ownership of the event and will delete it upon the
109  * next call to waitForEvent() or pollEvent() or when the dialog is
110  * deleted. This also means that the return value of this function can
111  * safely be ignored without fear of memory leaks.
112  *
113  * Applications can create YEventFilters to act upon some events before
114  * they are delivered to the application. Each event filter of this dialog
115  * is called (in undefined order) in waitForEvent(). An event filter can
116  * consume an event (in which case waitForEvent() will return to its
117  * internal event loop), pass it through unchanged, or even replace it with
118  * a new event. Refer to the YEventFilter documentation for more details.
119  *
120  * If this dialog is not the topmost dialog, an exception is thrown.
121  **/
122  YEvent * waitForEvent( int timeout_millisec = 0 );
123 
124  /**
125  * Check if a user event is pending. If there is one, return it.
126  * If there is none, do not wait for one - return 0.
127  *
128  * If open() has not been called for this dialog until now,
129  * it is called now.
130  *
131  * The dialog retains ownership of the event and will delete it upon the
132  * next call to waitForEvent() or pollEvent() or when the dialog is
133  * deleted. This also means that the return value of this function can
134  * safely be ignored without fear of memory leaks.
135  *
136  * If this dialog is not the topmost dialog, an exception is thrown.
137  **/
138  YEvent * pollEvent();
139 
140  /**
141  * Return 'true' if this dialog is the topmost dialog.
142  **/
143  bool isTopmostDialog() const;
144 
145  /**
146  * Request multiple passes of the layout engine.
147  *
148  * This is intended for widgets that don't know their preferred width and
149  * height immediately because one depends on the other, for example labels
150  * with auto-wrapping: They know (roughly) the area they will need, but
151  * they can calculate their preferred height only when their width is
152  * known.
153  *
154  * Once set, this option cannot be unset; it remains set for the life
155  * time of the dialog.
156  **/
157  void requestMultiPassLayout();
158 
159  /**
160  * Return the number of the current layout pass:
161  * 0: No layout going on right now
162  * 1: First pass
163  * 2: Second pass of a multi-pass layout
164  **/
165  int layoutPass() const;
166 
167  /**
168  * Close and delete this dialog (and all its children) if it is the topmost
169  * dialog. If this is not the topmost dialog, this will throw an exception
170  * if 'doThrow' is true (default).
171  *
172  * Remember that all pointers to the dialog and its children will be
173  * invalid after this operation.
174  *
175  * This is intentionally not named close() since close() would not imply
176  * that the dialog and its children are deleted.
177  *
178  * Returns 'true' upon success, 'false' upon failure.
179  **/
180  bool destroy( bool doThrow = true );
181 
182  /**
183  * Delete the topmost dialog.
184  *
185  * Will throw a YUINoDialogException if there is no dialog and 'doThrow' is
186  * 'true'.
187  *
188  * This is equivalent to YDialog::currentDialog()->destroy().
189  *
190  * Returns 'true' if there is another open dialog after deleting,
191  * 'false' if there is none.
192  **/
193  static bool deleteTopmostDialog( bool doThrow = true );
194 
195  /**
196  * Delete all open dialogs.
197  **/
198  static void deleteAllDialogs();
199 
200  /**
201  * Delete all dialogs from the topmost to the one specified.
202  **/
203  static void deleteTo( YDialog * dialog );
204 
205  /**
206  * Returns the number of currently open dialogs (from 1 on), i.e., the
207  * depth of the dialog stack.
208  **/
209  static int openDialogsCount();
210 
211  /**
212  * Return the current (topmost) dialog.
213  *
214  * If there is none, throw a YUINoDialogException if 'doThrow' is 'true'
215  * and return 0 if 'doThrow' is false.
216  **/
217  static YDialog * currentDialog( bool doThrow = true );
218 
219  /**
220  * Alias for currentDialog().
221  **/
222  static YDialog * topmostDialog( bool doThrow = true )
223  { return currentDialog( doThrow ); }
224 
225  /**
226  * Set the initial dialog size, depending on dialogType:
227  * YMainDialog dialogs get the UI's "default main window" size,
228  * YPopupDialog dialogs use their content's preferred size.
229  **/
230  void setInitialSize();
231 
232  /**
233  * Recalculate the layout of the dialog and of all its children after
234  * children have been added or removed or if any of them changed its
235  * preferred width of height.
236  *
237  * This is a very expensive operation. Call it only when really necessary.
238  * YDialog::open() includes a call to YDialog::setInitialSize() which does
239  * the same.
240  *
241  * The basic idea behind this function is to call it when the dialog
242  * changed after it (and its children hierarchy) was initially created.
243  **/
244  void recalcLayout();
245 
246  /**
247  * Return this dialog's type (YMainDialog / YPopupDialog /YWizardDialog).
248  **/
249  YDialogType dialogType() const;
250 
251  /**
252  * Return 'true' if this dialog is a dialog of main dialog size:
253  * YMainDialog or YWizardDialog.
254  **/
255  bool isMainDialog();
256 
257  /**
258  * Return this dialog's color mode.
259  **/
260  YDialogColorMode colorMode() const;
261 
262  /**
263  * Checks the keyboard shortcuts of widgets in this dialog unless shortcut
264  * checks are postponed or 'force' is 'true'.
265  *
266  * A forced shortcut check resets postponed checking.
267  **/
268  void checkShortcuts( bool force = false );
269 
270  /**
271  * From now on, postpone keyboard shortcut checks - i.e. normal (not
272  * forced) checkKeyboardShortcuts() will do nothing. Reset this mode by
273  * forcing a shortcut check with checkKeyboardShortcuts( true ).
274  **/
275  void postponeShortcutCheck();
276 
277  /**
278  * Return whether or not shortcut checking is currently postponed.
279  **/
280  bool shortcutCheckPostponed() const;
281 
282  /**
283  * Return this dialog's default button: The button that is activated when
284  * the user hits [Return] anywhere in this dialog. Note that this is not
285  * the same as the button that currently has the keyboard focus.
286  *
287  * This might return 0 if there is no default button.
288  **/
289  YPushButton * defaultButton() const;
290 
291  /**
292  * Delete an event.
293  **/
294  void deleteEvent( YEvent * event );
295 
296  /**
297  * Add an event filter. This can be useful to catch certain types of events
298  * before they are delivered to the application. All event filters are
299  * called (in unspecified order) in waitForEvent(). Each one may consume
300  * an event, pass it through unchanged, or replace it with a newly created
301  * event.
302  *
303  * Normally, an YEventFilter should be created on the heap with 'new'. In
304  * that case, the dialog's destructor will take care of deleting it.
305  *
306  * In rare cases it might make sense to create an YEventFilter on the stack
307  * (as a local variable) and rely on that variable to go out of scope and
308  * be destroyed before the dialog gets destroyed. But that may be risky.
309  *
310  * Notice that applications never need to call this function: YEventFilter
311  * does it automatically in its constructor.
312  **/
313  void addEventFilter( YEventFilter * eventFilter );
314 
315  /**
316  * Remove an event filter.
317  *
318  * Notice that applications never need to call this function: YEventFilter
319  * does it automatically in its destructor.
320  **/
321  void removeEventFilter( YEventFilter * eventFilter );
322 
323  /**
324  * Highlight a child widget of this dialog. This is meant for debugging:
325  * YDialogSpy and similar uses.
326  *
327  * No more than one widget can be highlighted at any one time in the same
328  * dialog. Highlighting another widget un-highlights a previously
329  * highlighted widget. 0 means 'unhighlight the last highlighted widget,
330  * but don't highlight any other'.
331  *
332  * This default implementation does nothing.
333  **/
334  virtual void highlight( YWidget * child ) {}
335 
336  /**
337  * Set this dialog's default button (the button that is activated when
338  * the user hits [Return] anywhere in this dialog). 0 means no default
339  * button.
340  *
341  * There should be no more than one default button in a dialog.
342  *
343  * Derived classes are free to overwrite this method, but they should
344  * call this base class method in the new implementation.
345  **/
346  virtual void setDefaultButton( YPushButton * defaultButton );
347 
348  /**
349  * Activate this dialog: Make sure that it is shown as the topmost dialog
350  * of this application and that it can receive input.
351  *
352  * Derived classes are required to implement this.
353  **/
354  virtual void activate() = 0;
355 
356 
357  //
358  // Dialog helpers - see source file YDialogHelpers.cc
359  //
360 
361  /**
362  * Show the specified text in a pop-up dialog with a local event loop.
363  * This is useful for help texts.
364  * 'richText' indicates if YRichText formatting should be applied.
365  **/
366  static void showText( const std::string & text, bool richText = false );
367 
368  /**
369  * Show the help text for the specified widget. If it doesn't have one,
370  * traverse up the widget hierarchy until there is one.
371  *
372  * If there is a help text, it is displayed in a pop-up dialog with a local
373  * event loop.
374  *
375  * This returns 'true' on success (there was a help text) and 'false' on
376  * failure (no help text).
377  **/
378  static bool showHelpText( YWidget * widget );
379 
380  /**
381  * Show the release notes
382  *
383  * If there are release notes, they are displayed in a pop-up dialog with a local
384  * event loop.
385  *
386  * This returns 'true' on success (there were relnotes) and 'false' on
387  * failure (no relnotes).
388  **/
389  static bool showRelNotesText();
390 
391 
392 protected:
393 
394  /**
395  * Internal open() method. This is called (exactly once during the life
396  * time of the dialog) in open().
397  *
398  * Derived classes are required to implement this to do whatever is
399  * necessary to make this dialog visible on the screen.
400  **/
401  virtual void openInternal() = 0;
402 
403  /**
404  * Calculate the layout and set the size of the dialog and all widgets.
405  **/
406  void doLayout();
407 
408  /**
409  * Wait for a user event.
410  *
411  * Derived classes are required to implement this.
412  **/
413  virtual YEvent * waitForEventInternal( int timeout_millisec ) = 0;
414 
415  /**
416  * Check if a user event is pending. If there is one, return it.
417  * If there is none, do not wait for one - return 0.
418  *
419  * Derived classes are required to implement this.
420  **/
421  virtual YEvent * pollEventInternal() = 0;
422 
423  /**
424  * Filter out invalid events: Return 0 if the event does not belong to this
425  * dialog or the unchanged event if it does.
426  **/
427  YEvent * filterInvalidEvents( YEvent * event );
428 
429  /**
430  * Call the installed event filters.
431  **/
432  YEvent * callEventFilters( YEvent * event );
433 
434  /**
435  * Delete all (remaining) event filters.
436  **/
437  void deleteEventFilters();
438 
439  /**
440  * Stack holding all currently existing dialogs.
441  **/
442  static std::stack<YDialog *> _dialogStack;
443 
444 private:
445 
447 };
448 
449 
450 #endif // YDialog_h
YDialog::waitForEventInternal
virtual YEvent * waitForEventInternal(int timeout_millisec)=0
Wait for a user event.
YWidget
Abstract base class of all UI widgets.
Definition: YWidget.h:54
YDialog::colorMode
YDialogColorMode colorMode() const
Return this dialog's color mode.
Definition: YDialog.cc:284
YDialog::deleteAllDialogs
static void deleteAllDialogs()
Delete all open dialogs.
Definition: YDialog.cc:570
YDialog::showHelpText
static bool showHelpText(YWidget *widget)
Show the help text for the specified widget.
Definition: YDialogHelpers.cc:102
YDialog::~YDialog
virtual ~YDialog()
Destructor.
Definition: YDialog.cc:153
YDialog::deleteTopmostDialog
static bool deleteTopmostDialog(bool doThrow=true)
Delete the topmost dialog.
Definition: YDialog.cc:553
YDialog::pollEventInternal
virtual YEvent * pollEventInternal()=0
Check if a user event is pending.
YDialog::defaultButton
YPushButton * defaultButton() const
Return this dialog's default button: The button that is activated when the user hits [Return] anywher...
Definition: YDialog.cc:323
YDialog::deleteEvent
void deleteEvent(YEvent *event)
Delete an event.
Definition: YDialog.cc:516
YEventFilter
Abstract base class to filter events.
Definition: YEventFilter.h:62
YDialog::activate
virtual void activate()=0
Activate this dialog: Make sure that it is shown as the topmost dialog of this application and that i...
YDialog::setDefaultButton
virtual void setDefaultButton(YPushButton *defaultButton)
Set this dialog's default button (the button that is activated when the user hits [Return] anywhere i...
Definition: YDialog.cc:330
YDialog::waitForEvent
YEvent * waitForEvent(int timeout_millisec=0)
Wait for a user event.
Definition: YDialog.cc:387
YDialog::addEventFilter
void addEventFilter(YEventFilter *eventFilter)
Add an event filter.
Definition: YDialog.cc:608
YDialog::pollEvent
YEvent * pollEvent()
Check if a user event is pending.
Definition: YDialog.cc:427
YDialog::deleteTo
static void deleteTo(YDialog *dialog)
Delete all dialogs from the topmost to the one specified.
Definition: YDialog.cc:580
YDialog::openInternal
virtual void openInternal()=0
Internal open() method.
YDialogPrivate
Definition: YDialog.cc:45
YDialog::YDialog
YDialog(YDialogType dialogType, YDialogColorMode colorMode=YDialogNormalColor)
Constructor.
Definition: YDialog.cc:136
YSingleChildContainerWidget
Container widget class that manages one child.
Definition: YSingleChildContainerWidget.h:34
YDialog::recalcLayout
void recalcLayout()
Recalculate the layout of the dialog and of all its children after children have been added or remove...
Definition: YDialog.cc:356
YDialog::isMainDialog
bool isMainDialog()
Return 'true' if this dialog is a dialog of main dialog size: YMainDialog or YWizardDialog.
Definition: YDialog.cc:266
YDialog::setInitialSize
void setInitialSize()
Set the initial dialog size, depending on dialogType: YMainDialog dialogs get the UI's "default main ...
Definition: YDialog.cc:344
YDialog::callEventFilters
YEvent * callEventFilters(YEvent *event)
Call the installed event filters.
Definition: YDialog.cc:642
ImplPtr< YDialogPrivate >
YDialog::filterInvalidEvents
YEvent * filterInvalidEvents(YEvent *event)
Filter out invalid events: Return 0 if the event does not belong to this dialog or the unchanged even...
Definition: YDialog.cc:452
YDialog::isTopmostDialog
bool isTopmostDialog() const
Return 'true' if this dialog is the topmost dialog.
Definition: YDialog.cc:210
YEvent
Abstract base class for events to be returned upon UI::UserInput() and related functions.
Definition: YEvent.h:43
YDialog::destroy
bool destroy(bool doThrow=true)
Close and delete this dialog (and all its children) if it is the topmost dialog.
Definition: YDialog.cc:238
YDialog::isOpen
bool isOpen() const
Return 'true' if open() has already been called for this dialog.
Definition: YDialog.cc:203
YDialog::_dialogStack
static std::stack< YDialog * > _dialogStack
Stack holding all currently existing dialogs.
Definition: YDialog.h:442
YShortcutManager
Helper class to manage keyboard shortcuts within one dialog and resolve keyboard shortcut conflicts.
Definition: YShortcutManager.h:38
YDialog::layoutPass
int layoutPass() const
Return the number of the current layout pass: 0: No layout going on right now 1: First pass 2: Second...
Definition: YDialog.cc:380
YDialog::shortcutCheckPostponed
bool shortcutCheckPostponed() const
Return whether or not shortcut checking is currently postponed.
Definition: YDialog.cc:298
YDialog::removeEventFilter
void removeEventFilter(YEventFilter *eventFilter)
Remove an event filter.
Definition: YDialog.cc:630
YDialog::openDialogsCount
static int openDialogsCount()
Returns the number of currently open dialogs (from 1 on), i.e., the depth of the dialog stack.
Definition: YDialog.cc:601
YDialogType
YDialogType
Type of dialog: Main / Popup / Wizard.
Definition: YTypes.h:66
YDialog::widgetClass
virtual const char * widgetClass() const
Return a descriptive name of this widget class for logging, debugging etc.
Definition: YDialog.h:74
YDialog::requestMultiPassLayout
void requestMultiPassLayout()
Request multiple passes of the layout engine.
Definition: YDialog.cc:662
YDialog::dialogType
YDialogType dialogType() const
Return this dialog's type (YMainDialog / YPopupDialog /YWizardDialog).
Definition: YDialog.cc:259
YDialog::deleteEventFilters
void deleteEventFilters()
Delete all (remaining) event filters.
Definition: YDialog.cc:223
YDialog::showText
static void showText(const std::string &text, bool richText=false)
Show the specified text in a pop-up dialog with a local event loop.
Definition: YDialogHelpers.cc:56
YDialog::open
void open()
Open a newly created dialog: Finalize it and make it visible on the screen.
Definition: YDialog.cc:189
YDialog::doLayout
void doLayout()
Calculate the layout and set the size of the dialog and all widgets.
Definition: YDialog.cc:364
YDialog::checkShortcuts
void checkShortcuts(bool force=false)
Checks the keyboard shortcuts of widgets in this dialog unless shortcut checks are postponed or 'forc...
Definition: YDialog.cc:305
YDialog::postponeShortcutCheck
void postponeShortcutCheck()
From now on, postpone keyboard shortcut checks - i.e.
Definition: YDialog.cc:291
YDialog::showRelNotesText
static bool showRelNotesText()
Show the release notes.
Definition: YDialogHelpers.cc:134
YDialog::highlight
virtual void highlight(YWidget *child)
Highlight a child widget of this dialog.
Definition: YDialog.h:334
YDialog
A window in the desktop environment.
Definition: YDialog.h:47
YPushButton
A push button; may have an icon, and a F-key shortcut.
Definition: YPushButton.h:37
YDialog::topmostDialog
static YDialog * topmostDialog(bool doThrow=true)
Alias for currentDialog().
Definition: YDialog.h:222
YDialog::currentDialog
static YDialog * currentDialog(bool doThrow=true)
Return the current (topmost) dialog.
Definition: YDialog.cc:539