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