libyui  2.42.5
 All Classes Functions Variables Enumerations Friends
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 
32 class YShortcutManager;
33 class YPushButton;
34 class YDialogPrivate;
35 class YEvent;
36 class YEventFilter;
37 
38 // See YTypes.h for enum YDialogType and enum YDialogColorMode
39 
40 
42 {
43 protected:
44  /**
45  * Constructor.
46  *
47  * 'dialogType' is one of YMainDialog or YPopupDialog.
48  *
49  * 'colorMode' can be set to YDialogWarnColor to use very bright "warning"
50  * colors or YDialogInfoColor to use more prominent, yet not quite as
51  * bright as "warning" colors. Use both only very rarely.
52  **/
53  YDialog( YDialogType dialogType,
54  YDialogColorMode colorMode = YDialogNormalColor );
55 
56  /**
57  * Destructor.
58  * Don't delete a dialog directly, use YDialog::deleteTopmostDialog()
59  * or YDialog::destroy().
60  **/
61  virtual ~YDialog();
62 
63 public:
64  /**
65  * Return a descriptive name of this widget class for logging,
66  * debugging etc.
67  **/
68  virtual const char * widgetClass() const { return "YDialog"; }
69 
70  /**
71  * Open a newly created dialog: Finalize it and make it visible
72  * on the screen.
73  *
74  * Applications should call this once after all children are created.
75  * If the application doesn't do this, it will be done automatically upon
76  * the next call of YDialog::waitForEvent() (or related). This is OK if
77  * YDialog::waitForEvent() is called immediately after creating the dialog
78  * anyway. If it is not, the application might appear sluggish to the user.
79  *
80  * Derived classes are free to reimplement this, but they should call this
81  * base class method in the new implementation.
82  **/
83  void open();
84 
85  /**
86  * Return 'true' if open() has already been called for this dialog.
87  **/
88  bool isOpen() const;
89 
90  /**
91  * Wait for a user event. In most cases, this means waiting until the user
92  * has clicked on a button in this dialog. If any widget has its 'notify'
93  * flag set (`opt(`notify) in YCP, setNotify( true ) in C++), an action on
94  * such a widget will also make waitForEvent() return.
95  *
96  * If the specified timeout elapses without any user event, a YTimeoutEvent
97  * will be returned. 0 means no timeout (wait forever).
98  *
99  * If open() has not been called for this dialog until now,
100  * it is called now.
101  *
102  * The dialog retains ownership of the event and will delete it upon the
103  * next call to waitForEvent() or pollEvent() or when the dialog is
104  * deleted. This also means that the return value of this function can
105  * safely be ignored without fear of memory leaks.
106  *
107  * Applications can create YEventFilters to act upon some events before
108  * they are delivered to the application. Each event filter of this dialog
109  * is called (in undefined order) in waitForEvent(). An event filter can
110  * consume an event (in which case waitForEvent() will return to its
111  * internal event loop), pass it through unchanged, or even replace it with
112  * a new event. Refer to the YEventFilter documentation for more details.
113  *
114  * If this dialog is not the topmost dialog, an exception is thrown.
115  **/
116  YEvent * waitForEvent( int timeout_millisec = 0 );
117 
118  /**
119  * Check if a user event is pending. If there is one, return it.
120  * If there is none, do not wait for one - return 0.
121  *
122  * If open() has not been called for this dialog until now,
123  * it is called now.
124  *
125  * The dialog retains ownership of the event and will delete it upon the
126  * next call to waitForEvent() or pollEvent() or when the dialog is
127  * deleted. This also means that the return value of this function can
128  * safely be ignored without fear of memory leaks.
129  *
130  * If this dialog is not the topmost dialog, an exception is thrown.
131  **/
132  YEvent * pollEvent();
133 
134  /**
135  * Return 'true' if this dialog is the topmost dialog.
136  **/
137  bool isTopmostDialog() const;
138 
139  /**
140  * Close and delete this dialog (and all its children) if it is the topmost
141  * dialog. If this is not the topmost dialog, this will throw an exception
142  * if 'doThrow' is true (default).
143  *
144  * Remember that all pointers to the dialog and its children will be
145  * invalid after this operation.
146  *
147  * This is intentionally not named close() since close() would not imply
148  * that the dialog and its children are deleted.
149  *
150  * Returns 'true' upon success, 'false' upon failure.
151  **/
152  bool destroy( bool doThrow = true );
153 
154  /**
155  * Delete the topmost dialog.
156  *
157  * Will throw a YUINoDialogException if there is no dialog and 'doThrow' is
158  * 'true'.
159  *
160  * This is equivalent to YDialog::currentDialog()->destroy().
161  *
162  * Returns 'true' if there is another open dialog after deleting,
163  * 'false' if there is none.
164  **/
165  static bool deleteTopmostDialog( bool doThrow = true );
166 
167  /**
168  * Delete all open dialogs.
169  **/
170  static void deleteAllDialogs();
171 
172  /**
173  * Delete all dialogs from the topmost to the one specified.
174  **/
175  static void deleteTo( YDialog * dialog );
176 
177  /**
178  * Returns the number of currently open dialogs (from 1 on), i.e., the
179  * depth of the dialog stack.
180  **/
181  static int openDialogsCount();
182 
183  /**
184  * Return the current (topmost) dialog.
185  *
186  * If there is none, throw a YUINoDialogException if 'doThrow' is 'true'
187  * and return 0 if 'doThrow' is false.
188  **/
189  static YDialog * currentDialog( bool doThrow = true );
190 
191  /**
192  * Alias for currentDialog().
193  **/
194  static YDialog * topmostDialog( bool doThrow = true )
195  { return currentDialog( doThrow ); }
196 
197  /**
198  * Set the initial dialog size, depending on dialogType:
199  * YMainDialog dialogs get the UI's "default main window" size,
200  * YPopupDialog dialogs use their content's preferred size.
201  **/
202  void setInitialSize();
203 
204  /**
205  * Recalculate the layout of the dialog and of all its children after
206  * children have been added or removed or if any of them changed its
207  * preferred width of height.
208  *
209  * This is a very expensive operation. Call it only when really necessary.
210  * YDialog::open() includes a call to YDialog::setInitialSize() which does
211  * the same.
212  *
213  * The basic idea behind this function is to call it when the dialog
214  * changed after it (and its children hierarchy) was initially created.
215  **/
216  void recalcLayout();
217 
218  /**
219  * Return this dialog's type (YMainDialog / YPopupDialog /YWizardDialog).
220  **/
221  YDialogType dialogType() const;
222 
223  /**
224  * Return 'true' if this dialog is a dialog of main dialog size:
225  * YMainDialog or YWizardDialog.
226  **/
227  bool isMainDialog();
228 
229  /**
230  * Return this dialog's color mode.
231  **/
232  YDialogColorMode colorMode() const;
233 
234  /**
235  * Checks the keyboard shortcuts of widgets in this dialog unless shortcut
236  * checks are postponed or 'force' is 'true'.
237  *
238  * A forced shortcut check resets postponed checking.
239  **/
240  void checkShortcuts( bool force = false );
241 
242  /**
243  * From now on, postpone keyboard shortcut checks - i.e. normal (not
244  * forced) checkKeyboardShortcuts() will do nothing. Reset this mode by
245  * forcing a shortcut check with checkKeyboardShortcuts( true ).
246  **/
247  void postponeShortcutCheck();
248 
249  /**
250  * Return whether or not shortcut checking is currently postponed.
251  **/
252  bool shortcutCheckPostponed() const;
253 
254  /**
255  * Return this dialog's default button: The button that is activated when
256  * the user hits [Return] anywhere in this dialog. Note that this is not
257  * the same as the button that currently has the keyboard focus.
258  *
259  * This might return 0 if there is no default button.
260  **/
261  YPushButton * defaultButton() const;
262 
263  /**
264  * Delete an event.
265  **/
266  void deleteEvent( YEvent * event );
267 
268  /**
269  * Add an event filter. This can be useful to catch certain types of events
270  * before they are delivered to the application. All event filters are
271  * called (in unspecified order) in waitForEvent(). Each one may consume
272  * an event, pass it through unchanged, or replace it with a newly created
273  * event.
274  *
275  * Normally, an YEventFilter should be created on the heap with 'new'. In
276  * that case, the dialog's destructor will take care of deleting it.
277  *
278  * In rare cases it might make sense to create an YEventFilter on the stack
279  * (as a local variable) and rely on that variable to go out of scope and
280  * be destroyed before the dialog gets destroyed. But that may be risky.
281  *
282  * Notice that applications never need to call this function: YEventFilter
283  * does it automatically in its constructor.
284  **/
285  void addEventFilter( YEventFilter * eventFilter );
286 
287  /**
288  * Remove an event filter.
289  *
290  * Notice that applications never need to call this function: YEventFilter
291  * does it automatically in its destructor.
292  **/
293  void removeEventFilter( YEventFilter * eventFilter );
294 
295  /**
296  * Highlight a child widget of this dialog. This is meant for debugging:
297  * YDialogSpy and similar uses.
298  *
299  * No more than one widget can be highlighted at any one time in the same
300  * dialog. Highlighting another widget un-highlights a previously
301  * highlighted widget. 0 means 'unhighlight the last highlighted widget,
302  * but don't highlight any other'.
303  *
304  * This default implementation does nothing.
305  **/
306  virtual void highlight( YWidget * child ) {}
307 
308  /**
309  * Set this dialog's default button (the button that is activated when
310  * the user hits [Return] anywhere in this dialog). 0 means no default
311  * button.
312  *
313  * There should be no more than one default button in a dialog.
314  *
315  * Derived classes are free to overwrite this method, but they should
316  * call this base class method in the new implementation.
317  **/
318  virtual void setDefaultButton( YPushButton * defaultButton );
319 
320  /**
321  * Activate this dialog: Make sure that it is shown as the topmost dialog
322  * of this application and that it can receive input.
323  *
324  * Derived classes are required to implement this.
325  **/
326  virtual void activate() = 0;
327 
328  /**
329  * Show the specified text in a pop-up dialog with a local event loop.
330  * This is useful for help texts.
331  * 'richText' indicates if YRichText formatting should be applied.
332  **/
333  static void showText( const std::string & text, bool richText = false );
334 
335  /**
336  * Show the help text for the specified widget. If it doesn't have one,
337  * traverse up the widget hierarchy until there is one.
338  *
339  * If there is a help text, it is displayed in a pop-up dialog with a local
340  * event loop.
341  *
342  * This returns 'true' on success (there was a help text) and 'false' on
343  * failure (no help text).
344  **/
345  static bool showHelpText( YWidget * widget );
346 
347 
348 protected:
349 
350  /**
351  * Internal open() method. This is called (exactly once during the life
352  * time of the dialog) in open().
353  *
354  * Derived classes are required to implement this to do whatever is
355  * necessary to make this dialog visible on the screen.
356  **/
357  virtual void openInternal() = 0;
358 
359  /**
360  * Wait for a user event.
361  *
362  * Derived classes are required to implement this.
363  **/
364  virtual YEvent * waitForEventInternal( int timeout_millisec ) = 0;
365 
366  /**
367  * Check if a user event is pending. If there is one, return it.
368  * If there is none, do not wait for one - return 0.
369  *
370  * Derived classes are required to implement this.
371  **/
372  virtual YEvent * pollEventInternal() = 0;
373 
374  /**
375  * Filter out invalid events: Return 0 if the event does not belong to this
376  * dialog or the unchanged event if it does.
377  **/
378  YEvent * filterInvalidEvents( YEvent * event );
379 
380  /**
381  * Call the installed event filters.
382  **/
383  YEvent * callEventFilters( YEvent * event );
384 
385  /**
386  * Delete all (remaining) event filters.
387  **/
388  void deleteEventFilters();
389 
390  /**
391  * Stack holding all currently existing dialogs.
392  **/
393  static std::stack<YDialog *> _dialogStack;
394 
395 private:
396 
398 };
399 
400 
401 #endif // YDialog_h