1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
22 #include <qapplication.h>
28 #include "YSimpleEventHandler.h"
31 #define YQWidgetMargin 4
32 #define YQWidgetSpacing 4
33 #define YQButtonBorder 3
40 class YQOptionalWidgetFactory;
41 class YQPackageSelectorPlugin;
42 class YQWidgetFactory;
49 class YQUI: public QObject, public YUI
60 const char * macro_file );
68 * Access the global Qt-UI.
70 static YQUI * ui() { return _ui; }
75 * Create the widget factory that provides all the createXY() methods for
76 * standard (mandatory, i.e. non-optional) widgets.
78 * Reimplemented from YUI.
80 virtual YWidgetFactory * createWidgetFactory();
83 * Create the widget factory that provides all the createXY() methods for
84 * optional ("special") widgets and the corresponding hasXYWidget()
87 * Reimplemented from YUI.
89 virtual YOptionalWidgetFactory * createOptionalWidgetFactory();
92 * Create the YApplication object that provides global methods.
94 * Reimplemented from YUI.
96 virtual YApplication * createApplication();
101 * Return the global YApplication object as YQApplication.
103 * This will create the Y(Q)Application upon the first call and return a
104 * pointer to the one and only (singleton) Y(Q)Application upon each
105 * subsequent call. This may throw exceptions if the Y(Q)Application
108 static YQApplication * yqApp();
111 * Widget event handlers (slots) call this when an event occured that
112 * should be the answer to a UserInput() / PollInput() (etc.) call.
114 * The UI assumes ownership of the event object that 'event' points to.
115 * In particular, it takes care to delete that object.
117 * It is an error to pass 0 for 'event'.
119 void sendEvent( YEvent * event );
122 * Returns 'true' if there is any event pending for the specified widget.
124 bool eventPendingFor( YWidget * widget ) const
125 { return _event_handler.eventPendingFor( widget ); }
128 * Returns the last event that isn't processed yet or 0 if there is none.
130 * The Qt UI keeps track of only one single (the last one) event.
132 YEvent * pendingEvent() const { return _event_handler.pendingEvent(); }
135 * Returns 'false" if the "--no-wm" was specified on the command line, i.e.
136 * we should assume no window manager is running.
138 bool haveWM() const { return _have_wm; }
141 * Returns 'true' if defaultsize windows should use the full screen.
143 bool fullscreen() const { return _fullscreen; }
146 * Returns 'false' if toplevel (defaultsize) windows should not get window
147 * manager decorations, i.e. "--noborder" was specified on the command
150 bool decorateToplevelWindow() const { return _decorate_toplevel_window; }
153 * Returns 'true' if the UI had a fatal error that requires the application
156 bool fatalError() const { return _fatal_error; }
159 * Raise a fatal UI error. It will be delivered when it is safe to do so.
160 * The caller should make sure it can continue for some time until the
161 * error is delivered.
163 void raiseFatalError() { _fatal_error = true; }
166 * Returns size for `opt(`defaultsize) dialogs (in one dimension).
168 int defaultSize( YUIDimension dim ) const;
171 * Make a screen shot in .png format and save it to 'filename'.
172 * Opens a file selection box if 'filename' is empty.
174 void makeScreenShot( string filename );
177 * UI-specific runPkgSeleciton method: Start the package selection.
178 * This implementation does the same as UserInput().
180 * Reimplemented from YUI.
182 YCPValue runPkgSelection( YWidget * packageSelector );
185 * Toggle macro recording (activated by Ctrl-Shift-Alt-M):
186 * Stop macro recording if it is in progress,
187 * open a file selection box and ask for a macro file name to save to and
188 * start recording if no recording has been in progress.
190 void toggleRecordMacro();
193 * Open file selection box and ask for a macro file to play
194 * (activated by Ctrl-Shift-Alt-P)
199 * Issue an internal error: Open popup with that message and wait.
201 * Reimplemented from YUI.
203 void internalError( const char * msg );
207 * Block WM_CLOSE events for the main window.
209 void blockWmClose() { _wm_close_blocked = true; }
212 * Unblock WM_CLOSE events for the main window.
214 void unblockWmClose() { _wm_close_blocked = false; }
217 * Check if dialogs are to be activated automatically
219 bool autoActivateDialogs() const { return _auto_activate_dialogs; }
222 * Change automatic dialog activation
224 void setAutoActivateDialogs( bool activate )
225 { _auto_activate_dialogs = activate; }
228 * Block (or unblock) events. If events are blocked, any event sent
229 * should be ignored until events are unblocked again.
231 * Reimplemented from YUI.
233 virtual void blockEvents( bool block = true )
234 { _event_handler.blockEvents( block ); }
237 * Returns 'true' if events are currently blocked.
239 * Reimplemented from YUI.
241 virtual bool eventsBlocked() const
242 { return _event_handler.eventsBlocked(); }
245 * Returns the current product name
246 * ("SuSE Linux", "SuSE Linux Enterprise Server", "United Linux", etc.)
249 QString productName() const;
252 * Beep - activate the system (X11) bell.
254 * Reimplemented from YUI.
262 * Show hourglass cursor.
264 * Reimplemented from YUI.
269 * Show pointer cursor.
271 * Reimplemented from YUI.
276 * Open file selection box and let the user Save y2logs to that location.
282 * Open dialog to configure logging.
285 void askConfigureLogging();
288 * Fun stuff (release dependent)
293 * A mouse click with the wrong mouse button was detected - e.g., a right
294 * click on a push button. The user might be left-handed, but his mouse
295 * might not (yet) be configured for left-handed use - e.g., during
296 * installation. Ask him if he would like his mouse temporarily configured
297 * as a left-handed mouse.
299 * This status can be queried with UI::GetDisplayInfo() ("LeftHandedMouse").
301 void maybeLeftHandedUser();
306 * Emitted upon WM_CLOSE
314 * Idle around until fd_ycp is readable and handle repaints.
315 * This is only used when a separate ui thread is running.
317 * Reimplemented from YUI.
319 void idleLoop( int fd_ycp );
322 * Return a representation for the glyph symbol specified in UTF-8 encoding
323 * or an empty string to get a default textual representation.
325 * Reimplemented from YUI.
327 YCPString glyph( const YCPSymbol & glyphSymbol );
330 * Go into event loop until next user input is available.
332 * Reimplemented from YUI.
334 YEvent * userInput( unsigned long timeout_millisec = 0 );
337 * Check the event queue for user input. Don't wait.
339 * Reimplemented from YUI.
341 YEvent * pollInput();
344 * Show and activate a dialog.
346 * Reimplemented from YUI.
348 void showDialog( YDialog * dialog );
351 * Decativate and close a dialog. This does not delete the dialog yet.
353 * Reimplemented from YUI.
355 void closeDialog( YDialog * dialog );
358 * Grab show events and work around QWidgetStack bug.
360 * Reimplemented from QObject.
362 bool eventFilter( QObject * obj, QEvent * ev );
365 * Make all UI windows usable without a mouse - even predefined Qt dialogs
366 * that don't know the UI's dialogs' activate() magic.
368 * Reimplemented from QObject.
370 bool showEventFilter( QObject * obj, QEvent * ev );
377 * Open a directory selection box and prompt the user for an existing directory.
378 * [Reimplemented from YUI]
380 * 'startDir' is the initial directory that is displayed.
382 * 'headline' is an explanatory text for the directory selection box.
383 * Graphical UIs may omit that if no window manager is running.
385 * Returns the selected directory name
386 * or 'nil' (YCPVoid() ) if the user canceled the operation.
388 YCPValue askForExistingDirectory ( const YCPString & startDir,
389 const YCPString & headline );
392 * Open a file selection box and prompt the user for an existing file.
393 * [Reimplemented from YUI]
395 * 'startWith' is the initial directory or file.
397 * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
399 * 'headline' is an explanatory text for the file selection box.
400 * Graphical UIs may omit that if no window manager is running.
402 * Returns the selected file name
403 * or 'nil' (YCPVoid() ) if the user canceled the operation.
405 YCPValue askForExistingFile ( const YCPString & startWith,
406 const YCPString & filter,
407 const YCPString & headline );
410 * Open a file selection box and prompt the user for a file to save data to.
411 * Automatically asks for confirmation if the user selects an existing file.
412 * [Reimplemented from YUI]
414 * 'startWith' is the initial directory or file.
416 * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
418 * 'headline' is an explanatory text for the file selection box.
419 * Graphical UIs may omit that if no window manager is running.
421 * Returns the selected file name
422 * or 'nil' (YCPVoid() ) if the user canceled the operation.
424 YCPValue askForSaveFileName ( const YCPString & startWith,
425 const YCPString & filter,
426 const YCPString & headline );
429 * Lower-level version that works with QStrings and does not change
432 QString askForSaveFileName( const QString & startWith,
433 const QString & filter,
434 const QString & headline );
439 QWidget* mainWidget();
442 * Initialize and set a textdomain for gettext()
444 static void setTextdomain( const char * domain );
447 * Returns a high-contrast color palette suitable for vision impaired users.
449 static QPalette visionImpairedPalette();
452 * Returns the normal color palette
454 QPalette normalPalette() const { return _normalPalette; }
457 * Toggle between the vision impaired and the normal color palette.
459 void toggleVisionImpairedPalette();
462 * Returns 'true' if high-contrast colors for vision impaired users is in use.
463 * This should be queried at other places before using custom colors.
465 bool usingVisionImpairedPalette() const { return _usingVisionImpairedPalette; }
468 * Convert logical layout spacing units into device dependent units.
469 * A default size dialog is assumed to be 80x25 layout spacing units
470 * and 640x480 device dependent spacing units.
472 * Reimplemented from YUI.
474 virtual int deviceUnits( YUIDimension dim, float layout_units );
477 * Convert device dependent units into logical layout spacing units.
478 * A default size dialog is assumed to be 80x25 layout spacing units
479 * and 640x480 device dependent spacing units.
481 * Reimplemented from YUI.
483 virtual float layoutUnits( YUIDimension dim, int device_units );
486 * Returns the package selector plugin singleton of this UI or creates it
487 * (including loading the plugin lib) if it does not exist yet.
489 YQPackageSelectorPlugin * packageSelectorPlugin();
495 * Display capabilities.
496 * [Reimplemented from YUI]
497 * See UI builtin GetDisplayInfo() doc for details.
499 int getDisplayWidth();
500 int getDisplayHeight();
501 int getDisplayDepth();
502 long getDisplayColors();
503 int getDefaultWidth();
504 int getDefaultHeight();
505 bool textMode() { return false; }
506 bool hasImageSupport() { return true; }
507 bool hasLocalImageSupport() { return true; }
508 bool hasAnimationSupport() { return true; }
509 bool hasIconSupport() { return false; } // not yet
510 bool hasFullUtf8Support() { return true; }
511 bool richTextSupportsTable() { return true; }
512 bool leftHandedMouse() { return _leftHandedMouse; }
515 QMap<QString, int> screenShotNo;
516 QString screenShotNameTemplate;
521 * Application shutdown
526 * Timeout during TimeoutUserInput() / WaitForEvent()
528 void userInputTimeout();
533 * Handle command line args
535 void processCommandLineArgs( int argc, char **argv );
538 * Calculate size of `opt(`defaultsize) dialogs
540 void calcDefaultSize();
549 * Assume presence of a window manager
554 * Use the entire available screen
559 * Decorate the toplevel window
561 bool _decorate_toplevel_window;
564 * Container for the widget stack. QWidgetStack cannot handle a WFlags
565 * argument, so this needs to be embedded into something else - and a QVBox
566 * at least handles all the sizeHint and resize stuff.
571 * Stack for the Qt widgets inside the main window.
573 QStackedWidget * _widget_stack;
576 * Stack to keep track of the stacking order of popup dialogs.
578 vector<QWidget *> _popup_stack;
581 * Size for `opt(`defaultsize) dialogs.
586 * This flag is set during @ref #userInput in order to tell
587 * @ref #returnNow to call exit_loop, which only may be called
593 * Event loop object. Required since a YaST2 UI needs to react to commands
594 * from the YCP command stream as well as to X11 / Qt events.
596 QEventLoop * _eventLoop;
599 * Window manager close events blocked?
601 bool _wm_close_blocked;
604 * Force new dialogs to the foreground and grab the keyboard focus?
605 * (Only if running without a window manager)
607 bool _auto_activate_dialogs;
610 * Global reference to the UI
615 * Indicate a fatal error that requires the UI to terminate
620 * Timer for TimeoutUserInput() / WaitForEvent().
622 QTimer _user_input_timer;
625 * Timer for delayed busy cursor
627 QTimer *_busy_cursor_timer;
630 * The handler for the single pending event this UI keeps track of
632 YSimpleEventHandler _event_handler;
635 * Saved normal palette
637 QPalette _normalPalette;
640 * Flag: currently using special palette for vision impaired users?
642 bool _usingVisionImpairedPalette;
645 * Flag: Does the user want to use a left-handed mouse?
647 bool _leftHandedMouse;
650 * Flag: Was the user already asked if he wants to use a left-handed mouse?
652 bool _askedForLeftHandedMouse;