]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/YQUI.h
233b299f6c15cea02b36784f04d7556b49b08ef4
[duncan/yast2-qt4.git] / src / YQUI.h
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:         YQUI.h
14
15   Author:       Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19 #ifndef YQUI_h
20 #define YQUI_h
21
22 #include <qapplication.h>
23 #include <QMap>
24 #include <QTimer>
25 #include <QPalette>
26 #include <vector>
27
28 #include "YSimpleEventHandler.h"
29 #include <YUI.h>
30
31 #define YQWidgetMargin  4
32 #define YQWidgetSpacing 4
33 #define YQButtonBorder  3
34
35 class QY2Styler;
36 class QCursor;
37 class QFrame;
38 class QStackedWidget;
39 class QY2Settings;
40 class YEvent;
41 class YQOptionalWidgetFactory;
42 class YQPackageSelectorPlugin;
43 class YQWidgetFactory;
44 class YQApplication;
45
46 using std::string;
47 using std::vector;
48
49
50 class YQUI: public QObject, public YUI
51 {
52     Q_OBJECT
53 public:
54
55     /**
56      * Constructor.
57      **/
58     YQUI( int           argc,
59           char **       argv,
60           bool          with_threads,
61           const char *  macro_file );
62
63     /**
64      * Destructor.
65      **/
66     ~YQUI();
67
68     /**
69      * Access the global Qt-UI.
70      **/
71     static YQUI * ui() { return _ui; }
72
73
74 protected:
75     /**
76      * Create the widget factory that provides all the createXY() methods for
77      * standard (mandatory, i.e. non-optional) widgets.
78      *
79      * Reimplemented from YUI.
80      **/
81     virtual YWidgetFactory * createWidgetFactory();
82
83     /**
84      * Create the widget factory that provides all the createXY() methods for
85      * optional ("special") widgets and the corresponding hasXYWidget()
86      * methods.
87      *
88      * Reimplemented from YUI.
89      **/
90     virtual YOptionalWidgetFactory * createOptionalWidgetFactory();
91
92     /*
93      * Create the YApplication object that provides global methods.
94      *
95      * Reimplemented from YUI.
96      **/
97     virtual YApplication * createApplication();
98
99 public:
100
101     /**
102      * Return the global YApplication object as YQApplication.
103      *
104      * This will create the Y(Q)Application upon the first call and return a
105      * pointer to the one and only (singleton) Y(Q)Application upon each
106      * subsequent call.  This may throw exceptions if the Y(Q)Application
107      * cannot be created.
108      **/
109     static YQApplication * yqApp();
110
111     /**
112      * Widget event handlers (slots) call this when an event occured that
113      * should be the answer to a UserInput() / PollInput() (etc.) call.
114      *
115      * The UI assumes ownership of the event object that 'event' points to.
116      * In particular, it takes care to delete that object.
117      *
118      * It is an error to pass 0 for 'event'.
119      **/
120     void sendEvent( YEvent * event );
121
122     /**
123      * Returns 'true' if there is any event pending for the specified widget.
124      **/
125     bool eventPendingFor( YWidget * widget ) const
126         { return _event_handler.eventPendingFor( widget ); }
127
128     /**
129      * Returns the last event that isn't processed yet or 0 if there is none.
130      *
131      * The Qt UI keeps track of only one single (the last one) event.
132      **/
133     YEvent * pendingEvent() const { return _event_handler.pendingEvent(); }
134
135     /**
136      * Return 'true' if defaultsize windows should use the full screen.
137      **/
138     bool fullscreen() const { return _fullscreen; }
139
140     /**
141      * Return 'true' if defaultsize windows should not get window manager
142      * borders / frames. 
143      **/
144     bool noBorder() const { return _noborder; }
145     /**
146      * Returns 'true' if the UI had a fatal error that requires the application
147      * to abort.
148      **/
149     bool fatalError() const { return _fatal_error; }
150
151     /**
152      * Raise a fatal UI error. It will be delivered when it is safe to do so.
153      * The caller should make sure it can continue for some time until the
154      * error is delivered.
155      **/
156     void raiseFatalError() { _fatal_error = true; }
157
158     /**
159      * Returns size for `opt(`defaultsize) dialogs (in one dimension).
160      **/
161     int defaultSize( YUIDimension dim ) const;
162
163     /**
164      * Make a screen shot in .png format and save it to 'filename'.
165      * Opens a file selection box if 'filename' is empty.
166      **/
167     void makeScreenShot( string filename );
168
169     /**
170      * UI-specific runPkgSeleciton method: Start the package selection.
171      * This implementation does the same as UserInput().
172      *
173      * Reimplemented from YUI.
174      **/
175     YCPValue runPkgSelection( YWidget * packageSelector );
176
177     /**
178      * Toggle macro recording (activated by Ctrl-Shift-Alt-M):
179      * Stop macro recording if it is in progress,
180      * open a file selection box and ask for a macro file name to save to and
181      * start recording if no recording has been in progress.
182      **/
183     void toggleRecordMacro();
184
185     /**
186      * Open file selection box and ask for a macro file to play
187      * (activated by Ctrl-Shift-Alt-P)
188      **/
189     void askPlayMacro();
190
191     /**
192      * Issue an internal error: Open popup with that message and wait.
193      *
194      * Reimplemented from YUI.
195      **/
196     void internalError( const char * msg );
197
198     /**
199      * Block (or unblock) events. If events are blocked, any event sent
200      * should be ignored until events are unblocked again.
201      *
202      * Reimplemented from YUI.
203      **/
204     virtual void blockEvents( bool block = true );
205
206     /**
207      * Returns 'true' if events are currently blocked.
208      *
209      * Reimplemented from YUI.
210      **/
211     virtual bool eventsBlocked() const;
212
213     /**
214      * Returns the current product name
215      * ("SuSE Linux", "SuSE Linux Enterprise Server", "United Linux", etc.)
216      * as QString.
217      **/
218     QString productName() const;
219
220     /**
221      * Beep - activate the system (X11) bell.
222      *
223      * Reimplemented from YUI.
224      **/
225     void beep();
226
227
228 public slots:
229
230     /**
231      * Show hourglass cursor.
232      *
233      * Reimplemented from YUI.
234      **/
235     void busyCursor();
236
237     /**
238      * Show pointer cursor.
239      *
240      * Reimplemented from YUI.
241      **/
242     void normalCursor();
243
244     /**
245      * Open file selection box and let the user Save y2logs to that location.
246      * (Shift-F8)
247      **/
248     void askSaveLogs();
249
250     /**
251      * Open dialog to configure logging.
252      * (Shift-F7)
253      **/
254     void askConfigureLogging();
255
256     /**
257      * A mouse click with the wrong mouse button was detected - e.g., a right
258      * click on a push button. The user might be left-handed, but his mouse
259      * might not (yet) be configured for left-handed use - e.g., during
260      * installation. Ask him if he would like his mouse temporarily configured
261      * as a left-handed mouse.
262      *
263      * This status can be queried with UI::GetDisplayInfo() ("LeftHandedMouse").
264      **/
265     void maybeLeftHandedUser();
266
267
268 protected:
269
270     /**
271      * Idle around until fd_ycp is readable and handle repaints.
272      * This is only used when a separate ui thread is running.
273      *
274      * Reimplemented from YUI.
275      **/
276     void idleLoop( int fd_ycp );
277
278     /**
279      * Return a representation for the glyph symbol specified in UTF-8 encoding
280      * or an empty string to get a default textual representation.
281      *
282      * Reimplemented from YUI.
283      **/
284     YCPString glyph( const YCPSymbol & glyphSymbol );
285
286     /**
287      * Go into event loop until next user input is available.
288      *
289      * Reimplemented from YUI.
290      **/
291     YEvent * userInput( unsigned long timeout_millisec = 0 );
292
293     /**
294      * Check the event queue for user input. Don't wait.
295      *
296      * Reimplemented from YUI.
297      **/
298     YEvent * pollInput();
299
300     /**
301      * Show and activate a dialog.
302      *
303      * Reimplemented from YUI.
304      **/
305     void showDialog( YDialog * dialog );
306
307     /**
308      * Decativate and close a dialog. This does not delete the dialog yet.
309      *
310      * Reimplemented from YUI.
311      **/
312     void closeDialog( YDialog * dialog );
313
314
315 public:
316
317     /**
318      *
319      * Open a directory selection box and prompt the user for an existing directory.
320      * [Reimplemented from YUI]
321      *
322      * 'startDir' is the initial directory that is displayed.
323      *
324      * 'headline' is an explanatory text for the directory selection box.
325      * Graphical UIs may omit that if no window manager is running.
326      *
327      * Returns the selected directory name
328      * or 'nil' (YCPVoid() ) if the user canceled the operation.
329      **/
330     YCPValue askForExistingDirectory ( const YCPString & startDir,
331                                        const YCPString & headline );
332
333     /**
334      * Open a file selection box and prompt the user for an existing file.
335      * [Reimplemented from YUI]
336      *
337      * 'startWith' is the initial directory or file.
338      *
339      * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
340      *
341      * 'headline' is an explanatory text for the file selection box.
342      * Graphical UIs may omit that if no window manager is running.
343      *
344      * Returns the selected file name
345      * or 'nil' (YCPVoid() ) if the user canceled the operation.
346      **/
347     YCPValue askForExistingFile ( const YCPString & startWith,
348                                   const YCPString & filter,
349                                   const YCPString & headline );
350
351     /**
352      * Open a file selection box and prompt the user for a file to save data to.
353      * Automatically asks for confirmation if the user selects an existing file.
354      * [Reimplemented from YUI]
355      *
356      * 'startWith' is the initial directory or file.
357      *
358      * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
359      *
360      * 'headline' is an explanatory text for the file selection box.
361      * Graphical UIs may omit that if no window manager is running.
362      *
363      * Returns the selected file name
364      * or 'nil' (YCPVoid() ) if the user canceled the operation.
365      **/
366     YCPValue askForSaveFileName ( const YCPString & startWith,
367                                   const YCPString & filter,
368                                   const YCPString & headline );
369
370     /**
371      * Lower-level version that works with QStrings and does not change
372      * the mouse cursor.
373      **/
374     QString askForSaveFileName( const QString & startWith,
375                                 const QString & filter,
376                                 const QString & headline );
377
378     /**
379      * Initialize and set a textdomain for gettext()
380      **/
381     static void setTextdomain( const char * domain );
382
383     /**
384      * Returns a high-contrast color palette suitable for vision impaired users.
385      **/
386     static QPalette visionImpairedPalette();
387
388     /**
389      * Returns the normal color palette
390      **/
391     QPalette normalPalette() const { return _normalPalette; }
392
393     /**
394      * Toggle between the vision impaired and the normal color palette.
395      **/
396     void toggleVisionImpairedPalette();
397
398     /**
399      * Returns 'true' if high-contrast colors for vision impaired users is in use.
400      * This should be queried at other places before using custom colors.
401      **/
402     bool usingVisionImpairedPalette() const { return _usingVisionImpairedPalette; }
403
404     /**
405      * Convert logical layout spacing units into device dependent units.
406      * A default size dialog is assumed to be 80x25 layout spacing units
407      * and 640x480 device dependent spacing units.
408      *
409      * Reimplemented from YUI.
410      **/
411     virtual int deviceUnits( YUIDimension dim, float layout_units );
412
413     /**
414      * Convert device dependent units into logical layout spacing units.
415      * A default size dialog is assumed to be 80x25 layout spacing units
416      * and 640x480 device dependent spacing units.
417      *
418      * Reimplemented from YUI.
419      **/
420     virtual float layoutUnits( YUIDimension dim, int device_units );
421
422     /**
423      * Returns the package selector plugin singleton of this UI or creates it
424      * (including loading the plugin lib) if it does not exist yet.
425      **/
426     YQPackageSelectorPlugin * packageSelectorPlugin();
427
428
429 protected:
430
431     /**
432      * Display capabilities.
433      * [Reimplemented from YUI]
434      * See UI builtin GetDisplayInfo() doc for details.
435      **/
436     int  getDisplayWidth();
437     int  getDisplayHeight();
438     int  getDisplayDepth();
439     long getDisplayColors();
440     int  getDefaultWidth();
441     int  getDefaultHeight();
442     bool textMode()                     { return false; }
443     bool hasImageSupport()              { return true;  }
444     bool hasLocalImageSupport()         { return true;  }
445     bool hasAnimationSupport()          { return true;  }
446     bool hasIconSupport()               { return false; }       // not yet
447     bool hasFullUtf8Support()           { return true;  }
448     bool richTextSupportsTable()        { return true; }
449     bool leftHandedMouse()              { return _leftHandedMouse; }
450
451
452     QMap<QString, int>  screenShotNo;
453     QString             screenShotNameTemplate;
454
455 protected slots:
456
457     /**
458      * Application shutdown
459      **/
460     bool close();
461
462     /**
463      * Timeout during TimeoutUserInput() / WaitForEvent()
464      **/
465     void userInputTimeout();
466
467 protected:
468
469     /**
470      * Handle command line args
471      **/
472     void processCommandLineArgs( int argc, char **argv );
473
474     /**
475      * Calculate size of `opt(`defaultsize) dialogs
476      **/
477     void calcDefaultSize();
478
479   void init_ui();
480
481     //
482     // Data members
483     //
484
485     /**
486      * Use the entire available screen
487      **/
488     bool _fullscreen;
489
490     /**
491      * No window border for the main window
492      **/
493     bool _noborder;
494
495     /**
496      * Container for the widget stack. QWidgetStack cannot handle a WFlags
497      * argument, so this needs to be embedded into something else - and a QVBox
498      * at least handles all the sizeHint and resize stuff.
499      **/
500     QWidget * _main_win;
501
502     /**
503      * Size for `opt(`defaultsize) dialogs.
504      **/
505     QSize _default_size;
506
507     /**
508      * This flag is set during @ref #userInput in order to tell
509      * @ref #returnNow to call exit_loop, which only may be called
510      * after enter_loop.
511      **/
512     bool _do_exit_loop;
513
514     /**
515      * Event loop object. Required since a YaST2 UI needs to react to commands
516      * from the YCP command stream as well as to X11 / Qt events.
517      **/
518     QEventLoop * _eventLoop;
519
520     /*
521      * Global reference to the UI
522      **/
523     static YQUI * _ui;
524
525     /**
526      * Indicate a fatal error that requires the UI to terminate
527      **/
528     bool _fatal_error;
529
530     /**
531      * Timer for TimeoutUserInput() / WaitForEvent().
532      **/
533     QTimer _user_input_timer;
534
535     /**
536      * Timer for delayed busy cursor
537      **/
538     QTimer *_busy_cursor_timer;
539
540     /**
541      * The handler for the single pending event this UI keeps track of
542      **/
543     YSimpleEventHandler _event_handler;
544
545     int blocked_level;
546
547     /**
548      * Saved normal palette
549      **/
550     QPalette _normalPalette;
551
552     /**
553      * Flag: currently using special palette for vision impaired users?
554      **/
555     bool _usingVisionImpairedPalette;
556
557     /**
558      * Flag: Does the user want to use a left-handed mouse?
559      **/
560     bool _leftHandedMouse;
561
562     /**
563      * Flag: Was the user already asked if he wants to use a left-handed mouse?
564      **/
565     bool _askedForLeftHandedMouse;
566
567     bool _ui_inited;
568     int _ui_argc;
569     char **_ui_argv;
570
571     /*
572      * Reads the style sheet, parses some comments and passes it to qapp
573      */ 
574     QY2Styler *_styler;
575 };
576
577 #endif // YQUI_h