25 #include <rpc/types.h>
33 #include <QSocketNotifier>
34 #include <QDesktopWidget>
40 #define YUILogComponent "qt-ui"
41 #include <yui/YUILog.h>
42 #include <yui/Libyui_config.h>
46 #include <yui/YEvent.h>
47 #include <yui/YCommandLine.h>
48 #include <yui/YButtonBox.h>
49 #include <yui/YUISymbols.h>
51 #include "QY2Styler.h"
52 #include "YQApplication.h"
54 #include "YQWidgetFactory.h"
55 #include "YQOptionalWidgetFactory.h"
68 #define BUSY_CURSOR_TIMEOUT 200 // milliseconds
69 #define VERBOSE_EVENT_LOOP 0
73 static void qMessageHandler( QtMsgType type,
const char * msg );
77 YUI * createUI(
bool withThreads )
83 if ( ui && ! withThreads )
96 , _do_exit_loop( false )
98 yuiDebug() <<
"YQUI constructor start" << std::endl;
99 yuiMilestone() <<
"This is libyui-qt " << VERSION << std::endl;
102 _uiInitialized =
false;
105 _usingVisionImpairedPalette =
false;
107 screenShotNameTemplate =
"";
110 qInstallMsgHandler( 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 _normalPalette = qApp->palette();
161 (void) QY2Styler::styler();
163 setButtonOrderFromEnvironment();
167 _do_exit_loop =
false;
175 _main_win =
new QWidget( 0, Qt::Window );
176 _main_win->setFocusPolicy( Qt::StrongFocus );
177 _main_win->setObjectName(
"main_window" );
179 _main_win->resize( _defaultSize );
182 _main_win->move( 0, 0 );
191 if ( progName ==
"y2base" )
192 _applicationTitle = QString(
"YaST2" );
194 _applicationTitle = fromUTF8( progName );
197 int displayArgPos = cmdLine.find(
"-display" );
200 if ( displayArgPos > 0 && displayArgPos+1 < cmdLine.argc() )
201 displayName = cmdLine[ displayArgPos+1 ].c_str();
203 displayName = getenv(
"DISPLAY" );
206 char hostname[ MAXHOSTNAMELEN+1 ];
207 if ( gethostname( hostname,
sizeof( hostname )-1 ) == 0 )
208 hostname[
sizeof( hostname ) -1 ] =
'\0';
213 if ( !displayName.startsWith(
":" ) && strlen( hostname ) > 0 )
215 _applicationTitle += QString(
"@" );
216 _applicationTitle += fromUTF8( hostname );
228 YButtonBoxMargins buttonBoxMargins;
229 buttonBoxMargins.left = 8;
230 buttonBoxMargins.right = 8;
231 buttonBoxMargins.top = 6;
232 buttonBoxMargins.bottom = 6;
234 buttonBoxMargins.spacing = 4;
235 buttonBoxMargins.helpButtonExtraSpacing = 16;
236 YButtonBox::setDefaultMargins( buttonBoxMargins );
258 QString qt_lib_name = QString( QTLIBDIR
"/libQtGui.so.%1" ).arg( QT_VERSION >> 16 );;
259 void * qt_lib = dlopen( qt_lib_name.toUtf8().constData(), RTLD_LAZY | RTLD_GLOBAL );
261 yuiMilestone() <<
"Forcing " << qt_lib_name.toUtf8().constData() <<
" open successful" << std::endl;
263 yuiError() <<
"Forcing " << qt_lib_name.toUtf8().constData() <<
" open failed" << std::endl;
267 qApp->setFont(
yqApp()->currentFont() );
271 QObject::connect( _busyCursorTimer, SIGNAL( timeout() ),
272 _signalReceiver, SLOT ( slotBusyCursor() ) );
274 yuiMilestone() <<
"YQUI initialized. Thread ID: 0x"
275 << hex << QThread::currentThreadId () << dec
278 qApp->processEvents();
293 for(
int i=0; i < argc; i++ )
295 QString opt = argv[i];
297 yuiMilestone() <<
"Qt argument: " << argv[i] << std::endl;
301 if ( opt.startsWith(
"--" ) )
304 if ( opt == QString(
"-fullscreen" ) ) _fullscreen =
true;
305 else if ( opt == QString(
"-noborder" ) ) _noborder =
true;
308 else if ( opt == QString(
"-gnome-button-order" ) ) YButtonBox::setLayoutPolicy( YButtonBox::gnomeLayoutPolicy() );
309 else if ( opt == QString(
"-kde-button-order" ) ) YButtonBox::setLayoutPolicy( YButtonBox::kdeLayoutPolicy() );
311 else if ( opt == QString(
"-help" ) )
314 "Command line options for the YaST2 Qt UI:\n"
316 "--nothreads run without additional UI threads\n"
317 "--fullscreen use full screen for `opt(`defaultsize) dialogs\n"
318 "--noborder no window manager border for `opt(`defaultsize) dialogs\n"
319 "--auto-fonts automatically pick fonts, disregard Qt standard settings\n"
320 "--help this help text\n"
322 "--macro <macro-file> play a macro right on startup\n"
324 "-no-wm, -noborder etc. are accepted as well as --no-wm, --noborder\n"
325 "to maintain backwards compatibility.\n"
341 yuiDebug() <<
"Closing down Qt UI." << std::endl;
352 delete _signalReceiver;
361 YUI_CHECK_NEW( factory );
368 YOptionalWidgetFactory *
372 YUI_CHECK_NEW( factory );
379 YQUI::createApplication()
382 YUI_CHECK_NEW( app );
390 QSize primaryScreenSize = qApp->desktop()->screenGeometry( qApp->desktop()->primaryScreen() ).size();
391 QSize availableSize = qApp->desktop()->availableGeometry( qApp->desktop()->primaryScreen() ).size();
395 _defaultSize = availableSize;
397 yuiMilestone() <<
"-fullscreen: using "
398 << _defaultSize.width() <<
" x " << _defaultSize.height()
399 <<
"for `opt(`defaultsize)"
408 if ( _defaultSize.width() < 800 ||
409 _defaultSize.height() < 600 )
411 if ( primaryScreenSize.width() >= 1024 && primaryScreenSize.height() >= 768 )
415 _defaultSize.setWidth ( max( (
int) (availableSize.width() * 0.7), 800 ) );
416 _defaultSize.setHeight( max( (
int) (availableSize.height() * 0.7), 600 ) );
420 _defaultSize = availableSize;
425 yuiMilestone() <<
"Forced size (via -geometry): "
426 << _defaultSize.width() <<
" x " << _defaultSize.height()
431 yuiMilestone() <<
"Default size: "
432 << _defaultSize.width() <<
" x " << _defaultSize.height()
441 _received_ycp_command =
false;
442 QSocketNotifier * notifier =
new QSocketNotifier( fd_ycp, QSocketNotifier::Read );
443 QObject::connect( notifier, SIGNAL( activated(
int ) ),
444 _signalReceiver, SLOT ( slotReceivedYCPCommand() ) );
446 notifier->setEnabled(
true );
453 #if VERBOSE_EVENT_LOOP
454 yuiDebug() <<
"Entering idle loop" << std::endl;
457 QEventLoop eventLoop( qApp );
459 while ( !_received_ycp_command )
460 eventLoop.processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents );
462 #if VERBOSE_EVENT_LOOP
463 yuiDebug() <<
"Leaving idle loop" << std::endl;
472 _received_ycp_command =
true;
480 _eventHandler.sendEvent( event );
490 yuiError() <<
"No dialog" << std::endl;
498 bindtextdomain( domain, YSettings::localeDir().c_str() );
499 bind_textdomain_codeset( domain,
"utf8" );
500 textdomain( domain );
504 extern int _nl_msg_cat_cntr;
516 if ( ++_blockedLevel == 1 )
518 _eventHandler.blockEvents(
true );
522 if ( dialog && dialog->
eventLoop()->isRunning() )
524 yuiWarning() <<
"blocking events in active event loop of " << dialog << std::endl;
531 if ( --_blockedLevel == 0 )
533 _eventHandler.blockEvents(
false );
548 _eventHandler.blockEvents(
false );
554 return _eventHandler.eventsBlocked();
560 qApp->setOverrideCursor( Qt::BusyCursor );
566 if ( _busyCursorTimer->isActive() )
567 _busyCursorTimer->stop();
569 while ( qApp->overrideCursor() )
570 qApp->restoreOverrideCursor();
579 _busyCursorTimer->start( BUSY_CURSOR_TIMEOUT );
585 return dim == YD_HORIZ ? _defaultSize.width() : _defaultSize.height();
591 int displayArgPos = cmdLine.find(
"-display" );
592 std::string displayNameStr;
594 if ( displayArgPos > 0 && displayArgPos+1 < cmdLine.argc() )
596 displayNameStr = cmdLine[ displayArgPos+1 ];
597 yuiMilestone() <<
"Using X11 display \"" << displayNameStr <<
"\"" << std::endl;
600 const char * displayName = ( displayNameStr.empty() ? 0 : displayNameStr.c_str() );
601 Display * display = XOpenDisplay( displayName );
605 yuiDebug() <<
"Probing X11 display successful" << std::endl;
606 XCloseDisplay( display );
610 string msg =
"Can't open display " + displayNameStr;
611 YUI_THROW( YUIException( msg ) );
618 _eventHandler.deletePendingEventsFor( widget );
624 if ( _usingVisionImpairedPalette )
628 _usingVisionImpairedPalette =
false;
634 _usingVisionImpairedPalette =
true;
642 const QColor dark ( 0x20, 0x20, 0x20 );
646 pal.setColor( QPalette::Active, QPalette::Background, Qt::black );
647 pal.setColor( QPalette::Active, QPalette::Foreground, Qt::cyan );
648 pal.setColor( QPalette::Active, QPalette::Text, Qt::cyan );
649 pal.setColor( QPalette::Active, QPalette::Base, dark );
650 pal.setColor( QPalette::Active, QPalette::Button, dark );
651 pal.setColor( QPalette::Active, QPalette::ButtonText, Qt::green );
652 pal.setColor( QPalette::Active, QPalette::Highlight, Qt::yellow );
653 pal.setColor( QPalette::Active, QPalette::HighlightedText, Qt::black );
656 pal.setColor( QPalette::Inactive, QPalette::Background, Qt::black );
657 pal.setColor( QPalette::Inactive, QPalette::Foreground, Qt::cyan );
658 pal.setColor( QPalette::Inactive, QPalette::Text, Qt::cyan );
659 pal.setColor( QPalette::Inactive, QPalette::Base, dark );
660 pal.setColor( QPalette::Inactive, QPalette::Button, dark );
661 pal.setColor( QPalette::Inactive, QPalette::ButtonText, Qt::green );
664 pal.setColor( QPalette::Disabled, QPalette::Background, Qt::black );
665 pal.setColor( QPalette::Disabled, QPalette::Foreground, Qt::gray );
666 pal.setColor( QPalette::Disabled, QPalette::Text, Qt::gray );
667 pal.setColor( QPalette::Disabled, QPalette::Base, dark );
668 pal.setColor( QPalette::Disabled, QPalette::Button, dark );
669 pal.setColor( QPalette::Disabled, QPalette::ButtonText, Qt::gray );
678 yuiMilestone() <<
"Closing application" << std::endl;
686 YQUISignalReceiver::YQUISignalReceiver()
692 void YQUISignalReceiver::slotBusyCursor()
698 void YQUISignalReceiver::slotReceivedYCPCommand()
706 qMessageHandler( QtMsgType type,
const char * msg )
711 yuiMilestone() <<
"<libqt-debug> " << msg << std::endl;
715 yuiWarning() <<
"<libqt-warning> " << msg << std::endl;
719 yuiError() <<
"<libqt-critical>" << msg << std::endl;
723 yuiError() <<
"<libqt-fatal> " << msg << std::endl;
728 if ( QString( msg ).contains(
"Fatal IO error", Qt::CaseInsensitive ) &&
729 QString( msg ).contains(
"client killed", Qt::CaseInsensitive ) )
730 yuiError() <<
"Client killed. Possibly caused by X server shutdown or crash." << std::endl;