| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kmainwindow.cpp

    00001  /* This file is part of the KDE libraries
    00002      Copyright
    00003      (C) 2000 Reginald Stadlbauer (reggie@kde.org)
    00004      (C) 1997 Stephan Kulow (coolo@kde.org)
    00005      (C) 1997-2000 Sven Radej (radej@kde.org)
    00006      (C) 1997-2000 Matthias Ettrich (ettrich@kde.org)
    00007      (C) 1999 Chris Schlaeger (cs@kde.org)
    00008      (C) 2002 Joseph Wenninger (jowenn@kde.org)
    00009
    00010      This library is free software; you can redistribute it and/or
    00011      modify it under the terms of the GNU Library General Public
    00012      License version 2 as published by the Free Software Foundation.
    00013
    00014      This library is distributed in the hope that it will be useful,
    00015      but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00017      Library General Public License for more details.
    00018
    00019      You should have received a copy of the GNU Library General Public License
    00020      along with this library; see the file COPYING.LIB.  If not, write to
    00021      the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00022      Boston, MA 02111-1307, USA.
    00023  */
    00024
    00025 #include "kmainwindow.h"
    00026 #include "kmainwindowiface.h"
    00027 #include "ktoolbarhandler.h"
    00028 #include <qsessionmanager.h>
    00029 #include <qobjectlist.h>
    00030 #include <qstyle.h>
    00031 #include <qlayout.h>
    00032 #include <qwidgetlist.h>
    00033 #include <qtimer.h>
    00034
    00035 #include <kaccel.h>
    00036 #include <kaction.h>
    00037 #include <kapplication.h>
    00038 #include <kconfig.h>
    00039 #include <kdebug.h>
    00040 #include <khelpmenu.h>
    00041 #include <kmenubar.h>
    00042 #include <kstatusbar.h>
    00043
    00044 #include <klocale.h>
    00045 #include <kstandarddirs.h>
    00046 #include <kstaticdeleter.h>
    00047 #ifndef Q_WS_QWS
    00048 #include <netwm.h>
    00049 #endif
    00050
    00051 #include <stdlib.h>
    00052 #include <ctype.h>
    00053 #include <assert.h>
    00054
    00055 class KMainWindowPrivate {
    00056 public:
    00057     bool showHelpMenu:1;
    00058
    00059     bool autoSaveSettings:1;
    00060     bool settingsDirty:1;
    00061     bool autoSaveWindowSize:1;
    00062     bool care_about_geometry:1;
    00063     QString autoSaveGroup;
    00064     KAccel * kaccel;
    00065     KMainWindowInterface *m_interface;
    00066     KDEPrivate::ToolBarHandler *toolBarHandler;
    00067     QTimer* settingsTimer;
    00068 };
    00069
    00070 QPtrList<KMainWindow>* KMainWindow::memberList = 0L;
    00071 static bool no_query_exit = false;
    00072 static KMWSessionManaged* ksm = 0;
    00073 static KStaticDeleter<KMWSessionManaged> ksmd;
    00074
    00075 class KMWSessionManaged : public KSessionManaged
    00076 {
    00077 public:
    00078     KMWSessionManaged()
    00079     {
    00080     };
    00081     ~KMWSessionManaged()
    00082     {
    00083     }
    00084     bool saveState( QSessionManager& )
    00085     {
    00086         KConfig* config = KApplication::kApplication()->sessionConfig();
    00087         if ( KMainWindow::memberList->first() ){
    00088             // According to Jochen Wilhelmy <digisnap@cs.tu-berlin.de>, this
    00089             // hook is usefull for better document orientation
    00090             KMainWindow::memberList->first()->saveGlobalProperties(config);
    00091         }
    00092
    00093         QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
    00094         int n = 0;
    00095         config->setGroup(QString::fromLatin1("Number"));
    00096         config->writeEntry(QString::fromLatin1("NumberOfWindows"), KMainWindow::memberList->count());
    00097         for (it.toFirst(); it.current(); ++it){
    00098             n++;
    00099             it.current()->savePropertiesInternal(config, n);
    00100         }
    00101         return TRUE;
    00102     }
    00103
    00104     bool commitData( QSessionManager& sm )
    00105     {
    00106         // not really a fast method but the only compatible one
    00107         if ( sm.allowsInteraction() ) {
    00108             bool cancelled = false;
    00109             QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
    00110             ::no_query_exit = true;
    00111             for (it.toFirst(); it.current() && !cancelled;){
    00112                 KMainWindow *window = *it;
    00113                 ++it; // Update now, the current window might get deleted
    00114                 if ( !window->testWState( Qt::WState_ForceHide ) ) {
    00115                     QCloseEvent e;
    00116                     QApplication::sendEvent( window, &e );
    00117                     cancelled = !e.isAccepted();
    00118                     /* Don't even think_about deleting widgets with
    00119                      Qt::WDestructiveClose flag set at this point. We
    00120                      are faking a close event, but we are *not*_
    00121                      closing the window. The purpose of the faked
    00122                      close event is to prepare the application so it
    00123                      can safely be quit without the user losing data
    00124                      (possibly showing a message box "do you want to
    00125                      save this or that?"). It is possible that the
    00126                      session manager quits the application later
    00127                      (emitting QApplication::aboutToQuit() when this
    00128                      happens), but it is also possible that the user
    00129                      cancels the shutdown, so the application will
    00130                      continue to run.
    00131                      */
    00132                 }
    00133             }
    00134             ::no_query_exit = false;
    00135             if (cancelled)
    00136                return false;
    00137
    00138             KMainWindow* last = 0;
    00139             for (it.toFirst(); it.current() && !cancelled; ++it){
    00140                 KMainWindow *window = *it;
    00141                 if ( !window->testWState( Qt::WState_ForceHide ) ) {
    00142                     last = window;
    00143                 }
    00144             }
    00145             if ( last )
    00146                 return last->queryExit();
    00147             // else
    00148             return true;
    00149         }
    00150
    00151         // the user wants it, the user gets it
    00152         return TRUE;
    00153     }
    00154 };
    00155
    00156 static bool beeing_first = true;
    00157
    00158 KMainWindow::KMainWindow( QWidget* parent, const char *name, WFlags f )
    00159     : QMainWindow( parent, name, f ), KXMLGUIBuilder( this ), helpMenu2( 0 ), factory_( 0 )
    00160 {
    00161     initKMainWindow(name);
    00162 }
    00163
    00164 void KMainWindow::initKMainWindow(const char *name)
    00165 {
    00166     setDockMenuEnabled( FALSE );
    00167     mHelpMenu = 0;
    00168     kapp->setTopWidget( this );
    00169     actionCollection()->setWidget( this );
    00170     connect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
    00171     if( !memberList )
    00172         memberList = new QPtrList<KMainWindow>;
    00173
    00174     if ( !ksm )
    00175         ksm = ksmd.setObject(new KMWSessionManaged());
    00176     // set a unique object name. Required by session management.
    00177     QCString objname;
    00178     QCString s;
    00179     int unusedNumber;
    00180     if ( !name )
    00181         { // no name given
    00182         objname = kapp->instanceName() + "-mainwindow#";
    00183         s = objname + '1'; // start adding number immediately
    00184         unusedNumber = 1;
    00185         }
    00186     else if( name[ strlen( name ) - 1 ] == '#' )
    00187         { // trailing # - always add a number
    00188         objname = name;
    00189         s = objname + '1'; // start adding number immediately
    00190         unusedNumber = 1;
    00191         }
    00192     else
    00193         {
    00194         objname = name;
    00195         s = objname;
    00196         unusedNumber = 0; // add numbers only when needed
    00197         }
    00198     for(;;) {
    00199         QWidgetList* list = kapp->topLevelWidgets();
    00200         QWidgetListIt it( *list );
    00201         bool found = false;
    00202         for( QWidget* w = it.current();
    00203              w != NULL;
    00204              ++it, w = it.current())
    00205             if( w != this && w->name() == s )
    00206                 {
    00207                 found = true;
    00208                 break;
    00209                 }
    00210         delete list;
    00211         if( !found )
    00212             break;
    00213         s.setNum( ++unusedNumber );
    00214         s = objname + s;
    00215     }
    00216     setName( s );
    00217
    00218     memberList->append( this );
    00219
    00220     d = new KMainWindowPrivate;
    00221     d->showHelpMenu = true;
    00222     d->settingsDirty = false;
    00223     d->autoSaveSettings = false;
    00224     d->autoSaveWindowSize = true; // for compatibility
    00225     d->kaccel = actionCollection()->kaccel();
    00226     d->toolBarHandler = 0;
    00227     d->settingsTimer = 0;
    00228     if ((d->care_about_geometry = beeing_first)) {
    00229         beeing_first = false;
    00230         if ( kapp->geometryArgument().isNull() ) // if there is no geometry, it doesn't mater
    00231             d->care_about_geometry = false;
    00232         else
    00233             parseGeometry(false);
    00234     }
    00235
    00236     setCaption( kapp->caption() );
    00237     // attach dcop interface
    00238     d->m_interface = new KMainWindowInterface(this);
    00239
    00240     if (!kapp->authorize("movable_toolbars"))
    00241         setDockWindowsMovable(false);
    00242 }
    00243
    00244 KAction *KMainWindow::toolBarMenuAction()
    00245 {
    00246     if ( !d->toolBarHandler )
    00247         return 0;
    00248
    00249     return d->toolBarHandler->toolBarMenuAction();
    00250 }
    00251
    00252 void KMainWindow::parseGeometry(bool parsewidth)
    00253 {
    00254     assert ( !kapp->geometryArgument().isNull() );
    00255     assert ( d->care_about_geometry );
    00256
    00257 #ifndef Q_WS_QWS
    00258     // FIXME: (E) Implement something similar for Qt Embedded (or decide we don't need it)
    00259     int x, y;
    00260     int w, h;
    00261     int m = XParseGeometry( kapp->geometryArgument().latin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h);
    00262     if (parsewidth) {
    00263         QSize minSize = minimumSize();
    00264         QSize maxSize = maximumSize();
    00265         if ( (m & WidthValue) == 0 )
    00266             w = width();
    00267         if ( (m & HeightValue) == 0 )
    00268             h = height();
    00269          w = QMIN(w,maxSize.width());
    00270          h = QMIN(h,maxSize.height());
    00271          w = QMAX(w,minSize.width());
    00272          h = QMAX(h,minSize.height());
    00273          resize(w, h);
    00274     } else {
    00275         if ( parsewidth && (m & XValue) == 0 )
    00276             x = geometry().x();
    00277         if ( parsewidth && (m & YValue) == 0 )
    00278             y = geometry().y();
    00279         if ( (m & XNegative) )
    00280             x = KApplication::desktop()->width()  + x - w;
    00281         if ( (m & YNegative) )
    00282             y = KApplication::desktop()->height() + y - h;
    00283         move(x, y);
    00284     }
    00285 #endif
    00286 }
    00287
    00288 KMainWindow::~KMainWindow()
    00289 {
    00290     delete d->settingsTimer;
    00291     QMenuBar* mb = internalMenuBar();
    00292     delete mb;
    00293     delete d->m_interface;
    00294     delete d;
    00295     memberList->remove( this );
    00296 }
    00297
    00298 KPopupMenu* KMainWindow::helpMenu( const QString &aboutAppText, bool showWhatsThis )
    00299 {
    00300     if( mHelpMenu == 0 ) {
    00301         if ( aboutAppText.isEmpty() )
    00302             mHelpMenu = new KHelpMenu( this, instance()->aboutData(), showWhatsThis);
    00303         else
    00304             mHelpMenu = new KHelpMenu( this, aboutAppText, showWhatsThis );
    00305
    00306         if ( mHelpMenu == 0 )
    00307             return 0;
    00308         connect( mHelpMenu, SIGNAL( showAboutApplication() ),
    00309                  this, SLOT( showAboutApplication() ) );
    00310     }
    00311
    00312     return mHelpMenu->menu();
    00313 }
    00314
    00315 KPopupMenu* KMainWindow::customHelpMenu( bool showWhatsThis )
    00316 {
    00317     if( mHelpMenu == 0 ) {
    00318         mHelpMenu = new KHelpMenu( this, QString::null, showWhatsThis );
    00319         connect( mHelpMenu, SIGNAL( showAboutApplication() ),
    00320                  this, SLOT( showAboutApplication() ) );
    00321     }
    00322
    00323     return mHelpMenu->menu();
    00324 }
    00325
    00326 bool KMainWindow::canBeRestored( int number )
    00327 {
    00328     if ( !kapp->isRestored() )
    00329         return FALSE;
    00330     KConfig *config = kapp->sessionConfig();
    00331     if ( !config )
    00332         return FALSE;
    00333     config->setGroup( QString::fromLatin1("Number") );
    00334     int n = config->readNumEntry( QString::fromLatin1("NumberOfWindows") , 1 );
    00335     return number >= 1 && number <= n;
    00336 }
    00337
    00338 const QString KMainWindow::classNameOfToplevel( int number )
    00339 {
    00340     if ( !kapp->isRestored() )
    00341         return QString::null;
    00342     KConfig *config = kapp->sessionConfig();
    00343     if ( !config )
    00344         return QString::null;
    00345     QString s;
    00346     s.setNum( number );
    00347     s.prepend( QString::fromLatin1("WindowProperties") );
    00348     config->setGroup( s );
    00349     if ( !config->hasKey( QString::fromLatin1("ClassName") ) )
    00350         return QString::null;
    00351     else
    00352         return config->readEntry( QString::fromLatin1("ClassName") );
    00353 }
    00354
    00355 bool KMainWindow::restore( int number, bool show )
    00356 {
    00357     if ( !canBeRestored( number ) )
    00358         return FALSE;
    00359     KConfig *config = kapp->sessionConfig();
    00360     if ( readPropertiesInternal( config, number ) ){
    00361         if ( show )
    00362             KMainWindow::show();
    00363         return FALSE;
    00364     }
    00365     return FALSE;
    00366 }
    00367
    00368 KXMLGUIFactory *KMainWindow::guiFactory()
    00369 {
    00370     if ( !factory_ )
    00371         factory_ = new KXMLGUIFactory( this, this, "guifactory" );
    00372     return factory_;
    00373 }
    00374
    00375 void KMainWindow::createGUI( const QString &xmlfile, bool _conserveMemory )
    00376 {
    00377     // disabling the updates prevents unnecessary redraws
    00378     setUpdatesEnabled( false );
    00379
    00380     // just in case we are rebuilding, let's remove our old client
    00381     guiFactory()->removeClient( this );
    00382
    00383     // make sure to have an empty GUI
    00384     QMenuBar* mb = internalMenuBar();
    00385     if ( mb )
    00386         mb->clear();
    00387
    00388     (void)toolBarIterator(); // make sure toolbarList is most-up-to-date
    00389     toolbarList.setAutoDelete( true );
    00390     toolbarList.clear();
    00391     toolbarList.setAutoDelete( false );
    00392
    00393     // don't build a help menu unless the user ask for it
    00394     if (d->showHelpMenu) {
    00395         // we always want a help menu
    00396         if (helpMenu2 == 0)
    00397             helpMenu2 = new KHelpMenu(this, instance()->aboutData(), true,
    00398                                       actionCollection());
    00399     }
    00400
    00401     // we always want to load in our global standards file
    00402     setXMLFile( locate( "config", "ui/ui_standards.rc", instance() ) );
    00403
    00404     // now, merge in our local xml file.  if this is null, then that
    00405     // means that we will be only using the global file
    00406     if ( !xmlfile.isNull() ) {
    00407         setXMLFile( xmlfile, true );
    00408     } else {
    00409         QString auto_file(instance()->instanceName() + "ui.rc");
    00410         setXMLFile( auto_file, true );
    00411     }
    00412
    00413     // make sure we don't have any state saved already
    00414     setXMLGUIBuildDocument( QDomDocument() );
    00415
    00416     // do the actual GUI building
    00417     guiFactory()->addClient( this );
    00418
    00419     // try and get back *some* of our memory
    00420     if ( _conserveMemory )
    00421     {
    00422       // before freeing the memory allocated by the DOM document we also
    00423       // free all memory allocated internally in the KXMLGUIFactory for
    00424       // the menubar and the toolbars . This however implies that we
    00425       // have to take care of deleting those widgets ourselves. For
    00426       // destruction this is no problem, but when rebuilding we have
    00427       // to take care of that (and we want to rebuild the GUI when
    00428       // using stuff like the toolbar editor ).
    00429       // In addition we have to take care of not removing containers
    00430       // like popupmenus, defined in the XML document.
    00431       // this code should probably go into a separate method in KMainWindow.
    00432       // there's just one problem: I'm bad in finding names ;-) , so
    00433       // I skipped this ;-)
    00434
    00435       QDomDocument doc = domDocument();
    00436
    00437       QDomElement e = doc.documentElement().firstChild().toElement();
    00438       for (; !e.isNull(); e = e.nextSibling().toElement() ) {
    00439           if ( e.tagName().lower() == "toolbar" )
    00440               factory_->resetContainer( e.attribute( "name" ) );
    00441           else if ( e.tagName().lower() == "menubar" )
    00442               factory_->resetContainer( e.tagName(), true );
    00443       }
    00444
    00445       conserveMemory();
    00446     }
    00447
    00448     setUpdatesEnabled( true );
    00449     updateGeometry();
    00450 }
    00451
    00452 void KMainWindow::setHelpMenuEnabled(bool showHelpMenu)
    00453 {
    00454     d->showHelpMenu = showHelpMenu;
    00455 }
    00456
    00457 bool KMainWindow::isHelpMenuEnabled()
    00458 {
    00459     return d->showHelpMenu;
    00460 }
    00461
    00462 void KMainWindow::setCaption( const QString &caption )
    00463 {
    00464     setPlainCaption( kapp->makeStdCaption(caption) );
    00465 }
    00466
    00467 void KMainWindow::setCaption( const QString &caption, bool modified )
    00468 {
    00469     setPlainCaption( kapp->makeStdCaption(caption, true, modified) );
    00470 }
    00471
    00472 void KMainWindow::setPlainCaption( const QString &caption )
    00473 {
    00474     QMainWindow::setCaption( caption );
    00475 #ifndef Q_WS_QWS
    00476     NETWinInfo info( qt_xdisplay(), winId(), qt_xrootwin(), 0 );
    00477     info.setName( caption.utf8().data() );
    00478 #endif
    00479 }
    00480
    00481 void KMainWindow::appHelpActivated( void )
    00482 {
    00483     if( mHelpMenu == 0 ) {
    00484         mHelpMenu = new KHelpMenu( this );
    00485         if ( mHelpMenu == 0 )
    00486             return;
    00487     }
    00488     mHelpMenu->appHelpActivated();
    00489 }
    00490
    00491 void KMainWindow::slotStateChanged(const QString &newstate)
    00492 {
    00493   stateChanged(newstate, KXMLGUIClient::StateNoReverse);
    00494 }
    00495
    00496 /*
    00497  * Get rid of this for KDE 4.0
    00498  */
    00499 void KMainWindow::slotStateChanged(const QString &newstate,
    00500                                    KXMLGUIClient::ReverseStateChange reverse)
    00501 {
    00502   stateChanged(newstate, reverse);
    00503 }
    00504
    00505 /*
    00506  * Enable this for KDE 4.0
    00507  */
    00508 // void KMainWindow::slotStateChanged(const QString &newstate,
    00509 //                                    bool reverse)
    00510 // {
    00511 //   stateChanged(newstate,
    00512 //                reverse ? KXMLGUIClient::StateReverse : KXMLGUIClient::StateNoReverse);
    00513 // }
    00514
    00515 void KMainWindow::closeEvent ( QCloseEvent *e )
    00516 {
    00517     // Save settings if auto-save is enabled, and settings have changed
    00518     if (d->settingsDirty && d->autoSaveSettings)
    00519         saveAutoSaveSettings();
    00520
    00521     if (queryClose()) {
    00522         e->accept();
    00523
    00524         int not_withdrawn = 0;
    00525         QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
    00526         for (it.toFirst(); it.current(); ++it){
    00527             if ( !it.current()->isHidden() && it.current()->isTopLevel() && it.current() != this )
    00528                 not_withdrawn++;
    00529         }
    00530
    00531         if ( !no_query_exit && not_withdrawn <= 0 ) { // last window close accepted?
    00532             if ( queryExit() && !kapp->sessionSaving()) {            // Yes, Quit app?
    00533                 // We saved the toolbars already
    00534                 disconnect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
    00535                 kapp->deref();             // ...and quit aplication.
    00536             }  else {
    00537                 // cancel closing, it's stupid to end up with no windows at all....
    00538                 e->ignore();
    00539             }
    00540         }
    00541     }
    00542 }
    00543
    00544 bool KMainWindow::queryExit()
    00545 {
    00546     return TRUE;
    00547 }
    00548
    00549 bool KMainWindow::queryClose()
    00550 {
    00551     return TRUE;
    00552 }
    00553
    00554 void KMainWindow::saveGlobalProperties( KConfig*  )
    00555 {
    00556 }
    00557
    00558 void KMainWindow::readGlobalProperties( KConfig*  )
    00559 {
    00560 }
    00561
    00562 #if defined(KDE_COMPAT)
    00563 void KMainWindow::updateRects()
    00564 {
    00565 }
    00566 #endif
    00567
    00568 void KMainWindow::showAboutApplication()
    00569 {
    00570 }
    00571
    00572 void KMainWindow::savePropertiesInternal( KConfig *config, int number )
    00573 {
    00574     bool oldASWS = d->autoSaveWindowSize;
    00575     d->autoSaveWindowSize = true; // make saveMainWindowSettings save the window size
    00576
    00577     QString s;
    00578     s.setNum(number);
    00579     s.prepend(QString::fromLatin1("WindowProperties"));
    00580     config->setGroup(s);
    00581
    00582     // store objectName, className, Width and Height  for later restoring
    00583     // (Only useful for session management)
    00584     config->writeEntry(QString::fromLatin1("ObjectName"), name());
    00585     config->writeEntry(QString::fromLatin1("ClassName"), className());
    00586
    00587     saveMainWindowSettings(config); // Menubar, statusbar and Toolbar settings.
    00588
    00589     s.setNum(number);
    00590     config->setGroup(s);
    00591     saveProperties(config);
    00592
    00593     d->autoSaveWindowSize = oldASWS;
    00594 }
    00595
    00596 void KMainWindow::saveMainWindowSettings(KConfig *config, const QString &configGroup)
    00597 {
    00598     kdDebug(200) << "KMainWindow::saveMainWindowSettings " << configGroup << endl;
    00599     QString entry;
    00600     QStrList entryList;
    00601
    00602     if (!configGroup.isEmpty())
    00603        config->setGroup(configGroup);
    00604
    00605     // Called by session management - or if we want to save the window size anyway
    00606     if ( d->autoSaveWindowSize )
    00607         saveWindowSize( config );
    00608
    00609     QStatusBar* sb = internalStatusBar();
    00610     if (sb) {
    00611         entryList.clear();
    00612         if ( sb->isHidden() )
    00613             entryList.append("Disabled");
    00614         else
    00615             entryList.append("Enabled");
    00616         config->writeEntry(QString::fromLatin1("StatusBar"), entryList, ';');
    00617     }
    00618
    00619     QMenuBar* mb = internalMenuBar();
    00620     if (mb) {
    00621         entryList.clear();
    00622         if ( mb->isHidden() )
    00623             entryList.append("Disabled");
    00624         else
    00625             entryList.append("Enabled");
    00626         config->writeEntry(QString::fromLatin1("MenuBar"), entryList, ';');
    00627     }
    00628
    00629     int n = 1; // Toolbar counter. toolbars are counted from 1,
    00630     KToolBar *toolbar = 0;
    00631     QString toolKey;
    00632     QPtrListIterator<KToolBar> it( toolBarIterator() );
    00633     while ( ( toolbar = it.current() ) ) {
    00634         ++it;
    00635         QString group;
    00636         if (!configGroup.isEmpty())
    00637         {
    00638            // Give a number to the toolbar, but prefer a name if there is one,
    00639            // because there's no real guarantee on the ordering of toolbars
    00640            group = (!::qstrcmp(toolbar->name(), "unnamed") ? QString::number(n) : QString(" ")+toolbar->name());
    00641            group.prepend(" Toolbar");
    00642            group.prepend(configGroup);
    00643         }
    00644         toolbar->saveSettings(config, group);
    00645         n++;
    00646     }
    00647 }
    00648
    00649 void KMainWindow::setStandardToolBarMenuEnabled( bool enable )
    00650 {
    00651     if ( enable ) {
    00652         if ( d->toolBarHandler )
    00653             return;
    00654
    00655         d->toolBarHandler = new KDEPrivate::ToolBarHandler( this );
    00656
    00657         if ( factory() )
    00658             factory()->addClient( d->toolBarHandler );
    00659     } else {
    00660         if ( !d->toolBarHandler )
    00661             return;
    00662
    00663         if ( factory() )
    00664             factory()->removeClient( d->toolBarHandler );
    00665
    00666         delete d->toolBarHandler;
    00667         d->toolBarHandler = 0;
    00668     }
    00669 }
    00670
    00671 bool KMainWindow::isStandardToolBarMenuEnabled() const
    00672 {
    00673     return ( d->toolBarHandler != 0 );
    00674 }
    00675
    00676 bool KMainWindow::readPropertiesInternal( KConfig *config, int number )
    00677 {
    00678     if ( number == 1 )
    00679         readGlobalProperties( config );
    00680
    00681     // in order they are in toolbar list
    00682     QString s;
    00683     s.setNum(number);
    00684     s.prepend(QString::fromLatin1("WindowProperties"));
    00685
    00686     config->setGroup(s);
    00687
    00688     // restore the object name (window role)
    00689     if ( config->hasKey(QString::fromLatin1("ObjectName" )) )
    00690         setName( config->readEntry(QString::fromLatin1("ObjectName")).latin1()); // latin1 is right here
    00691
    00692     applyMainWindowSettings(config); // Menubar, statusbar and toolbar settings.
    00693
    00694     s.setNum(number);
    00695     config->setGroup(s);
    00696     readProperties(config);
    00697     return true;
    00698 }
    00699
    00700 void KMainWindow::applyMainWindowSettings(KConfig *config, const QString &configGroup)
    00701 {
    00702     kdDebug(200) << "KMainWindow::applyMainWindowSettings" << endl;
    00703     QString entry;
    00704     QStrList entryList;
    00705     int i = 0; // Number of entries in list
    00706
    00707     if (!configGroup.isEmpty())
    00708        config->setGroup(configGroup);
    00709
    00710     restoreWindowSize(config);
    00711
    00712     QStatusBar* sb = internalStatusBar();
    00713     if (sb) {
    00714         entryList.clear();
    00715         i = config->readListEntry (QString::fromLatin1("StatusBar"), entryList, ';');
    00716         entry = entryList.first();
    00717         if (entry == QString::fromLatin1("Disabled"))
    00718             sb->hide();
    00719         else
    00720             sb->show();
    00721     }
    00722
    00723     QMenuBar* mb = internalMenuBar();
    00724     if (mb) {
    00725         entryList.clear();
    00726         i = config->readListEntry (QString::fromLatin1("MenuBar"), entryList, ';');
    00727         entry = entryList.first();
    00728         if (entry==QString::fromLatin1("Disabled"))
    00729             mb->hide();
    00730         else
    00731             mb->show();
    00732     }
    00733
    00734     int n = 1; // Toolbar counter. toolbars are counted from 1,
    00735     KToolBar *toolbar;
    00736     QString toolKey;
    00737     QPtrListIterator<KToolBar> it( toolBarIterator() ); // must use own iterator
    00738
    00739     for ( ; it.current(); ++it) {
    00740         toolbar= it.current();
    00741         QString group;
    00742         if (!configGroup.isEmpty())
    00743         {
    00744            // Give a number to the toolbar, but prefer a name if there is one,
    00745            // because there's no real guarantee on the ordering of toolbars
    00746            group = (!::qstrcmp(toolbar->name(), "unnamed") ? QString::number(n) : QString(" ")+toolbar->name());
    00747            group.prepend(" Toolbar");
    00748            group.prepend(configGroup);
    00749         }
    00750         toolbar->applySettings(config, group);
    00751         n++;
    00752     }
    00753
    00754     finalizeGUI( true );
    00755 }
    00756
    00757 void KMainWindow::finalizeGUI( bool force )
    00758 {
    00759     //kdDebug(200) << "KMainWindow::finalizeGUI force=" << force << endl;
    00760     // The whole reason for this is that moveToolBar relies on the indexes
    00761     // of the other toolbars, so in theory it should be called only once per
    00762     // toolbar, but in increasing order of indexes.
    00763     // Since we can't do that immediately, we move them, and _then_
    00764     // we call positionYourself again for each of them, but this time
    00765     // the toolbariterator should give them in the proper order.
    00766     // Both the XMLGUI and applySettings call this, hence "force" for the latter.
    00767     QPtrListIterator<KToolBar> it( toolBarIterator() );
    00768     for ( ; it.current() ; ++ it )
    00769             it.current()->positionYourself( force );
    00770
    00771     d->settingsDirty = false;
    00772 }
    00773
    00774 void KMainWindow::saveWindowSize( KConfig * config ) const
    00775 {
    00776     int scnum = QApplication::desktop()->screenNumber(parentWidget());
    00777     QRect desk = QApplication::desktop()->screenGeometry(scnum);
    00778     config->writeEntry(QString::fromLatin1("Width %1").arg(desk.width()), width() );
    00779     config->writeEntry(QString::fromLatin1("Height %1").arg(desk.height()), height() );
    00780 }
    00781
    00782 void KMainWindow::restoreWindowSize( KConfig * config )
    00783 {
    00784     if (d->care_about_geometry) {
    00785         parseGeometry(true);
    00786     } else {
    00787         // restore the size
    00788         int scnum = QApplication::desktop()->screenNumber(parentWidget());
    00789         QRect desk = QApplication::desktop()->screenGeometry(scnum);
    00790         QSize size( config->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 0 ),
    00791                     config->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 0 ) );
    00792         if (size.isEmpty()) {
    00793             // try the KDE 2.0 way
    00794             size = QSize( config->readNumEntry( QString::fromLatin1("Width"), 0 ),
    00795                           config->readNumEntry( QString::fromLatin1("Height"), 0 ) );
    00796             if (!size.isEmpty()) {
    00797                 // make sure the other resolutions don't get old settings
    00798                 config->writeEntry( QString::fromLatin1("Width"), 0 );
    00799                 config->writeEntry( QString::fromLatin1("Height"), 0 );
    00800             }
    00801         }
    00802         if ( !size.isEmpty() )
    00803             resize( size );
    00804     }
    00805 }
    00806
    00807 bool KMainWindow::initialGeometrySet() const
    00808 {
    00809     return d->care_about_geometry;
    00810 }
    00811
    00812 void KMainWindow::setSettingsDirty()
    00813 {
    00814     //kdDebug(200) << "KMainWindow::setSettingsDirty" << endl;
    00815     d->settingsDirty = true;
    00816     if ( d->autoSaveSettings )
    00817     {
    00818         // Use a timer to save "immediately" user-wise, but not too immediately
    00819         // (to compress calls and save only once, in case of multiple changes)
    00820         if ( !d->settingsTimer )
    00821         {
    00822            d->settingsTimer = new QTimer( this );
    00823            connect( d->settingsTimer, SIGNAL( timeout() ), SLOT( saveAutoSaveSettings() ) );
    00824         }
    00825         d->settingsTimer->start( 500, true );
    00826     }
    00827 }
    00828
    00829 bool KMainWindow::settingsDirty() const
    00830 {
    00831     return d->settingsDirty;
    00832 }
    00833
    00834 QString KMainWindow::settingsGroup() const
    00835 {
    00836     return d->autoSaveGroup;
    00837 }
    00838
    00839 void KMainWindow::setAutoSaveSettings( const QString & groupName, bool saveWindowSize )
    00840 {
    00841     d->autoSaveSettings = true;
    00842     d->autoSaveGroup = groupName;
    00843     d->autoSaveWindowSize = saveWindowSize;
    00844     // Get notified when the user moves a toolbar around
    00845     connect( this, SIGNAL( dockWindowPositionChanged( QDockWindow * ) ),
    00846              this, SLOT( setSettingsDirty() ) );
    00847     // Now read the previously saved settings
    00848     applyMainWindowSettings( KGlobal::config(), groupName );
    00849 }
    00850
    00851 void KMainWindow::resetAutoSaveSettings()
    00852 {
    00853     d->autoSaveSettings = false;
    00854     if ( d->settingsTimer )
    00855         d->settingsTimer->stop();
    00856 }
    00857
    00858 bool KMainWindow::autoSaveSettings() const
    00859 {
    00860     return d->autoSaveSettings;
    00861 }
    00862
    00863 QString KMainWindow::autoSaveGroup() const
    00864 {
    00865     return d->autoSaveGroup;
    00866 }
    00867
    00868 void KMainWindow::saveAutoSaveSettings()
    00869 {
    00870     Q_ASSERT( d->autoSaveSettings );
    00871     //kdDebug(200) << "KMainWindow::saveAutoSaveSettings -> saving settings" << endl;
    00872     saveMainWindowSettings( KGlobal::config(), d->autoSaveGroup );
    00873     KGlobal::config()->sync();
    00874     d->settingsDirty = false;
    00875     if ( d->settingsTimer )
    00876         d->settingsTimer->stop();
    00877 }
    00878
    00879 void KMainWindow::resizeEvent( QResizeEvent * )
    00880 {
    00881     if ( d->autoSaveWindowSize )
    00882         setSettingsDirty();
    00883 }
    00884
    00885 bool KMainWindow::hasMenuBar()
    00886 {
    00887         return (internalMenuBar());
    00888 }
    00889
    00890 KMenuBar *KMainWindow::menuBar()
    00891 {
    00892     KMenuBar * mb = internalMenuBar();
    00893     if ( !mb ) {
    00894         mb = new KMenuBar( this );
    00895         // trigger a re-layout and trigger a call to the private
    00896         // setMenuBar method.
    00897         QMainWindow::menuBar();
    00898     }
    00899     return mb;
    00900 }
    00901
    00902 KStatusBar *KMainWindow::statusBar()
    00903 {
    00904     KStatusBar * sb = internalStatusBar();
    00905     if ( !sb ) {
    00906         sb = new KStatusBar( this );
    00907         // trigger a re-layout and trigger a call to the private
    00908         // setStatusBar method.
    00909         QMainWindow::statusBar();
    00910     }
    00911     return sb;
    00912 }
    00913
    00914 void KMainWindow::shuttingDown()
    00915 {
    00916     // Needed for Qt <= 3.0.3 at least to prevent reentrancy
    00917     // when queryExit() shows a dialog. Check before removing!
    00918     static bool reentrancy_protection = false;
    00919     if (!reentrancy_protection)
    00920     {
    00921        reentrancy_protection = true;
    00922        // call the virtual queryExit
    00923        queryExit();
    00924        reentrancy_protection = false;
    00925     }
    00926
    00927 }
    00928
    00929 KMenuBar *KMainWindow::internalMenuBar()
    00930 {
    00931     QObjectList *l = queryList( "KMenuBar" );
    00932     if ( !l || !l->first() ) {
    00933         delete l;
    00934         return 0;
    00935     }
    00936
    00937     KMenuBar *m = (KMenuBar*)l->first();
    00938     delete l;
    00939     return m;
    00940 }
    00941
    00942 KStatusBar *KMainWindow::internalStatusBar()
    00943 {
    00944     QObjectList *l = queryList( "KStatusBar" );
    00945     if ( !l || !l->first() ) {
    00946         delete l;
    00947         return 0;
    00948     }
    00949
    00950     KStatusBar *s = (KStatusBar*)l->first();
    00951     delete l;
    00952     return s;
    00953 }
    00954
    00955 void KMainWindow::childEvent( QChildEvent* e)
    00956 {
    00957     QMainWindow::childEvent( e );
    00958 }
    00959
    00960 KToolBar *KMainWindow::toolBar( const char * name )
    00961 {
    00962     if (!name)
    00963        name = "mainToolBar";
    00964     KToolBar *tb = (KToolBar*)child( name, "KToolBar" );
    00965     if ( tb )
    00966         return tb;
    00967     bool honor_mode = (name == "mainToolBar");
    00968
    00969     if ( builderClient() )
    00970         return new KToolBar(this, name, honor_mode); // XMLGUI constructor
    00971     else
    00972         return new KToolBar(this, DockTop, false, name, honor_mode ); // non-XMLGUI
    00973 }
    00974
    00975 QPtrListIterator<KToolBar> KMainWindow::toolBarIterator()
    00976 {
    00977     toolbarList.clear();
    00978     QPtrList<QToolBar> lst;
    00979     for ( int i = (int)QMainWindow::DockUnmanaged; i <= (int)DockMinimized; ++i ) {
    00980         lst = toolBars( (ToolBarDock)i );
    00981         for ( QToolBar *tb = lst.first(); tb; tb = lst.next() ) {
    00982             if ( !tb->inherits( "KToolBar" ) )
    00983                 continue;
    00984             toolbarList.append( (KToolBar*)tb );
    00985         }
    00986     }
    00987     return QPtrListIterator<KToolBar>( toolbarList );
    00988 }
    00989
    00990 KAccel * KMainWindow::accel()
    00991 {
    00992     if ( !d->kaccel )
    00993         d->kaccel = new KAccel( this, "kmw-kaccel" );
    00994     return d->kaccel;
    00995 }
    00996
    00997 void KMainWindow::paintEvent( QPaintEvent * )
    00998 {
    00999     // do nothing
    01000 }
    01001
    01002 QSize KMainWindow::sizeForCentralWidgetSize(QSize size)
    01003 {
    01004     KToolBar *tb = toolBar();
    01005     if (!tb->isHidden()) {
    01006         switch( tb->barPos() )
    01007         {
    01008           case KToolBar::Top:
    01009           case KToolBar::Bottom:
    01010             size += QSize(0, tb->sizeHint().height());
    01011             break;
    01012
    01013           case KToolBar::Left:
    01014           case KToolBar::Right:
    01015             size += QSize(toolBar()->sizeHint().width(), 0);
    01016             break;
    01017
    01018           case KToolBar::Flat:
    01019             size += QSize(0, 3+kapp->style().pixelMetric( QStyle::PM_DockWindowHandleExtent ));
    01020             break;
    01021
    01022           default:
    01023             break;
    01024         }
    01025     }
    01026     KMenuBar *mb = menuBar();
    01027     if (!mb->isHidden()) {
    01028         size += QSize(0,mb->heightForWidth(size.width()));
    01029         if (style().styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, this))
    01030            size += QSize( 0, dockWindowsMovable() ? 1 : 2);
    01031     }
    01032     QStatusBar *sb = internalStatusBar();
    01033     if( sb && !sb->isHidden() )
    01034        size += QSize(0, sb->sizeHint().height());
    01035
    01036     return size;
    01037 }
    01038
    01039 // why do we support old gcc versions? using KXMLGUIBuilder::finalizeGUI;
    01040 void KMainWindow::finalizeGUI( KXMLGUIClient *client )
    01041 { KXMLGUIBuilder::finalizeGUI( client ); }
    01042
    01043 void KMainWindow::virtual_hook( int id, void* data )
    01044 { KXMLGUIBuilder::virtual_hook( id, data );
    01045   KXMLGUIClient::virtual_hook( id, data ); }
    01046
    01047
    01048
    01049 #include "kmainwindow.moc"
    01050

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:57:20 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001