libyui-qt  2.49.16
YQUI.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: YQUI.h
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 #ifndef YQUI_h
26 #define YQUI_h
27 
28 #include <qapplication.h>
29 #include <QMap>
30 #include <QTimer>
31 #include <QIcon>
32 #include <vector>
33 #include <type_traits>
34 
35 #include <yui/YUI.h>
36 #include <yui/YSimpleEventHandler.h>
37 #include <yui/YCommandLine.h>
38 
39 #define YQWidgetMargin 4
40 #define YQWidgetSpacing 4
41 #define YQButtonBorder 3
42 
43 //! The class of a pointer expression.
44 // To be used in connect(foo, &pclass(foo)::mysignal, bar, &pclass(bar)::myslot);
45 // That checks types at compile time,
46 // unlike the string based SIGNAL and SLOT macros.
47 #define pclass(ptr) std::remove_reference<decltype(*ptr)>::type
48 
49 
50 class QCursor;
51 class QFrame;
52 class QStackedWidget;
53 class YEvent;
55 class YQWidgetFactory;
56 class YQApplication;
57 class YQUISignalReceiver;
58 
59 using std::string;
60 using std::vector;
61 
62 class YQUI: public YUI
63 {
64  friend class YQUISignalReceiver;
65 
66 public:
67 
68  /**
69  * Constructor.
70  **/
71  YQUI( bool withThreads );
72 
73  /**
74  * Destructor.
75  **/
76  virtual ~YQUI();
77 
78  /**
79  * Access the global Qt-UI.
80  **/
81  static YQUI * ui() { return _ui; }
82 
83  /**
84  * Post-constructor initialization. If running with threads, this has to be
85  * called in the UI thread. Any subsequent calls will do nothing.
86  **/
87  void initUI();
88 
89 protected:
90  /**
91  * Create the widget factory that provides all the createXY() methods for
92  * standard (mandatory, i.e. non-optional) widgets.
93  *
94  * Reimplemented from YUI.
95  **/
96  virtual YWidgetFactory * createWidgetFactory();
97 
98  /**
99  * Create the widget factory that provides all the createXY() methods for
100  * optional ("special") widgets and the corresponding hasXYWidget()
101  * methods.
102  *
103  * Reimplemented from YUI.
104  **/
105  virtual YOptionalWidgetFactory * createOptionalWidgetFactory();
106 
107  /*
108  * Create the YApplication object that provides global methods.
109  *
110  * Reimplemented from YUI.
111  **/
112  virtual YApplication * createApplication();
113 
114 public:
115 
116  /**
117  * Return the global YApplication object as YQApplication.
118  *
119  * This will create the Y(Q)Application upon the first call and return a
120  * pointer to the one and only (singleton) Y(Q)Application upon each
121  * subsequent call. This may throw exceptions if the Y(Q)Application
122  * cannot be created.
123  **/
124  static YQApplication * yqApp();
125 
126  /**
127  * Widget event handlers (slots) call this when an event occured that
128  * should be the answer to a UserInput() / PollInput() (etc.) call.
129  *
130  * The UI assumes ownership of the event object that 'event' points to.
131  * In particular, it takes care to delete that object.
132  *
133  * It is an error to pass 0 for 'event'.
134  **/
135  void sendEvent( YEvent * event );
136 
137  /**
138  * Returns 'true' if there is any event pending for the specified widget.
139  **/
140  bool eventPendingFor( YWidget * widget ) const
141  { return _eventHandler.eventPendingFor( widget ); }
142 
143  /**
144  * Returns the last event that isn't processed yet or 0 if there is none.
145  *
146  * The Qt UI keeps track of only one single (the last one) event.
147  **/
148  YEvent * pendingEvent() const { return _eventHandler.pendingEvent(); }
149 
150  /**
151  * Return the pending event, if there is one, and mark it as "consumed".
152  *
153  * This returns 0 if there is no pending event.
154  **/
155  YEvent * consumePendingEvent() { return _eventHandler.consumePendingEvent(); }
156 
157  /**
158  * Notification that a widget is being deleted.
159  *
160  * Reimplemented from YUI.
161  **/
162  virtual void deleteNotify( YWidget * widget );
163 
164  /**
165  * Return 'true' if defaultsize windows should use the full screen.
166  **/
167  bool fullscreen() const { return _fullscreen; }
168 
169  /**
170  * Return 'true' if defaultsize windows should not get window manager
171  * borders / frames.
172  **/
173  bool noBorder() const { return _noborder; }
174  /**
175  * Returns 'true' if the UI had a fatal error that requires the application
176  * to abort.
177  **/
178  bool fatalError() const { return _fatalError; }
179 
180  /**
181  * Raise a fatal UI error. It will be delivered when it is safe to do so.
182  * The caller should make sure it can continue for some time until the
183  * error is delivered.
184  **/
185  void raiseFatalError() { _fatalError = true; }
186 
187  /**
188  * Returns size for `opt(`defaultsize) dialogs (in one dimension).
189  **/
190  int defaultSize( YUIDimension dim ) const;
191 
192  /**
193  * Make a screen shot in .png format and save it to 'filename'.
194  * Opens a file selection box if 'filename' is empty.
195  **/
196  void makeScreenShot( std::string filename );
197 
198  /**
199  * UI-specific runPkgSeleciton method: Start the package selection.
200  * This implementation does the same as UserInput().
201  *
202  * Reimplemented from YUI.
203  **/
204  virtual YEvent * runPkgSelection( YWidget * packageSelector );
205 
206  /**
207  * Toggle macro recording (activated by Ctrl-Shift-Alt-M):
208  * Stop macro recording if it is in progress,
209  * open a file selection box and ask for a macro file name to save to and
210  * start recording if no recording has been in progress.
211  **/
212  void toggleRecordMacro();
213 
214  /**
215  * Open file selection box and ask for a macro file to play
216  * (activated by Ctrl-Shift-Alt-P)
217  **/
218  void askPlayMacro();
219 
220  /**
221  * Open a pop-up dialog to ask the user for a widget ID and then send it
222  * with sendWidgetID().
223  **/
224  void askSendWidgetID();
225 
226  /**
227  * Block (or unblock) events. If events are blocked, any event sent
228  * should be ignored until events are unblocked again.
229  *
230  * Reimplemented from YUI.
231  **/
232  virtual void blockEvents( bool block = true );
233 
234  /**
235  * Returns 'true' if events are currently blocked.
236  *
237  * Reimplemented from YUI.
238  **/
239  virtual bool eventsBlocked() const;
240 
241  /**
242  * Force unblocking all events, no matter how many times blockEvents() has
243  * This returns 0 if there is no pending eventbeen called before.
244  **/
245  void forceUnblockEvents();
246 
247  /**
248  * Show mouse cursor indicating busy state.
249  **/
250  void busyCursor();
251 
252  /**
253  * Show normal mouse cursor not indicating busy status.
254  **/
255  void normalCursor();
256 
257  /**
258  * Show mouse cursor indicating busy state if the UI is unable to respond
259  * to user input for more than a predefined timeout (200 millisec).
260  **/
261  void timeoutBusyCursor();
262 
263  /**
264  * Open file selection box and let the user save y2logs to that location.
265  * (Shift-F8)
266  **/
267  void askSaveLogs();
268 
269  /**
270  * Open dialog to configure logging.
271  * (Shift-F7)
272  **/
273  void askConfigureLogging();
274 
275  /**
276  * Initialize and set a textdomain for gettext()
277  **/
278  static void setTextdomain( const char * domain );
279 
280  /**
281  * Returns the application name for the window title (e.g. "YaST2@hostname")
282  **/
283  QString applicationTitle() { return _applicationTitle; }
284 
285  /**
286  * Sets the application name for the window title
287  **/
288  void setApplicationTitle(const QString & title) { _applicationTitle=title; }
289 
290  /**
291  * Load an icon. This tries several locations:
292  *
293  * - The icon theme from the current desktop
294  * - The compiled-in Qt resources
295  * - An external file
296  *
297  * If the icon does not have a filename extension, the icon theme will try
298  * to append ".svg" and ".png". For the compiled-in Qt resources, there are
299  * aliases specified ("foo" -> "foo.svg"), so it will also work without an
300  * extension.
301  *
302  * For external files, a path and an extension will be necessary.
303  *
304  * If no icon could be loaded, this will return a null QIcon (check with
305  * icon.isNull()), and a warning is logged.
306  **/
307  QIcon loadIcon( const string & iconName ) const;
308 
309 protected:
310 
311  /**
312  * Handle command line args
313  **/
314  void processCommandLineArgs( int argc, char **argv );
315 
316  /**
317  * Probe the X11 display. Throw exception upon failure.
318  * A "-display" command line argument is taken into account.
319  **/
320  void probeX11Display( const YCommandLine & cmdLine );
321 
322  /**
323  * Calculate size of `opt(`defaultsize) dialogs
324  **/
325  void calcDefaultSize();
326 
327  /**
328  * Idle around until fd_ycp is readable and handle repaints.
329  * This is only used when a separate ui thread is running.
330  *
331  * Reimplemented from YUI.
332  **/
333  virtual void idleLoop( int fd_ycp );
334 
335  /**
336  * Destroy whatever needs to be destroyed within the UI thread.
337  *
338  * Reimplemented from YUI.
339  **/
340  virtual void uiThreadDestructor();
341 
342  /**
343  * Notification that a YCP command has been received on fd_ycp
344  * to leave idleLoop()
345  **/
346  void receivedYCPCommand();
347 
348  /**
349  * Application shutdown
350  **/
351  bool close();
352 
353 
354  //
355  // Data members
356  //
357 
358  static YQUI * _ui;
359 
360  QMap<QString, int> screenShotNo;
361  QString screenShotNameTemplate;
362 
363  bool _fullscreen;
364  bool _noborder;
365  QSize _defaultSize;
366 
367  bool _do_exit_loop;
368  bool _received_ycp_command;
369  bool _fatalError;
370 
371  QTimer * _busyCursorTimer;
372 
373  YSimpleEventHandler _eventHandler;
374  int _blockedLevel;
375 
376  bool _leftHandedMouse;
377  bool _askedForLeftHandedMouse;
378 
379  bool _uiInitialized;
380 
381  YQUISignalReceiver * _signalReceiver;
382  QString _applicationTitle;
383 
384  // Qt copies the _reference_ to argc, so we need to store argc
385  int _ui_argc;
386 };
387 
388 
389 /**
390  * Helper class that acts as a Qt signal receiver for YQUI.
391  * YQUI itself cannot be a QObject to avoid problems with starting up the UI
392  * with multiple threads.
393  **/
394 class YQUISignalReceiver : public QObject
395 {
396  Q_OBJECT
397 
398 public:
400 
401 public slots:
402 
403  void slotBusyCursor();
404  void slotReceivedYCPCommand();
405 };
406 
407 
408 /**
409  * Create a new UI if there is none yet or return the existing one if there is.
410  *
411  * This is the UI plugin's interface to the outside world, so don't change the
412  * name or signature!
413  **/
414 YUI * createUI( bool withThreads );
415 
416 
417 #endif // YQUI_h
int defaultSize(YUIDimension dim) const
Returns size for opt(defaultsize) dialogs (in one dimension).
Definition: YQUI.cc:576
bool fatalError() const
Returns &#39;true&#39; if the UI had a fatal error that requires the application to abort.
Definition: YQUI.h:178
void receivedYCPCommand()
Notification that a YCP command has been received on fd_ycp to leave idleLoop()
Definition: YQUI.cc:463
bool eventPendingFor(YWidget *widget) const
Returns &#39;true&#39; if there is any event pending for the specified widget.
Definition: YQUI.h:140
static YQApplication * yqApp()
Return the global YApplication object as YQApplication.
Definition: YQUI.cc:257
void askConfigureLogging()
Open dialog to configure logging.
void forceUnblockEvents()
Force unblocking all events, no matter how many times blockEvents() has This returns 0 if there is no...
Definition: YQUI.cc:537
bool noBorder() const
Return &#39;true&#39; if defaultsize windows should not get window manager borders / frames.
Definition: YQUI.h:173
void setApplicationTitle(const QString &title)
Sets the application name for the window title.
Definition: YQUI.h:288
YEvent * pendingEvent() const
Returns the last event that isn&#39;t processed yet or 0 if there is none.
Definition: YQUI.h:148
void makeScreenShot(std::string filename)
Make a screen shot in .png format and save it to &#39;filename&#39;.
void askSaveLogs()
Open file selection box and let the user save y2logs to that location.
virtual YEvent * runPkgSelection(YWidget *packageSelector)
UI-specific runPkgSeleciton method: Start the package selection.
void toggleRecordMacro()
Toggle macro recording (activated by Ctrl-Shift-Alt-M): Stop macro recording if it is in progress...
virtual YOptionalWidgetFactory * createOptionalWidgetFactory()
Create the widget factory that provides all the createXY() methods for optional ("special") widgets a...
Definition: YQUI.cc:362
void askSendWidgetID()
Open a pop-up dialog to ask the user for a widget ID and then send it with sendWidgetID().
Definition: YQUI.cc:602
QString applicationTitle()
Returns the application name for the window title (e.g.
Definition: YQUI.h:283
void calcDefaultSize()
Calculate size of opt(defaultsize) dialogs.
Definition: YQUI.cc:381
QIcon loadIcon(const string &iconName) const
Load an icon.
Definition: YQUI.cc:695
Helper class that acts as a Qt signal receiver for YQUI.
Definition: YQUI.h:394
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
Definition: YQUI.cc:469
YQUI(bool withThreads)
Constructor.
Definition: YQUI.cc:96
virtual void idleLoop(int fd_ycp)
Idle around until fd_ycp is readable and handle repaints.
Definition: YQUI.cc:430
void probeX11Display(const YCommandLine &cmdLine)
Probe the X11 display.
Definition: YQUI.cc:582
virtual void deleteNotify(YWidget *widget)
Notification that a widget is being deleted.
Definition: YQUI.cc:588
void busyCursor()
Show mouse cursor indicating busy state.
Definition: YQUI.cc:551
Definition: YQUI.h:62
void processCommandLineArgs(int argc, char **argv)
Handle command line args.
Definition: YQUI.cc:263
bool fullscreen() const
Return &#39;true&#39; if defaultsize windows should use the full screen.
Definition: YQUI.h:167
YEvent * consumePendingEvent()
Return the pending event, if there is one, and mark it as "consumed".
Definition: YQUI.h:155
Concrete widget factory for mandatory widgets.
virtual void uiThreadDestructor()
Destroy whatever needs to be destroyed within the UI thread.
Definition: YQUI.cc:330
virtual void blockEvents(bool block=true)
Block (or unblock) events.
Definition: YQUI.cc:503
void timeoutBusyCursor()
Show mouse cursor indicating busy state if the UI is unable to respond to user input for more than a ...
Definition: YQUI.cc:567
bool close()
Application shutdown.
Definition: YQUI.cc:594
void normalCursor()
Show normal mouse cursor not indicating busy status.
Definition: YQUI.cc:557
void initUI()
Post-constructor initialization.
Definition: YQUI.cc:122
void askPlayMacro()
Open file selection box and ask for a macro file to play (activated by Ctrl-Shift-Alt-P) ...
virtual ~YQUI()
Destructor.
Definition: YQUI.cc:313
void raiseFatalError()
Raise a fatal UI error.
Definition: YQUI.h:185
static void setTextdomain(const char *domain)
Initialize and set a textdomain for gettext()
Definition: YQUI.cc:489
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:81
Widget factory for optional ("special") widgets.
virtual bool eventsBlocked() const
Returns &#39;true&#39; if events are currently blocked.
Definition: YQUI.cc:545
virtual YWidgetFactory * createWidgetFactory()
Create the widget factory that provides all the createXY() methods for standard (mandatory, i.e.
Definition: YQUI.cc:351