libyui  3.0.10
/usr/src/RPM/BUILD/libyui-3.0.10/src/YUI.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:         YUI.h
00020 
00021   Author:       Stefan Hundhammer <sh@suse.de>
00022 
00023 /-*/
00024 
00025 #ifndef YUI_h
00026 #define YUI_h
00027 
00028 #include <pthread.h>
00029 #include <string>
00030 
00031 #include "YTypes.h"
00032 #include "YSettings.h"
00033 
00034 class YApplication;
00035 class YWidget;
00036 class YWidgetFactory;
00037 class YOptionalWidgetFactory;
00038 class YEvent;
00039 class YBuiltinCaller;
00040 class YDialog;
00041 class YMacroPlayer;
00042 class YMacroRecorder;
00043 
00044 
00045 /**
00046  * Abstract base class of a libYUI user interface.
00047  **/
00048 class YUI
00049 {
00050     friend class YUIFunction;
00051     friend class YUITerminator;
00052 
00053 protected:
00054     /**
00055      * Constructor.
00056      **/
00057     YUI( bool withThreads );
00058 
00059 public:
00060 
00061     /**
00062      * Destructor.
00063      **/
00064     virtual ~YUI();
00065 
00066     /**
00067      * Shut down multithreading. This needs to be called before the destructor
00068      * if the UI was created with threads. If the UI was created without
00069      * threads, this does nothing.
00070      **/
00071     void shutdownThreads();
00072 
00073     /**
00074      * Access the global UI.
00075      **/
00076     static YUI * ui();
00077 
00078     /**
00079      * Return the widget factory that provides all the createXY() methods for
00080      * standard (mandatory, i.e. non-optional) widgets.
00081      *
00082      * This will create the factory upon the first call and return a pointer to
00083      * the one and only (singleton) factory upon each subsequent call.
00084      * This may throw exceptions if the factory cannot be created.
00085      **/
00086     static YWidgetFactory * widgetFactory();
00087 
00088     /**
00089      * Return the widget factory that provides all the createXY() methods for
00090      * optional ("special") widgets and the corresponding hasXYWidget()
00091      * methods.
00092      *
00093      * This will create the factory upon the first call and return a pointer to
00094      * the one and only (singleton) factory upon each subsequent call.
00095      * This may throw exceptions if the factory cannot be created.
00096      **/
00097     static YOptionalWidgetFactory * optionalWidgetFactory();
00098 
00099     /**
00100      * Return the global YApplication object.
00101      *
00102      * This will create the YApplication upon the first call and return a
00103      * pointer to the one and only (singleton) YApplication upon each
00104      * subsequent call.  This may throw exceptions if the YApplication cannot
00105      * be created.
00106      **/
00107     static YApplication * app();
00108 
00109     /**
00110      * Aliases for YUI::app()
00111      **/
00112     static YApplication * application() { return app(); }
00113     static YApplication * yApp()        { return app(); }
00114 
00115     /**
00116      * Make sure there is a UI (with a UI plug-in) created.
00117      *
00118      * If there is none yet, this will use all-default parameters to load a UI
00119      * plug-in and create a UI (without threads).
00120      **/
00121     static void ensureUICreated();
00122 
00123 
00124 protected:
00125 
00126     /**
00127      * Create the widget factory that provides all the createXY() methods for
00128      * standard (mandatory, i.e. non-optional) widgets.
00129      *
00130      * Derived classes are required to implement this.
00131      **/
00132     virtual YWidgetFactory * createWidgetFactory() = 0;
00133 
00134     /**
00135      * Create the widget factory that provides all the createXY() methods for
00136      * optional ("special") widgets and the corresponding hasXYWidget()
00137      * methods.
00138      *
00139      * Derived classes are required to implement this.
00140      **/
00141     virtual YOptionalWidgetFactory * createOptionalWidgetFactory() = 0;
00142 
00143     /**
00144      * Create the YApplication object that provides global methods.
00145      *
00146      * Derived classes are required to implement this.
00147      **/
00148     virtual YApplication * createApplication() = 0;
00149 
00150 
00151 public:
00152 
00153     /**
00154      * Block (or unblock) events. If events are blocked, any event sent
00155      * should be ignored until events are unblocked again.
00156      *
00157      * This default implementation keeps track of a simple internal flag that
00158      * can be queried with eventsBlocked(), so if you reimplement
00159      * blockEvents(), be sure to reimplement eventsBlocked() as well.
00160      **/
00161     virtual void blockEvents( bool block = true ) { _eventsBlocked = block; }
00162 
00163     /**
00164      * Unblock events previously blocked. This is just an alias for
00165      * blockEvents( false) for better readability.
00166      *
00167      * Note: This method is intentionally not virtual.
00168      **/
00169     void unblockEvents() { blockEvents( false ); }
00170 
00171     /**
00172      * Returns 'true' if events are currently blocked.
00173      *
00174      * Reimplement this if you reimplement blockEvents().
00175      **/
00176     virtual bool eventsBlocked() const { return _eventsBlocked; }
00177 
00178     /**
00179      * Notification that a widget is being deleted.
00180      * This is called from the YWidget destructor.
00181      *
00182      * Derived classes can implement this for any clean-up actions such as
00183      * deleting any events that might be pending for that widget.
00184      **/
00185     virtual void deleteNotify( YWidget * widget ) {}
00186 
00187     /**
00188      * Must be called after the constructor of the Qt/NCurses ui
00189      * is ready. Starts the ui thread.
00190      **/
00191     void topmostConstructorHasFinished();
00192 
00193     /**
00194      * Running with threads?
00195      **/
00196     bool runningWithThreads() const { return _withThreads; }
00197 
00198     /**
00199      * This method implements the UI thread in case it is existing.
00200      * The loop consists of calling idleLoop, getting the next
00201      * command from the @ref YCPUIComponent, evaluating it, which
00202      * possibly invovles calling userInput() or pollInput()
00203      * and writes the answer back to the other thread where the request
00204      * came from.
00205      **/
00206     void uiThreadMainLoop();
00207 
00208     /**
00209      * Return the transparent inter-thread communication.
00210      * This will return 0 until set from the outside.
00211      **/
00212     YBuiltinCaller * builtinCaller() const { return _builtinCaller; }
00213 
00214     /**
00215      * Set the transparent inter-thread communication.
00216      * Built-ins are only really called if there is a valid YBuiltinCaller set.
00217      **/
00218     void setBuiltinCaller( YBuiltinCaller * caller )
00219         { _builtinCaller = caller; }
00220 
00221     /**
00222      * UI-specific runPkgSelection method.
00223      *
00224      * Derived classes are required to implement this.
00225      *
00226      * The packageSelector's dialog will take care of the event and delete it
00227      * when appropriate. The returned pointer is valid until the next call to
00228      * YDialog::userInput(), YDialog::pollInput(), or YUI::runPkgSelection() or
00229      * until the dialog with the packageSelector is destroyed.
00230      **/
00231     virtual YEvent * runPkgSelection( YWidget * packageSelector ) = 0;
00232 
00233 
00234 protected:
00235 
00236     /**
00237      * This virtual method is called when threads are activated in case the
00238      * execution control is currently on the side of the module.  This means
00239      * that no UserInput() or PollInput() is pending. The module just does some
00240      * work. The UI <-> module protocol is in the "UI waits for the next
00241      * command" state. The UI can override this method when it wants to react
00242      * to user input or other external events such as repaint requests from the
00243      * X server.
00244      *
00245      * 'fd_ycp' file descriptor that should be used to determine when
00246      * to leave the idle loop. As soon as it is readable, the loop must
00247      * be left. In order to avoid polling you can combine it with other
00248      * ui-specific fds and do a common select() call.
00249      **/
00250     virtual void idleLoop( int fd_ycp ) = 0;
00251 
00252     /**
00253      * Tells the ui thread that it should terminate and waits
00254      * until it does so.
00255      **/
00256     void terminateUIThread();
00257 
00258     /**
00259      * Creates and launches the ui thread.
00260      **/
00261     void createUIThread();
00262     friend void *start_ui_thread( void *ui_int );
00263 
00264     /**
00265      * Destructor for the UI thread. This will be called as the last thing the
00266      * UI thread does.
00267      *
00268      * Derived classes can overwrite this. In most cases it makes sense to call
00269      * this base class method in the new implementation.
00270      **/
00271     virtual void uiThreadDestructor();
00272 
00273     /**
00274      * Signals the ui thread by sending one byte through the pipe
00275      * to it.
00276      **/
00277     void signalUIThread();
00278 
00279     /**
00280      * Waits for the ui thread to send one byte through the pipe
00281      * to the ycp thread and reads this byte from the pipe.
00282      **/
00283     bool waitForUIThread();
00284 
00285     /**
00286      * Signals the ycp thread by sending one byte through the pipe
00287      * to it.
00288      **/
00289     void signalYCPThread();
00290 
00291     /**
00292      * Waits for the ycp thread to send one byte through the pipe
00293      * to the ycp thread and reads this byte from the pipe.
00294      **/
00295     bool waitForYCPThread();
00296 
00297     /**
00298      * Set the button order (in YButtonBox widgets) from environment
00299      * variables:
00300      *
00301      *     $Y2_BUTTON_ORDER="KDE"
00302      *     $Y2_BUTTON_ORDER="Gnome"
00303      *
00304      * (all case insensitive)
00305      **/
00306     void setButtonOrderFromEnvironment();
00307 
00308 
00309     //
00310     // Data members
00311     //
00312 
00313     /**
00314      * true if a seperate UI thread is created
00315      **/
00316     bool _withThreads;
00317 
00318     /**
00319      * Handle to the ui thread.
00320      **/
00321     pthread_t _uiThread;
00322 
00323     /**
00324      * Inter-thread communication between the YCP thread and the UI thread:
00325      * The YCP thread supplies data here and signals the UI thread,
00326      * the UI thread picks up the data, executes the function, puts
00327      * the result here and signals the YCP thread that waits until
00328      * the result is available.
00329      **/
00330     YBuiltinCaller * _builtinCaller;
00331 
00332     /**
00333      * Used to synchronize data transfer with the ui thread.
00334      * It stores a pair of file descriptors of a pipe. For each YCP value
00335      * we send to the ui thread, we write one aribrary byte here.
00336      **/
00337     int pipe_to_ui[2];
00338 
00339     /**
00340      * Used to synchronize data transfer with the ui thread.
00341      * It stores a pair of file descriptors of a pipe. For each YCP value
00342      * we get from the ui thread, we read one aribrary byte from here.
00343      **/
00344     int pipe_from_ui[2];
00345 
00346     /**
00347      * This is a flag that signals the ui thread that it should
00348      * terminate. This is done by setting the flag to true. The ui
00349      * thread replies by setting the flag back to false directly
00350      * after terminating itself.
00351      **/
00352     bool _terminate_ui_thread;
00353 
00354     /**
00355      * Flag that keeps track of blocked events.
00356      * Never query this directly, use eventsBlocked() instead.
00357      **/
00358     bool _eventsBlocked;
00359 
00360 private:
00361 
00362     static YUI * _ui;
00363 };
00364 
00365 
00366 
00367 #endif // YUI_h
 All Classes Functions Variables Enumerations Friends