00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "kmainwindow.h"
00028 #include "kmainwindow_p.h"
00029 #include "kmainwindowiface_p.h"
00030 #include "ktoolbarhandler.h"
00031 #include "kwhatsthismanager_p.h"
00032 #include "kcmdlineargs.h"
00033 #include "ktoggleaction.h"
00034 #include "ksessionmanager.h"
00035 #include "kstandardaction.h"
00036
00037 #include <QtCore/QList>
00038 #include <QtCore/QObject>
00039 #include <QtCore/QTimer>
00040 #include <QtGui/QCloseEvent>
00041 #include <QtGui/QDesktopWidget>
00042 #include <QtGui/QDockWidget>
00043 #include <QtGui/QLayout>
00044 #include <QtGui/QSessionManager>
00045 #include <QtGui/QStyle>
00046 #include <QtGui/QWidget>
00047
00048 #include <kaction.h>
00049 #include <kapplication.h>
00050 #include <kauthorized.h>
00051 #include <kconfig.h>
00052 #include <kdebug.h>
00053 #include <kdialog.h>
00054 #include <khelpmenu.h>
00055 #include <klocale.h>
00056 #include <kmenubar.h>
00057 #include <kstandarddirs.h>
00058 #include <kstatusbar.h>
00059 #include <ktoolbar.h>
00060 #include <kwindowsystem.h>
00061 #include <kconfiggroup.h>
00062 #include <kglobalsettings.h>
00063
00064 #if defined Q_WS_X11
00065 #include <qx11info_x11.h>
00066 #include <netwm.h>
00067 #endif
00068
00069 #include <stdlib.h>
00070 #include <ctype.h>
00071 #include <assert.h>
00072
00073 #include <config.h>
00074
00075 static bool no_query_exit = false;
00076
00077 static KMenuBar *internalMenuBar(KMainWindow *mw)
00078 {
00079 return qFindChild<KMenuBar *>(mw);
00080 }
00081
00082 static KStatusBar *internalStatusBar(KMainWindow *mw)
00083 {
00084 const QObjectList &children = mw->children();
00085 for (int i = 0; i < children.size(); ++i) {
00086 KStatusBar* sb = qobject_cast<KStatusBar *>(children.at(i));
00087 if (sb) {
00088 return sb;
00089 }
00090 }
00091 return 0;
00092 }
00093
00101 class DockResizeListener : public QObject
00102 {
00103 public:
00104 DockResizeListener(KMainWindow *win);
00105 virtual ~DockResizeListener();
00106 virtual bool eventFilter(QObject *watched, QEvent *event);
00107
00108 private:
00109 KMainWindow *m_win;
00110 };
00111
00112 DockResizeListener::DockResizeListener(KMainWindow *win) :
00113 QObject(win),
00114 m_win(win)
00115 {
00116 }
00117
00118 DockResizeListener::~DockResizeListener()
00119 {
00120 }
00121
00122 bool DockResizeListener::eventFilter(QObject *watched, QEvent *event)
00123 {
00124 switch( event->type() ) {
00125 case QEvent::Resize:
00126 case QEvent::Move:
00127 case QEvent::Hide:
00128 m_win->k_ptr->setSettingsDirty(KMainWindowPrivate::CompressCalls);
00129 break;
00130
00131 default:
00132 break;
00133 }
00134
00135 return QObject::eventFilter(watched, event);
00136 }
00137
00138 class KMWSessionManager : public KSessionManager
00139 {
00140 public:
00141 KMWSessionManager()
00142 {
00143 }
00144 ~KMWSessionManager()
00145 {
00146 }
00147 bool dummyInit() { return true; }
00148 bool saveState( QSessionManager& )
00149 {
00150 KConfig* config = KApplication::kApplication()->sessionConfig();
00151 if ( KMainWindow::memberList().count() ){
00152
00153
00154 KMainWindow::memberList().first()->saveGlobalProperties(config);
00155 }
00156
00157 int n = 0;
00158 foreach (KMainWindow* mw, KMainWindow::memberList()) {
00159 n++;
00160 mw->savePropertiesInternal(config, n);
00161 }
00162
00163 KConfigGroup group( config, "Number" );
00164 group.writeEntry("NumberOfWindows", n );
00165 return true;
00166 }
00167
00168 bool commitData( QSessionManager& sm )
00169 {
00170
00171 if ( sm.allowsInteraction() ) {
00172 bool canceled = false;
00173 ::no_query_exit = true;
00174
00175 foreach (KMainWindow *window, KMainWindow::memberList()) {
00176 if ( !window->testAttribute( Qt::WA_WState_Hidden ) ) {
00177 QCloseEvent e;
00178 QApplication::sendEvent( window, &e );
00179 canceled = !e.isAccepted();
00180 if (canceled)
00181 break;
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 }
00197 }
00198 ::no_query_exit = false;
00199 if (canceled)
00200 return false;
00201
00202 KMainWindow* last = 0;
00203 foreach (KMainWindow *window, KMainWindow::memberList()) {
00204 if ( !window->testAttribute( Qt::WA_WState_Hidden ) ) {
00205 last = window;
00206 }
00207 }
00208 if ( last )
00209 return last->queryExit();
00210
00211 return true;
00212 }
00213
00214
00215 return true;
00216 }
00217 };
00218
00219 K_GLOBAL_STATIC(KMWSessionManager, ksm)
00220 K_GLOBAL_STATIC(QList<KMainWindow*>, sMemberList)
00221 static bool being_first = true;
00222
00223 KMainWindow::KMainWindow( QWidget* parent, Qt::WFlags f )
00224 : QMainWindow(parent, f), k_ptr(new KMainWindowPrivate)
00225 {
00226 k_ptr->init(this);
00227 }
00228
00229 KMainWindow::KMainWindow(KMainWindowPrivate &dd, QWidget *parent, Qt::WFlags f)
00230 : QMainWindow(parent, f), k_ptr(&dd)
00231 {
00232 k_ptr->init(this);
00233 }
00234
00235 void KMainWindowPrivate::init(KMainWindow *_q)
00236 {
00237 KGlobal::ref();
00238
00239
00240
00241
00242 KGlobal::setAllowQuit(true);
00243
00244 q = _q;
00245
00246 q->setAnimated(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects);
00247
00248 q->setAttribute( Qt::WA_DeleteOnClose );
00249
00250
00251
00252
00253
00254
00255
00256 if (qApp)
00257 qApp->setQuitOnLastWindowClosed(false);
00258
00259 KWhatsThisManager::init ();
00260
00261 helpMenu = 0;
00262
00263
00264 QObject::connect(qApp, SIGNAL(aboutToQuit()), q, SLOT(_k_shuttingDown()));
00265 QObject::connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)),
00266 q, SLOT(_k_slotSettingsChanged(int)));
00267
00268
00269 ksm->dummyInit();
00270
00271 sMemberList->append( q );
00272
00273 settingsDirty = false;
00274 autoSaveSettings = false;
00275 autoSaveWindowSize = true;
00276
00277 settingsTimer = 0;
00278 sizeTimer = 0;
00279 shuttingDown = false;
00280 if ((care_about_geometry = being_first)) {
00281 being_first = false;
00282
00283 QString geometry;
00284 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
00285 if (args && args->isSet("geometry"))
00286 geometry = args->getOption("geometry");
00287
00288 if ( geometry.isNull() )
00289 care_about_geometry = false;
00290 else
00291 q->parseGeometry(false);
00292 }
00293
00294 q->setWindowTitle( KGlobal::caption() );
00295
00296 dockResizeListener = new DockResizeListener(_q);
00297 letDirtySettings = true;
00298
00299 sizeApplied = false;
00300 }
00301
00302 static bool endsWithHashNumber( const QString& s )
00303 {
00304 for( int i = s.length() - 1;
00305 i > 0;
00306 --i )
00307 {
00308 if( s[ i ] == '#' && i != s.length() - 1 )
00309 return true;
00310 if( !s[ i ].isDigit())
00311 break;
00312 }
00313 return false;
00314 }
00315
00316 void KMainWindowPrivate::polish(KMainWindow *q)
00317 {
00318
00319 QString objname;
00320 QString s;
00321 int unusedNumber = 1;
00322 const QString name = q->objectName();
00323 bool startNumberingImmediately = true;
00324 bool tryReuse = false;
00325 if ( name.isEmpty() )
00326 {
00327 objname = "MainWindow#";
00328 }
00329 else if( name.endsWith( QLatin1Char( '#' ) ) )
00330 {
00331 objname = name;
00332 }
00333 else if( endsWithHashNumber( name ))
00334 {
00335 objname = name;
00336 tryReuse = true;
00337 startNumberingImmediately = false;
00338 }
00339 else
00340 {
00341 objname = name;
00342 startNumberingImmediately = false;
00343 }
00344
00345 s = objname;
00346 if ( startNumberingImmediately )
00347 s += '1';
00348
00349 for(;;) {
00350 const QList<QWidget*> list = qApp->topLevelWidgets();
00351 bool found = false;
00352 foreach ( QWidget* w, list ) {
00353 if( w != q && w->objectName() == s )
00354 {
00355 found = true;
00356 break;
00357 }
00358 }
00359 if( !found )
00360 break;
00361 if( tryReuse ) {
00362 objname = name.left( name.length() - 1 );
00363 unusedNumber = 0;
00364 tryReuse = false;
00365 }
00366 s.setNum( ++unusedNumber );
00367 s = objname + s;
00368 }
00369 q->setObjectName( s );
00370 q->winId();
00371 q->setWindowRole( s );
00372
00373 QString pathname = q->objectName();
00374
00375 const int len = pathname.length();
00376 for ( int i = 0; i < len; ++i ) {
00377 if ( !pathname[i].isLetterOrNumber() )
00378 pathname[i] = QLatin1Char('_');
00379 }
00380 pathname = '/' + qApp->applicationName() + '/' + pathname;
00381
00382 dbusName = pathname;
00383 QDBusConnection::sessionBus().registerObject(dbusName, q, QDBusConnection::ExportScriptableSlots |
00384 QDBusConnection::ExportScriptableProperties |
00385 QDBusConnection::ExportNonScriptableSlots |
00386 QDBusConnection::ExportNonScriptableProperties |
00387 QDBusConnection::ExportAdaptors);
00388 }
00389
00390 void KMainWindowPrivate::setSettingsDirty(CallCompression callCompression)
00391 {
00392 if (!letDirtySettings) {
00393 return;
00394 }
00395
00396 settingsDirty = true;
00397 if (autoSaveSettings) {
00398 if (callCompression == CompressCalls) {
00399 if (!settingsTimer) {
00400 settingsTimer = new QTimer(q);
00401 settingsTimer->setInterval(500);
00402 settingsTimer->setSingleShot(true);
00403 QObject::connect(settingsTimer, SIGNAL(timeout()), q, SLOT(saveAutoSaveSettings()));
00404 }
00405 settingsTimer->start();
00406 } else {
00407 q->saveAutoSaveSettings();
00408 }
00409 }
00410 }
00411
00412 void KMainWindowPrivate::setSizeDirty()
00413 {
00414 if (autoSaveWindowSize) {
00415 if (!sizeTimer) {
00416 sizeTimer = new QTimer(q);
00417 sizeTimer->setInterval(500);
00418 sizeTimer->setSingleShot(true);
00419 QObject::connect(sizeTimer, SIGNAL(timeout()), q, SLOT(_k_slotSaveAutoSaveSize()));
00420 }
00421 sizeTimer->start();
00422 }
00423 }
00424
00425 void KMainWindow::parseGeometry(bool parsewidth)
00426 {
00427 K_D(KMainWindow);
00428 QString cmdlineGeometry;
00429 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
00430 if (args->isSet("geometry"))
00431 cmdlineGeometry = args->getOption("geometry");
00432
00433 assert ( !cmdlineGeometry.isNull() );
00434 assert ( d->care_about_geometry );
00435 Q_UNUSED(d);
00436
00437 #if defined Q_WS_X11
00438 int x, y;
00439 int w, h;
00440 int m = XParseGeometry( cmdlineGeometry.toLatin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h);
00441 if (parsewidth) {
00442 const QSize minSize = minimumSize();
00443 const QSize maxSize = maximumSize();
00444 if ( !(m & WidthValue) )
00445 w = width();
00446 if ( !(m & HeightValue) )
00447 h = height();
00448 w = qMin(w,maxSize.width());
00449 h = qMin(h,maxSize.height());
00450 w = qMax(w,minSize.width());
00451 h = qMax(h,minSize.height());
00452 resize(w, h);
00453 } else {
00454 if ( (m & XNegative) )
00455 x = KApplication::desktop()->width() + x - w;
00456 else if ( (m & XValue) )
00457 x = geometry().x();
00458 if ( (m & YNegative) )
00459 y = KApplication::desktop()->height() + y - h;
00460 else if ( (m & YValue) )
00461 y = geometry().y();
00462
00463 move(x, y);
00464 }
00465 #endif
00466 }
00467
00468 KMainWindow::~KMainWindow()
00469 {
00470 sMemberList->removeAll( this );
00471 delete static_cast<QObject *>(k_ptr->dockResizeListener);
00472 delete k_ptr;
00473 KGlobal::deref();
00474 }
00475
00476 KMenu* KMainWindow::helpMenu( const QString &aboutAppText, bool showWhatsThis )
00477 {
00478 K_D(KMainWindow);
00479 if(!d->helpMenu) {
00480 if ( aboutAppText.isEmpty() )
00481 d->helpMenu = new KHelpMenu( this, KGlobal::mainComponent().aboutData(), showWhatsThis);
00482 else
00483 d->helpMenu = new KHelpMenu( this, aboutAppText, showWhatsThis );
00484
00485 if (!d->helpMenu)
00486 return 0;
00487 }
00488
00489 return d->helpMenu->menu();
00490 }
00491
00492 KMenu* KMainWindow::customHelpMenu( bool showWhatsThis )
00493 {
00494 K_D(KMainWindow);
00495 if (!d->helpMenu) {
00496 d->helpMenu = new KHelpMenu( this, QString(), showWhatsThis );
00497 connect(d->helpMenu, SIGNAL( showAboutApplication()),
00498 this, SLOT( showAboutApplication() ));
00499 }
00500
00501 return d->helpMenu->menu();
00502 }
00503
00504 bool KMainWindow::canBeRestored( int number )
00505 {
00506 if ( !qApp->isSessionRestored() )
00507 return false;
00508 KConfig *config = kapp->sessionConfig();
00509 if ( !config )
00510 return false;
00511
00512 KConfigGroup group( config, "Number" );
00513 const int n = group.readEntry( "NumberOfWindows", 1 );
00514 return number >= 1 && number <= n;
00515 }
00516
00517 const QString KMainWindow::classNameOfToplevel( int number )
00518 {
00519 if ( !qApp->isSessionRestored() )
00520 return QString();
00521 KConfig *config = kapp->sessionConfig();
00522 if ( !config )
00523 return QString();
00524 QString s;
00525 s.setNum( number );
00526 s.prepend( QLatin1String("WindowProperties") );
00527
00528 KConfigGroup group( config, s );
00529 if ( !group.hasKey( "ClassName" ) )
00530 return QString();
00531 else
00532 return group.readEntry( "ClassName" );
00533 }
00534
00535 bool KMainWindow::restore( int number, bool show )
00536 {
00537 if ( !canBeRestored( number ) )
00538 return false;
00539 KConfig *config = kapp->sessionConfig();
00540 if ( readPropertiesInternal( config, number ) ){
00541 if ( show )
00542 KMainWindow::show();
00543 return false;
00544 }
00545 return false;
00546 }
00547
00548 void KMainWindow::setCaption( const QString &caption )
00549 {
00550 setPlainCaption( KDialog::makeStandardCaption( caption, this ) );
00551 }
00552
00553 void KMainWindow::setCaption( const QString &caption, bool modified )
00554 {
00555 KDialog::CaptionFlags flags = KDialog::HIGCompliantCaption;
00556
00557 if ( modified )
00558 {
00559 flags |= KDialog::ModifiedCaption;
00560 }
00561
00562 setPlainCaption( KDialog::makeStandardCaption(caption, this, flags) );
00563 }
00564
00565 void KMainWindow::setPlainCaption( const QString &caption )
00566 {
00567 setWindowTitle(caption);
00568 }
00569
00570 void KMainWindow::appHelpActivated( void )
00571 {
00572 K_D(KMainWindow);
00573 if( !d->helpMenu ) {
00574 d->helpMenu = new KHelpMenu( this );
00575 if ( !d->helpMenu )
00576 return;
00577 }
00578 d->helpMenu->appHelpActivated();
00579 }
00580
00581 void KMainWindow::closeEvent ( QCloseEvent *e )
00582 {
00583 K_D(KMainWindow);
00584
00585
00586 if (d->settingsTimer && d->settingsTimer->isActive()) {
00587 d->settingsTimer->stop();
00588 saveAutoSaveSettings();
00589 }
00590 if (d->sizeTimer && d->sizeTimer->isActive()) {
00591 d->sizeTimer->stop();
00592 d->_k_slotSaveAutoSaveSize();
00593 }
00594
00595 if (queryClose()) {
00596 e->accept();
00597
00598 int not_withdrawn = 0;
00599 foreach (KMainWindow* mw, KMainWindow::memberList()) {
00600 if ( !mw->isHidden() && mw->isTopLevel() && mw != this )
00601 not_withdrawn++;
00602 }
00603
00604 if ( !no_query_exit && not_withdrawn <= 0 ) {
00605 if (!( queryExit() && ( !kapp || !kapp->sessionSaving() ) && !d->shuttingDown )) {
00606
00607 e->ignore();
00608 }
00609 }
00610 } else e->ignore();
00611 }
00612
00613 bool KMainWindow::queryExit()
00614 {
00615 return true;
00616 }
00617
00618 bool KMainWindow::queryClose()
00619 {
00620 return true;
00621 }
00622
00623 void KMainWindow::saveGlobalProperties( KConfig* )
00624 {
00625 }
00626
00627 void KMainWindow::readGlobalProperties( KConfig* )
00628 {
00629 }
00630
00631 void KMainWindow::showAboutApplication()
00632 {
00633 }
00634
00635 void KMainWindow::savePropertiesInternal( KConfig *config, int number )
00636 {
00637 K_D(KMainWindow);
00638 const bool oldASWS = d->autoSaveWindowSize;
00639 d->autoSaveWindowSize = true;
00640
00641 QString s;
00642 s.setNum(number);
00643 s.prepend(QLatin1String("WindowProperties"));
00644 KConfigGroup cg(config, s);
00645
00646
00647
00648 cg.writeEntry(QLatin1String("ObjectName"), objectName());
00649 cg.writeEntry(QLatin1String("ClassName"), metaObject()->className());
00650
00651 saveMainWindowSettings(cg);
00652
00653 s.setNum(number);
00654 cg = KConfigGroup(config, s);
00655 saveProperties(cg);
00656
00657 d->autoSaveWindowSize = oldASWS;
00658 }
00659
00660 void KMainWindow::saveMainWindowSettings(const KConfigGroup &_cg)
00661 {
00662 K_D(KMainWindow);
00663
00664
00665
00666 if ( d->autoSaveWindowSize )
00667 saveWindowSize( _cg );
00668
00669 KConfigGroup cg(_cg);
00670
00671
00672
00673 const QByteArray state = saveState();
00674 cg.writeEntry(QString("State"), state.toBase64());
00675
00676 QStatusBar* sb = internalStatusBar(this);
00677 if (sb) {
00678 if(!cg.hasDefault("StatusBar") && !sb->isHidden() )
00679 cg.revertToDefault("StatusBar");
00680 else
00681 cg.writeEntry("StatusBar", sb->isHidden() ? "Disabled" : "Enabled");
00682 }
00683
00684 QMenuBar* mb = internalMenuBar(this);
00685 if (mb) {
00686 const QString MenuBar = QLatin1String("MenuBar");
00687 if(!cg.hasDefault("MenuBar") && !mb->isHidden() )
00688 cg.revertToDefault("MenuBar");
00689 else
00690 cg.writeEntry("MenuBar", mb->isHidden() ? "Disabled" : "Enabled");
00691 }
00692
00693 if ( !autoSaveSettings() || cg.name() == autoSaveGroup() ) {
00694 if(!cg.hasDefault("ToolBarsMovable") && !KToolBar::toolBarsLocked())
00695 cg.revertToDefault("ToolBarsMovable");
00696 else
00697 cg.writeEntry("ToolBarsMovable", KToolBar::toolBarsLocked() ? "Disabled" : "Enabled");
00698 }
00699
00700 int n = 1;
00701 foreach (KToolBar* toolbar, toolBars()) {
00702 QString group("Toolbar");
00703
00704
00705 group += (toolbar->objectName().isEmpty() ? QString::number(n) : QString(" ")+toolbar->objectName());
00706
00707 KConfigGroup toolbarGroup(&cg, group);
00708 toolbar->saveSettings(toolbarGroup);
00709 n++;
00710 }
00711 }
00712
00713 bool KMainWindow::readPropertiesInternal( KConfig *config, int number )
00714 {
00715 K_D(KMainWindow);
00716
00717 const bool oldLetDirtySettings = d->letDirtySettings;
00718 d->letDirtySettings = false;
00719
00720 if ( number == 1 )
00721 readGlobalProperties( config );
00722
00723
00724 QString s;
00725 s.setNum(number);
00726 s.prepend(QLatin1String("WindowProperties"));
00727
00728 KConfigGroup cg(config, s);
00729
00730
00731 if ( cg.hasKey(QLatin1String("ObjectName" )) )
00732 setObjectName( cg.readEntry("ObjectName").toLatin1());
00733
00734 d->sizeApplied = false;
00735
00736 applyMainWindowSettings(cg);
00737
00738 s.setNum(number);
00739 KConfigGroup grp(config, s);
00740 readProperties(grp);
00741
00742 d->letDirtySettings = oldLetDirtySettings;
00743
00744 return true;
00745 }
00746
00747 void KMainWindow::applyMainWindowSettings(const KConfigGroup &cg, bool force)
00748 {
00749 K_D(KMainWindow);
00750 kDebug(200) << "KMainWindow::applyMainWindowSettings " << cg.name();
00751
00752 QWidget *focusedWidget = QApplication::focusWidget();
00753
00754 const bool oldLetDirtySettings = d->letDirtySettings;
00755 d->letDirtySettings = false;
00756
00757 if (!d->sizeApplied) {
00758 restoreWindowSize(cg);
00759 d->sizeApplied = true;
00760 }
00761
00762 QStatusBar* sb = internalStatusBar(this);
00763 if (sb) {
00764 QString entry = cg.readEntry("StatusBar", "Enabled");
00765 if ( entry == "Disabled" )
00766 sb->hide();
00767 else
00768 sb->show();
00769 }
00770
00771 QMenuBar* mb = internalMenuBar(this);
00772 if (mb) {
00773 QString entry = cg.readEntry ("MenuBar", "Enabled");
00774 if ( entry == "Disabled" )
00775 mb->hide();
00776 else
00777 mb->show();
00778 }
00779
00780 if ( !autoSaveSettings() || cg.name() == autoSaveGroup() ) {
00781 QString entry = cg.readEntry ("ToolBarsMovable", "Enabled");
00782 if ( entry == "Disabled" )
00783 KToolBar::setToolBarsLocked(true);
00784 else
00785 KToolBar::setToolBarsLocked(false);
00786 }
00787
00788 int n = 1;
00789 foreach (KToolBar* toolbar, toolBars()) {
00790 QString group("Toolbar");
00791
00792
00793 group += (toolbar->objectName().isEmpty() ? QString::number(n) : QString(" ")+toolbar->objectName());
00794
00795 KConfigGroup toolbarGroup(&cg, group);
00796 toolbar->applySettings(toolbarGroup, force);
00797 n++;
00798 }
00799
00800 QByteArray state;
00801 if (cg.hasKey("State")) {
00802 state = cg.readEntry("State", state);
00803 state = QByteArray::fromBase64(state);
00804
00805 restoreState(state);
00806 }
00807
00808 if (focusedWidget) {
00809 focusedWidget->setFocus();
00810 }
00811
00812 d->settingsDirty = false;
00813 d->letDirtySettings = oldLetDirtySettings;
00814 }
00815
00816 #ifdef Q_WS_WIN
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 void KMainWindow::restoreWindowSize( const KConfigGroup & _cg )
00833 {
00834 K_D(KMainWindow);
00835
00836 int scnum = QApplication::desktop()->screenNumber(parentWidget());
00837 QRect desk = QApplication::desktop()->screenGeometry(scnum);
00838
00839
00840 if (QApplication::desktop()->isVirtualDesktop())
00841 desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen());
00842
00843 QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desk.width()).arg(desk.height());
00844 QByteArray geometry = _cg.readEntry( geometryKey, QByteArray() );
00845
00846 if (!restoreGeometry( QByteArray::fromBase64(geometry) ))
00847 move( (desk.width()-width())/2, (desk.height()-height())/2 );
00848 }
00849
00850 void KMainWindow::saveWindowSize( const KConfigGroup & _cg ) const
00851 {
00852 K_D(const KMainWindow);
00853 int scnum = QApplication::desktop()->screenNumber(parentWidget());
00854 QRect desk = QApplication::desktop()->screenGeometry(scnum);
00855
00856
00857 if (QApplication::desktop()->isVirtualDesktop())
00858 desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen());
00859
00860
00861 QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desk.width()).arg(desk.height());
00862 QByteArray geometry = saveGeometry();
00863 KConfigGroup cg(_cg);
00864 cg.writeEntry( geometryKey, geometry.toBase64() );
00865 }
00866 #else
00867 void KMainWindow::saveWindowSize( const KConfigGroup & _cg ) const
00868 {
00869 K_D(const KMainWindow);
00870 int scnum = QApplication::desktop()->screenNumber(parentWidget());
00871 QRect desk = QApplication::desktop()->screenGeometry(scnum);
00872
00873
00874 if (QApplication::desktop()->isVirtualDesktop())
00875 desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen());
00876
00877 int w, h;
00878 #if defined Q_WS_X11
00879
00880 KWindowInfo info = KWindowSystem::windowInfo( winId(), NET::WMState );
00881 w = info.state() & NET::MaxHoriz ? desk.width() + 1 : width();
00882 h = info.state() & NET::MaxVert ? desk.height() + 1 : height();
00883 #else
00884 if (isMaximized()) {
00885 w = desk.width() + 1;
00886 h = desk.height() + 1;
00887 } else {
00888 w = width();
00889 h = height();
00890 }
00891
00892 #endif
00893 KConfigGroup cg(_cg);
00894
00895 QRect size( desk.width(), w, desk.height(), h );
00896 bool defaultSize = (size == d->defaultWindowSize);
00897 QString widthString = QString::fromLatin1("Width %1").arg(desk.width());
00898 QString heightString = QString::fromLatin1("Height %1").arg(desk.height());
00899 if (!cg.hasDefault(widthString) && defaultSize)
00900 cg.revertToDefault(widthString);
00901 else
00902 cg.writeEntry(widthString, w );
00903
00904 if (!cg.hasDefault(heightString) && defaultSize)
00905 cg.revertToDefault(heightString);
00906 else
00907 cg.writeEntry(heightString, h );
00908 }
00909
00910 void KMainWindow::restoreWindowSize( const KConfigGroup & config )
00911 {
00912 K_D(KMainWindow);
00913 if (d->care_about_geometry) {
00914 parseGeometry(true);
00915 } else {
00916
00917 const int scnum = QApplication::desktop()->screenNumber(parentWidget());
00918 QRect desk = QApplication::desktop()->screenGeometry(scnum);
00919
00920
00921 if (QApplication::desktop()->isVirtualDesktop())
00922 desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen());
00923
00924 if ( d->defaultWindowSize.isNull() )
00925 d->defaultWindowSize = QRect(desk.width(), width(), desk.height(), height());
00926 const QSize size( config.readEntry( QString::fromLatin1("Width %1").arg(desk.width()), 0 ),
00927 config.readEntry( QString::fromLatin1("Height %1").arg(desk.height()), 0 ) );
00928 if ( !size.isEmpty() ) {
00929 #ifdef Q_WS_X11
00930 int state = ( size.width() > desk.width() ? NET::MaxHoriz : 0 )
00931 | ( size.height() > desk.height() ? NET::MaxVert : 0 );
00932 if(( state & NET::Max ) == NET::Max )
00933 resize( desk.width(), desk.height() );
00934
00935 else if(( state & NET::MaxHoriz ) == NET::MaxHoriz )
00936 resize( desk.width(), size.height() );
00937 else if(( state & NET::MaxVert ) == NET::MaxVert )
00938 resize( size.width(), desk.height() );
00939 else
00940 resize( size );
00941
00942 KWindowSystem::setState( winId(), state );
00943 #else
00944 if (size.width() > desk.width() || size.height() > desk.height())
00945 setWindowState( Qt::WindowMaximized );
00946 else
00947 resize( size );
00948 #endif
00949 }
00950 }
00951 }
00952 #endif
00953
00954 bool KMainWindow::initialGeometrySet() const
00955 {
00956 K_D(const KMainWindow);
00957 return d->care_about_geometry;
00958 }
00959
00960 void KMainWindow::ignoreInitialGeometry()
00961 {
00962 K_D(KMainWindow);
00963 d->care_about_geometry = false;
00964 }
00965
00966 void KMainWindow::setSettingsDirty()
00967 {
00968 K_D(KMainWindow);
00969 d->setSettingsDirty();
00970 }
00971
00972 bool KMainWindow::settingsDirty() const
00973 {
00974 K_D(const KMainWindow);
00975 return d->settingsDirty;
00976 }
00977
00978 void KMainWindow::setAutoSaveSettings( const QString & groupName, bool saveWindowSize )
00979 {
00980 setAutoSaveSettings(KConfigGroup(KGlobal::config(), groupName), saveWindowSize);
00981 }
00982
00983 void KMainWindow::setAutoSaveSettings( const KConfigGroup & group,
00984 bool saveWindowSize )
00985 {
00986 K_D(KMainWindow);
00987 d->autoSaveSettings = true;
00988 d->autoSaveGroup = group;
00989 d->autoSaveWindowSize = saveWindowSize;
00990
00991 if (!saveWindowSize && d->sizeTimer) {
00992 d->sizeTimer->stop();
00993 }
00994
00995
00996 applyMainWindowSettings(d->autoSaveGroup);
00997 }
00998
00999 void KMainWindow::resetAutoSaveSettings()
01000 {
01001 K_D(KMainWindow);
01002 d->autoSaveSettings = false;
01003 if (d->settingsTimer) {
01004 d->settingsTimer->stop();
01005 }
01006 }
01007
01008 bool KMainWindow::autoSaveSettings() const
01009 {
01010 K_D(const KMainWindow);
01011 return d->autoSaveSettings;
01012 }
01013
01014 QString KMainWindow::autoSaveGroup() const
01015 {
01016 K_D(const KMainWindow);
01017 return d->autoSaveSettings ? d->autoSaveGroup.name() : QString();
01018 }
01019
01020 KConfigGroup KMainWindow::autoSaveConfigGroup() const
01021 {
01022 K_D(const KMainWindow);
01023 return d->autoSaveSettings ? d->autoSaveGroup : KConfigGroup();
01024 }
01025
01026 void KMainWindow::saveAutoSaveSettings()
01027 {
01028 K_D(KMainWindow);
01029 Q_ASSERT( d->autoSaveSettings );
01030
01031 saveMainWindowSettings(d->autoSaveGroup);
01032 d->autoSaveGroup.sync();
01033 d->settingsDirty = false;
01034 }
01035
01036 bool KMainWindow::event( QEvent* ev )
01037 {
01038 K_D(KMainWindow);
01039 switch( ev->type() ) {
01040 #ifdef Q_WS_WIN
01041 case QEvent::Move:
01042 #endif
01043 case QEvent::Resize:
01044 d->setSizeDirty();
01045 break;
01046 case QEvent::Polish:
01047 d->polish(this);
01048 break;
01049 case QEvent::ChildPolished:
01050 {
01051 QChildEvent *event = static_cast<QChildEvent*>(ev);
01052 QDockWidget *dock = qobject_cast<QDockWidget*>(event->child());
01053 KToolBar *toolbar = qobject_cast<KToolBar*>(event->child());
01054 QMenuBar *menubar = qobject_cast<QMenuBar*>(event->child());
01055 if (dock) {
01056 connect(dock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),
01057 this, SLOT(setSettingsDirty()));
01058 connect(dock, SIGNAL(visibilityChanged(bool)),
01059 this, SLOT(setSettingsDirty()));
01060 connect(dock, SIGNAL(topLevelChanged(bool)),
01061 this, SLOT(setSettingsDirty()));
01062
01063
01064
01065 dock->installEventFilter(k_ptr->dockResizeListener);
01066 } else if (toolbar) {
01067
01068
01069 toolbar->installEventFilter(k_ptr->dockResizeListener);
01070 } else if (menubar) {
01071
01072
01073 menubar->installEventFilter(k_ptr->dockResizeListener);
01074 }
01075 }
01076 break;
01077 case QEvent::ChildRemoved:
01078 {
01079 QChildEvent *event = static_cast<QChildEvent*>(ev);
01080 QDockWidget *dock = qobject_cast<QDockWidget*>(event->child());
01081 KToolBar *toolbar = qobject_cast<KToolBar*>(event->child());
01082 QMenuBar *menubar = qobject_cast<QMenuBar*>(event->child());
01083 if (dock) {
01084 disconnect(dock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),
01085 this, SLOT(setSettingsDirty()));
01086 disconnect(dock, SIGNAL(visibilityChanged(bool)),
01087 this, SLOT(setSettingsDirty()));
01088 disconnect(dock, SIGNAL(topLevelChanged(bool)),
01089 this, SLOT(setSettingsDirty()));
01090 dock->removeEventFilter(k_ptr->dockResizeListener);
01091 } else if (toolbar) {
01092 toolbar->removeEventFilter(k_ptr->dockResizeListener);
01093 } else if (menubar) {
01094 menubar->removeEventFilter(k_ptr->dockResizeListener);
01095 }
01096 }
01097 break;
01098 default:
01099 break;
01100 }
01101 return QMainWindow::event( ev );
01102 }
01103
01104 bool KMainWindow::hasMenuBar()
01105 {
01106 return internalMenuBar(this);
01107 }
01108
01109 KMenuBar *KMainWindow::menuBar()
01110 {
01111 KMenuBar * mb = internalMenuBar(this);
01112 if ( !mb ) {
01113 mb = new KMenuBar( this );
01114
01115
01116 setMenuBar(mb);
01117 }
01118 return mb;
01119 }
01120
01121 KStatusBar *KMainWindow::statusBar()
01122 {
01123 KStatusBar * sb = internalStatusBar(this);
01124 if ( !sb ) {
01125 sb = new KStatusBar( this );
01126
01127
01128 setStatusBar(sb);
01129 }
01130 return sb;
01131 }
01132
01133 void KMainWindowPrivate::_k_shuttingDown()
01134 {
01135
01136
01137 static bool reentrancy_protection = false;
01138 if (!reentrancy_protection)
01139 {
01140 reentrancy_protection = true;
01141 shuttingDown = true;
01142
01143 q->queryExit();
01144 reentrancy_protection = false;
01145 }
01146 }
01147
01148 void KMainWindowPrivate::_k_slotSettingsChanged(int category)
01149 {
01150 Q_UNUSED(category);
01151
01152
01153
01154
01155
01156
01157
01158 q->setAnimated(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects);
01159 }
01160
01161 void KMainWindowPrivate::_k_slotSaveAutoSaveSize()
01162 {
01163 if (autoSaveGroup.isValid()) {
01164 q->saveWindowSize(autoSaveGroup);
01165 }
01166 }
01167
01168 KToolBar *KMainWindow::toolBar( const QString& name )
01169 {
01170 QString childName = name;
01171 if (childName.isEmpty())
01172 childName = "mainToolBar";
01173
01174 KToolBar *tb = findChild<KToolBar*>(childName);
01175 if ( tb )
01176 return tb;
01177
01178 KToolBar* toolbar = new KToolBar(childName, this);
01179 return toolbar;
01180 }
01181
01182 QList<KToolBar*> KMainWindow::toolBars() const
01183 {
01184 QList<KToolBar*> ret;
01185
01186 foreach (QObject* child, children())
01187 if (KToolBar* toolBar = qobject_cast<KToolBar*>(child))
01188 ret.append(toolBar);
01189
01190 return ret;
01191 }
01192
01193 QList<KMainWindow*> KMainWindow::memberList() { return *sMemberList; }
01194
01195 QString KMainWindow::dbusName() const
01196 {
01197 return k_func()->dbusName;
01198 }
01199
01200 #include "kmainwindow.moc"
01201