25 #include <rpc/types.h>
33 #include <QSocketNotifier>
34 #include <QDesktopWidget>
38 #include <QMessageLogContext>
41 #define YUILogComponent "qt-ui"
42 #include <yui/YUILog.h>
43 #include <yui/Libyui_config.h>
47 #include <yui/YEvent.h>
48 #include <yui/YCommandLine.h>
49 #include <yui/YButtonBox.h>
50 #include <yui/YUISymbols.h>
52 #include "QY2Styler.h"
53 #include "YQApplication.h"
55 #include "YQWidgetFactory.h"
56 #include "YQOptionalWidgetFactory.h"
69 #define BUSY_CURSOR_TIMEOUT 200 // milliseconds
70 #define VERBOSE_EVENT_LOOP 0
74 static void qMessageHandler( QtMsgType type,
const QMessageLogContext &,
const QString & msg );
78 YUI * createUI(
bool withThreads )
84 if ( ui && ! withThreads )
97 , _do_exit_loop( false )
99 yuiDebug() <<
"YQUI constructor start" << std::endl;
100 yuiMilestone() <<
"This is libyui-qt " << VERSION << std::endl;
103 _uiInitialized =
false;
107 screenShotNameTemplate =
"";
110 qInstallMessageHandler( qMessageHandler );
112 yuiDebug() <<
"YQUI constructor finished" << std::endl;
114 topmostConstructorHasFinished();
120 if ( _uiInitialized )
123 _uiInitialized =
true;
124 yuiDebug() <<
"Initializing Qt part" << std::endl;
126 YCommandLine cmdLine;
127 std::string progName;
129 if ( cmdLine.argc() > 0 )
131 progName = cmdLine[0];
132 std::size_t lastSlashPos = progName.find_last_of(
'/' );
134 if ( lastSlashPos != std::string::npos )
135 progName = progName.substr( lastSlashPos+1 );
141 if ( progName ==
"y2base" )
142 cmdLine.replace( 0,
"YaST2" );
145 _ui_argc = cmdLine.argc();
146 char ** argv = cmdLine.argv();
151 yuiDebug() <<
"Creating QApplication" << std::endl;
152 new QApplication( _ui_argc, argv );
157 _busyCursorTimer =
new QTimer( _signalReceiver );
158 _busyCursorTimer->setSingleShot(
true );
160 (void) QY2Styler::styler();
162 setButtonOrderFromEnvironment();
166 _do_exit_loop =
false;
174 _main_win =
new QWidget( 0, Qt::Window );
175 _main_win->setFocusPolicy( Qt::StrongFocus );
176 _main_win->setObjectName(
"main_window" );
178 _main_win->resize( _defaultSize );
181 _main_win->move( 0, 0 );
190 if ( progName ==
"y2base" )
191 _applicationTitle = QString(
"YaST2" );
193 _applicationTitle = fromUTF8( progName );
196 int displayArgPos = cmdLine.find(
"-display" );
199 if ( displayArgPos > 0 && displayArgPos+1 < cmdLine.argc() )
200 displayName = cmdLine[ displayArgPos+1 ].c_str();
202 displayName = getenv(
"DISPLAY" );
205 char hostname[ MAXHOSTNAMELEN+1 ];
206 if ( gethostname( hostname,
sizeof( hostname )-1 ) == 0 )
207 hostname[
sizeof( hostname ) -1 ] =
'\0';
212 if ( !displayName.startsWith(
":" ) && strlen( hostname ) > 0 )
214 _applicationTitle += QString(
"@" );
215 _applicationTitle += fromUTF8( hostname );
227 YButtonBoxMargins buttonBoxMargins;
228 buttonBoxMargins.left = 8;
229 buttonBoxMargins.right = 8;
230 buttonBoxMargins.top = 6;
231 buttonBoxMargins.bottom = 6;
233 buttonBoxMargins.spacing = 4;
234 buttonBoxMargins.helpButtonExtraSpacing = 16;
235 YButtonBox::setDefaultMargins( buttonBoxMargins );
239 qApp->setFont(
yqApp()->currentFont() );
243 QObject::connect( _busyCursorTimer, &pclass(_busyCursorTimer)::timeout,
244 _signalReceiver, &pclass(_signalReceiver)::slotBusyCursor );
246 yuiMilestone() <<
"YQUI initialized. Thread ID: 0x"
247 << hex << QThread::currentThreadId () << dec
250 qApp->processEvents();
265 for(
int i=0; i < argc; i++ )
267 QString opt = argv[i];
269 yuiMilestone() <<
"Qt argument: " << argv[i] << std::endl;
273 if ( opt.startsWith(
"--" ) )
276 if ( opt == QString(
"-fullscreen" ) ) _fullscreen =
true;
277 else if ( opt == QString(
"-noborder" ) ) _noborder =
true;
280 else if ( opt == QString(
"-gnome-button-order" ) ) YButtonBox::setLayoutPolicy( YButtonBox::gnomeLayoutPolicy() );
281 else if ( opt == QString(
"-kde-button-order" ) ) YButtonBox::setLayoutPolicy( YButtonBox::kdeLayoutPolicy() );
283 else if ( opt == QString(
"-help" ) )
286 "Command line options for the YaST2 Qt UI:\n"
288 "--nothreads run without additional UI threads\n"
289 "--fullscreen use full screen for `opt(`defaultsize) dialogs\n"
290 "--noborder no window manager border for `opt(`defaultsize) dialogs\n"
291 "--auto-fonts automatically pick fonts, disregard Qt standard settings\n"
292 "--help this help text\n"
294 "--macro <macro-file> play a macro right on startup\n"
296 "-no-wm, -noborder etc. are accepted as well as --no-wm, --noborder\n"
297 "to maintain backwards compatibility.\n"
313 yuiDebug() <<
"Closing down Qt UI." << std::endl;
324 delete _signalReceiver;
342 YUI_CHECK_NEW( factory );
349 YOptionalWidgetFactory *
353 YUI_CHECK_NEW( factory );
360 YQUI::createApplication()
363 YUI_CHECK_NEW( app );
371 QSize primaryScreenSize = qApp->desktop()->screenGeometry( qApp->desktop()->primaryScreen() ).size();
372 QSize availableSize = qApp->desktop()->availableGeometry( qApp->desktop()->primaryScreen() ).size();
376 _defaultSize = availableSize;
378 yuiMilestone() <<
"-fullscreen: using "
379 << _defaultSize.width() <<
" x " << _defaultSize.height()
380 <<
"for `opt(`defaultsize)"
389 if ( _defaultSize.width() < 800 ||
390 _defaultSize.height() < 600 )
392 if ( primaryScreenSize.width() >= 1024 && primaryScreenSize.height() >= 768 )
396 _defaultSize.setWidth ( max( (
int) (availableSize.width() * 0.7), 800 ) );
397 _defaultSize.setHeight( max( (
int) (availableSize.height() * 0.7), 600 ) );
401 _defaultSize = availableSize;
406 yuiMilestone() <<
"Forced size (via -geometry): "
407 << _defaultSize.width() <<
" x " << _defaultSize.height()
412 yuiMilestone() <<
"Default size: "
413 << _defaultSize.width() <<
" x " << _defaultSize.height()
422 _received_ycp_command =
false;
423 QSocketNotifier * notifier =
new QSocketNotifier( fd_ycp, QSocketNotifier::Read );
424 QObject::connect( notifier, &pclass(notifier)::activated,
425 _signalReceiver, &pclass(_signalReceiver)::slotReceivedYCPCommand );
427 notifier->setEnabled(
true );
434 #if VERBOSE_EVENT_LOOP
435 yuiDebug() <<
"Entering idle loop" << std::endl;
438 QEventLoop eventLoop( qApp );
440 while ( !_received_ycp_command )
441 eventLoop.processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents );
443 #if VERBOSE_EVENT_LOOP
444 yuiDebug() <<
"Leaving idle loop" << std::endl;
453 _received_ycp_command =
true;
461 _eventHandler.sendEvent( event );
471 yuiError() <<
"No dialog" << std::endl;
479 bindtextdomain( domain, YSettings::localeDir().c_str() );
480 bind_textdomain_codeset( domain,
"utf8" );
481 textdomain( domain );
485 extern int _nl_msg_cat_cntr;
497 if ( ++_blockedLevel == 1 )
499 _eventHandler.blockEvents(
true );
503 if ( dialog && dialog->
eventLoop()->isRunning() )
505 yuiWarning() <<
"blocking events in active event loop of " << dialog << std::endl;
512 if ( --_blockedLevel == 0 )
514 _eventHandler.blockEvents(
false );
529 _eventHandler.blockEvents(
false );
535 return _eventHandler.eventsBlocked();
541 qApp->setOverrideCursor( Qt::BusyCursor );
547 if ( _busyCursorTimer->isActive() )
548 _busyCursorTimer->stop();
550 while ( qApp->overrideCursor() )
551 qApp->restoreOverrideCursor();
560 _busyCursorTimer->start( BUSY_CURSOR_TIMEOUT );
566 return dim == YD_HORIZ ? _defaultSize.width() : _defaultSize.height();
572 int displayArgPos = cmdLine.find(
"-display" );
573 std::string displayNameStr;
575 if ( displayArgPos > 0 && displayArgPos+1 < cmdLine.argc() )
577 displayNameStr = cmdLine[ displayArgPos+1 ];
578 yuiMilestone() <<
"Using X11 display \"" << displayNameStr <<
"\"" << std::endl;
581 const char * displayName = ( displayNameStr.empty() ? 0 : displayNameStr.c_str() );
582 Display * display = XOpenDisplay( displayName );
586 yuiDebug() <<
"Probing X11 display successful" << std::endl;
587 XCloseDisplay( display );
591 string msg =
"Can't open display " + displayNameStr;
592 YUI_THROW( YUIException( msg ) );
599 _eventHandler.deletePendingEventsFor( widget );
605 yuiMilestone() <<
"Closing application" << std::endl;
613 YQUISignalReceiver::YQUISignalReceiver()
619 void YQUISignalReceiver::slotBusyCursor()
625 void YQUISignalReceiver::slotReceivedYCPCommand()
633 qMessageHandler( QtMsgType type,
const QMessageLogContext &,
const QString & msg )
638 yuiMilestone() <<
"<libqt-debug> " << msg << std::endl;
641 #if QT_VERSION >= 0x050500
643 yuiMilestone() <<
"<libqt-info> " << msg << std::endl;
648 yuiWarning() <<
"<libqt-warning> " << msg << std::endl;
652 yuiError() <<
"<libqt-critical>" << msg << std::endl;
656 yuiError() <<
"<libqt-fatal> " << msg << std::endl;
661 if ( QString( msg ).contains(
"Fatal IO error", Qt::CaseInsensitive ) &&
662 QString( msg ).contains(
"client killed", Qt::CaseInsensitive ) )
663 yuiError() <<
"Client killed. Possibly caused by X server shutdown or crash." << std::endl;
void receivedYCPCommand()
Notification that a YCP command has been received on fd_ycp to leave idleLoop()
static YQApplication * yqApp()
Return the global YApplication object as YQApplication.
void forceUnblockEvents()
Force unblocking all events, no matter how many times blockEvents() has This returns 0 if there is no...
int defaultSize(YUIDimension dim) const
Returns size for opt(defaultsize) dialogs (in one dimension).
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...
void calcDefaultSize()
Calculate size of opt(defaultsize) dialogs.
QEventLoop * eventLoop()
Access to this dialog's event loop.
Helper class that acts as a Qt signal receiver for YQUI.
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
YQUI(bool withThreads)
Constructor.
virtual void idleLoop(int fd_ycp)
Idle around until fd_ycp is readable and handle repaints.
void probeX11Display(const YCommandLine &cmdLine)
Probe the X11 display.
virtual bool eventsBlocked() const
Returns 'true' if events are currently blocked.
virtual void deleteNotify(YWidget *widget)
Notification that a widget is being deleted.
void busyCursor()
Show mouse cursor indicating busy state.
void processCommandLineArgs(int argc, char **argv)
Handle command line args.
virtual void uiThreadDestructor()
Destroy whatever needs to be destroyed within the UI thread.
virtual void blockEvents(bool block=true)
Block (or unblock) events.
void timeoutBusyCursor()
Show mouse cursor indicating busy state if the UI is unable to respond to user input for more than a ...
bool close()
Application shutdown.
void normalCursor()
Show normal mouse cursor not indicating busy status.
void initUI()
Post-constructor initialization.
virtual ~YQUI()
Destructor.
void raiseFatalError()
Raise a fatal UI error.
static void setTextdomain(const char *domain)
Initialize and set a textdomain for gettext()
static YQUI * ui()
Access the global Qt-UI.
virtual YWidgetFactory * createWidgetFactory()
Create the widget factory that provides all the createXY() methods for standard (mandatory, i.e.