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 );
236 * Returns 'true' if events are currently blocked.
238 * Reimplemented from YUI.
240 virtual bool eventsBlocked() const;
243 * Returns the current product name
244 * ("SuSE Linux", "SuSE Linux Enterprise Server", "United Linux", etc.)
247 QString productName() const;
250 * Beep - activate the system (X11) bell.
252 * Reimplemented from YUI.
260 * Show hourglass cursor.
262 * Reimplemented from YUI.
267 * Show pointer cursor.
269 * Reimplemented from YUI.
274 * Open file selection box and let the user Save y2logs to that location.
280 * Open dialog to configure logging.
283 void askConfigureLogging();
286 * Fun stuff (release dependent)
291 * A mouse click with the wrong mouse button was detected - e.g., a right
292 * click on a push button. The user might be left-handed, but his mouse
293 * might not (yet) be configured for left-handed use - e.g., during
294 * installation. Ask him if he would like his mouse temporarily configured
295 * as a left-handed mouse.
297 * This status can be queried with UI::GetDisplayInfo() ("LeftHandedMouse").
299 void maybeLeftHandedUser();
304 * Emitted upon WM_CLOSE
312 * Idle around until fd_ycp is readable and handle repaints.
313 * This is only used when a separate ui thread is running.
315 * Reimplemented from YUI.
317 void idleLoop( int fd_ycp );
320 * Return a representation for the glyph symbol specified in UTF-8 encoding
321 * or an empty string to get a default textual representation.
323 * Reimplemented from YUI.
325 YCPString glyph( const YCPSymbol & glyphSymbol );
328 * Go into event loop until next user input is available.
330 * Reimplemented from YUI.
332 YEvent * userInput( unsigned long timeout_millisec = 0 );
335 * Check the event queue for user input. Don't wait.
337 * Reimplemented from YUI.
339 YEvent * pollInput();
342 * Show and activate a dialog.
344 * Reimplemented from YUI.
346 void showDialog( YDialog * dialog );
349 * Decativate and close a dialog. This does not delete the dialog yet.
351 * Reimplemented from YUI.
353 void closeDialog( YDialog * dialog );
356 * Grab show events and work around QWidgetStack bug.
358 * Reimplemented from QObject.
360 bool eventFilter( QObject * obj, QEvent * ev );
363 * Make all UI windows usable without a mouse - even predefined Qt dialogs
364 * that don't know the UI's dialogs' activate() magic.
366 * Reimplemented from QObject.
368 bool showEventFilter( QObject * obj, QEvent * ev );
375 * Open a directory selection box and prompt the user for an existing directory.
376 * [Reimplemented from YUI]
378 * 'startDir' is the initial directory that is displayed.
380 * 'headline' is an explanatory text for the directory selection box.
381 * Graphical UIs may omit that if no window manager is running.
383 * Returns the selected directory name
384 * or 'nil' (YCPVoid() ) if the user canceled the operation.
386 YCPValue askForExistingDirectory ( const YCPString & startDir,
387 const YCPString & headline );
390 * Open a file selection box and prompt the user for an existing file.
391 * [Reimplemented from YUI]
393 * 'startWith' is the initial directory or file.
395 * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
397 * 'headline' is an explanatory text for the file selection box.
398 * Graphical UIs may omit that if no window manager is running.
400 * Returns the selected file name
401 * or 'nil' (YCPVoid() ) if the user canceled the operation.
403 YCPValue askForExistingFile ( const YCPString & startWith,
404 const YCPString & filter,
405 const YCPString & headline );
408 * Open a file selection box and prompt the user for a file to save data to.
409 * Automatically asks for confirmation if the user selects an existing file.
410 * [Reimplemented from YUI]
412 * 'startWith' is the initial directory or file.
414 * 'filter' is one or more blank-separated file patterns, e.g. "*.png *.jpg"
416 * 'headline' is an explanatory text for the file selection box.
417 * Graphical UIs may omit that if no window manager is running.
419 * Returns the selected file name
420 * or 'nil' (YCPVoid() ) if the user canceled the operation.
422 YCPValue askForSaveFileName ( const YCPString & startWith,
423 const YCPString & filter,
424 const YCPString & headline );
427 * Lower-level version that works with QStrings and does not change
430 QString askForSaveFileName( const QString & startWith,
431 const QString & filter,
432 const QString & headline );
437 QWidget* mainWidget();
440 * Initialize and set a textdomain for gettext()
442 static void setTextdomain( const char * domain );
445 * Returns a high-contrast color palette suitable for vision impaired users.
447 static QPalette visionImpairedPalette();
450 * Returns the normal color palette
452 QPalette normalPalette() const { return _normalPalette; }
455 * Toggle between the vision impaired and the normal color palette.
457 void toggleVisionImpairedPalette();
460 * Returns 'true' if high-contrast colors for vision impaired users is in use.
461 * This should be queried at other places before using custom colors.
463 bool usingVisionImpairedPalette() const { return _usingVisionImpairedPalette; }
466 * Convert logical layout spacing units into device dependent units.
467 * A default size dialog is assumed to be 80x25 layout spacing units
468 * and 640x480 device dependent spacing units.
470 * Reimplemented from YUI.
472 virtual int deviceUnits( YUIDimension dim, float layout_units );
475 * Convert device dependent units into logical layout spacing units.
476 * A default size dialog is assumed to be 80x25 layout spacing units
477 * and 640x480 device dependent spacing units.
479 * Reimplemented from YUI.
481 virtual float layoutUnits( YUIDimension dim, int device_units );
484 * Returns the package selector plugin singleton of this UI or creates it
485 * (including loading the plugin lib) if it does not exist yet.
487 YQPackageSelectorPlugin * packageSelectorPlugin();
493 * Display capabilities.
494 * [Reimplemented from YUI]
495 * See UI builtin GetDisplayInfo() doc for details.
497 int getDisplayWidth();
498 int getDisplayHeight();
499 int getDisplayDepth();
500 long getDisplayColors();
501 int getDefaultWidth();
502 int getDefaultHeight();
503 bool textMode() { return false; }
504 bool hasImageSupport() { return true; }
505 bool hasLocalImageSupport() { return true; }
506 bool hasAnimationSupport() { return true; }
507 bool hasIconSupport() { return false; } // not yet
508 bool hasFullUtf8Support() { return true; }
509 bool richTextSupportsTable() { return true; }
510 bool leftHandedMouse() { return _leftHandedMouse; }
513 QMap<QString, int> screenShotNo;
514 QString screenShotNameTemplate;
519 * Application shutdown
524 * Timeout during TimeoutUserInput() / WaitForEvent()
526 void userInputTimeout();
531 * Handle command line args
533 void processCommandLineArgs( int argc, char **argv );
536 * Calculate size of `opt(`defaultsize) dialogs
538 void calcDefaultSize();
547 * Assume presence of a window manager
552 * Use the entire available screen
557 * Decorate the toplevel window
559 bool _decorate_toplevel_window;
562 * Container for the widget stack. QWidgetStack cannot handle a WFlags
563 * argument, so this needs to be embedded into something else - and a QVBox
564 * at least handles all the sizeHint and resize stuff.
569 * Stack for the Qt widgets inside the main window.
571 QStackedWidget * _widget_stack;
574 * Stack to keep track of the stacking order of popup dialogs.
576 vector<QWidget *> _popup_stack;
579 * Size for `opt(`defaultsize) dialogs.
584 * This flag is set during @ref #userInput in order to tell
585 * @ref #returnNow to call exit_loop, which only may be called
591 * Event loop object. Required since a YaST2 UI needs to react to commands
592 * from the YCP command stream as well as to X11 / Qt events.
594 QEventLoop * _eventLoop;
597 * Window manager close events blocked?
599 bool _wm_close_blocked;
602 * Force new dialogs to the foreground and grab the keyboard focus?
603 * (Only if running without a window manager)
605 bool _auto_activate_dialogs;
608 * Global reference to the UI
613 * Indicate a fatal error that requires the UI to terminate
618 * Timer for TimeoutUserInput() / WaitForEvent().
620 QTimer _user_input_timer;
623 * Timer for delayed busy cursor
625 QTimer *_busy_cursor_timer;
628 * The handler for the single pending event this UI keeps track of
630 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;