28 #include "kmainwindow_p.h"
29 #include "kmainwindowiface_p.h"
30 #include "ktoolbarhandler_p.h"
36 #include <QtCore/QList>
37 #include <QtCore/QObject>
38 #include <QtCore/QTimer>
39 #include <QtGui/QCloseEvent>
40 #include <QtGui/QDesktopWidget>
41 #include <QtGui/QDockWidget>
42 #include <QtGui/QLayout>
43 #include <QtGui/QSessionManager>
44 #include <QtGui/QStyle>
45 #include <QtGui/QWidget>
64 #include <qx11info_x11.h>
78 return KGlobal::findDirectChild<KMenuBar *>(mw);
85 return KGlobal::findDirectChild<KStatusBar *>(mw);
95 class DockResizeListener :
public QObject
99 virtual ~DockResizeListener();
100 virtual bool eventFilter(
QObject *watched, QEvent *event);
106 DockResizeListener::DockResizeListener(
KMainWindow *win) :
112 DockResizeListener::~DockResizeListener()
116 bool DockResizeListener::eventFilter(
QObject *watched, QEvent *event)
118 switch( event->type() ) {
122 m_win->k_ptr->setSettingsDirty(KMainWindowPrivate::CompressCalls);
129 return QObject::eventFilter(watched, event);
141 bool dummyInit() {
return true; }
158 group.writeEntry(
"NumberOfWindows", n );
165 if ( sm.allowsInteraction() ) {
166 bool canceled =
false;
170 if ( !window->testAttribute( Qt::WA_WState_Hidden ) ) {
172 QApplication::sendEvent( window, &e );
173 canceled = !e.isAccepted();
198 if ( !window->testAttribute( Qt::WA_WState_Hidden ) ) {
217 KMainWindow::KMainWindow(
QWidget* parent, Qt::WindowFlags f )
218 :
QMainWindow(parent, f), k_ptr(new KMainWindowPrivate)
236 KGlobal::setAllowQuit(
true);
242 q->setAttribute( Qt::WA_DeleteOnClose );
251 qApp->setQuitOnLastWindowClosed(
false);
256 QObject::connect(qApp, SIGNAL(aboutToQuit()), q, SLOT(_k_shuttingDown()));
258 q, SLOT(_k_slotSettingsChanged(
int)));
263 sMemberList->append( q );
265 settingsDirty =
false;
266 autoSaveSettings =
false;
267 autoSaveWindowSize =
true;
271 shuttingDown =
false;
277 if (args && args->
isSet(
"geometry"))
280 if ( geometry.isNull() )
281 care_about_geometry =
false;
283 q->parseGeometry(
false);
286 q->setWindowTitle( KGlobal::caption() );
288 dockResizeListener =
new DockResizeListener(_q);
289 letDirtySettings =
true;
296 for(
int i = s.length() - 1;
300 if( s[ i ] ==
'#' && i != s.length() - 1 )
302 if( !s[ i ].isDigit())
310 register ushort u = c.unicode();
311 return (u >=
'a' && u <=
'z')
312 || (u >=
'A' && u <=
'Z')
313 || (u >=
'0' && u <=
'9')
314 || (u ==
'_') || (u ==
'/');
322 int unusedNumber = 1;
324 bool startNumberingImmediately =
true;
325 bool tryReuse =
false;
326 if ( name.isEmpty() )
328 objname =
"MainWindow#";
330 else if( name.endsWith( QLatin1Char(
'#' ) ) )
338 startNumberingImmediately =
false;
343 startNumberingImmediately =
false;
347 if ( startNumberingImmediately )
354 if( w != q && w->objectName() == s )
363 objname = name.left( name.length() - 1 );
367 s.setNum( ++unusedNumber );
370 q->setObjectName( s );
372 q->setWindowRole( s );
374 dbusName =
'/' + qApp->applicationName() +
'/' + q->objectName().replace(QLatin1Char(
'/'), QLatin1Char(
'_'));
376 const int len = dbusName.length();
377 for (
int i = 0; i < len; ++i ) {
379 dbusName[i] = QLatin1Char(
'_');
382 QDBusConnection::sessionBus().registerObject(dbusName, q, QDBusConnection::ExportScriptableSlots |
383 QDBusConnection::ExportScriptableProperties |
384 QDBusConnection::ExportNonScriptableSlots |
385 QDBusConnection::ExportNonScriptableProperties |
386 QDBusConnection::ExportAdaptors);
389 void KMainWindowPrivate::setSettingsDirty(CallCompression callCompression)
391 if (!letDirtySettings) {
395 settingsDirty =
true;
396 if (autoSaveSettings) {
397 if (callCompression == CompressCalls) {
398 if (!settingsTimer) {
399 settingsTimer =
new QTimer(q);
400 settingsTimer->setInterval(500);
401 settingsTimer->setSingleShot(
true);
402 QObject::connect(settingsTimer, SIGNAL(
timeout()), q, SLOT(saveAutoSaveSettings()));
404 settingsTimer->start();
411 void KMainWindowPrivate::setSizeDirty()
413 if (autoSaveWindowSize) {
415 sizeTimer =
new QTimer(q);
416 sizeTimer->setInterval(500);
417 sizeTimer->setSingleShot(
true);
418 QObject::connect(sizeTimer, SIGNAL(
timeout()), q, SLOT(_k_slotSaveAutoSaveSize()));
429 if (args->
isSet(
"geometry"))
430 cmdlineGeometry = args->
getOption(
"geometry");
432 assert ( !cmdlineGeometry.isNull() );
433 assert ( d->care_about_geometry );
439 int m = XParseGeometry( cmdlineGeometry.toLatin1(), &x, &y, (
unsigned int*)&w, (
unsigned int*)&h);
441 const QSize minSize = minimumSize();
442 const QSize maxSize = maximumSize();
443 if ( !(m & WidthValue) )
445 if ( !(m & HeightValue) )
447 w = qMin(w,maxSize.width());
448 h = qMin(h,maxSize.height());
449 w = qMax(w,minSize.width());
450 h = qMax(h,minSize.height());
453 if ( (m & XNegative) )
454 x = KApplication::desktop()->width() + x - w;
455 else if ( !(m & XValue) )
457 if ( (m & YNegative) )
458 y = KApplication::desktop()->height() + y - h;
459 else if ( !(m & YValue) )
469 sMemberList->removeAll(
this );
470 delete static_cast<QObject *
>(
k_ptr->dockResizeListener);
479 if ( aboutAppText.isEmpty() )
480 d->helpMenu =
new KHelpMenu(
this, KGlobal::mainComponent().aboutData(), showWhatsThis);
482 d->helpMenu =
new KHelpMenu(
this, aboutAppText, showWhatsThis );
488 return d->helpMenu->menu();
500 return d->helpMenu->menu();
505 if ( !qApp->isSessionRestored() )
512 const int n = group.
readEntry(
"NumberOfWindows", 1 );
513 return number >= 1 && number <= n;
518 if ( !qApp->isSessionRestored() )
525 s.prepend( QLatin1String(
"WindowProperties") );
528 if ( !group.
hasKey(
"ClassName" ) )
566 setWindowTitle(caption);
577 d->helpMenu->appHelpActivated();
585 if (d->settingsTimer && d->settingsTimer->isActive()) {
586 d->settingsTimer->stop();
589 if (d->sizeTimer && d->sizeTimer->isActive()) {
590 d->sizeTimer->stop();
591 d->_k_slotSaveAutoSaveSize();
597 int not_withdrawn = 0;
599 if ( !mw->isHidden() && mw->isTopLevel() && mw != this )
603 if ( !no_query_exit && not_withdrawn <= 0 ) {
604 if (!(
queryExit() && ( !
kapp || !
kapp->sessionSaving() ) && !d->shuttingDown )) {
637 const bool oldASWS = d->autoSaveWindowSize;
638 d->autoSaveWindowSize =
true;
642 s.prepend(QLatin1String(
"WindowProperties"));
647 cg.
writeEntry(QLatin1String(
"ObjectName"), objectName());
648 cg.
writeEntry(QLatin1String(
"ClassName"), metaObject()->className());
656 d->autoSaveWindowSize = oldASWS;
665 if ( d->autoSaveWindowSize )
672 const QByteArray state = saveState();
677 if(!cg.
hasDefault(
"StatusBar") && !sb->isHidden() )
680 cg.
writeEntry(
"StatusBar", sb->isHidden() ?
"Disabled" :
"Enabled");
685 const QString MenuBar = QLatin1String(
"MenuBar");
686 if(!cg.
hasDefault(
"MenuBar") && !mb->isHidden() )
689 cg.
writeEntry(
"MenuBar", mb->isHidden() ?
"Disabled" :
"Enabled");
704 group += (toolbar->objectName().isEmpty() ? QString::number(n) :
QString(
" ")+toolbar->objectName());
716 const bool oldLetDirtySettings = d->letDirtySettings;
717 d->letDirtySettings =
false;
725 s.prepend(QLatin1String(
"WindowProperties"));
730 if ( cg.
hasKey(QLatin1String(
"ObjectName" )) )
731 setObjectName( cg.
readEntry(
"ObjectName").toLatin1());
733 d->sizeApplied =
false;
741 d->letDirtySettings = oldLetDirtySettings;
749 kDebug(200) <<
"KMainWindow::applyMainWindowSettings " << cg.
name();
751 QWidget *focusedWidget = QApplication::focusWidget();
753 const bool oldLetDirtySettings = d->letDirtySettings;
754 d->letDirtySettings =
false;
756 if (!d->sizeApplied) {
758 d->sizeApplied =
true;
764 if ( entry ==
"Disabled" )
773 if ( entry ==
"Disabled" )
781 if ( entry ==
"Disabled" )
792 group += (toolbar->objectName().isEmpty() ? QString::number(n) :
QString(
" ")+toolbar->objectName());
802 state = QByteArray::fromBase64(state);
808 focusedWidget->setFocus();
811 d->settingsDirty =
false;
812 d->letDirtySettings = oldLetDirtySettings;
835 int scnum = QApplication::desktop()->screenNumber(window());
836 QRect desk = QApplication::desktop()->screenGeometry(scnum);
838 QString geometryKey = QString::fromLatin1(
"geometry-%1-%2").arg(desk.width()).arg(desk.height());
839 QByteArray geometry = _cg.
readEntry( geometryKey, QByteArray() );
841 if (!restoreGeometry( QByteArray::fromBase64(geometry) ))
842 move( (desk.width()-width())/2, (desk.height()-height())/2 );
848 int scnum = QApplication::desktop()->screenNumber(window());
849 QRect desk = QApplication::desktop()->screenGeometry(scnum);
852 QString geometryKey = QString::fromLatin1(
"geometry-%1-%2").arg(desk.width()).arg(desk.height());
853 QByteArray geometry = saveGeometry();
855 cg.
writeEntry( geometryKey, geometry.toBase64() );
861 int scnum = QApplication::desktop()->screenNumber(window());
862 QRect desk = QApplication::desktop()->screenGeometry(scnum);
872 w = desk.width() + 1;
873 h = desk.height() + 1;
882 QRect size( desk.width(), w, desk.height(), h );
883 bool defaultSize = (size == d->defaultWindowSize);
884 QString widthString = QString::fromLatin1(
"Width %1").arg(desk.width());
885 QString heightString = QString::fromLatin1(
"Height %1").arg(desk.height());
886 if (!cg.hasDefault(widthString) && defaultSize)
887 cg.revertToDefault(widthString);
889 cg.writeEntry(widthString, w );
891 if (!cg.hasDefault(heightString) && defaultSize)
892 cg.revertToDefault(heightString);
894 cg.writeEntry(heightString, h );
900 if (d->care_about_geometry) {
904 const int scnum = QApplication::desktop()->screenNumber(window());
905 QRect desk = QApplication::desktop()->screenGeometry(scnum);
907 if ( d->defaultWindowSize.isNull() )
908 d->defaultWindowSize =
QRect(desk.width(), width(), desk.height(), height());
909 const QSize size( config.
readEntry( QString::fromLatin1(
"Width %1").arg(desk.width()), 0 ),
910 config.
readEntry( QString::fromLatin1(
"Height %1").arg(desk.height()), 0 ) );
911 if ( !size.isEmpty() ) {
913 int state = ( size.width() > desk.width() ?
NET::MaxHoriz : 0 )
916 resize( desk.width(), desk.height() );
919 resize( desk.width(), size.height() );
921 resize( size.width(), desk.height() );
927 if (size.width() > desk.width() || size.height() > desk.height())
928 setWindowState( Qt::WindowMaximized );
940 return d->care_about_geometry;
946 d->care_about_geometry =
false;
952 d->setSettingsDirty();
958 return d->settingsDirty;
967 bool saveWindowSize )
970 d->autoSaveSettings =
true;
971 d->autoSaveGroup = group;
974 if (!saveWindowSize && d->sizeTimer) {
975 d->sizeTimer->stop();
985 d->autoSaveSettings =
false;
986 if (d->settingsTimer) {
987 d->settingsTimer->stop();
994 return d->autoSaveSettings;
1000 return d->autoSaveSettings ? d->autoSaveGroup.name() :
QString();
1006 return d->autoSaveSettings ? d->autoSaveGroup :
KConfigGroup();
1012 Q_ASSERT( d->autoSaveSettings );
1015 d->autoSaveGroup.sync();
1016 d->settingsDirty =
false;
1022 switch( ev->type() ) {
1026 case QEvent::Resize:
1029 case QEvent::Polish:
1032 case QEvent::ChildPolished:
1034 QChildEvent *
event =
static_cast<QChildEvent*
>(ev);
1035 QDockWidget *dock = qobject_cast<QDockWidget*>(
event->child());
1039 connect(dock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),
1041 connect(dock, SIGNAL(visibilityChanged(
bool)),
1043 connect(dock, SIGNAL(topLevelChanged(
bool)),
1048 dock->installEventFilter(
k_ptr->dockResizeListener);
1049 }
else if (toolbar) {
1052 toolbar->installEventFilter(
k_ptr->dockResizeListener);
1053 }
else if (menubar) {
1056 menubar->installEventFilter(
k_ptr->dockResizeListener);
1060 case QEvent::ChildRemoved:
1062 QChildEvent *
event =
static_cast<QChildEvent*
>(ev);
1063 QDockWidget *dock = qobject_cast<QDockWidget*>(
event->child());
1067 disconnect(dock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),
1069 disconnect(dock, SIGNAL(visibilityChanged(
bool)),
1071 disconnect(dock, SIGNAL(topLevelChanged(
bool)),
1073 dock->removeEventFilter(
k_ptr->dockResizeListener);
1074 }
else if (toolbar) {
1075 toolbar->removeEventFilter(
k_ptr->dockResizeListener);
1076 }
else if (menubar) {
1077 menubar->removeEventFilter(
k_ptr->dockResizeListener);
1084 return QMainWindow::event( ev );
1116 void KMainWindowPrivate::_k_shuttingDown()
1120 static bool reentrancy_protection =
false;
1121 if (!reentrancy_protection)
1123 reentrancy_protection =
true;
1124 shuttingDown =
true;
1127 reentrancy_protection =
false;
1131 void KMainWindowPrivate::_k_slotSettingsChanged(
int category)
1144 void KMainWindowPrivate::_k_slotSaveAutoSaveSize()
1146 if (autoSaveGroup.isValid()) {
1154 if (childName.isEmpty())
1155 childName =
"mainToolBar";
1157 KToolBar *tb = findChild<KToolBar*>(childName);
1169 foreach (
QObject* child, children())
1180 return k_func()->dbusName;
1183 #include "kmainwindow.moc"