libyui
3.0.10
|
00001 /* 00002 Copyright (C) 2000-2012 Novell, Inc 00003 This library is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU Lesser General Public License as 00005 published by the Free Software Foundation; either version 2.1 of the 00006 License, or (at your option) version 3.0 of the License. This library 00007 is distributed in the hope that it will be useful, but WITHOUT ANY 00008 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00009 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00010 License for more details. You should have received a copy of the GNU 00011 Lesser General Public License along with this library; if not, write 00012 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth 00013 Floor, Boston, MA 02110-1301 USA 00014 */ 00015 00016 00017 /*-/ 00018 00019 File: YDialog.h 00020 00021 Author: Stefan Hundhammer <sh@suse.de> 00022 00023 /-*/ 00024 00025 00026 #ifndef YDialog_h 00027 #define YDialog_h 00028 00029 #include "YSingleChildContainerWidget.h" 00030 #include <stack> 00031 00032 class YShortcutManager; 00033 class YPushButton; 00034 class YDialogPrivate; 00035 class YEvent; 00036 class YEventFilter; 00037 00038 // See YTypes.h for enum YDialogType and enum YDialogColorMode 00039 00040 00041 class YDialog : public YSingleChildContainerWidget 00042 { 00043 protected: 00044 /** 00045 * Constructor. 00046 * 00047 * 'dialogType' is one of YMainDialog or YPopupDialog. 00048 * 00049 * 'colorMode' can be set to YDialogWarnColor to use very bright "warning" 00050 * colors or YDialogInfoColor to use more prominent, yet not quite as 00051 * bright as "warning" colors. Use both only very rarely. 00052 **/ 00053 YDialog( YDialogType dialogType, 00054 YDialogColorMode colorMode = YDialogNormalColor ); 00055 00056 /** 00057 * Destructor. 00058 * Don't delete a dialog directly, use YDialog::deleteTopmostDialog() 00059 * or YDialog::destroy(). 00060 **/ 00061 virtual ~YDialog(); 00062 00063 public: 00064 /** 00065 * Return a descriptive name of this widget class for logging, 00066 * debugging etc. 00067 **/ 00068 virtual const char * widgetClass() const { return "YDialog"; } 00069 00070 /** 00071 * Open a newly created dialog: Finalize it and make it visible 00072 * on the screen. 00073 * 00074 * Applications should call this once after all children are created. 00075 * If the application doesn't do this, it will be done automatically upon 00076 * the next call of YDialog::waitForEvent() (or related). This is OK if 00077 * YDialog::waitForEvent() is called immediately after creating the dialog 00078 * anyway. If it is not, the application might appear sluggish to the user. 00079 * 00080 * Derived classes are free to reimplement this, but they should call this 00081 * base class method in the new implementation. 00082 **/ 00083 void open(); 00084 00085 /** 00086 * Return 'true' if open() has already been called for this dialog. 00087 **/ 00088 bool isOpen() const; 00089 00090 /** 00091 * Wait for a user event. In most cases, this means waiting until the user 00092 * has clicked on a button in this dialog. If any widget has its 'notify' 00093 * flag set (`opt(`notify) in YCP, setNotify( true ) in C++), an action on 00094 * such a widget will also make waitForEvent() return. 00095 * 00096 * If the specified timeout elapses without any user event, a YTimeoutEvent 00097 * will be returned. 0 means no timeout (wait forever). 00098 * 00099 * If open() has not been called for this dialog until now, 00100 * it is called now. 00101 * 00102 * The dialog retains ownership of the event and will delete it upon the 00103 * next call to waitForEvent() or pollEvent() or when the dialog is 00104 * deleted. This also means that the return value of this function can 00105 * safely be ignored without fear of memory leaks. 00106 * 00107 * Applications can create YEventFilters to act upon some events before 00108 * they are delivered to the application. Each event filter of this dialog 00109 * is called (in undefined order) in waitForEvent(). An event filter can 00110 * consume an event (in which case waitForEvent() will return to its 00111 * internal event loop), pass it through unchanged, or even replace it with 00112 * a new event. Refer to the YEventFilter documentation for more details. 00113 * 00114 * If this dialog is not the topmost dialog, an exception is thrown. 00115 **/ 00116 YEvent * waitForEvent( int timeout_millisec = 0 ); 00117 00118 /** 00119 * Check if a user event is pending. If there is one, return it. 00120 * If there is none, do not wait for one - return 0. 00121 * 00122 * If open() has not been called for this dialog until now, 00123 * it is called now. 00124 * 00125 * The dialog retains ownership of the event and will delete it upon the 00126 * next call to waitForEvent() or pollEvent() or when the dialog is 00127 * deleted. This also means that the return value of this function can 00128 * safely be ignored without fear of memory leaks. 00129 * 00130 * If this dialog is not the topmost dialog, an exception is thrown. 00131 **/ 00132 YEvent * pollEvent(); 00133 00134 /** 00135 * Return 'true' if this dialog is the topmost dialog. 00136 **/ 00137 bool isTopmostDialog() const; 00138 00139 /** 00140 * Close and delete this dialog (and all its children) if it is the topmost 00141 * dialog. If this is not the topmost dialog, this will throw an exception 00142 * if 'doThrow' is true (default). 00143 * 00144 * Remember that all pointers to the dialog and its children will be 00145 * invalid after this operation. 00146 * 00147 * This is intentionally not named close() since close() would not imply 00148 * that the dialog and its children are deleted. 00149 * 00150 * Returns 'true' upon success, 'false' upon failure. 00151 **/ 00152 bool destroy( bool doThrow = true ); 00153 00154 /** 00155 * Delete the topmost dialog. 00156 * 00157 * Will throw a YUINoDialogException if there is no dialog and 'doThrow' is 00158 * 'true'. 00159 * 00160 * This is equivalent to YDialog::currentDialog()->destroy(). 00161 * 00162 * Returns 'true' if there is another open dialog after deleting, 00163 * 'false' if there is none. 00164 **/ 00165 static bool deleteTopmostDialog( bool doThrow = true ); 00166 00167 /** 00168 * Delete all open dialogs. 00169 **/ 00170 static void deleteAllDialogs(); 00171 00172 /** 00173 * Delete all dialogs from the topmost to the one specified. 00174 **/ 00175 static void deleteTo( YDialog * dialog ); 00176 00177 /** 00178 * Returns the number of currently open dialogs (from 1 on), i.e., the 00179 * depth of the dialog stack. 00180 **/ 00181 static int openDialogsCount(); 00182 00183 /** 00184 * Return the current (topmost) dialog. 00185 * 00186 * If there is none, throw a YUINoDialogException if 'doThrow' is 'true' 00187 * and return 0 if 'doThrow' is false. 00188 **/ 00189 static YDialog * currentDialog( bool doThrow = true ); 00190 00191 /** 00192 * Alias for currentDialog(). 00193 **/ 00194 static YDialog * topmostDialog( bool doThrow = true ) 00195 { return currentDialog( doThrow ); } 00196 00197 /** 00198 * Set the initial dialog size, depending on dialogType: 00199 * YMainDialog dialogs get the UI's "default main window" size, 00200 * YPopupDialog dialogs use their content's preferred size. 00201 **/ 00202 void setInitialSize(); 00203 00204 /** 00205 * Recalculate the layout of the dialog and of all its children after 00206 * children have been added or removed or if any of them changed its 00207 * preferred width of height. 00208 * 00209 * This is a very expensive operation. Call it only when really necessary. 00210 * YDialog::open() includes a call to YDialog::setInitialSize() which does 00211 * the same. 00212 * 00213 * The basic idea behind this function is to call it when the dialog 00214 * changed after it (and its children hierarchy) was initially created. 00215 **/ 00216 void recalcLayout(); 00217 00218 /** 00219 * Return this dialog's type (YMainDialog / YPopupDialog /YWizardDialog). 00220 **/ 00221 YDialogType dialogType() const; 00222 00223 /** 00224 * Return 'true' if this dialog is a dialog of main dialog size: 00225 * YMainDialog or YWizardDialog. 00226 **/ 00227 bool isMainDialog(); 00228 00229 /** 00230 * Return this dialog's color mode. 00231 **/ 00232 YDialogColorMode colorMode() const; 00233 00234 /** 00235 * Checks the keyboard shortcuts of widgets in this dialog unless shortcut 00236 * checks are postponed or 'force' is 'true'. 00237 * 00238 * A forced shortcut check resets postponed checking. 00239 **/ 00240 void checkShortcuts( bool force = false ); 00241 00242 /** 00243 * From now on, postpone keyboard shortcut checks - i.e. normal (not 00244 * forced) checkKeyboardShortcuts() will do nothing. Reset this mode by 00245 * forcing a shortcut check with checkKeyboardShortcuts( true ). 00246 **/ 00247 void postponeShortcutCheck(); 00248 00249 /** 00250 * Return whether or not shortcut checking is currently postponed. 00251 **/ 00252 bool shortcutCheckPostponed() const; 00253 00254 /** 00255 * Return this dialog's default button: The button that is activated when 00256 * the user hits [Return] anywhere in this dialog. Note that this is not 00257 * the same as the button that currently has the keyboard focus. 00258 * 00259 * This might return 0 if there is no default button. 00260 **/ 00261 YPushButton * defaultButton() const; 00262 00263 /** 00264 * Delete an event. 00265 **/ 00266 void deleteEvent( YEvent * event ); 00267 00268 /** 00269 * Add an event filter. This can be useful to catch certain types of events 00270 * before they are delivered to the application. All event filters are 00271 * called (in unspecified order) in waitForEvent(). Each one may consume 00272 * an event, pass it through unchanged, or replace it with a newly created 00273 * event. 00274 * 00275 * Normally, an YEventFilter should be created on the heap with 'new'. In 00276 * that case, the dialog's destructor will take care of deleting it. 00277 * 00278 * In rare cases it might make sense to create an YEventFilter on the stack 00279 * (as a local variable) and rely on that variable to go out of scope and 00280 * be destroyed before the dialog gets destroyed. But that may be risky. 00281 * 00282 * Notice that applications never need to call this function: YEventFilter 00283 * does it automatically in its constructor. 00284 **/ 00285 void addEventFilter( YEventFilter * eventFilter ); 00286 00287 /** 00288 * Remove an event filter. 00289 * 00290 * Notice that applications never need to call this function: YEventFilter 00291 * does it automatically in its destructor. 00292 **/ 00293 void removeEventFilter( YEventFilter * eventFilter ); 00294 00295 /** 00296 * Highlight a child widget of this dialog. This is meant for debugging: 00297 * YDialogSpy and similar uses. 00298 * 00299 * No more than one widget can be highlighted at any one time in the same 00300 * dialog. Highlighting another widget un-highlights a previously 00301 * highlighted widget. 0 means 'unhighlight the last highlighted widget, 00302 * but don't highlight any other'. 00303 * 00304 * This default implementation does nothing. 00305 **/ 00306 virtual void highlight( YWidget * child ) {} 00307 00308 /** 00309 * Set this dialog's default button (the button that is activated when 00310 * the user hits [Return] anywhere in this dialog). 0 means no default 00311 * button. 00312 * 00313 * There should be no more than one default button in a dialog. 00314 * 00315 * Derived classes are free to overwrite this method, but they should 00316 * call this base class method in the new implementation. 00317 **/ 00318 virtual void setDefaultButton( YPushButton * defaultButton ); 00319 00320 /** 00321 * Activate this dialog: Make sure that it is shown as the topmost dialog 00322 * of this application and that it can receive input. 00323 * 00324 * Derived classes are required to implement this. 00325 **/ 00326 virtual void activate() = 0; 00327 00328 /** 00329 * Show the specified text in a pop-up dialog with a local event loop. 00330 * This is useful for help texts. 00331 * 'richText' indicates if YRichText formatting should be applied. 00332 **/ 00333 static void showText( const std::string & text, bool richText = false ); 00334 00335 /** 00336 * Show the help text for the specified widget. If it doesn't have one, 00337 * traverse up the widget hierarchy until there is one. 00338 * 00339 * If there is a help text, it is displayed in a pop-up dialog with a local 00340 * event loop. 00341 * 00342 * This returns 'true' on success (there was a help text) and 'false' on 00343 * failure (no help text). 00344 **/ 00345 static bool showHelpText( YWidget * widget ); 00346 00347 00348 protected: 00349 00350 /** 00351 * Internal open() method. This is called (exactly once during the life 00352 * time of the dialog) in open(). 00353 * 00354 * Derived classes are required to implement this to do whatever is 00355 * necessary to make this dialog visible on the screen. 00356 **/ 00357 virtual void openInternal() = 0; 00358 00359 /** 00360 * Wait for a user event. 00361 * 00362 * Derived classes are required to implement this. 00363 **/ 00364 virtual YEvent * waitForEventInternal( int timeout_millisec ) = 0; 00365 00366 /** 00367 * Check if a user event is pending. If there is one, return it. 00368 * If there is none, do not wait for one - return 0. 00369 * 00370 * Derived classes are required to implement this. 00371 **/ 00372 virtual YEvent * pollEventInternal() = 0; 00373 00374 /** 00375 * Filter out invalid events: Return 0 if the event does not belong to this 00376 * dialog or the unchanged event if it does. 00377 **/ 00378 YEvent * filterInvalidEvents( YEvent * event ); 00379 00380 /** 00381 * Call the installed event filters. 00382 **/ 00383 YEvent * callEventFilters( YEvent * event ); 00384 00385 /** 00386 * Delete all (remaining) event filters. 00387 **/ 00388 void deleteEventFilters(); 00389 00390 /** 00391 * Stack holding all currently existing dialogs. 00392 **/ 00393 static std::stack<YDialog *> _dialogStack; 00394 00395 private: 00396 00397 ImplPtr<YDialogPrivate> priv; 00398 }; 00399 00400 00401 #endif // YDialog_h