libyui  3.0.10
/usr/src/RPM/BUILD/libyui-3.0.10/src/YWidget.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:         YWidget.h
00020 
00021   Author:       Stefan Hundhammer <sh@suse.de>
00022 
00023 /-*/
00024 
00025 #ifndef YWidget_h
00026 #define YWidget_h
00027 
00028 #include <string>
00029 #include <iosfwd>
00030 
00031 #include "YTypes.h"
00032 #include "YProperty.h"
00033 #include "YUISymbols.h"
00034 #include "YUIException.h"
00035 #include "YChildrenManager.h"
00036 #include "ImplPtr.h"
00037 
00038 
00039 class YDialog;
00040 class YWidgetID;
00041 class YMacroRecorder;
00042 
00043 
00044 typedef YChildrenManager<YWidget>       YWidgetChildrenManager;
00045 typedef YSingleChildManager<YWidget>    YSingleWidgetChildManager;
00046 typedef YChildrenRejector<YWidget>      YWidgetChildrenRejector;
00047 
00048 class YWidgetPrivate;
00049 
00050 
00051 /**
00052  * Abstract base class of all UI widgets
00053  **/
00054 class YWidget
00055 {
00056 protected:
00057     /**
00058      * Constructor.
00059      **/
00060     YWidget( YWidget * parent );
00061 
00062 public:
00063     /**
00064      * Destructor.
00065      **/
00066     virtual ~YWidget();
00067 
00068     /**
00069      * Returns a descriptive name of this widget class for logging,
00070      * debugging etc.
00071      **/
00072     virtual const char * widgetClass() const { return "YWidget"; }
00073 
00074     /**
00075      * Returns a descriptive label of this widget instance.
00076      *
00077      * This default implementation returns this widget's "shortcut property"
00078      * (possibly trunctated to avoid over-long texts) - the property that
00079      * contains the keyboard shortcut used to activate this widget or to move
00080      * the keyboard focus to it. In most cases this is this widget's label.
00081      *
00082      * Note: This is usually translated to the user's target language.
00083      * This makes this useful for debugging only.
00084      **/
00085     virtual std::string debugLabel() const;
00086 
00087     /**
00088      * Return the help text for this widget.
00089      **/
00090     std::string helpText() const;
00091 
00092     /**
00093      * Set a help text for this widget.
00094      *
00095      * Currently, the UI does not do anything with this text but store it.
00096      * Displaying the text at a convenient time is currently the application's
00097      * responsibility. This may change in future versions.
00098      **/
00099     void setHelpText( const std::string & helpText );
00100 
00101 
00102     //
00103     // Property Management
00104     //
00105 
00106     /**
00107      * Return this class's property set.
00108      * This also initializes the property upon the first call.
00109      *
00110      * Derived classes should reimplement this.
00111      *
00112      * Remember to add the base class's property set to your own
00113      * in reimplemented versions, e.g.:
00114      *
00115      *     const YPropertySet &
00116      *     MyWidgetClass::propertySet()
00117      *     {
00118      *         static YPropertySet propSet;
00119      *
00120      *         if ( propSet.isEmpty() )
00121      *         {
00122      *             // Add properties for the derived class
00123      *             propSet.add( YProperty( YUIProperty_Value, YStringProperty ) );
00124      *             propSet.add( YProperty( YUIProperty_Label, YStringProperty ) );
00125      *
00126      *             // Add base class properties
00127      *             propSet.add( YWidget::propertySet() );
00128      *         }
00129      *
00130      *         return propSet;
00131      *     }
00132      *
00133      * Otherwise the base class's properties will not be available in the
00134      * derived class. It is also important that the base class's properties
00135      * are added after those of the derived class so the derived class's
00136      * properties have priority over those of the base class.
00137      **/
00138     virtual const YPropertySet & propertySet();
00139 
00140     /**
00141      * Set a property. Derived classes need to implement this.
00142      *
00143      * This method may throw exceptions, for example
00144      *   - if there is no property with that name
00145      *   - if the expected type and the type mismatch
00146      *   - if the value is out of range
00147      *
00148      * This function returns 'true' if the value was successfully set and
00149      * 'false' if that value requires special handling (not in error cases:
00150      * those are covered by exceptions).
00151      **/
00152     virtual bool setProperty( const std::string & propertyName,
00153                               const YPropertyValue & val );
00154 
00155     /**
00156      * Get a property. Derived classes need to implement this.
00157      *
00158      * This method may throw exceptions, for example
00159      *   - if there is no property with that name
00160      **/
00161     virtual YPropertyValue getProperty( const std::string & propertyName );
00162 
00163 
00164     //
00165     // Children Management
00166     //
00167     // Even though many widget classes are leaf classes and thus cannot have
00168     // children by design, it makes sense to have the children management in
00169     // this base class: Then descending down a widget tree is transparent to
00170     // the outside without the need to check for container widget classes,
00171     // casting to those container widget classes and only calling child
00172     // management methods in that case.
00173     //
00174     // By default, YWidget and derived classes have a YWidgetChildrenRejector
00175     // as their children manager, i.e. any attempt to add a child will result
00176     // in a YUITooManyChildrenException.
00177     //
00178     // Derived classes that can (semantically) handle children should set the
00179     // children manager to one of
00180     //
00181     // - YWidgetChildrenManager: handles any number of child widgets;
00182     //   useful for VBox / HBox
00183     //
00184     // - YSingleWidgetChildManager: handles exactly one child
00185     //   useful for widgets like Alignment, Frame, Dialog
00186     //
00187 
00188 
00189     /**
00190      * Returns 'true' if this widget has any children.
00191      **/
00192     bool hasChildren() const
00193         { return childrenManager()->hasChildren(); }
00194 
00195     /**
00196      * Returns the first child or 0 if there is none.
00197      * Useful mostly for children managers that handle only one child.
00198      **/
00199     YWidget * firstChild() const
00200         { return childrenManager()->firstChild(); }
00201 
00202     /**
00203      * Returns the last child or 0 if there is none.
00204      **/
00205     YWidget * lastChild() const
00206         { return childrenManager()->lastChild(); }
00207 
00208     /**
00209      * Return an iterator that points to the first child or to childrenEnd() if
00210      * there are no children.
00211      **/
00212     YWidgetListConstIterator childrenBegin() const
00213         { return childrenManager()->begin(); }
00214 
00215     /**
00216      * Return an interator that points after the last child.
00217      **/
00218     YWidgetListConstIterator childrenEnd() const
00219         { return childrenManager()->end(); }
00220 
00221     /**
00222      * Returns the current number of children.
00223      **/
00224     int childrenCount() const { return childrenManager()->count(); }
00225 
00226     /**
00227      * Checks if 'child' is a (direct!) child of this widget.
00228      **/
00229     bool contains( YWidget * child ) const
00230         { return childrenManager()->contains( child ); }
00231 
00232     /**
00233      * Add a new child.
00234      *
00235      * This may throw exceptions if more children are added than this widget
00236      * can handle.
00237      **/
00238     virtual void addChild( YWidget * child );
00239 
00240     /**
00241      * Remove a child. This only removes the child from the children manager's
00242      * list; it does not delete it.
00243      **/
00244     virtual void removeChild( YWidget * child );
00245 
00246     /**
00247      * Delete all children and remove them from the children manager's list.
00248      **/
00249     void deleteChildren();
00250 
00251     /**
00252      * Return this widget's parent or 0 if it doesn't have a parent.
00253      **/
00254     YWidget * parent() const;
00255 
00256     /**
00257      * Return 'true' if this widget has a parent, 'false' if not.
00258      **/
00259     bool hasParent() const;
00260 
00261     /**
00262      * Set this widget's parent.
00263      **/
00264     void setParent( YWidget * newParent );
00265 
00266     /**
00267      * Traverse up the widget hierarchy and find the dialog this widget belongs
00268      * to. Returns 0 if there is none.
00269      **/
00270     YDialog * findDialog();
00271 
00272     /**
00273      * Recursively find a widget by its ID.
00274      * If there is no widget with that ID, this function throws a
00275      * YUIWidgetNotFoundException if 'doThrow' is 'true'. It returns 0 if
00276      * 'doThrow' is 'false'.
00277      **/
00278     YWidget * findWidget( YWidgetID * id, bool doThrow = true ) const;
00279 
00280 
00281     //
00282     // Geometry Management
00283     //
00284 
00285     /**
00286      * Preferred width of the widget.
00287      *
00288      * Derived classes are required to implement this.
00289      **/
00290     virtual int preferredWidth() = 0;
00291 
00292     /**
00293      * Preferred height of the widget.
00294      *
00295      * Derived classes are required to implement this.
00296      **/
00297     virtual int preferredHeight() = 0;
00298 
00299     /**
00300      * Preferred size of the widget in the specified dimension.
00301      * This default implementation calls preferredWidth() or preferredHeight()
00302      * which makes sense for most cases.
00303      *
00304      * Derived classes can reimplement this, but this is discouraged.
00305      *
00306      * Note: Even in that case, preferredWidth() and preferredHeight() need to
00307      * be implemented, but they might then call preferredSize().
00308      **/
00309     virtual int preferredSize( YUIDimension dim );
00310 
00311     /**
00312      * Set the new size of the widget.
00313      *
00314      * Layout manager widgets (like YLayoutBox) call this during geometry
00315      * management after all widgets are queried about their preferred widths
00316      * and heights. Depending on layout constraints, widgets might be resized
00317      * beyond or below their preferred size.
00318      *
00319      * The sizes passed here are not meant to affect any future
00320      * preferredWidth() or preferredHeight() calls; they are just the outcome
00321      * of all kinds of compromises (too little screen space or too much) for
00322      * the current geometry management calculation.
00323      *
00324      * Derived classes are required to implement this function.
00325      **/
00326     virtual void setSize( int newWidth, int newHeight ) = 0;
00327 
00328 
00329     //
00330     // Misc
00331     //
00332 
00333 
00334     /**
00335      * Checks whether or not this object is valid. This is to enable
00336      * dangling pointer error checking (i.e. this object is already
00337      * deallocated, but a pointer to it is still in use).
00338      *
00339      * See also the YUI_CHECK_WIDGET() macro in YUIException.h
00340      **/
00341     bool isValid() const;
00342 
00343     /**
00344      * Check if this widget is in the process of being destroyed.
00345      **/
00346     bool beingDestroyed() const;
00347 
00348     /**
00349      * Return a pointer to the underlying toolkit's (Qt, ...) widget
00350      * representing this abstract UI widget.
00351      **/
00352     void * widgetRep() const;
00353 
00354     /**
00355      * Set the pointer to the underlying toolkit's (Qt, ...) widget
00356      * representing this abstract UI widget.
00357      *
00358      * This pointer might be useful for derived UIs to store a counterpart of
00359      * the toolkit widget in each YWidget. The abstract UI does not need that,
00360      * though; this is purely for the convenience of derived UIs. All the
00361      * abstract UI ever does with that pointer is store it.
00362      **/
00363     void setWidgetRep( void * toolkitWidgetRep );
00364 
00365     /**
00366      * Returns 'true' if this widget has an ID.
00367      **/
00368     bool hasId() const;
00369 
00370     /**
00371      * Returns this widget's ID.
00372      **/
00373     YWidgetID * id() const;
00374 
00375     /**
00376      * Set this widget's ID.
00377      *
00378      * The widget assumes ownership of this ID and will delete it when needed.
00379      * (In the widget's destructor or when a new ID is set)
00380      *
00381      * Widget IDs are purely for application use. C++ applications don't need
00382      * to use them; they are much better off using widget pointers. For other
00383      * languages, though, that can't use C++ pointers (e.g., YCP) it makes
00384      * sense to have widget IDs to identify widgets.
00385      **/
00386     void setId( YWidgetID * newId_disown );
00387 
00388     /**
00389      * Enable or disable this widget, i.e. make it accept or reject user input.
00390      *
00391      * Derived classes should call the base class method to update the internal
00392      *"enabled" flag.
00393      **/
00394     virtual void setEnabled( bool enabled = true );
00395 
00396     /**
00397      * Disable this widget (overloaded for better readability).
00398      **/
00399     void setDisabled() { setEnabled( false); }
00400 
00401     /**
00402      * Returns 'true' if this widget is enabled.
00403      **/
00404     virtual bool isEnabled() const;
00405 
00406     /**
00407      * This is a boolean value that determines whether the widget is resizable
00408      * beyond its preferred size in the specified dimension. A selection box is
00409      * stretchable in both dimensions, a push button is not stretchable by
00410      * default, a frame is stretchable if its contents are stretchable. Most
00411      * widgets accept a `hstretch or `vstretch option to become stretchable
00412      * even when by default they are not.
00413      **/
00414     virtual bool stretchable( YUIDimension dim ) const;
00415 
00416     /**
00417      * Set the stretchable state to "newStretch" regardless of any `hstretch or
00418      * `vstretch options.
00419      **/
00420     void setStretchable( YUIDimension dim, bool newStretch );
00421 
00422     /**
00423      * Set the stretchable state to "newStretch".
00424      * `hstretch or `vstretch options may override this.
00425      **/
00426     void setDefaultStretchable( YUIDimension dim, bool newStretch );
00427 
00428     /**
00429      * The weight is used in situations where all widgets can get their
00430      * preferred size and yet space is available. The remaining space will be
00431      * devided between all stretchable widgets according to their weights. A
00432      * widget with greater weight will get more space. The default weight for
00433      * all widgets is 0.
00434      *
00435      * Derived classes can overwrite this function, but they should call this
00436      * base class function in the new function.
00437      **/
00438     virtual int weight( YUIDimension dim );
00439 
00440     /**
00441      * Return whether or not the widget has a weight in the specified
00442      * dimension.
00443      **/
00444     bool hasWeight( YUIDimension dim );
00445 
00446     /**
00447      * Set a weight in the specified dimension.
00448      **/
00449     void setWeight( YUIDimension dim, int weight );
00450 
00451     /**
00452      * Sets the Notify property
00453      **/
00454     void setNotify( bool notify = true );
00455 
00456     /**
00457      * Returns whether the widget will notify, i.e. will case UserInput to
00458      * return.
00459      **/
00460     bool notify() const;
00461 
00462     /**
00463      * Sets the notifyContextMenu property
00464      **/
00465     void setNotifyContextMenu( bool notifyContextMenu = true );
00466 
00467     /**
00468      * Returns whether the widget will send an event when the user
00469      * clicks selects the context menu e.g. via right click.
00470      **/
00471     bool notifyContextMenu() const;
00472 
00473 
00474     /**
00475      * Returns 'true' if this widget should send key events, i.e. if it has
00476      * `opt(`keyEvent) set.
00477      **/
00478     bool sendKeyEvents() const;
00479 
00480     /**
00481      * Specify whether or not this widget should send key events.
00482      **/
00483     void setSendKeyEvents( bool doSend );
00484 
00485     /**
00486      * Returns 'true' if a keyboard shortcut should automatically be assigned
00487      * to this widget - without complaints in the log file.
00488      **/
00489     bool autoShortcut() const;
00490 
00491     /**
00492      * Sets the 'autoShortcut' flag.
00493      **/
00494     void setAutoShortcut( bool _newAutoShortcut );
00495 
00496     /**
00497      * Return a function key number that is assigned to this widget.
00498      * (1 for F1, 2 for F2, etc.; 0 for none)
00499      **/
00500     int functionKey() const;
00501 
00502     /**
00503      * Check if a function key is assigned to this widget.
00504      **/
00505     bool hasFunctionKey() const;
00506 
00507     /**
00508      * Assign a function key to this widget
00509      * (1 for F1, 2 for F2, etc.; 0 for none)
00510      *
00511      * Derived classes may want to overwrite this function, but they should
00512      * call this base class function in the new function.
00513      **/
00514     virtual void setFunctionKey( int fkey_no );
00515 
00516     /**
00517      * Set the keyboard focus to this widget.
00518      * The default implementation just emits a warning message.
00519      * Overwrite this function for all widgets that can accept the
00520      * keyboard focus.
00521      *
00522      * This function returns true if the widget did accept the
00523      * keyboard focus, and false if not.
00524      **/
00525     virtual bool setKeyboardFocus();
00526 
00527     /**
00528      * Get the string of this widget that holds the keyboard shortcut, if any.
00529      * Most widgets will return label().
00530      *
00531      * Overwrite this for widgets that can have keyboard shortcuts.
00532      **/
00533     virtual std::string shortcutString() const { return std::string( "" ); }
00534 
00535     /**
00536      * Set the string of this widget that holds the keyboard shortcut, if any.
00537      * Most widgets will call setLabel().
00538      *
00539      * Overwrite this for widgets that can have keyboard shortcuts.
00540      **/
00541     virtual void setShortcutString( const std::string & str );
00542 
00543     /**
00544      * The name of the widget property that will return user input, if there is
00545      * any.  Widgets that do have user input (such as InputField, ComboBox,
00546      * SelBox) should overwrite this methods. Widgets that are purely passive
00547      * (such as Label, RichText) should not.
00548      **/
00549     virtual const char * userInputProperty() { return (const char *) 0; }
00550 
00551     /**
00552      * Debugging function:
00553      * Dump the widget tree from here on to the log file.
00554      **/
00555     void dumpWidgetTree( int indentationLevel = 0 );
00556 
00557     /**
00558      * Debugging function:
00559      * Dump the widget tree from this widget's dialog parent.
00560      * If there is no such dialog parent, dump the widget tree from
00561      * here on.
00562      **/
00563     void dumpDialogWidgetTree();
00564 
00565     /**
00566      * Enable or disable all widgets in this widget tree.
00567      **/
00568     void setChildrenEnabled( bool enabled );
00569 
00570     //
00571     // Macro Recorder Support
00572     //
00573 
00574     /**
00575      * Recursively save the user input of all child widgets to a macro
00576      * recorder:
00577      *
00578      * All child widgets that could contain data entered by the user
00579      * are requested to send their contents to the macro recorder, e.g. input
00580      * fields, check boxes etc.
00581      *
00582      * This default implementation records this widget's user input property
00583      * (the property returned by userInputProperty) and then recursively calls
00584      * saveUserInput() for all child widgets. This is suitable for most cases,
00585      * for container widgets as well as for leaf widgets that have no or
00586      * exactly one property that needs to be recorded.
00587      *
00588      * Widgets that need another number of properties recorded should
00589      * reimplement this method (and NOT call this default method in the new
00590      * implementation).
00591      **/
00592     virtual void saveUserInput( YMacroRecorder *macroRecorder );
00593 
00594     /**
00595      * Overloaded operator new to ensure widgets are always created on the
00596      * heap, never on the stack.
00597      *
00598      * Simpler implementations of this have a tendency to be fooled by poorly
00599      * implemented derived classes.
00600      **/
00601     void * operator new( size_t size );
00602 
00603 
00604     // NCurses optimizations
00605 
00606 
00607     /**
00608      * In some UIs updating the screen content is an expensive operation. Use
00609      * startMultipleChanges() to tell the ui that you're going to perform
00610      * multiple chages to the widget.  The UI may delay any screen updates
00611      * until doneMultipleChanges() is called.
00612      **/
00613     virtual void startMultipleChanges() {}
00614     virtual void doneMultipleChanges() {}
00615 
00616 
00617 protected:
00618 
00619     /**
00620      * Returns this widget's children manager.
00621      **/
00622     YWidgetChildrenManager * childrenManager() const;
00623 
00624     /**
00625      * Sets a new children manager for this widget. The widget assumes
00626      * ownership of this children manager and will delete it when appropriate.
00627      *
00628      * The default children manager (a YWidgetChildrenRejector) rejects all
00629      * children. This is useful for leaf widgets such as PushButton, ComboBox
00630      * etc.
00631      *
00632      * Derived classes that can handle children might want to set the children
00633      * manager to a YWidgetChildrenManager (the base class that does not reject
00634      * children) or to a YSingleWidgetChildManager (the class that handles
00635      * exactly one child widget).
00636      **/
00637     void setChildrenManager( YWidgetChildrenManager * manager );
00638 
00639     /**
00640      * Set the "being destroyed" flag, i.e. indicate that this widget is in the
00641      * process of being destroyed. The base class method already sets this, but
00642      * sometimes it might be useful to call this in a derived class's
00643      * destructor so certain optimizations work better.
00644      *
00645      * This status intentionally cannot be reverted to "not being destroyed".
00646      **/
00647      void setBeingDestroyed();
00648 
00649     /**
00650      * Helper function for dumpWidgetTree():
00651      * Dump one widget to the log file.
00652      **/
00653     void dumpWidget( YWidget *w, int indentationLevel );
00654 
00655 
00656 private:
00657 
00658     /**
00659      * Make this widget invalid. This operation cannot be reversed.
00660      **/
00661     void invalidate();
00662 
00663     /**
00664      * Disable copy constructor.
00665      **/
00666     YWidget( const YWidget & other );
00667 
00668     /**
00669      * Disable assignment operator.
00670      **/
00671     const YWidget & operator=( const YWidget & other );
00672 
00673 private:
00674 
00675     //
00676     // Data Members
00677     //
00678 
00679     int                         _magic; // should always be the first member
00680     ImplPtr<YWidgetPrivate>     priv;
00681     static YPropertySet         _propertySet;
00682     static bool                 _usedOperatorNew;
00683 
00684 
00685 #include "YWidget_OptimizeChanges.h"
00686 
00687 };
00688 
00689 
00690 std::ostream & operator<<( std::ostream & stream, const YWidget * widget );
00691 
00692 
00693 #endif // YWidget_h
 All Classes Functions Variables Enumerations Friends