libyui  3.3.1
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  * Close and delete this dialog (and all its children) if it is the topmost
147  * dialog. If this is not the topmost dialog, this will throw an exception
148  * if 'doThrow' is true (default).
149  *
150  * Remember that all pointers to the dialog and its children will be
151  * invalid after this operation.
152  *
153  * This is intentionally not named close() since close() would not imply
154  * that the dialog and its children are deleted.
155  *
156  * Returns 'true' upon success, 'false' upon failure.
157  **/
158  bool destroy( bool doThrow = true );
159 
160  /**
161  * Delete the topmost dialog.
162  *
163  * Will throw a YUINoDialogException if there is no dialog and 'doThrow' is
164  * 'true'.
165  *
166  * This is equivalent to YDialog::currentDialog()->destroy().
167  *
168  * Returns 'true' if there is another open dialog after deleting,
169  * 'false' if there is none.
170  **/
171  static bool deleteTopmostDialog( bool doThrow = true );
172 
173  /**
174  * Delete all open dialogs.
175  **/
176  static void deleteAllDialogs();
177 
178  /**
179  * Delete all dialogs from the topmost to the one specified.
180  **/
181  static void deleteTo( YDialog * dialog );
182 
183  /**
184  * Returns the number of currently open dialogs (from 1 on), i.e., the
185  * depth of the dialog stack.
186  **/
187  static int openDialogsCount();
188 
189  /**
190  * Return the current (topmost) dialog.
191  *
192  * If there is none, throw a YUINoDialogException if 'doThrow' is 'true'
193  * and return 0 if 'doThrow' is false.
194  **/
195  static YDialog * currentDialog( bool doThrow = true );
196 
197  /**
198  * Alias for currentDialog().
199  **/
200  static YDialog * topmostDialog( bool doThrow = true )
201  { return currentDialog( doThrow ); }
202 
203  /**
204  * Set the initial dialog size, depending on dialogType:
205  * YMainDialog dialogs get the UI's "default main window" size,
206  * YPopupDialog dialogs use their content's preferred size.
207  **/
208  void setInitialSize();
209 
210  /**
211  * Recalculate the layout of the dialog and of all its children after
212  * children have been added or removed or if any of them changed its
213  * preferred width of height.
214  *
215  * This is a very expensive operation. Call it only when really necessary.
216  * YDialog::open() includes a call to YDialog::setInitialSize() which does
217  * the same.
218  *
219  * The basic idea behind this function is to call it when the dialog
220  * changed after it (and its children hierarchy) was initially created.
221  **/
222  void recalcLayout();
223 
224  /**
225  * Return this dialog's type (YMainDialog / YPopupDialog /YWizardDialog).
226  **/
227  YDialogType dialogType() const;
228 
229  /**
230  * Return 'true' if this dialog is a dialog of main dialog size:
231  * YMainDialog or YWizardDialog.
232  **/
233  bool isMainDialog();
234 
235  /**
236  * Return this dialog's color mode.
237  **/
238  YDialogColorMode colorMode() const;
239 
240  /**
241  * Checks the keyboard shortcuts of widgets in this dialog unless shortcut
242  * checks are postponed or 'force' is 'true'.
243  *
244  * A forced shortcut check resets postponed checking.
245  **/
246  void checkShortcuts( bool force = false );
247 
248  /**
249  * From now on, postpone keyboard shortcut checks - i.e. normal (not
250  * forced) checkKeyboardShortcuts() will do nothing. Reset this mode by
251  * forcing a shortcut check with checkKeyboardShortcuts( true ).
252  **/
253  void postponeShortcutCheck();
254 
255  /**
256  * Return whether or not shortcut checking is currently postponed.
257  **/
258  bool shortcutCheckPostponed() const;
259 
260  /**
261  * Return this dialog's default button: The button that is activated when
262  * the user hits [Return] anywhere in this dialog. Note that this is not
263  * the same as the button that currently has the keyboard focus.
264  *
265  * This might return 0 if there is no default button.
266  **/
267  YPushButton * defaultButton() const;
268 
269  /**
270  * Delete an event.
271  **/
272  void deleteEvent( YEvent * event );
273 
274  /**
275  * Add an event filter. This can be useful to catch certain types of events
276  * before they are delivered to the application. All event filters are
277  * called (in unspecified order) in waitForEvent(). Each one may consume
278  * an event, pass it through unchanged, or replace it with a newly created
279  * event.
280  *
281  * Normally, an YEventFilter should be created on the heap with 'new'. In
282  * that case, the dialog's destructor will take care of deleting it.
283  *
284  * In rare cases it might make sense to create an YEventFilter on the stack
285  * (as a local variable) and rely on that variable to go out of scope and
286  * be destroyed before the dialog gets destroyed. But that may be risky.
287  *
288  * Notice that applications never need to call this function: YEventFilter
289  * does it automatically in its constructor.
290  **/
291  void addEventFilter( YEventFilter * eventFilter );
292 
293  /**
294  * Remove an event filter.
295  *
296  * Notice that applications never need to call this function: YEventFilter
297  * does it automatically in its destructor.
298  **/
299  void removeEventFilter( YEventFilter * eventFilter );
300 
301  /**
302  * Highlight a child widget of this dialog. This is meant for debugging:
303  * YDialogSpy and similar uses.
304  *
305  * No more than one widget can be highlighted at any one time in the same
306  * dialog. Highlighting another widget un-highlights a previously
307  * highlighted widget. 0 means 'unhighlight the last highlighted widget,
308  * but don't highlight any other'.
309  *
310  * This default implementation does nothing.
311  **/
312  virtual void highlight( YWidget * child ) {}
313 
314  /**
315  * Set this dialog's default button (the button that is activated when
316  * the user hits [Return] anywhere in this dialog). 0 means no default
317  * button.
318  *
319  * There should be no more than one default button in a dialog.
320  *
321  * Derived classes are free to overwrite this method, but they should
322  * call this base class method in the new implementation.
323  **/
324  virtual void setDefaultButton( YPushButton * defaultButton );
325 
326  /**
327  * Activate this dialog: Make sure that it is shown as the topmost dialog
328  * of this application and that it can receive input.
329  *
330  * Derived classes are required to implement this.
331  **/
332  virtual void activate() = 0;
333 
334  /**
335  * Show the specified text in a pop-up dialog with a local event loop.
336  * This is useful for help texts.
337  * 'richText' indicates if YRichText formatting should be applied.
338  **/
339  static void showText( const std::string & text, bool richText = false );
340 
341  /**
342  * Show the help text for the specified widget. If it doesn't have one,
343  * traverse up the widget hierarchy until there is one.
344  *
345  * If there is a help text, it is displayed in a pop-up dialog with a local
346  * event loop.
347  *
348  * This returns 'true' on success (there was a help text) and 'false' on
349  * failure (no help text).
350  **/
351  static bool showHelpText( YWidget * widget );
352 
353  /**
354  * Show the release notes
355  *
356  * If there are release notes, they are displayed in a pop-up dialog with a local
357  * event loop.
358  *
359  * This returns 'true' on success (there were relnotes) and 'false' on
360  * failure (no relnotes).
361  **/
362  static bool showRelNotesText();
363 
364 
365 protected:
366 
367  /**
368  * Internal open() method. This is called (exactly once during the life
369  * time of the dialog) in open().
370  *
371  * Derived classes are required to implement this to do whatever is
372  * necessary to make this dialog visible on the screen.
373  **/
374  virtual void openInternal() = 0;
375 
376  /**
377  * Wait for a user event.
378  *
379  * Derived classes are required to implement this.
380  **/
381  virtual YEvent * waitForEventInternal( int timeout_millisec ) = 0;
382 
383  /**
384  * Check if a user event is pending. If there is one, return it.
385  * If there is none, do not wait for one - return 0.
386  *
387  * Derived classes are required to implement this.
388  **/
389  virtual YEvent * pollEventInternal() = 0;
390 
391  /**
392  * Filter out invalid events: Return 0 if the event does not belong to this
393  * dialog or the unchanged event if it does.
394  **/
395  YEvent * filterInvalidEvents( YEvent * event );
396 
397  /**
398  * Call the installed event filters.
399  **/
400  YEvent * callEventFilters( YEvent * event );
401 
402  /**
403  * Delete all (remaining) event filters.
404  **/
405  void deleteEventFilters();
406 
407  /**
408  * Stack holding all currently existing dialogs.
409  **/
410  static std::stack<YDialog *> _dialogStack;
411 
412 private:
413 
415 };
416 
417 
418 #endif // YDialog_h
void deleteEvent(YEvent *event)
Delete an event.
Definition: YDialog.cc:508
static bool showHelpText(YWidget *widget)
Show the help text for the specified widget.
Definition: YDialog.cc:700
void deleteEventFilters()
Delete all (remaining) event filters.
Definition: YDialog.cc:237
virtual void setDefaultButton(YPushButton *defaultButton)
Set this dialog&#39;s default button (the button that is activated when the user hits [Return] anywhere i...
Definition: YDialog.cc:344
YDialogType
Type of dialog: Main / Popup / Wizard.
Definition: YTypes.h:66
Helper class to manage keyboard shortcuts within one dialog and resolve keyboard shortcut conflicts...
void postponeShortcutCheck()
From now on, postpone keyboard shortcut checks - i.e.
Definition: YDialog.cc:305
static bool deleteTopmostDialog(bool doThrow=true)
Delete the topmost dialog.
Definition: YDialog.cc:545
Abstract base class to filter events.
Definition: YEventFilter.h:62
Abstract base class for events to be returned upon UI::UserInput() and related functions.
Definition: YEvent.h:43
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:444
bool isTopmostDialog() const
Return &#39;true&#39; if this dialog is the topmost dialog.
Definition: YDialog.cc:224
void checkShortcuts(bool force=false)
Checks the keyboard shortcuts of widgets in this dialog unless shortcut checks are postponed or &#39;forc...
Definition: YDialog.cc:319
Container widget class that manages one child.
void removeEventFilter(YEventFilter *eventFilter)
Remove an event filter.
Definition: YDialog.cc:622
YDialogColorMode colorMode() const
Return this dialog&#39;s color mode.
Definition: YDialog.cc:298
A push button; may have an icon, and a F-key shortcut.
Definition: YPushButton.h:37
virtual const char * widgetClass() const
Return a descriptive name of this widget class for logging, debugging etc.
Definition: YDialog.h:74
virtual void openInternal()=0
Internal open() method.
static void deleteAllDialogs()
Delete all open dialogs.
Definition: YDialog.cc:562
bool isOpen() const
Return &#39;true&#39; if open() has already been called for this dialog.
Definition: YDialog.cc:217
virtual YEvent * pollEventInternal()=0
Check if a user event is pending.
static YDialog * currentDialog(bool doThrow=true)
Return the current (topmost) dialog.
Definition: YDialog.cc:531
bool shortcutCheckPostponed() const
Return whether or not shortcut checking is currently postponed.
Definition: YDialog.cc:312
YEvent * callEventFilters(YEvent *event)
Call the installed event filters.
Definition: YDialog.cc:634
virtual void highlight(YWidget *child)
Highlight a child widget of this dialog.
Definition: YDialog.h:312
void open()
Open a newly created dialog: Finalize it and make it visible on the screen.
Definition: YDialog.cc:203
void addEventFilter(YEventFilter *eventFilter)
Add an event filter.
Definition: YDialog.cc:600
YDialog(YDialogType dialogType, YDialogColorMode colorMode=YDialogNormalColor)
Constructor.
Definition: YDialog.cc:150
void setInitialSize()
Set the initial dialog size, depending on dialogType: YMainDialog dialogs get the UI&#39;s "default main ...
Definition: YDialog.cc:358
static void deleteTo(YDialog *dialog)
Delete all dialogs from the topmost to the one specified.
Definition: YDialog.cc:572
static bool showRelNotesText()
Show the release notes.
Definition: YDialog.cc:731
YDialogType dialogType() const
Return this dialog&#39;s type (YMainDialog / YPopupDialog /YWizardDialog).
Definition: YDialog.cc:273
virtual void activate()=0
Activate this dialog: Make sure that it is shown as the topmost dialog of this application and that i...
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: YDialog.cc:654
static int openDialogsCount()
Returns the number of currently open dialogs (from 1 on), i.e., the depth of the dialog stack...
Definition: YDialog.cc:593
virtual ~YDialog()
Destructor.
Definition: YDialog.cc:167
void recalcLayout()
Recalculate the layout of the dialog and of all its children after children have been added or remove...
Definition: YDialog.cc:370
YPushButton * defaultButton() const
Return this dialog&#39;s default button: The button that is activated when the user hits [Return] anywher...
Definition: YDialog.cc:337
A window in the desktop environment.
Definition: YDialog.h:47
virtual YEvent * waitForEventInternal(int timeout_millisec)=0
Wait for a user event.
YEvent * pollEvent()
Check if a user event is pending.
Definition: YDialog.cc:419
Abstract base class of all UI widgets.
Definition: YWidget.h:54
static YDialog * topmostDialog(bool doThrow=true)
Alias for currentDialog().
Definition: YDialog.h:200
bool destroy(bool doThrow=true)
Close and delete this dialog (and all its children) if it is the topmost dialog.
Definition: YDialog.cc:252
static std::stack< YDialog * > _dialogStack
Stack holding all currently existing dialogs.
Definition: YDialog.h:410
YEvent * waitForEvent(int timeout_millisec=0)
Wait for a user event.
Definition: YDialog.cc:379
bool isMainDialog()
Return &#39;true&#39; if this dialog is a dialog of main dialog size: YMainDialog or YWizardDialog.
Definition: YDialog.cc:280