libyui-qt  2.49.11
YQUI.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YQUI.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 #include <sys/param.h> // MAXHOSTNAMELEN
26 #include <dlfcn.h>
27 #include <libintl.h>
28 #include <algorithm>
29 #include <stdio.h>
30 
31 #include <QWidget>
32 #include <QThread>
33 #include <QSocketNotifier>
34 #include <QDesktopWidget>
35 #include <QEvent>
36 #include <QCursor>
37 #include <QLocale>
38 #include <QMessageLogContext>
39 #include <QMessageBox>
40 #include <QInputDialog>
41 
42 
43 #define YUILogComponent "qt-ui"
44 #include <yui/YUILog.h>
45 #include <yui/Libyui_config.h>
46 
47 #include "YQUI.h"
48 
49 #include <yui/YEvent.h>
50 #include <yui/YCommandLine.h>
51 #include <yui/YButtonBox.h>
52 #include <yui/YUISymbols.h>
53 
54 #include "QY2Styler.h"
55 #include "YQApplication.h"
56 #include "YQDialog.h"
57 #include "YQWidgetFactory.h"
58 #include "YQOptionalWidgetFactory.h"
59 
60 #include "YQWizardButton.h"
61 
62 #include "YQi18n.h"
63 #include "utf8.h"
64 
65 // Include low-level X headers AFTER Qt headers:
66 // X.h pollutes the global namespace (!!!) with pretty useless #defines
67 // like "Above", "Below" etc. that clash with some Qt headers.
68 #include <X11/Xlib.h>
69 
70 
71 using std::max;
72 
73 #define BUSY_CURSOR_TIMEOUT 200 // milliseconds
74 #define VERBOSE_EVENT_LOOP 0
75 
76 
77 
78 static void qMessageHandler( QtMsgType type, const QMessageLogContext &, const QString & msg );
79 YQUI * YQUI::_ui = 0;
80 
81 
82 YUI * createUI( bool withThreads )
83 {
84  if ( ! YQUI::ui() )
85  {
86  YQUI * ui = new YQUI( withThreads );
87 
88  if ( ui && ! withThreads )
89  ui->initUI();
90  }
91 
92  return YQUI::ui();
93 }
94 
95 
96 YQUI::YQUI( bool withThreads )
97  : YUI( withThreads )
98 #if 0
99  , _main_win( NULL )
100 #endif
101  , _do_exit_loop( false )
102 {
103  yuiDebug() << "YQUI constructor start" << std::endl;
104  yuiMilestone() << "This is libyui-qt " << VERSION << std::endl;
105 
106  _ui = this;
107  _uiInitialized = false;
108  _fatalError = false;
109  _fullscreen = false;
110  _noborder = false;
111  screenShotNameTemplate = "";
112  _blockedLevel = 0;
113 
114  qInstallMessageHandler( qMessageHandler );
115 
116  yuiDebug() << "YQUI constructor finished" << std::endl;
117 
118  topmostConstructorHasFinished();
119 }
120 
121 
123 {
124  if ( _uiInitialized )
125  return;
126 
127  _uiInitialized = true;
128  yuiDebug() << "Initializing Qt part" << std::endl;
129 
130  YCommandLine cmdLine; // Retrieve command line args from /proc/<pid>/cmdline
131  std::string progName;
132 
133  if ( cmdLine.argc() > 0 )
134  {
135  progName = cmdLine[0];
136  std::size_t lastSlashPos = progName.find_last_of( '/' );
137 
138  if ( lastSlashPos != std::string::npos )
139  progName = progName.substr( lastSlashPos+1 );
140 
141  // Qt will display argv[0] as the window manager title.
142  // For YaST2, display "YaST2" instead of "y2base".
143  // For other applications, leave argv[0] alone.
144 
145  if ( progName == "y2base" )
146  cmdLine.replace( 0, "YaST2" );
147  }
148 
149  _ui_argc = cmdLine.argc();
150  char ** argv = cmdLine.argv();
151 
152  yuiDebug() << "Creating QApplication" << std::endl;
153  QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
154  new QApplication( _ui_argc, argv );
155  Q_CHECK_PTR( qApp );
156  // Qt keeps track to a global QApplication in qApp.
157 
158  _signalReceiver = new YQUISignalReceiver();
159  _busyCursorTimer = new QTimer( _signalReceiver );
160  _busyCursorTimer->setSingleShot( true );
161 
162  (void) QY2Styler::styler(); // Make sure QY2Styler singleton is created
163 
164  setButtonOrderFromEnvironment();
165  processCommandLineArgs( _ui_argc, argv );
166  calcDefaultSize();
167 
168  _do_exit_loop = false;
169 
170 #if 0
171  // Create main window for `opt(`defaultsize) dialogs.
172  //
173  // We have to use something else than QWidgetStack since QWidgetStack
174  // doesn't accept a WFlags arg which we badly need here.
175 
176  _main_win = new QWidget( 0, Qt::Window ); // parent, wflags
177  _main_win->setFocusPolicy( Qt::StrongFocus );
178  _main_win->setObjectName( "main_window" );
179 
180  _main_win->resize( _defaultSize );
181 
182  if ( _fullscreen )
183  _main_win->move( 0, 0 );
184 #endif
185 
186 
187  //
188  // Set application title (used by YQDialog and YQWizard)
189  //
190 
191  // for YaST2, display "YaST2" instead of "y2base"
192  if ( progName == "y2base" )
193  _applicationTitle = QString( "YaST2" );
194  else
195  _applicationTitle = fromUTF8( progName );
196 
197  // read x11 display from commandline or environment variable
198  int displayArgPos = cmdLine.find( "-display" );
199  QString displayName;
200 
201  if ( displayArgPos > 0 && displayArgPos+1 < cmdLine.argc() )
202  displayName = cmdLine[ displayArgPos+1 ].c_str();
203  else
204  displayName = getenv( "DISPLAY" );
205 
206  // identify hostname
207  char hostname[ MAXHOSTNAMELEN+1 ];
208  if ( gethostname( hostname, sizeof( hostname )-1 ) == 0 )
209  hostname[ sizeof( hostname ) -1 ] = '\0'; // make sure it's terminated
210  else
211  hostname[0] = '\0';
212 
213  // add hostname to the window title if it's not a local display
214  if ( !displayName.startsWith( ":" ) && strlen( hostname ) > 0 )
215  {
216  _applicationTitle += QString( "@" );
217  _applicationTitle += fromUTF8( hostname );
218  }
219 
220 
221 #if 0
222  // Hide the main window for now. The first call to UI::OpenDialog() on an
223  // `opt(`defaultSize) dialog will trigger a dialog->open() call that shows
224  // the main window - there is nothing to display yet.
225 
226  _main_win->hide();
227 #endif
228 
229  YButtonBoxMargins buttonBoxMargins;
230  buttonBoxMargins.left = 8;
231  buttonBoxMargins.right = 8;
232  buttonBoxMargins.top = 6;
233  buttonBoxMargins.bottom = 6;
234 
235  buttonBoxMargins.spacing = 4;
236  buttonBoxMargins.helpButtonExtraSpacing = 16;
237  YButtonBox::setDefaultMargins( buttonBoxMargins );
238 
239  // Init other stuff
240 
241  qApp->setFont( yqApp()->currentFont() );
242  busyCursor();
243 
244 
245  QObject::connect( _busyCursorTimer, &pclass(_busyCursorTimer)::timeout,
246  _signalReceiver, &pclass(_signalReceiver)::slotBusyCursor );
247 
248  yuiMilestone() << "YQUI initialized. Thread ID: 0x"
249  << hex << QThread::currentThreadId () << dec
250  << std::endl;
251 
252  qApp->processEvents();
253 }
254 
255 
258 {
259  return static_cast<YQApplication *>( app() );
260 }
261 
262 
263 void YQUI::processCommandLineArgs( int argc, char **argv )
264 {
265  if ( argv )
266  {
267  for( int i=0; i < argc; i++ )
268  {
269  QString opt = argv[i];
270 
271  yuiMilestone() << "Qt argument: " << argv[i] << std::endl;
272 
273  // Normalize command line option - accept "--xy" as well as "-xy"
274 
275  if ( opt.startsWith( "--" ) )
276  opt.remove(0, 1);
277 
278  if ( opt == QString( "-fullscreen" ) ) _fullscreen = true;
279  else if ( opt == QString( "-noborder" ) ) _noborder = true;
280  else if ( opt == QString( "-auto-font" ) ) yqApp()->setAutoFonts( true );
281  else if ( opt == QString( "-auto-fonts" ) ) yqApp()->setAutoFonts( true );
282  else if ( opt == QString( "-gnome-button-order" ) ) YButtonBox::setLayoutPolicy( YButtonBox::gnomeLayoutPolicy() );
283  else if ( opt == QString( "-kde-button-order" ) ) YButtonBox::setLayoutPolicy( YButtonBox::kdeLayoutPolicy() );
284  // --macro is handled by YUI_component
285  else if ( opt == QString( "-help" ) )
286  {
287  fprintf( stderr,
288  "Command line options for the YaST2 Qt UI:\n"
289  "\n"
290  "--nothreads run without additional UI threads\n"
291  "--fullscreen use full screen for `opt(`defaultsize) dialogs\n"
292  "--noborder no window manager border for `opt(`defaultsize) dialogs\n"
293  "--auto-fonts automatically pick fonts, disregard Qt standard settings\n"
294  "--help this help text\n"
295  "\n"
296  "--macro <macro-file> play a macro right on startup\n"
297  "\n"
298  "-no-wm, -noborder etc. are accepted as well as --no-wm, --noborder\n"
299  "to maintain backwards compatibility.\n"
300  "\n"
301  );
302 
303  raiseFatalError();
304  }
305  }
306  }
307 
308  // Qt handles command line option "-reverse" for Arabic / Hebrew
309 }
310 
311 
312 
314 {
315  yuiMilestone() <<"Closing down Qt UI." << std::endl;
316 
317  // Intentionally NOT calling dlclose() to libqt-mt
318  // (see constructor for explanation)
319 
320  if ( qApp ) // might already be reset to 0 internally from Qt
321  {
322  qApp->exit();
323  qApp->deleteLater();
324  }
325 
326  delete _signalReceiver;
327 }
328 
329 void
331 {
332  yuiMilestone() <<"Destroying UI thread" << std::endl;
333 
334  if ( qApp ) // might already be reset to 0 internally from Qt
335  {
336  if ( YDialog::openDialogsCount() > 0 )
337  {
338  yuiError() << YDialog::openDialogsCount() << " open dialogs left over" << endl;
339  yuiError() << "Topmost dialog:" << endl;
340  YDialog::topmostDialog()->dumpWidgetTree();
341  }
342 
343  YDialog::deleteAllDialogs();
344  qApp->exit();
345  qApp->deleteLater();
346  }
347 }
348 
349 
350 YWidgetFactory *
352 {
353  YQWidgetFactory * factory = new YQWidgetFactory();
354  YUI_CHECK_NEW( factory );
355 
356  return factory;
357 }
358 
359 
360 
361 YOptionalWidgetFactory *
363 {
365  YUI_CHECK_NEW( factory );
366 
367  return factory;
368 }
369 
370 
371 YApplication *
372 YQUI::createApplication()
373 {
374  YQApplication * app = new YQApplication();
375  YUI_CHECK_NEW( app );
376 
377  return app;
378 }
379 
380 
382 {
383  QSize primaryScreenSize = qApp->desktop()->screenGeometry( qApp->desktop()->primaryScreen() ).size();
384  QSize availableSize = qApp->desktop()->availableGeometry( qApp->desktop()->primaryScreen() ).size();
385 
386  if ( _fullscreen )
387  {
388  _defaultSize = availableSize;
389 
390  yuiMilestone() << "-fullscreen: using "
391  << _defaultSize.width() << " x " << _defaultSize.height()
392  << "for `opt(`defaultsize)"
393  << std::endl;
394  }
395  else
396  {
397  // Get _defaultSize via -geometry command line option (if set)
398 
399  // Set min defaultsize or figure one out if -geometry was not used
400 
401  if ( _defaultSize.width() < 800 ||
402  _defaultSize.height() < 600 )
403  {
404  if ( primaryScreenSize.width() >= 1024 && primaryScreenSize.height() >= 768 )
405  {
406  // Scale down to 70% of screen size
407 
408  _defaultSize.setWidth ( max( (int) (availableSize.width() * 0.7), 800 ) );
409  _defaultSize.setHeight( max( (int) (availableSize.height() * 0.7), 600 ) );
410  }
411  else
412  {
413  _defaultSize = availableSize;
414  }
415  }
416  else
417  {
418  yuiMilestone() << "Forced size (via -geometry): "
419  << _defaultSize.width() << " x " << _defaultSize.height()
420  << std::endl;
421  }
422  }
423 
424  yuiMilestone() << "Default size: "
425  << _defaultSize.width() << " x " << _defaultSize.height()
426  << std::endl;
427 }
428 
429 
430 void YQUI::idleLoop( int fd_ycp )
431 {
432  initUI();
433 
434  _received_ycp_command = false;
435  QSocketNotifier * notifier = new QSocketNotifier( fd_ycp, QSocketNotifier::Read );
436  QObject::connect( notifier, &pclass(notifier)::activated,
437  _signalReceiver, &pclass(_signalReceiver)::slotReceivedYCPCommand );
438 
439  notifier->setEnabled( true );
440 
441 
442  //
443  // Process Qt events until fd_ycp is readable
444  //
445 
446 #if VERBOSE_EVENT_LOOP
447  yuiDebug() << "Entering idle loop" << std::endl;
448 #endif
449 
450  QEventLoop eventLoop( qApp );
451 
452  while ( !_received_ycp_command )
453  eventLoop.processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents );
454 
455 #if VERBOSE_EVENT_LOOP
456  yuiDebug() << "Leaving idle loop" << std::endl;
457 #endif
458 
459  delete notifier;
460 }
461 
462 
464 {
465  _received_ycp_command = true;
466 }
467 
468 
469 void YQUI::sendEvent( YEvent * event )
470 {
471  if ( event )
472  {
473  _eventHandler.sendEvent( event );
474  YQDialog * dialog = (YQDialog *) YDialog::currentDialog( false ); // don't throw
475 
476  if ( dialog )
477  {
478  if ( dialog->eventLoop()->isRunning() )
479  dialog->eventLoop()->exit( 0 );
480  }
481  else
482  {
483  yuiError() << "No dialog" << std::endl;
484  }
485  }
486 }
487 
488 
489 void YQUI::setTextdomain( const char * domain )
490 {
491  bindtextdomain( domain, YSettings::localeDir().c_str() );
492  bind_textdomain_codeset( domain, "utf8" );
493  textdomain( domain );
494 
495  // Make change known.
496  {
497  extern int _nl_msg_cat_cntr;
498  ++_nl_msg_cat_cntr;
499  }
500 }
501 
502 
503 void YQUI::blockEvents( bool block )
504 {
505  initUI();
506 
507  if ( block )
508  {
509  if ( ++_blockedLevel == 1 )
510  {
511  _eventHandler.blockEvents( true );
512 
513  YQDialog * dialog = (YQDialog *) YDialog::currentDialog( false ); // don't throw
514 
515  if ( dialog && dialog->eventLoop()->isRunning() )
516  {
517  yuiWarning() << "blocking events in active event loop of " << dialog << std::endl;
518  dialog->eventLoop()->exit();
519  }
520  }
521  }
522  else
523  {
524  if ( --_blockedLevel == 0 )
525  {
526  _eventHandler.blockEvents( false );
527 
528  YQDialog * dialog = (YQDialog *) YDialog::currentDialog( false ); // don't throw
529 
530  if ( dialog )
531  dialog->eventLoop()->wakeUp();
532  }
533  }
534 }
535 
536 
538 {
539  initUI();
540  _blockedLevel = 0;
541  _eventHandler.blockEvents( false );
542 }
543 
544 
546 {
547  return _eventHandler.eventsBlocked();
548 }
549 
550 
552 {
553  qApp->setOverrideCursor( Qt::BusyCursor );
554 }
555 
556 
558 {
559  if ( _busyCursorTimer->isActive() )
560  _busyCursorTimer->stop();
561 
562  while ( qApp->overrideCursor() )
563  qApp->restoreOverrideCursor();
564 }
565 
566 
568 {
569  // Display a busy cursor, but only if there is no other activity within
570  // BUSY_CURSOR_TIMEOUT milliseconds: Avoid cursor flicker.
571 
572  _busyCursorTimer->start( BUSY_CURSOR_TIMEOUT ); // single shot
573 }
574 
575 
576 int YQUI::defaultSize(YUIDimension dim) const
577 {
578  return dim == YD_HORIZ ? _defaultSize.width() : _defaultSize.height();
579 }
580 
581 
582 void YQUI::probeX11Display( const YCommandLine & cmdLine )
583 {
584  // obsolete, see https://bugzilla.suse.com/show_bug.cgi?id=1072411
585 }
586 
587 
588 void YQUI::deleteNotify( YWidget * widget )
589 {
590  _eventHandler.deletePendingEventsFor( widget );
591 }
592 
593 // FIXME: Does this still do anything now that YQUI is no longer a QObject?
595 {
596  yuiMilestone() << "Closing application" << std::endl;
597  sendEvent( new YCancelEvent() );
598  return true;
599 }
600 
601 
603 {
604  QWidget * parent = 0;
605  YDialog * dialog = YDialog::currentDialog( false ); // doThrow
606 
607  if ( dialog )
608  parent = (QWidget *) dialog->widgetRep();
609 
610  QString id = QInputDialog::getText( parent,
611  _( "Widget ID" ), // dialog title
612  _( "Enter Widget ID:" ) // label
613  );
614  if ( ! id.isEmpty() )
615  {
616  try
617  {
618  YWidget * widget = sendWidgetID( toUTF8( id ) );
619  YQGenericButton * yqButton = dynamic_cast<YQGenericButton *>( widget );
620 
621  if ( yqButton )
622  {
623  yuiMilestone() << "Activating " << widget << endl;
624  yqButton->activate();
625  }
626  }
627  catch ( YUIWidgetNotFoundException & ex )
628  {
629  YUI_CAUGHT( ex );
630  QMessageBox::warning( parent,
631  _( "Error" ), // title
632  _( "No widget with ID \"%1\"" ).arg( id ) );
633  }
634  }
635 }
636 
637 
638 
639 
640 
641 YQUISignalReceiver::YQUISignalReceiver()
642  : QObject()
643 {
644 }
645 
646 
647 void YQUISignalReceiver::slotBusyCursor()
648 {
649  YQUI::ui()->busyCursor();
650 }
651 
652 
653 void YQUISignalReceiver::slotReceivedYCPCommand()
654 {
656 }
657 
658 
659 
660 static void
661 qMessageHandler( QtMsgType type, const QMessageLogContext &, const QString & msg )
662 {
663  switch (type)
664  {
665  case QtDebugMsg:
666  yuiMilestone() << "<libqt-debug> " << msg << std::endl;
667  break;
668 
669 #if QT_VERSION >= 0x050500
670  case QtInfoMsg:
671  yuiMilestone() << "<libqt-info> " << msg << std::endl;
672  break;
673 #endif
674 
675  case QtWarningMsg:
676  yuiWarning() << "<libqt-warning> " << msg << std::endl;
677  break;
678 
679  case QtCriticalMsg:
680  yuiError() << "<libqt-critical>" << msg << std::endl;
681  break;
682 
683  case QtFatalMsg:
684  yuiError() << "<libqt-fatal> " << msg << std::endl;
685  abort();
686  exit(1); // Qt does the same
687  }
688 
689  if ( QString( msg ).contains( "Fatal IO error", Qt::CaseInsensitive ) &&
690  QString( msg ).contains( "client killed", Qt::CaseInsensitive ) )
691  yuiError() << "Client killed. Possibly caused by X server shutdown or crash." << std::endl;
692 }
693 
694 QIcon YQUI::loadIcon( const string & iconName ) const
695 {
696  QIcon icon;
697  const QString resource = ":/";
698  if ( QIcon::hasThemeIcon( iconName.c_str() ) )
699  {
700  yuiDebug() << "Trying theme icon from: " << iconName << std::endl;
701  icon = QIcon::fromTheme( iconName.c_str(), QIcon( resource + iconName.c_str() ) );
702  }
703 
704  if ( icon.isNull() )
705  {
706  yuiDebug() << "Trying icon from resource: " << iconName << std::endl;
707  icon = QIcon( resource + iconName.c_str() );
708 
709  }
710 
711  if ( icon.isNull() )
712  {
713  yuiDebug() << "Trying icon from path: " << iconName << std::endl;
714  icon = QIcon( iconName.c_str() );
715  }
716 
717  if ( icon.isNull() )
718  yuiWarning() << "Couldn't load icon: " << iconName << std::endl;
719  return icon;
720 }
721 
722 
int defaultSize(YUIDimension dim) const
Returns size for opt(defaultsize) dialogs (in one dimension).
Definition: YQUI.cc:576
void receivedYCPCommand()
Notification that a YCP command has been received on fd_ycp to leave idleLoop()
Definition: YQUI.cc:463
void activate()
Activate (animated) this button.
static YQApplication * yqApp()
Return the global YApplication object as YQApplication.
Definition: YQUI.cc:257
void forceUnblockEvents()
Force unblocking all events, no matter how many times blockEvents() has This returns 0 if there is no...
Definition: YQUI.cc:537
void setAutoFonts(bool useAutoFonts)
Set whether or not fonts should automatically be picked.
virtual YOptionalWidgetFactory * createOptionalWidgetFactory()
Create the widget factory that provides all the createXY() methods for optional ("special") widgets a...
Definition: YQUI.cc:362
void askSendWidgetID()
Open a pop-up dialog to ask the user for a widget ID and then send it with sendWidgetID().
Definition: YQUI.cc:602
void calcDefaultSize()
Calculate size of opt(defaultsize) dialogs.
Definition: YQUI.cc:381
QEventLoop * eventLoop()
Access to this dialog's event loop.
Definition: YQDialog.h:201
Helper class that acts as a Qt signal receiver for YQUI.
Definition: YQUI.h:377
Abstract base class for push button and similar widgets - all that can become a YQDialog's "default b...
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
Definition: YQUI.cc:469
YQUI(bool withThreads)
Constructor.
Definition: YQUI.cc:96
virtual void idleLoop(int fd_ycp)
Idle around until fd_ycp is readable and handle repaints.
Definition: YQUI.cc:430
void probeX11Display(const YCommandLine &cmdLine)
Probe the X11 display.
Definition: YQUI.cc:582
virtual void deleteNotify(YWidget *widget)
Notification that a widget is being deleted.
Definition: YQUI.cc:588
void busyCursor()
Show mouse cursor indicating busy state.
Definition: YQUI.cc:551
Definition: YQUI.h:62
void processCommandLineArgs(int argc, char **argv)
Handle command line args.
Definition: YQUI.cc:263
Concrete widget factory for mandatory widgets.
virtual void uiThreadDestructor()
Destroy whatever needs to be destroyed within the UI thread.
Definition: YQUI.cc:330
virtual void blockEvents(bool block=true)
Block (or unblock) events.
Definition: YQUI.cc:503
void timeoutBusyCursor()
Show mouse cursor indicating busy state if the UI is unable to respond to user input for more than a ...
Definition: YQUI.cc:567
bool close()
Application shutdown.
Definition: YQUI.cc:594
void normalCursor()
Show normal mouse cursor not indicating busy status.
Definition: YQUI.cc:557
void initUI()
Post-constructor initialization.
Definition: YQUI.cc:122
virtual ~YQUI()
Destructor.
Definition: YQUI.cc:313
void raiseFatalError()
Raise a fatal UI error.
Definition: YQUI.h:185
static void setTextdomain(const char *domain)
Initialize and set a textdomain for gettext()
Definition: YQUI.cc:489
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:81
Widget factory for optional ("special") widgets.
virtual bool eventsBlocked() const
Returns 'true' if events are currently blocked.
Definition: YQUI.cc:545
virtual YWidgetFactory * createWidgetFactory()
Create the widget factory that provides all the createXY() methods for standard (mandatory,...
Definition: YQUI.cc:351