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