1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
22 #include <qapplication.h>
24 #include <Qt/qtimer.h>
27 #include "YSimpleEventHandler.h"
30 #define YQWidgetMargin 4
31 #define YQWidgetSpacing 4
32 #define YQButtonBorder 3
39 class YQOptionalWidgetFactory;
40 class YQPackageSelectorPlugin;
41 class YQWidgetFactory;
48 class YQUI: public QObject, public YUI
59 const char * macro_file );
67 * Access the global Qt-UI.
69 static YQUI * ui() { return _ui; }
74 * Create the widget factory that provides all the createXY() methods for
75 * standard (mandatory, i.e. non-optional) widgets.
77 * Reimplemented from YUI.
79 virtual YWidgetFactory * createWidgetFactory();
82 * Create the widget factory that provides all the createXY() methods for
83 * optional ("special") widgets and the corresponding hasXYWidget()
86 * Reimplemented from YUI.
88 virtual YOptionalWidgetFactory * createOptionalWidgetFactory();
91 * Create the YApplication object that provides global methods.
93 * Reimplemented from YUI.
95 virtual YApplication * createApplication();
100 * Return the global YApplication object as YQApplication.
102 * This will create the Y(Q)Application upon the first call and return a
103 * pointer to the one and only (singleton) Y(Q)Application upon each
104 * subsequent call. This may throw exceptions if the Y(Q)Application
107 static YQApplication * yqApp();
110 * Widget event handlers (slots) call this when an event occured that
111 * should be the answer to a UserInput() / PollInput() (etc.) call.
113 * The UI assumes ownership of the event object that 'event' points to.
114 * In particular, it takes care to delete that object.
116 * It is an error to pass 0 for 'event'.
118 void sendEvent( YEvent * event );
121 * Returns 'true' if there is any event pending for the specified widget.
123 bool eventPendingFor( YWidget * widget ) const
124 { return _event_handler.eventPendingFor( widget ); }
127 * Returns the last event that isn't processed yet or 0 if there is none.
129 * The Qt UI keeps track of only one single (the last one) event.
131 YEvent * pendingEvent() const { return _event_handler.pendingEvent(); }
134 * Returns 'false" if the "--no-wm" was specified on the command line, i.e.
135 * we should assume no window manager is running.
137 bool haveWM() const { return _have_wm; }
140 * Returns 'true' if defaultsize windows should use the full screen.
142 bool fullscreen() const { return _fullscreen; }
145 * Returns 'false' if toplevel (defaultsize) windows should not get window
146 * manager decorations, i.e. "--noborder" was specified on the command
149 bool decorateToplevelWindow() const { return _decorate_toplevel_window; }
152 * Returns 'true' if the UI had a fatal error that requires the application
155 bool fatalError() const { return _fatal_error; }
158 * Raise a fatal UI error. It will be delivered when it is safe to do so.
159 * The caller should make sure it can continue for some time until the
160 * error is delivered.
162 void raiseFatalError() { _fatal_error = true; }
165 * Returns size for `opt(`defaultsize) dialogs (in one dimension).
167 int defaultSize( YUIDimension dim ) const;
170 * Make a screen shot in .png format and save it to 'filename'.
171 * Opens a file selection box if 'filename' is empty.
173 void makeScreenShot( string filename );
176 * UI-specific runPkgSeleciton method: Start the package selection.
177 * This implementation does the same as UserInput().
179 * Reimplemented from YUI.
181 YCPValue runPkgSelection( YWidget * packageSelector );
184 * Toggle macro recording (activated by Ctrl-Shift-Alt-M):
185 * Stop macro recording if it is in progress,
186 * open a file selection box and ask for a macro file name to save to and
187 * start recording if no recording has been in progress.
189 void toggleRecordMacro();
192 * Open file selection box and ask for a macro file to play
193 * (activated by Ctrl-Shift-Alt-P)
198 * Issue an internal error: Open popup with that message and wait.
200 * Reimplemented from YUI.
202 void internalError( const char * msg );
206 * Block WM_CLOSE events for the main window.
208 void blockWmClose() { _wm_close_blocked = true; }
211 * Unblock WM_CLOSE events for the main window.
213 void unblockWmClose() { _wm_close_blocked = false; }
216 * Check if dialogs are to be activated automatically
218 bool autoActivateDialogs() const { return _auto_activate_dialogs; }
221 * Change automatic dialog activation
223 void setAutoActivateDialogs( bool activate )
224 { _auto_activate_dialogs = activate; }
227 * Block (or unblock) events. If events are blocked, any event sent
228 * should be ignored until events are unblocked again.
230 * Reimplemented from YUI.
232 virtual void blockEvents( bool block = true )
233 { _event_handler.blockEvents( block ); }
236 * Returns 'true' if events are currently blocked.
238 * Reimplemented from YUI.
240 virtual bool eventsBlocked() const
241 { return _event_handler.eventsBlocked(); }
244 * Returns the current product name
245 * ("SuSE Linux", "SuSE Linux Enterprise Server", "United Linux", etc.)
248 QString productName() const;
251 * Beep - activate the system (X11) bell.
253 * Reimplemented from YUI.
261 * Show hourglass cursor.
263 * Reimplemented from YUI.
268 * Show pointer cursor.
270 * Reimplemented from YUI.
275 * Open file selection box and let the user Save y2logs to that location.
281 * Open dialog to configure logging.
284 void askConfigureLogging();
287 * Fun stuff (release dependent)
292 * A mouse click with the wrong mouse button was detected - e.g., a right
293 * click on a push button. The user might be left-handed, but his mouse
294 * might not (yet) be configured for left-handed use - e.g., during
295 * installation. Ask him if he would like his mouse temporarily configured
296 * as a left-handed mouse.
298 * This status can be queried with UI::GetDisplayInfo() ("LeftHandedMouse").
300 void maybeLeftHandedUser();
305 * Emitted upon WM_CLOSE
313 * Idle around until fd_ycp is readable and handle repaints.
314 * This is only used when a separate ui thread is running.
316 * Reimplemented from YUI.
318 void idleLoop( int fd_ycp );
321 * Return a representation for the glyph symbol specified in UTF-8 encoding
322 * or an empty string to get a default textual representation.
324 * Reimplemented from YUI.
326 YCPString glyph( const YCPSymbol & glyphSymbol );
329 * Go into event loop until next user input is available.
331 * Reimplemented from YUI.
333 YEvent * userInput( unsigned long timeout_millisec = 0 );
336 * Check the event queue for user input. Don't wait.
338 * Reimplemented from YUI.
340 YEvent * pollInput();
345 * Reimplemented from YUI.
347 YDialog * createDialog( YWidgetOpt & opt );
350 * Show and activate a dialog.
352 * Reimplemented from YUI.
354 void showDialog( YDialog * dialog );
357 * Decativate and close a dialog. This does not delete the dialog yet.
359 * Reimplemented from YUI.
361 void closeDialog( YDialog * dialog );
364 * Grab show events and work around QWidgetStack bug.
366 * Reimplemented from QObject.
368 bool eventFilter( QObject * obj, QEvent * ev );
371 * Make all UI windows usable without a mouse - even predefined Qt dialogs
372 * that don't know the UI's dialogs' activate() magic.
374 * Reimplemented from QObject.
376 bool showEventFilter( QObject * obj, QEvent * ev );
383 * Open a directory selection box and prompt the user for an existing directory.
384 * [Reimplemented from YUI]
386 * 'startDir' is the initial directory that is displayed.
388 * 'headline' is an explanatory text for the directory selection box.
389 * Graphical UIs may omit that if no window manager is running.
391 * Returns the selected directory name
392 * or 'nil' (YCPVoid() ) if the user canceled the operation.
394 YCPValue askForExistingDirectory ( const YCPString & startDir,
395 const YCPString & headline );
398 * Open a file selection box and prompt the user for an existing file.
399 * [Reimplemented from YUI]
401 * 'startWith' is the initial directory or file.
403 * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
405 * 'headline' is an explanatory text for the file selection box.
406 * Graphical UIs may omit that if no window manager is running.
408 * Returns the selected file name
409 * or 'nil' (YCPVoid() ) if the user canceled the operation.
411 YCPValue askForExistingFile ( const YCPString & startWith,
412 const YCPString & filter,
413 const YCPString & headline );
416 * Open a file selection box and prompt the user for a file to save data to.
417 * Automatically asks for confirmation if the user selects an existing file.
418 * [Reimplemented from YUI]
420 * 'startWith' is the initial directory or file.
422 * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
424 * 'headline' is an explanatory text for the file selection box.
425 * Graphical UIs may omit that if no window manager is running.
427 * Returns the selected file name
428 * or 'nil' (YCPVoid() ) if the user canceled the operation.
430 YCPValue askForSaveFileName ( const YCPString & startWith,
431 const YCPString & filter,
432 const YCPString & headline );
435 * Lower-level version that works with QStrings and does not change
438 QString askForSaveFileName( const QString & startWith,
439 const QString & filter,
440 const QString & headline );
445 QWidget* mainWidget();
448 * Initialize and set a textdomain for gettext()
450 static void setTextdomain( const char * domain );
453 * Returns a high-contrast color palette suitable for vision impaired users.
455 static QPalette visionImpairedPalette();
458 * Returns the normal color palette
460 QPalette normalPalette() const { return _normalPalette; }
463 * Toggle between the vision impaired and the normal color palette.
465 void toggleVisionImpairedPalette();
468 * Returns 'true' if high-contrast colors for vision impaired users is in use.
469 * This should be queried at other places before using custom colors.
471 bool usingVisionImpairedPalette() const { return _usingVisionImpairedPalette; }
474 * Convert logical layout spacing units into device dependent units.
475 * A default size dialog is assumed to be 80x25 layout spacing units
476 * and 640x480 device dependent spacing units.
478 * Reimplemented from YUI.
480 virtual int deviceUnits( YUIDimension dim, float layout_units );
483 * Convert device dependent units into logical layout spacing units.
484 * A default size dialog is assumed to be 80x25 layout spacing units
485 * and 640x480 device dependent spacing units.
487 * Reimplemented from YUI.
489 virtual float layoutUnits( YUIDimension dim, int device_units );
492 * Returns the package selector plugin singleton of this UI or creates it
493 * (including loading the plugin lib) if it does not exist yet.
495 YQPackageSelectorPlugin * packageSelectorPlugin();
501 * Display capabilities.
502 * [Reimplemented from YUI]
503 * See UI builtin GetDisplayInfo() doc for details.
505 int getDisplayWidth();
506 int getDisplayHeight();
507 int getDisplayDepth();
508 long getDisplayColors();
509 int getDefaultWidth();
510 int getDefaultHeight();
511 bool textMode() { return false; }
512 bool hasImageSupport() { return true; }
513 bool hasLocalImageSupport() { return true; }
514 bool hasAnimationSupport() { return true; }
515 bool hasIconSupport() { return false; } // not yet
516 bool hasFullUtf8Support() { return true; }
517 bool richTextSupportsTable() { return true; }
518 bool leftHandedMouse() { return _leftHandedMouse; }
521 QMap<QString, int> screenShotNo;
522 QString screenShotNameTemplate;
527 * Application shutdown
532 * Timeout during TimeoutUserInput() / WaitForEvent()
534 void userInputTimeout();
539 * Handle command line args
541 void processCommandLineArgs( int argc, char **argv );
544 * Calculate size of `opt(`defaultsize) dialogs
546 void calcDefaultSize();
555 * Assume presence of a window manager
560 * Use the entire available screen
565 * Decorate the toplevel window
567 bool _decorate_toplevel_window;
570 * Container for the widget stack. QWidgetStack cannot handle a WFlags
571 * argument, so this needs to be embedded into something else - and a QVBox
572 * at least handles all the sizeHint and resize stuff.
577 * Stack for the Qt widgets inside the main window.
579 QStackedWidget * _widget_stack;
582 * Stack to keep track of the stacking order of popup dialogs.
584 vector<QWidget *> _popup_stack;
587 * Size for `opt(`defaultsize) dialogs.
592 * This flag is set during @ref #userInput in order to tell
593 * @ref #returnNow to call exit_loop, which only may be called
599 * Event loop object. Required since a YaST2 UI needs to react to commands
600 * from the YCP command stream as well as to X11 / Qt events.
602 QEventLoop * _eventLoop;
605 * Window manager close events blocked?
607 bool _wm_close_blocked;
610 * Force new dialogs to the foreground and grab the keyboard focus?
611 * (Only if running without a window manager)
613 bool _auto_activate_dialogs;
616 * Global reference to the UI
621 * Indicate a fatal error that requires the UI to terminate
626 * Timer for TimeoutUserInput() / WaitForEvent().
628 QTimer _user_input_timer;
631 * Timer for delayed busy cursor
633 QTimer *_busy_cursor_timer;
636 * The handler for the single pending event this UI keeps track of
638 YSimpleEventHandler _event_handler;
641 * Saved normal palette
643 QPalette _normalPalette;
646 * Flag: currently using special palette for vision impaired users?
648 bool _usingVisionImpairedPalette;
651 * Flag: Does the user want to use a left-handed mouse?
653 bool _leftHandedMouse;
656 * Flag: Was the user already asked if he wants to use a left-handed mouse?
658 bool _askedForLeftHandedMouse;