libyui  3.0.10
/usr/src/RPM/BUILD/libyui-3.0.10/src/YDialog.h
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
 All Classes Functions Variables Enumerations Friends