• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

kmainwindow.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00022      Boston, MA 02110-1301, USA.
00023  */
00024 #include "config.h"
00025 
00026 #include "kmainwindow.h"
00027 #include "kmainwindowiface.h"
00028 #include "ktoolbarhandler.h"
00029 #include "kwhatsthismanager_p.h"
00030 #include <qsessionmanager.h>
00031 #include <qobjectlist.h>
00032 #include <qstyle.h>
00033 #include <qlayout.h>
00034 #include <qwidgetlist.h>
00035 #include <qtimer.h>
00036 
00037 #include <kaccel.h>
00038 #include <kaction.h>
00039 #include <kapplication.h>
00040 #include <kconfig.h>
00041 #include <kdebug.h>
00042 #include <khelpmenu.h>
00043 #include <kmenubar.h>
00044 #include <kstatusbar.h>
00045 #include <kwin.h>
00046 #include <kedittoolbar.h>
00047 #include <kmainwindow.h>
00048 
00049 #include <klocale.h>
00050 #include <kstandarddirs.h>
00051 #include <kstaticdeleter.h>
00052 #if defined Q_WS_X11
00053 #include <netwm.h>
00054 #endif
00055 
00056 #include <stdlib.h>
00057 #include <ctype.h>
00058 #include <assert.h>
00059 
00060 class KMainWindowPrivate {
00061 public:
00062     bool showHelpMenu:1;
00063 
00064     bool autoSaveSettings:1;
00065     bool settingsDirty:1;
00066     bool autoSaveWindowSize:1;
00067     bool care_about_geometry:1;
00068     bool shuttingDown:1;
00069     QString autoSaveGroup;
00070     KAccel * kaccel;
00071     KMainWindowInterface *m_interface;
00072     KDEPrivate::ToolBarHandler *toolBarHandler;
00073     QTimer* settingsTimer;
00074     KToggleAction *showStatusBarAction;
00075     QRect defaultWindowSize;
00076     QPtrList<QDockWindow> hiddenDockWindows;
00077 };
00078 
00079 QPtrList<KMainWindow>* KMainWindow::memberList = 0L;
00080 static bool no_query_exit = false;
00081 static KMWSessionManaged* ksm = 0;
00082 static KStaticDeleter<KMWSessionManaged> ksmd;
00083 
00084 class KMWSessionManaged : public KSessionManaged
00085 {
00086 public:
00087     KMWSessionManaged()
00088     {
00089     }
00090     ~KMWSessionManaged()
00091     {
00092     }
00093     bool saveState( QSessionManager& )
00094     {
00095         KConfig* config = KApplication::kApplication()->sessionConfig();
00096         if ( KMainWindow::memberList->first() ){
00097             // According to Jochen Wilhelmy <digisnap@cs.tu-berlin.de>, this
00098             // hook is useful for better document orientation
00099             KMainWindow::memberList->first()->saveGlobalProperties(config);
00100         }
00101 
00102         QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
00103         int n = 0;
00104         for (it.toFirst(); it.current(); ++it){
00105             n++;
00106             it.current()->savePropertiesInternal(config, n);
00107         }
00108         config->setGroup(QString::fromLatin1("Number"));
00109         config->writeEntry(QString::fromLatin1("NumberOfWindows"), n );
00110         return true;
00111     }
00112 
00113     bool commitData( QSessionManager& sm )
00114     {
00115         // not really a fast method but the only compatible one
00116         if ( sm.allowsInteraction() ) {
00117             bool canceled = false;
00118             QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
00119             ::no_query_exit = true;
00120             for (it.toFirst(); it.current() && !canceled;){
00121                 KMainWindow *window = *it;
00122                 ++it; // Update now, the current window might get deleted
00123                 if ( !window->testWState( Qt::WState_ForceHide ) ) {
00124                     QCloseEvent e;
00125                     QApplication::sendEvent( window, &e );
00126                     canceled = !e.isAccepted();
00127             /* Don't even think_about deleting widgets with
00128              Qt::WDestructiveClose flag set at this point. We
00129              are faking a close event, but we are *not*_
00130              closing the window. The purpose of the faked
00131              close event is to prepare the application so it
00132              can safely be quit without the user losing data
00133              (possibly showing a message box "do you want to
00134              save this or that?"). It is possible that the
00135              session manager quits the application later
00136              (emitting QApplication::aboutToQuit() when this
00137              happens), but it is also possible that the user
00138              cancels the shutdown, so the application will
00139              continue to run.
00140              */
00141                 }
00142             }
00143             ::no_query_exit = false;
00144             if (canceled)
00145                return false;
00146 
00147             KMainWindow* last = 0;
00148             for (it.toFirst(); it.current() && !canceled; ++it){
00149                 KMainWindow *window = *it;
00150                 if ( !window->testWState( Qt::WState_ForceHide ) ) {
00151                     last = window;
00152                 }
00153             }
00154             if ( last )
00155                 return last->queryExit();
00156             // else
00157             return true;
00158         }
00159 
00160         // the user wants it, the user gets it
00161         return true;
00162     }
00163 };
00164 
00165 static bool being_first = true;
00166 
00167 KMainWindow::KMainWindow( QWidget* parent, const char *name, WFlags f )
00168     : QMainWindow( parent, name, f ), KXMLGUIBuilder( this ), helpMenu2( 0 ), factory_( 0 )
00169 {
00170     initKMainWindow(name, 0);
00171 }
00172 
00173 KMainWindow::KMainWindow( int cflags, QWidget* parent, const char *name, WFlags f )
00174     : QMainWindow( parent, name, f ), KXMLGUIBuilder( this ), helpMenu2( 0 ), factory_( 0 )
00175 {
00176     initKMainWindow(name, cflags);
00177 }
00178 
00179 void KMainWindow::initKMainWindow(const char *name, int cflags)
00180 {
00181     KWhatsThisManager::init ();
00182     setDockMenuEnabled( false );
00183     mHelpMenu = 0;
00184     kapp->setTopWidget( this );
00185     actionCollection()->setWidget( this );
00186     connect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
00187     if( !memberList )
00188         memberList = new QPtrList<KMainWindow>;
00189 
00190     if ( !ksm )
00191         ksm = ksmd.setObject(ksm, new KMWSessionManaged());
00192     // set a unique object name. Required by session management.
00193     QCString objname;
00194     QCString s;
00195     int unusedNumber;
00196     if ( !name )
00197         { // no name given
00198         objname = kapp->instanceName() + "-mainwindow#";
00199         s = objname + '1'; // start adding number immediately
00200         unusedNumber = 1;
00201         }
00202     else if( name[0] != '\0' && name[ strlen( name ) - 1 ] == '#' )
00203         { // trailing # - always add a number
00204         objname = name;
00205         s = objname + '1'; // start adding number immediately
00206         unusedNumber = 1;
00207         }
00208     else
00209         {
00210         objname = name;
00211         s = objname;
00212         unusedNumber = 0; // add numbers only when needed
00213         }
00214     for(;;) {
00215         QWidgetList* list = kapp->topLevelWidgets();
00216         QWidgetListIt it( *list );
00217         bool found = false;
00218         for( QWidget* w = it.current();
00219              w != NULL;
00220              ++it, w = it.current())
00221             if( w != this && w->name() == s )
00222                 {
00223                 found = true;
00224                 break;
00225                 }
00226         delete list;
00227         if( !found )
00228             break;
00229         s.setNum( ++unusedNumber );
00230         s = objname + s;
00231     }
00232     setName( s );
00233 
00234     memberList->append( this );
00235 
00236     d = new KMainWindowPrivate;
00237     d->showHelpMenu = true;
00238     d->settingsDirty = false;
00239     d->autoSaveSettings = false;
00240     d->autoSaveWindowSize = true; // for compatibility
00241     d->kaccel = actionCollection()->kaccel();
00242     d->toolBarHandler = 0;
00243     d->settingsTimer = 0;
00244     d->showStatusBarAction = NULL;
00245     d->shuttingDown = false;
00246     if ((d->care_about_geometry = being_first)) {
00247         being_first = false;
00248         if ( kapp->geometryArgument().isNull() ) // if there is no geometry, it doesn't mater
00249             d->care_about_geometry = false;
00250         else
00251             parseGeometry(false);
00252     }
00253 
00254     setCaption( kapp->caption() );
00255     if ( cflags & NoDCOPObject)
00256         d->m_interface = 0;
00257     else
00258         d->m_interface = new KMainWindowInterface(this);
00259 
00260     if (!kapp->authorize("movable_toolbars"))
00261         setDockWindowsMovable(false);
00262 }
00263 
00264 KAction *KMainWindow::toolBarMenuAction()
00265 {
00266     if ( !d->toolBarHandler )
00267     return 0;
00268 
00269     return d->toolBarHandler->toolBarMenuAction();
00270 }
00271 
00272 
00273 void KMainWindow::setupToolbarMenuActions()
00274 {
00275     if ( d->toolBarHandler )
00276         d->toolBarHandler->setupActions();
00277 }
00278 
00279 void KMainWindow::parseGeometry(bool parsewidth)
00280 {
00281     assert ( !kapp->geometryArgument().isNull() );
00282     assert ( d->care_about_geometry );
00283 
00284 #if defined Q_WS_X11
00285     int x, y;
00286     int w, h;
00287     int m = XParseGeometry( kapp->geometryArgument().latin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h);
00288     if (parsewidth) {
00289         QSize minSize = minimumSize();
00290         QSize maxSize = maximumSize();
00291         if ( !(m & WidthValue) )
00292             w = width();
00293         if ( !(m & HeightValue) )
00294             h = height();
00295          w = QMIN(w,maxSize.width());
00296          h = QMIN(h,maxSize.height());
00297          w = QMAX(w,minSize.width());
00298          h = QMAX(h,minSize.height());
00299          resize(w, h);
00300     } else {
00301         if ( parsewidth && !(m & XValue) )
00302             x = geometry().x();
00303         if ( parsewidth && !(m & YValue) )
00304             y = geometry().y();
00305         if ( (m & XNegative) )
00306             x = KApplication::desktop()->width()  + x - w;
00307         if ( (m & YNegative) )
00308             y = KApplication::desktop()->height() + y - h;
00309         move(x, y);
00310     }
00311 #endif
00312 }
00313 
00314 KMainWindow::~KMainWindow()
00315 {
00316     delete d->settingsTimer;
00317     QMenuBar* mb = internalMenuBar();
00318     delete mb;
00319     delete d->m_interface;
00320     delete d;
00321     memberList->remove( this );
00322 }
00323 
00324 KPopupMenu* KMainWindow::helpMenu( const QString &aboutAppText, bool showWhatsThis )
00325 {
00326     if( !mHelpMenu ) {
00327         if ( aboutAppText.isEmpty() )
00328             mHelpMenu = new KHelpMenu( this, instance()->aboutData(), showWhatsThis);
00329         else
00330             mHelpMenu = new KHelpMenu( this, aboutAppText, showWhatsThis );
00331 
00332         if ( !mHelpMenu )
00333             return 0;
00334         connect( mHelpMenu, SIGNAL( showAboutApplication() ),
00335                  this, SLOT( showAboutApplication() ) );
00336     }
00337 
00338     return mHelpMenu->menu();
00339 }
00340 
00341 KPopupMenu* KMainWindow::customHelpMenu( bool showWhatsThis )
00342 {
00343     if( !mHelpMenu ) {
00344         mHelpMenu = new KHelpMenu( this, QString::null, showWhatsThis );
00345         connect( mHelpMenu, SIGNAL( showAboutApplication() ),
00346                  this, SLOT( showAboutApplication() ) );
00347     }
00348 
00349     return mHelpMenu->menu();
00350 }
00351 
00352 bool KMainWindow::canBeRestored( int number )
00353 {
00354     if ( !kapp->isRestored() )
00355         return false;
00356     KConfig *config = kapp->sessionConfig();
00357     if ( !config )
00358         return false;
00359     config->setGroup( QString::fromLatin1("Number") );
00360     int n = config->readNumEntry( QString::fromLatin1("NumberOfWindows") , 1 );
00361     return number >= 1 && number <= n;
00362 }
00363 
00364 const QString KMainWindow::classNameOfToplevel( int number )
00365 {
00366     if ( !kapp->isRestored() )
00367         return QString::null;
00368     KConfig *config = kapp->sessionConfig();
00369     if ( !config )
00370         return QString::null;
00371     QString s;
00372     s.setNum( number );
00373     s.prepend( QString::fromLatin1("WindowProperties") );
00374     config->setGroup( s );
00375     if ( !config->hasKey( QString::fromLatin1("ClassName") ) )
00376         return QString::null;
00377     else
00378         return config->readEntry( QString::fromLatin1("ClassName") );
00379 }
00380 
00381 void KMainWindow::show()
00382 {
00383     QMainWindow::show();
00384 
00385     for ( QPtrListIterator<QDockWindow> it( d->hiddenDockWindows ); it.current(); ++it )
00386     it.current()->show();
00387 
00388     d->hiddenDockWindows.clear();
00389 }
00390 
00391 void KMainWindow::hide()
00392 {
00393     if ( isVisible() ) {
00394 
00395         d->hiddenDockWindows.clear();
00396 
00397         QObjectList *list = queryList( "QDockWindow" );
00398         for( QObjectListIt it( *list ); it.current(); ++it ) {
00399             QDockWindow *dw = (QDockWindow*)it.current();
00400             if ( dw->isTopLevel() && dw->isVisible() ) {
00401                 d->hiddenDockWindows.append( dw );
00402                 dw->hide();
00403             }
00404         }
00405         delete list;
00406     }
00407 
00408     QWidget::hide();
00409 }
00410 
00411 bool KMainWindow::restore( int number, bool show )
00412 {
00413     if ( !canBeRestored( number ) )
00414         return false;
00415     KConfig *config = kapp->sessionConfig();
00416     if ( readPropertiesInternal( config, number ) ){
00417         if ( show )
00418             KMainWindow::show();
00419         return false;
00420     }
00421     return false;
00422 }
00423 
00424 KXMLGUIFactory *KMainWindow::guiFactory()
00425 {
00426     if ( !factory_ )
00427         factory_ = new KXMLGUIFactory( this, this, "guifactory" );
00428     return factory_;
00429 }
00430 
00431 int KMainWindow::configureToolbars()
00432 {
00433     saveMainWindowSettings(KGlobal::config());
00434     KEditToolbar dlg(actionCollection(), xmlFile(), true, this);
00435     connect(&dlg, SIGNAL(newToolbarConfig()), SLOT(saveNewToolbarConfig()));
00436     return dlg.exec();
00437 }
00438 
00439 void KMainWindow::saveNewToolbarConfig()
00440 {
00441     createGUI(xmlFile());
00442     applyMainWindowSettings( KGlobal::config() );
00443 }
00444 
00445 void KMainWindow::setupGUI( int options, const QString & xmlfile ) {
00446     setupGUI(QSize(), options, xmlfile);
00447 }
00448 
00449 void KMainWindow::setupGUI( QSize defaultSize, int options, const QString & xmlfile ) {
00450     if( options & Keys ){
00451         KStdAction::keyBindings(guiFactory(),
00452                     SLOT(configureShortcuts()), actionCollection());
00453     }
00454 
00455     if( (options & StatusBar) && internalStatusBar() ){
00456         createStandardStatusBarAction();
00457     }
00458 
00459     if( options & ToolBar ){
00460         setStandardToolBarMenuEnabled( true );
00461         KStdAction::configureToolbars(this,
00462                       SLOT(configureToolbars() ), actionCollection());
00463     }
00464 
00465     if( options & Create ){
00466         createGUI(xmlfile,false);
00467     }
00468 
00469     if( options & Save ){
00470         // setupGUI() is typically called in the constructor before show(),
00471         // so the default window size will be incorrect unless the application
00472         // hard coded the size which they should try not to do (i.e. use
00473         // size hints).
00474         if(initialGeometrySet())
00475         {
00476           // Do nothing...
00477         }
00478         else if(defaultSize.isValid())
00479         {
00480           resize(defaultSize);
00481         }
00482         else if(!isShown())
00483         {
00484           adjustSize();
00485         }
00486         setAutoSaveSettings();
00487     }
00488 
00489 }
00490 
00491 void KMainWindow::createGUI( const QString &xmlfile, bool _conserveMemory )
00492 {
00493     // disabling the updates prevents unnecessary redraws
00494     setUpdatesEnabled( false );
00495 
00496     // just in case we are rebuilding, let's remove our old client
00497     guiFactory()->removeClient( this );
00498 
00499     // make sure to have an empty GUI
00500     QMenuBar* mb = internalMenuBar();
00501     if ( mb )
00502         mb->clear();
00503 
00504     (void)toolBarIterator(); // make sure toolbarList is most-up-to-date
00505     toolbarList.setAutoDelete( true );
00506     toolbarList.clear();
00507     toolbarList.setAutoDelete( false );
00508 
00509     // don't build a help menu unless the user ask for it
00510     if (d->showHelpMenu) {
00511         // we always want a help menu
00512         if (!helpMenu2)
00513             helpMenu2 = new KHelpMenu(this, instance()->aboutData(), true,
00514                                       actionCollection());
00515     }
00516 
00517     // we always want to load in our global standards file
00518     setXMLFile( locate( "config", "ui/ui_standards.rc", instance() ) );
00519 
00520     // now, merge in our local xml file.  if this is null, then that
00521     // means that we will be only using the global file
00522     if ( !xmlfile.isNull() ) {
00523         setXMLFile( xmlfile, true );
00524     } else {
00525         QString auto_file(instance()->instanceName() + "ui.rc");
00526         setXMLFile( auto_file, true );
00527     }
00528 
00529     // make sure we don't have any state saved already
00530     setXMLGUIBuildDocument( QDomDocument() );
00531 
00532     // do the actual GUI building
00533     guiFactory()->addClient( this );
00534 
00535     // try and get back *some* of our memory
00536     if ( _conserveMemory )
00537     {
00538       // before freeing the memory allocated by the DOM document we also
00539       // free all memory allocated internally in the KXMLGUIFactory for
00540       // the menubar and the toolbars . This however implies that we
00541       // have to take care of deleting those widgets ourselves. For
00542       // destruction this is no problem, but when rebuilding we have
00543       // to take care of that (and we want to rebuild the GUI when
00544       // using stuff like the toolbar editor ).
00545       // In addition we have to take care of not removing containers
00546       // like popupmenus, defined in the XML document.
00547       // this code should probably go into a separate method in KMainWindow.
00548       // there's just one problem: I'm bad in finding names ;-) , so
00549       // I skipped this ;-)
00550 
00551       QDomDocument doc = domDocument();
00552 
00553       for( QDomNode n = doc.documentElement().firstChild();
00554            !n.isNull(); n = n.nextSibling())
00555       {
00556           QDomElement e = n.toElement();
00557 
00558           if ( e.tagName().lower() == "toolbar" )
00559               factory_->resetContainer( e.attribute( "name" ) );
00560           else if ( e.tagName().lower() == "menubar" )
00561               factory_->resetContainer( e.tagName(), true );
00562       }
00563 
00564       conserveMemory();
00565     }
00566 
00567     setUpdatesEnabled( true );
00568     updateGeometry();
00569 }
00570 
00571 void KMainWindow::setHelpMenuEnabled(bool showHelpMenu)
00572 {
00573     d->showHelpMenu = showHelpMenu;
00574 }
00575 
00576 bool KMainWindow::isHelpMenuEnabled()
00577 {
00578     return d->showHelpMenu;
00579 }
00580 
00581 void KMainWindow::setCaption( const QString &caption )
00582 {
00583     setPlainCaption( kapp->makeStdCaption(caption) );
00584 }
00585 
00586 void KMainWindow::setCaption( const QString &caption, bool modified )
00587 {
00588     setPlainCaption( kapp->makeStdCaption(caption, true, modified) );
00589 }
00590 
00591 void KMainWindow::setPlainCaption( const QString &caption )
00592 {
00593     QMainWindow::setCaption( caption );
00594 #if defined Q_WS_X11
00595     NETWinInfo info( qt_xdisplay(), winId(), qt_xrootwin(), 0 );
00596     info.setName( caption.utf8().data() );
00597 #endif
00598 }
00599 
00600 void KMainWindow::appHelpActivated( void )
00601 {
00602     if( !mHelpMenu ) {
00603         mHelpMenu = new KHelpMenu( this );
00604         if ( !mHelpMenu )
00605             return;
00606     }
00607     mHelpMenu->appHelpActivated();
00608 }
00609 
00610 void KMainWindow::slotStateChanged(const QString &newstate)
00611 {
00612   stateChanged(newstate, KXMLGUIClient::StateNoReverse);
00613 }
00614 
00615 /*
00616  * Get rid of this for KDE 4.0
00617  */
00618 void KMainWindow::slotStateChanged(const QString &newstate,
00619                                    KXMLGUIClient::ReverseStateChange reverse)
00620 {
00621   stateChanged(newstate, reverse);
00622 }
00623 
00624 /*
00625  * Enable this for KDE 4.0
00626  */
00627 // void KMainWindow::slotStateChanged(const QString &newstate,
00628 //                                    bool reverse)
00629 // {
00630 //   stateChanged(newstate,
00631 //                reverse ? KXMLGUIClient::StateReverse : KXMLGUIClient::StateNoReverse);
00632 // }
00633 
00634 void KMainWindow::closeEvent ( QCloseEvent *e )
00635 {
00636     // Save settings if auto-save is enabled, and settings have changed
00637     if (d->settingsDirty && d->autoSaveSettings)
00638         saveAutoSaveSettings();
00639 
00640     if (queryClose()) {
00641         e->accept();
00642 
00643         int not_withdrawn = 0;
00644         QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
00645         for (it.toFirst(); it.current(); ++it){
00646             if ( !it.current()->isHidden() && it.current()->isTopLevel() && it.current() != this )
00647                 not_withdrawn++;
00648         }
00649 
00650         if ( !no_query_exit && not_withdrawn <= 0 ) { // last window close accepted?
00651             if ( queryExit() && !kapp->sessionSaving() && !d->shuttingDown ) { // Yes, Quit app?
00652                 // don't call queryExit() twice
00653                 disconnect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
00654                 d->shuttingDown = true;
00655                 kapp->deref();             // ...and quit application.
00656             }  else {
00657                 // cancel closing, it's stupid to end up with no windows at all....
00658                 e->ignore();
00659             }
00660         }
00661     }
00662 }
00663 
00664 bool KMainWindow::queryExit()
00665 {
00666     return true;
00667 }
00668 
00669 bool KMainWindow::queryClose()
00670 {
00671     return true;
00672 }
00673 
00674 void KMainWindow::saveGlobalProperties( KConfig*  )
00675 {
00676 }
00677 
00678 void KMainWindow::readGlobalProperties( KConfig*  )
00679 {
00680 }
00681 
00682 #if defined(KDE_COMPAT)
00683 void KMainWindow::updateRects()
00684 {
00685 }
00686 #endif
00687 
00688 void KMainWindow::showAboutApplication()
00689 {
00690 }
00691 
00692 void KMainWindow::savePropertiesInternal( KConfig *config, int number )
00693 {
00694     bool oldASWS = d->autoSaveWindowSize;
00695     d->autoSaveWindowSize = true; // make saveMainWindowSettings save the window size
00696 
00697     QString s;
00698     s.setNum(number);
00699     s.prepend(QString::fromLatin1("WindowProperties"));
00700     config->setGroup(s);
00701 
00702     // store objectName, className, Width and Height  for later restoring
00703     // (Only useful for session management)
00704     config->writeEntry(QString::fromLatin1("ObjectName"), name());
00705     config->writeEntry(QString::fromLatin1("ClassName"), className());
00706 
00707     saveMainWindowSettings(config); // Menubar, statusbar and Toolbar settings.
00708 
00709     s.setNum(number);
00710     config->setGroup(s);
00711     saveProperties(config);
00712 
00713     d->autoSaveWindowSize = oldASWS;
00714 }
00715 
00716 void KMainWindow::saveMainWindowSettings(KConfig *config, const QString &configGroup)
00717 {
00718     kdDebug(200) << "KMainWindow::saveMainWindowSettings " << configGroup << endl;
00719     QString oldGroup;
00720 
00721     if (!configGroup.isEmpty())
00722     {
00723        oldGroup = config->group();
00724        config->setGroup(configGroup);
00725     }
00726 
00727     // Called by session management - or if we want to save the window size anyway
00728     if ( d->autoSaveWindowSize )
00729         saveWindowSize( config );
00730 
00731     QStatusBar* sb = internalStatusBar();
00732     if (sb) {
00733        if(!config->hasDefault("StatusBar") && !sb->isHidden() )
00734            config->revertToDefault("StatusBar");
00735        else
00736            config->writeEntry("StatusBar", sb->isHidden() ? "Disabled" : "Enabled");
00737     }
00738 
00739     QMenuBar* mb = internalMenuBar();
00740     if (mb) {
00741        QString MenuBar = QString::fromLatin1("MenuBar");
00742        if(!config->hasDefault("MenuBar") && !mb->isHidden() )
00743            config->revertToDefault("MenuBar");
00744        else
00745            config->writeEntry("MenuBar", mb->isHidden() ? "Disabled" : "Enabled");
00746     }
00747 
00748     int n = 1; // Toolbar counter. toolbars are counted from 1,
00749     KToolBar *toolbar = 0;
00750     QPtrListIterator<KToolBar> it( toolBarIterator() );
00751     while ( ( toolbar = it.current() ) ) {
00752         ++it;
00753         QString group;
00754         if (!configGroup.isEmpty())
00755         {
00756            // Give a number to the toolbar, but prefer a name if there is one,
00757            // because there's no real guarantee on the ordering of toolbars
00758            group = (!::qstrcmp(toolbar->name(), "unnamed") ? QString::number(n) : QString(" ")+toolbar->name());
00759            group.prepend(" Toolbar");
00760            group.prepend(configGroup);
00761         }
00762         toolbar->saveSettings(config, group);
00763         n++;
00764     }
00765     if (!configGroup.isEmpty())
00766        config->setGroup(oldGroup);
00767 }
00768 
00769 void KMainWindow::setStandardToolBarMenuEnabled( bool enable )
00770 {
00771     if ( enable ) {
00772         if ( d->toolBarHandler )
00773             return;
00774 
00775     d->toolBarHandler = new KDEPrivate::ToolBarHandler( this );
00776 
00777     if ( factory() )
00778         factory()->addClient( d->toolBarHandler );
00779     } else {
00780         if ( !d->toolBarHandler )
00781             return;
00782 
00783         if ( factory() )
00784             factory()->removeClient( d->toolBarHandler );
00785 
00786         delete d->toolBarHandler;
00787         d->toolBarHandler = 0;
00788     }
00789 }
00790 
00791 bool KMainWindow::isStandardToolBarMenuEnabled() const
00792 {
00793     return ( d->toolBarHandler );
00794 }
00795 
00796 void KMainWindow::createStandardStatusBarAction(){
00797   if(!d->showStatusBarAction){
00798     d->showStatusBarAction = KStdAction::showStatusbar(this, SLOT(setSettingsDirty()), actionCollection());
00799     KStatusBar *sb = statusBar(); // Creates statusbar if it doesn't exist already.
00800     connect(d->showStatusBarAction, SIGNAL(toggled(bool)), sb, SLOT(setShown(bool)));
00801     d->showStatusBarAction->setChecked(sb->isHidden());
00802   }
00803 }
00804 
00805 bool KMainWindow::readPropertiesInternal( KConfig *config, int number )
00806 {
00807     if ( number == 1 )
00808         readGlobalProperties( config );
00809 
00810     // in order they are in toolbar list
00811     QString s;
00812     s.setNum(number);
00813     s.prepend(QString::fromLatin1("WindowProperties"));
00814 
00815     config->setGroup(s);
00816 
00817     // restore the object name (window role)
00818     if ( config->hasKey(QString::fromLatin1("ObjectName" )) )
00819         setName( config->readEntry(QString::fromLatin1("ObjectName")).latin1()); // latin1 is right here
00820 
00821     applyMainWindowSettings(config); // Menubar, statusbar and toolbar settings.
00822 
00823     s.setNum(number);
00824     config->setGroup(s);
00825     readProperties(config);
00826     return true;
00827 }
00828 
00829 void KMainWindow::applyMainWindowSettings(KConfig *config, const QString &configGroup)
00830 {
00831     return applyMainWindowSettings(config,configGroup,false);
00832 }
00833 
00834 void KMainWindow::applyMainWindowSettings(KConfig *config, const QString &configGroup,bool force)
00835 {
00836     kdDebug(200) << "KMainWindow::applyMainWindowSettings" << endl;
00837 
00838     KConfigGroupSaver saver( config, configGroup.isEmpty() ? config->group() : configGroup );
00839 
00840     restoreWindowSize(config);
00841 
00842     QStatusBar* sb = internalStatusBar();
00843     if (sb) {
00844         QString entry = config->readEntry("StatusBar", "Enabled");
00845         if ( entry == "Disabled" )
00846            sb->hide();
00847         else
00848            sb->show();
00849         if(d->showStatusBarAction)
00850             d->showStatusBarAction->setChecked(!sb->isHidden());
00851     }
00852 
00853     QMenuBar* mb = internalMenuBar();
00854     if (mb) {
00855         QString entry = config->readEntry ("MenuBar", "Enabled");
00856         if ( entry == "Disabled" )
00857            mb->hide();
00858         else
00859            mb->show();
00860     }
00861 
00862     int n = 1; // Toolbar counter. toolbars are counted from 1,
00863     KToolBar *toolbar;
00864     QPtrListIterator<KToolBar> it( toolBarIterator() ); // must use own iterator
00865 
00866     for ( ; it.current(); ++it) {
00867         toolbar= it.current();
00868         QString group;
00869         if (!configGroup.isEmpty())
00870         {
00871            // Give a number to the toolbar, but prefer a name if there is one,
00872            // because there's no real guarantee on the ordering of toolbars
00873            group = (!::qstrcmp(toolbar->name(), "unnamed") ? QString::number(n) : QString(" ")+toolbar->name());
00874            group.prepend(" Toolbar");
00875            group.prepend(configGroup);
00876         }
00877         toolbar->applySettings(config, group, force);
00878         n++;
00879     }
00880 
00881     finalizeGUI( true );
00882 }
00883 
00884 void KMainWindow::finalizeGUI( bool force )
00885 {
00886     //kdDebug(200) << "KMainWindow::finalizeGUI force=" << force << endl;
00887     // The whole reason for this is that moveToolBar relies on the indexes
00888     // of the other toolbars, so in theory it should be called only once per
00889     // toolbar, but in increasing order of indexes.
00890     // Since we can't do that immediately, we move them, and _then_
00891     // we call positionYourself again for each of them, but this time
00892     // the toolbariterator should give them in the proper order.
00893     // Both the XMLGUI and applySettings call this, hence "force" for the latter.
00894     QPtrListIterator<KToolBar> it( toolBarIterator() );
00895     for ( ; it.current() ; ++it ) {
00896         it.current()->positionYourself( force );
00897     }
00898 
00899     d->settingsDirty = false;
00900 }
00901 
00902 void KMainWindow::saveWindowSize( KConfig * config ) const
00903 {
00904   int scnum = QApplication::desktop()->screenNumber(parentWidget());
00905   QRect desk = QApplication::desktop()->screenGeometry(scnum);
00906   int w, h;
00907 #if defined Q_WS_X11
00908   // save maximalization as desktop size + 1 in that direction
00909   KWin::WindowInfo info = KWin::windowInfo( winId(), NET::WMState );
00910   w = info.state() & NET::MaxHoriz ? desk.width() + 1 : width();
00911   h = info.state() & NET::MaxVert ? desk.height() + 1 : height();
00912 #else
00913   if (isMaximized()) {
00914     w = desk.width() + 1;
00915     h = desk.height() + 1;
00916   }
00917   //TODO: add "Maximized" property instead "+1" hack
00918 #endif
00919   QRect size( desk.width(), w, desk.height(), h );
00920   bool defaultSize = (size == d->defaultWindowSize);
00921   QString widthString = QString::fromLatin1("Width %1").arg(desk.width());
00922   QString heightString = QString::fromLatin1("Height %1").arg(desk.height());
00923   if (!config->hasDefault(widthString) && defaultSize)
00924      config->revertToDefault(widthString);
00925   else
00926      config->writeEntry(widthString, w );
00927 
00928   if (!config->hasDefault(heightString) && defaultSize)
00929      config->revertToDefault(heightString);
00930   else
00931      config->writeEntry(heightString, h );
00932 }
00933 
00934 void KMainWindow::restoreWindowSize( KConfig * config )
00935 {
00936     if (d->care_about_geometry) {
00937         parseGeometry(true);
00938     } else {
00939         // restore the size
00940         int scnum = QApplication::desktop()->screenNumber(parentWidget());
00941         QRect desk = QApplication::desktop()->screenGeometry(scnum);
00942         if ( d->defaultWindowSize.isNull() ) // only once
00943           d->defaultWindowSize = QRect(desk.width(), width(), desk.height(), height()); // store default values
00944         QSize size( config->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 0 ),
00945                     config->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 0 ) );
00946         if (size.isEmpty()) {
00947             // try the KDE 2.0 way
00948             size = QSize( config->readNumEntry( QString::fromLatin1("Width"), 0 ),
00949                           config->readNumEntry( QString::fromLatin1("Height"), 0 ) );
00950             if (!size.isEmpty()) {
00951                 // make sure the other resolutions don't get old settings
00952                 config->writeEntry( QString::fromLatin1("Width"), 0 );
00953                 config->writeEntry( QString::fromLatin1("Height"), 0 );
00954             }
00955         }
00956         if ( !size.isEmpty() ) {
00957 #ifdef Q_WS_X11
00958             int state = ( size.width() > desk.width() ? NET::MaxHoriz : 0 )
00959                         | ( size.height() > desk.height() ? NET::MaxVert : 0 );
00960             if(( state & NET::Max ) == NET::Max )
00961                 ; // no resize
00962             else if(( state & NET::MaxHoriz ) == NET::MaxHoriz )
00963                 resize( width(), size.height());
00964             else if(( state & NET::MaxVert ) == NET::MaxVert )
00965                 resize( size.width(), height());
00966             else
00967                 resize( size );
00968             // QWidget::showMaximized() is both insufficient and broken
00969             KWin::setState( winId(), state );
00970 #else
00971             if (size.width() > desk.width() || size.height() > desk.height())
00972               setWindowState( WindowMaximized );
00973             else
00974               resize( size );
00975 #endif
00976         }
00977     }
00978 }
00979 
00980 bool KMainWindow::initialGeometrySet() const
00981 {
00982     return d->care_about_geometry;
00983 }
00984 
00985 void KMainWindow::ignoreInitialGeometry()
00986 {
00987     d->care_about_geometry = false;
00988 }
00989 
00990 void KMainWindow::setSettingsDirty()
00991 {
00992     //kdDebug(200) << "KMainWindow::setSettingsDirty" << endl;
00993     d->settingsDirty = true;
00994     if ( d->autoSaveSettings )
00995     {
00996         // Use a timer to save "immediately" user-wise, but not too immediately
00997         // (to compress calls and save only once, in case of multiple changes)
00998         if ( !d->settingsTimer )
00999         {
01000            d->settingsTimer = new QTimer( this );
01001            connect( d->settingsTimer, SIGNAL( timeout() ), SLOT( saveAutoSaveSettings() ) );
01002         }
01003         d->settingsTimer->start( 500, true );
01004     }
01005 }
01006 
01007 bool KMainWindow::settingsDirty() const
01008 {
01009     return d->settingsDirty;
01010 }
01011 
01012 QString KMainWindow::settingsGroup() const
01013 {
01014     return d->autoSaveGroup;
01015 }
01016 
01017 void KMainWindow::setAutoSaveSettings( const QString & groupName, bool saveWindowSize )
01018 {
01019     d->autoSaveSettings = true;
01020     d->autoSaveGroup = groupName;
01021     d->autoSaveWindowSize = saveWindowSize;
01022     // Get notified when the user moves a toolbar around
01023     disconnect( this, SIGNAL( dockWindowPositionChanged( QDockWindow * ) ),
01024                 this, SLOT( setSettingsDirty() ) );
01025     connect( this, SIGNAL( dockWindowPositionChanged( QDockWindow * ) ),
01026              this, SLOT( setSettingsDirty() ) );
01027 
01028     // Now read the previously saved settings
01029     applyMainWindowSettings( KGlobal::config(), groupName );
01030 }
01031 
01032 void KMainWindow::resetAutoSaveSettings()
01033 {
01034     d->autoSaveSettings = false;
01035     if ( d->settingsTimer )
01036         d->settingsTimer->stop();
01037 }
01038 
01039 bool KMainWindow::autoSaveSettings() const
01040 {
01041     return d->autoSaveSettings;
01042 }
01043 
01044 QString KMainWindow::autoSaveGroup() const
01045 {
01046     return d->autoSaveGroup;
01047 }
01048 
01049 void KMainWindow::saveAutoSaveSettings()
01050 {
01051     Q_ASSERT( d->autoSaveSettings );
01052     //kdDebug(200) << "KMainWindow::saveAutoSaveSettings -> saving settings" << endl;
01053     saveMainWindowSettings( KGlobal::config(), d->autoSaveGroup );
01054     KGlobal::config()->sync();
01055     d->settingsDirty = false;
01056     if ( d->settingsTimer )
01057         d->settingsTimer->stop();
01058 }
01059 
01060 void KMainWindow::resizeEvent( QResizeEvent * )
01061 {
01062     if ( d->autoSaveWindowSize )
01063         setSettingsDirty();
01064 }
01065 
01066 bool KMainWindow::hasMenuBar()
01067 {
01068     return (internalMenuBar());
01069 }
01070 
01071 KMenuBar *KMainWindow::menuBar()
01072 {
01073     KMenuBar * mb = internalMenuBar();
01074     if ( !mb ) {
01075         mb = new KMenuBar( this );
01076         // trigger a re-layout and trigger a call to the private
01077         // setMenuBar method.
01078         QMainWindow::menuBar();
01079     }
01080     return mb;
01081 }
01082 
01083 KStatusBar *KMainWindow::statusBar()
01084 {
01085     KStatusBar * sb = internalStatusBar();
01086     if ( !sb ) {
01087         sb = new KStatusBar( this );
01088         // trigger a re-layout and trigger a call to the private
01089         // setStatusBar method.
01090         QMainWindow::statusBar();
01091     }
01092     return sb;
01093 }
01094 
01095 void KMainWindow::shuttingDown()
01096 {
01097     // Needed for Qt <= 3.0.3 at least to prevent reentrancy
01098     // when queryExit() shows a dialog. Check before removing!
01099     static bool reentrancy_protection = false;
01100     if (!reentrancy_protection)
01101     {
01102        reentrancy_protection = true;
01103        // call the virtual queryExit
01104        queryExit();
01105        reentrancy_protection = false;
01106     }
01107 
01108 }
01109 
01110 KMenuBar *KMainWindow::internalMenuBar()
01111 {
01112     QObjectList *l = queryList( "KMenuBar", 0, false, false );
01113     if ( !l || !l->first() ) {
01114         delete l;
01115         return 0;
01116     }
01117 
01118     KMenuBar *m = (KMenuBar*)l->first();
01119     delete l;
01120     return m;
01121 }
01122 
01123 KStatusBar *KMainWindow::internalStatusBar()
01124 {
01125     QObjectList *l = queryList( "KStatusBar", 0, false, false );
01126     if ( !l || !l->first() ) {
01127         delete l;
01128         return 0;
01129     }
01130 
01131     KStatusBar *s = (KStatusBar*)l->first();
01132     delete l;
01133     return s;
01134 }
01135 
01136 void KMainWindow::childEvent( QChildEvent* e)
01137 {
01138     QMainWindow::childEvent( e );
01139 }
01140 
01141 KToolBar *KMainWindow::toolBar( const char * name )
01142 {
01143     if (!name)
01144        name = "mainToolBar";
01145     KToolBar *tb = (KToolBar*)child( name, "KToolBar" );
01146     if ( tb )
01147         return tb;
01148     bool honor_mode = (!strcmp(name, "mainToolBar"));
01149 
01150     if ( builderClient() )
01151         return new KToolBar(this, name, honor_mode); // XMLGUI constructor
01152     else
01153         return new KToolBar(this, DockTop, false, name, honor_mode ); // non-XMLGUI
01154 }
01155 
01156 QPtrListIterator<KToolBar> KMainWindow::toolBarIterator()
01157 {
01158     toolbarList.clear();
01159     QPtrList<QToolBar> lst;
01160     for ( int i = (int)QMainWindow::DockUnmanaged; i <= (int)DockMinimized; ++i ) {
01161         lst = toolBars( (ToolBarDock)i );
01162         for ( QToolBar *tb = lst.first(); tb; tb = lst.next() ) {
01163             if ( !tb->inherits( "KToolBar" ) )
01164                 continue;
01165             toolbarList.append( (KToolBar*)tb );
01166         }
01167     }
01168     return QPtrListIterator<KToolBar>( toolbarList );
01169 }
01170 
01171 KAccel * KMainWindow::accel()
01172 {
01173     if ( !d->kaccel )
01174         d->kaccel = new KAccel( this, "kmw-kaccel" );
01175     return d->kaccel;
01176 }
01177 
01178 void KMainWindow::paintEvent( QPaintEvent * pe )
01179 {
01180     QMainWindow::paintEvent(pe); //Upcall to handle SH_MainWindow_SpaceBelowMenuBar rendering
01181 }
01182 
01183 QSize KMainWindow::sizeForCentralWidgetSize(QSize size)
01184 {
01185     KToolBar *tb = (KToolBar*)child( "mainToolBar", "KToolBar" );
01186     if (tb && !tb->isHidden()) {
01187         switch( tb->barPos() )
01188         {
01189           case KToolBar::Top:
01190           case KToolBar::Bottom:
01191             size += QSize(0, tb->sizeHint().height());
01192             break;
01193 
01194           case KToolBar::Left:
01195           case KToolBar::Right:
01196             size += QSize(toolBar()->sizeHint().width(), 0);
01197             break;
01198 
01199           case KToolBar::Flat:
01200             size += QSize(0, 3+kapp->style().pixelMetric( QStyle::PM_DockWindowHandleExtent ));
01201             break;
01202 
01203           default:
01204             break;
01205         }
01206     }
01207     KMenuBar *mb = internalMenuBar();
01208     if (mb && !mb->isHidden()) {
01209         size += QSize(0,mb->heightForWidth(size.width()));
01210         if (style().styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, this))
01211            size += QSize( 0, dockWindowsMovable() ? 1 : 2);
01212     }
01213     QStatusBar *sb = internalStatusBar();
01214     if( sb && !sb->isHidden() )
01215        size += QSize(0, sb->sizeHint().height());
01216 
01217     return size;
01218 }
01219 
01220 #if KDE_IS_VERSION( 3, 9, 0 )
01221 #ifdef __GNUC__
01222 #warning Remove, should be in Qt
01223 #endif
01224 #endif
01225 void KMainWindow::setIcon( const QPixmap& p )
01226 {
01227     QMainWindow::setIcon( p );
01228 #ifdef Q_WS_X11 
01229     // Qt3 doesn't support _NET_WM_ICON, but KApplication::setTopWidget(), which
01230     // is used by KMainWindow, sets it
01231     KWin::setIcons( winId(), p, QPixmap());
01232 #endif
01233 }
01234 
01235 QPtrList<KMainWindow>* KMainWindow::getMemberList() { return memberList; }
01236 
01237 // why do we support old gcc versions? using KXMLGUIBuilder::finalizeGUI;
01238 // DF: because they compile KDE much faster :)
01239 void KMainWindow::finalizeGUI( KXMLGUIClient *client )
01240 { KXMLGUIBuilder::finalizeGUI( client ); }
01241 
01242 void KMainWindow::virtual_hook( int id, void* data )
01243 { KXMLGUIBuilder::virtual_hook( id, data );
01244   KXMLGUIClient::virtual_hook( id, data ); }
01245 
01246 
01247 
01248 #include "kmainwindow.moc"
01249 

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal