/* This file is part of the KDE libraries Copyright (C) 2000 Reginald Stadlbauer (reggie@kde.org) (C) 1997 Stephan Kulow (coolo@kde.org) (C) 1997-2000 Sven Radej (radej@kde.org) (C) 1997-2000 Matthias Ettrich (ettrich@kde.org) (C) 1999 Chris Schlaeger (cs@kde.org) (C) 2002 Joseph Wenninger (jowenn@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "tdemainwindow.h" #include "tdemainwindowiface.h" #include "tdetoolbarhandler.h" #include "kwhatsthismanager_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined Q_WS_X11 #include #endif #include #include #include class TDEMainWindowPrivate { public: bool showHelpMenu:1; bool autoSaveSettings:1; bool settingsDirty:1; bool autoSaveWindowSize:1; bool care_about_geometry:1; bool shuttingDown:1; bool newStyleRefCounting:1; TQString autoSaveGroup; TDEAccel * tdeaccel; TDEMainWindowInterface *m_interface; KDEPrivate::ToolBarHandler *toolBarHandler; TQTimer* settingsTimer; TDEToggleAction *showStatusBarAction; TQRect defaultWindowSize; TQPtrList hiddenDockWindows; }; TQPtrList* TDEMainWindow::memberList = 0L; static bool no_query_exit = false; static KMWSessionManaged* ksm = 0; static KStaticDeleter ksmd; class KMWSessionManaged : public KSessionManaged { public: KMWSessionManaged() { } ~KMWSessionManaged() { } bool saveState( TQSessionManager& ) { TDEConfig* config = TDEApplication::kApplication()->sessionConfig(); if ( TDEMainWindow::memberList->first() ){ // According to Jochen Wilhelmy , this // hook is useful for better document orientation TDEMainWindow::memberList->first()->saveGlobalProperties(config); } TQPtrListIterator it(*TDEMainWindow::memberList); int n = 0; for (it.toFirst(); it.current(); ++it){ n++; it.current()->savePropertiesInternal(config, n); } config->setGroup(TQString::fromLatin1("Number")); config->writeEntry(TQString::fromLatin1("NumberOfWindows"), n ); return true; } bool commitData( TQSessionManager& sm ) { // not really a fast method but the only compatible one if ( sm.allowsInteraction() ) { bool canceled = false; TQPtrListIterator it(*TDEMainWindow::memberList); ::no_query_exit = true; for (it.toFirst(); it.current() && !canceled;){ TDEMainWindow *window = *it; ++it; // Update now, the current window might get deleted if ( !window->testWState( TQt::WState_ForceHide ) ) { TQCloseEvent e; TQApplication::sendEvent( window, &e ); canceled = !e.isAccepted(); /* Don't even think_about deleting widgets with Qt::WDestructiveClose flag set at this point. We are faking a close event, but we are *not*_ closing the window. The purpose of the faked close event is to prepare the application so it can safely be quit without the user losing data (possibly showing a message box "do you want to save this or that?"). It is possible that the session manager quits the application later (emitting TQApplication::aboutToQuit() when this happens), but it is also possible that the user cancels the shutdown, so the application will continue to run. */ } } ::no_query_exit = false; if (canceled) return false; TDEMainWindow* last = 0; for (it.toFirst(); it.current() && !canceled; ++it){ TDEMainWindow *window = *it; if ( !window->testWState( TQt::WState_ForceHide ) ) { last = window; } } if ( last ) return last->queryExit(); // else return true; } // the user wants it, the user gets it return true; } }; static bool being_first = true; TDEMainWindow::TDEMainWindow( TQWidget* parent, const char *name, WFlags f ) : TQMainWindow( parent, name, f ), KXMLGUIBuilder( this ), helpMenu2( 0 ), factory_( 0 ) { initTDEMainWindow(name, 0); } TDEMainWindow::TDEMainWindow( int cflags, TQWidget* parent, const char *name, WFlags f ) : TQMainWindow( parent, name, f ), KXMLGUIBuilder( this ), helpMenu2( 0 ), factory_( 0 ) { initTDEMainWindow(name, cflags); } void TDEMainWindow::initTDEMainWindow(const char *name, int cflags) { KWhatsThisManager::init (); setDockMenuEnabled( false ); mHelpMenu = 0; kapp->setTopWidget( this ); actionCollection()->setWidget( this ); connect(kapp, TQT_SIGNAL(shutDown()), this, TQT_SLOT(shuttingDown())); if( !memberList ) memberList = new TQPtrList; if ( !ksm ) ksm = ksmd.setObject(ksm, new KMWSessionManaged()); // set a unique object name. Required by session management. TQCString objname; TQCString s; int unusedNumber; if ( !name ) { // no name given objname = kapp->instanceName() + "-mainwindow#"; s = objname + '1'; // start adding number immediately unusedNumber = 1; } else if( name[0] != '\0' && name[ strlen( name ) - 1 ] == '#' ) { // trailing # - always add a number objname = name; s = objname + '1'; // start adding number immediately unusedNumber = 1; } else { objname = name; s = objname; unusedNumber = 0; // add numbers only when needed } for(;;) { TQWidgetList* list = kapp->topLevelWidgets(); TQWidgetListIt it( *list ); bool found = false; for( TQWidget* w = it.current(); w != NULL; ++it, w = it.current()) if( w != this && w->name() == s ) { found = true; break; } delete list; if( !found ) break; s.setNum( ++unusedNumber ); s = objname + s; } setName( s ); memberList->append( this ); d = new TDEMainWindowPrivate; d->showHelpMenu = true; d->settingsDirty = false; d->autoSaveSettings = false; d->autoSaveWindowSize = true; // for compatibility d->tdeaccel = actionCollection()->tdeaccel(); d->toolBarHandler = 0; d->settingsTimer = 0; d->showStatusBarAction = NULL; d->shuttingDown = false; if ((d->care_about_geometry = being_first)) { being_first = false; if ( kapp->geometryArgument().isNull() ) // if there is no geometry, it doesn't matter d->care_about_geometry = false; else parseGeometry(false); } setCaption( kapp->caption() ); if ( cflags & NoDCOPObject) d->m_interface = 0; else d->m_interface = new TDEMainWindowInterface(this); if ( cflags & NewRefCountMode ) { d->newStyleRefCounting = true; kapp->ref(); } else { d->newStyleRefCounting = false; } if (!kapp->authorize("movable_toolbars")) setDockWindowsMovable(false); } TDEAction *TDEMainWindow::toolBarMenuAction() { if ( !d->toolBarHandler ) return 0; return d->toolBarHandler->toolBarMenuAction(); } void TDEMainWindow::setupToolbarMenuActions() { if ( d->toolBarHandler ) d->toolBarHandler->setupActions(); } void TDEMainWindow::parseGeometry(bool parsewidth) { assert ( !kapp->geometryArgument().isNull() ); assert ( d->care_about_geometry ); #if defined Q_WS_X11 int x, y; int w, h; int m = XParseGeometry( kapp->geometryArgument().latin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h); if (parsewidth) { TQSize minSize = minimumSize(); TQSize maxSize = maximumSize(); if ( !(m & WidthValue) ) w = width(); if ( !(m & HeightValue) ) h = height(); w = TQMIN(w,maxSize.width()); h = TQMIN(h,maxSize.height()); w = TQMAX(w,minSize.width()); h = TQMAX(h,minSize.height()); resize(w, h); } else { if ( parsewidth && !(m & XValue) ) x = geometry().x(); if ( parsewidth && !(m & YValue) ) y = geometry().y(); if ( (m & XNegative) ) x = TDEApplication::desktop()->width() + x - w; if ( (m & YNegative) ) y = TDEApplication::desktop()->height() + y - h; move(x, y); } #endif } TDEMainWindow::~TDEMainWindow() { delete d->settingsTimer; TQMenuBar* mb = internalMenuBar(); delete mb; delete d->m_interface; delete d; memberList->remove( this ); } TDEPopupMenu* TDEMainWindow::helpMenu( const TQString &aboutAppText, bool showWhatsThis ) { if( !mHelpMenu ) { if ( aboutAppText.isEmpty() ) mHelpMenu = new KHelpMenu( this, instance()->aboutData(), showWhatsThis); else mHelpMenu = new KHelpMenu( this, aboutAppText, showWhatsThis ); if ( !mHelpMenu ) return 0; connect( mHelpMenu, TQT_SIGNAL( showAboutApplication() ), this, TQT_SLOT( showAboutApplication() ) ); } return mHelpMenu->menu(); } TDEPopupMenu* TDEMainWindow::customHelpMenu( bool showWhatsThis ) { if( !mHelpMenu ) { mHelpMenu = new KHelpMenu( this, TQString::null, showWhatsThis ); connect( mHelpMenu, TQT_SIGNAL( showAboutApplication() ), this, TQT_SLOT( showAboutApplication() ) ); } return mHelpMenu->menu(); } bool TDEMainWindow::canBeRestored( int number ) { if ( !kapp->isRestored() ) return false; TDEConfig *config = kapp->sessionConfig(); if ( !config ) return false; config->setGroup( TQString::fromLatin1("Number") ); int n = config->readNumEntry( TQString::fromLatin1("NumberOfWindows") , 1 ); return number >= 1 && number <= n; } const TQString TDEMainWindow::classNameOfToplevel( int number ) { if ( !kapp->isRestored() ) return TQString::null; TDEConfig *config = kapp->sessionConfig(); if ( !config ) return TQString::null; TQString s; s.setNum( number ); s.prepend( TQString::fromLatin1("WindowProperties") ); config->setGroup( s ); if ( !config->hasKey( TQString::fromLatin1("ClassName") ) ) return TQString::null; else return config->readEntry( TQString::fromLatin1("ClassName") ); } void TDEMainWindow::show() { TQMainWindow::show(); for ( TQPtrListIterator it( d->hiddenDockWindows ); it.current(); ++it ) it.current()->show(); d->hiddenDockWindows.clear(); } void TDEMainWindow::hide() { if ( isVisible() ) { d->hiddenDockWindows.clear(); TQObjectList *list = queryList( TQDOCKWINDOW_OBJECT_NAME_STRING ); for( TQObjectListIt it( *list ); it.current(); ++it ) { TQDockWindow *dw = (TQDockWindow*)it.current(); if ( dw->isTopLevel() && dw->isVisible() ) { d->hiddenDockWindows.append( dw ); dw->hide(); } } delete list; } TQWidget::hide(); } bool TDEMainWindow::restore( int number, bool show ) { if ( !canBeRestored( number ) ) return false; TDEConfig *config = kapp->sessionConfig(); if ( readPropertiesInternal( config, number ) ){ if ( show ) TDEMainWindow::show(); return false; } return false; } KXMLGUIFactory *TDEMainWindow::guiFactory() { if ( !factory_ ) factory_ = new KXMLGUIFactory( this, TQT_TQOBJECT(this), "guifactory" ); return factory_; } int TDEMainWindow::configureToolbars() { saveMainWindowSettings(TDEGlobal::config()); KEditToolbar dlg(actionCollection(), xmlFile(), true, this); connect(&dlg, TQT_SIGNAL(newToolbarConfig()), TQT_SLOT(saveNewToolbarConfig())); return dlg.exec(); } void TDEMainWindow::saveNewToolbarConfig() { createGUI(xmlFile()); applyMainWindowSettings( TDEGlobal::config() ); } void TDEMainWindow::setupGUI( int options, const TQString & xmlfile ) { setupGUI(TQSize(), options, xmlfile); } void TDEMainWindow::setupGUI( TQSize defaultSize, int options, const TQString & xmlfile ) { if( options & Keys ){ KStdAction::keyBindings(guiFactory(), TQT_SLOT(configureShortcuts()), actionCollection()); } if( (options & StatusBar) && internalStatusBar() ){ createStandardStatusBarAction(); } if( options & ToolBar ){ setStandardToolBarMenuEnabled( true ); KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(configureToolbars() ), actionCollection()); } if( options & Create ){ createGUI(xmlfile,false); } if( options & Save ){ // setupGUI() is typically called in the constructor before show(), // so the default window size will be incorrect unless the application // hard coded the size which they should try not to do (i.e. use // size hints). if(initialGeometrySet()) { // Do nothing... } else if(defaultSize.isValid()) { resize(defaultSize); } else if(!isShown()) { adjustSize(); } setAutoSaveSettings(); } } void TDEMainWindow::createGUI( const TQString &xmlfile, bool _conserveMemory ) { // disabling the updates prevents unnecessary redraws setUpdatesEnabled( false ); // just in case we are rebuilding, let's remove our old client guiFactory()->removeClient( this ); // make sure to have an empty GUI TQMenuBar* mb = internalMenuBar(); if ( mb ) mb->clear(); (void)toolBarIterator(); // make sure toolbarList is most-up-to-date toolbarList.setAutoDelete( true ); toolbarList.clear(); toolbarList.setAutoDelete( false ); // don't build a help menu unless the user ask for it if (d->showHelpMenu) { // we always want a help menu if (!helpMenu2) helpMenu2 = new KHelpMenu(this, instance()->aboutData(), true, actionCollection()); } // we always want to load in our global standards file setXMLFile( locate( "config", "ui/ui_standards.rc", instance() ) ); // now, merge in our local xml file. if this is null, then that // means that we will be only using the global file if ( !xmlfile.isNull() ) { setXMLFile( xmlfile, true ); } else { TQString auto_file(instance()->instanceName() + "ui.rc"); setXMLFile( auto_file, true ); } // make sure we don't have any state saved already setXMLGUIBuildDocument( TQDomDocument() ); // do the actual GUI building guiFactory()->addClient( this ); // try and get back *some* of our memory if ( _conserveMemory ) { // before freeing the memory allocated by the DOM document we also // free all memory allocated internally in the KXMLGUIFactory for // the menubar and the toolbars . This however implies that we // have to take care of deleting those widgets ourselves. For // destruction this is no problem, but when rebuilding we have // to take care of that (and we want to rebuild the GUI when // using stuff like the toolbar editor ). // In addition we have to take care of not removing containers // like popupmenus, defined in the XML document. // this code should probably go into a separate method in TDEMainWindow. // there's just one problem: I'm bad in finding names ;-) , so // I skipped this ;-) TQDomDocument doc = domDocument(); for( TQDomNode n = doc.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) { TQDomElement e = n.toElement(); if ( e.tagName().lower() == "toolbar" ) factory_->resetContainer( e.attribute( "name" ) ); else if ( e.tagName().lower() == "menubar" ) factory_->resetContainer( e.tagName(), true ); } conserveMemory(); } setUpdatesEnabled( true ); updateGeometry(); } void TDEMainWindow::setHelpMenuEnabled(bool showHelpMenu) { d->showHelpMenu = showHelpMenu; } bool TDEMainWindow::isHelpMenuEnabled() { return d->showHelpMenu; } void TDEMainWindow::setCaption( const TQString &caption ) { setPlainCaption( kapp->makeStdCaption(caption) ); } void TDEMainWindow::setCaption( const TQString &caption, bool modified ) { setPlainCaption( kapp->makeStdCaption(caption, true, modified) ); } void TDEMainWindow::setPlainCaption( const TQString &caption ) { TQMainWindow::setCaption( caption ); #if defined Q_WS_X11 NETWinInfo info( tqt_xdisplay(), winId(), tqt_xrootwin(), 0 ); info.setName( caption.utf8().data() ); #endif } void TDEMainWindow::appHelpActivated( void ) { if( !mHelpMenu ) { mHelpMenu = new KHelpMenu( this ); if ( !mHelpMenu ) return; } mHelpMenu->appHelpActivated(); } void TDEMainWindow::slotStateChanged(const TQString &newstate) { stateChanged(newstate, KXMLGUIClient::StateNoReverse); } /* * Get rid of this for KDE 4.0 */ void TDEMainWindow::slotStateChanged(const TQString &newstate, KXMLGUIClient::ReverseStateChange reverse) { stateChanged(newstate, reverse); } /* * Enable this for KDE 4.0 */ // void TDEMainWindow::slotStateChanged(const TQString &newstate, // bool reverse) // { // stateChanged(newstate, // reverse ? KXMLGUIClient::StateReverse : KXMLGUIClient::StateNoReverse); // } void TDEMainWindow::closeEvent ( TQCloseEvent *e ) { // Save settings if auto-save is enabled, and settings have changed if (d->settingsDirty && d->autoSaveSettings) saveAutoSaveSettings(); if (queryClose()) { e->accept(); int not_withdrawn = 0; TQPtrListIterator it(*TDEMainWindow::memberList); for (it.toFirst(); it.current(); ++it){ if ( !it.current()->isHidden() && it.current()->isTopLevel() && it.current() != this ) not_withdrawn++; } if ( !no_query_exit && not_withdrawn <= 0 ) { // last window close accepted? if ( queryExit() && !kapp->sessionSaving() && !d->shuttingDown ) { // Yes, Quit app? // don't call queryExit() twice disconnect(kapp, TQT_SIGNAL(shutDown()), this, TQT_SLOT(shuttingDown())); d->shuttingDown = true; kapp->deref(); // ...and quit application. } else { // cancel closing, it's stupid to end up with no windows at all.... e->ignore(); } } } } bool TDEMainWindow::queryExit() { return true; } bool TDEMainWindow::queryClose() { return true; } void TDEMainWindow::saveGlobalProperties( TDEConfig* ) { } void TDEMainWindow::readGlobalProperties( TDEConfig* ) { } #if defined(KDE_COMPAT) void TDEMainWindow::updateRects() { } #endif void TDEMainWindow::showAboutApplication() { } void TDEMainWindow::savePropertiesInternal( TDEConfig *config, int number ) { bool oldASWS = d->autoSaveWindowSize; d->autoSaveWindowSize = true; // make saveMainWindowSettings save the window size TQString s; s.setNum(number); s.prepend(TQString::fromLatin1("WindowProperties")); config->setGroup(s); // store objectName, className, Width and Height for later restoring // (Only useful for session management) config->writeEntry(TQString::fromLatin1("ObjectName"), name()); config->writeEntry(TQString::fromLatin1("ClassName"), className()); saveMainWindowSettings(config); // Menubar, statusbar and Toolbar settings. s.setNum(number); config->setGroup(s); saveProperties(config); d->autoSaveWindowSize = oldASWS; } void TDEMainWindow::saveMainWindowSettings(TDEConfig *config, const TQString &configGroup) { kdDebug(200) << "TDEMainWindow::saveMainWindowSettings " << configGroup << endl; TQString oldGroup; if (!configGroup.isEmpty()) { oldGroup = config->group(); config->setGroup(configGroup); } // Called by session management - or if we want to save the window size anyway if ( d->autoSaveWindowSize ) saveWindowSize( config ); TQStatusBar* sb = internalStatusBar(); if (sb) { if(!config->hasDefault("StatusBar") && !sb->isHidden() ) config->revertToDefault("StatusBar"); else config->writeEntry("StatusBar", sb->isHidden() ? "Disabled" : "Enabled"); } TQMenuBar* mb = internalMenuBar(); if (mb) { TQString MenuBar = TQString::fromLatin1("MenuBar"); if(!config->hasDefault("MenuBar") && !mb->isHidden() ) config->revertToDefault("MenuBar"); else config->writeEntry("MenuBar", mb->isHidden() ? "Disabled" : "Enabled"); } int n = 1; // Toolbar counter. toolbars are counted from 1, TDEToolBar *toolbar = 0; TQPtrListIterator it( toolBarIterator() ); while ( ( toolbar = it.current() ) ) { ++it; TQString group; if (!configGroup.isEmpty()) { // Give a number to the toolbar, but prefer a name if there is one, // because there's no real guarantee on the ordering of toolbars group = (!::qstrcmp(toolbar->name(), "unnamed") ? TQString::number(n) : TQString(" ")+toolbar->name()); group.prepend(" Toolbar"); group.prepend(configGroup); } toolbar->saveSettings(config, group); n++; } if (!configGroup.isEmpty()) config->setGroup(oldGroup); } void TDEMainWindow::setStandardToolBarMenuEnabled( bool enable ) { if ( enable ) { if ( d->toolBarHandler ) return; d->toolBarHandler = new KDEPrivate::ToolBarHandler( this ); if ( factory() ) factory()->addClient( d->toolBarHandler ); } else { if ( !d->toolBarHandler ) return; if ( factory() ) factory()->removeClient( d->toolBarHandler ); delete d->toolBarHandler; d->toolBarHandler = 0; } } bool TDEMainWindow::isStandardToolBarMenuEnabled() const { return ( d->toolBarHandler ); } void TDEMainWindow::createStandardStatusBarAction(){ if(!d->showStatusBarAction){ d->showStatusBarAction = KStdAction::showStatusbar(TQT_TQOBJECT(this), TQT_SLOT(setSettingsDirty()), actionCollection()); KStatusBar *sb = statusBar(); // Creates statusbar if it doesn't exist already. connect(d->showStatusBarAction, TQT_SIGNAL(toggled(bool)), sb, TQT_SLOT(setShown(bool))); d->showStatusBarAction->setChecked(sb->isHidden()); } } bool TDEMainWindow::readPropertiesInternal( TDEConfig *config, int number ) { if ( number == 1 ) readGlobalProperties( config ); // in order they are in toolbar list TQString s; s.setNum(number); s.prepend(TQString::fromLatin1("WindowProperties")); config->setGroup(s); // restore the object name (window role) if ( config->hasKey(TQString::fromLatin1("ObjectName" )) ) setName( config->readEntry(TQString::fromLatin1("ObjectName")).latin1()); // latin1 is right here applyMainWindowSettings(config); // Menubar, statusbar and toolbar settings. s.setNum(number); config->setGroup(s); readProperties(config); return true; } void TDEMainWindow::applyMainWindowSettings(TDEConfig *config, const TQString &configGroup) { return applyMainWindowSettings(config,configGroup,false); } void TDEMainWindow::applyMainWindowSettings(TDEConfig *config, const TQString &configGroup,bool force) { kdDebug(200) << "TDEMainWindow::applyMainWindowSettings" << endl; TDEConfigGroupSaver saver( config, configGroup.isEmpty() ? config->group() : configGroup ); restoreWindowSize(config); TQStatusBar* sb = internalStatusBar(); if (sb) { TQString entry = config->readEntry("StatusBar", "Enabled"); if ( entry == "Disabled" ) sb->hide(); else sb->show(); if(d->showStatusBarAction) d->showStatusBarAction->setChecked(!sb->isHidden()); } TQMenuBar* mb = internalMenuBar(); if (mb) { TQString entry = config->readEntry ("MenuBar", "Enabled"); if ( entry == "Disabled" ) mb->hide(); else mb->show(); } int n = 1; // Toolbar counter. toolbars are counted from 1, TDEToolBar *toolbar; TQPtrListIterator it( toolBarIterator() ); // must use own iterator for ( ; it.current(); ++it) { toolbar= it.current(); TQString group; if (!configGroup.isEmpty()) { // Give a number to the toolbar, but prefer a name if there is one, // because there's no real guarantee on the ordering of toolbars group = (!::qstrcmp(toolbar->name(), "unnamed") ? TQString::number(n) : TQString(" ")+toolbar->name()); group.prepend(" Toolbar"); group.prepend(configGroup); } toolbar->applySettings(config, group, force); n++; } finalizeGUI( true ); } void TDEMainWindow::finalizeGUI( bool force ) { //kdDebug(200) << "TDEMainWindow::finalizeGUI force=" << force << endl; // The whole reason for this is that moveToolBar relies on the indexes // of the other toolbars, so in theory it should be called only once per // toolbar, but in increasing order of indexes. // Since we can't do that immediately, we move them, and _then_ // we call positionYourself again for each of them, but this time // the toolbariterator should give them in the proper order. // Both the XMLGUI and applySettings call this, hence "force" for the latter. TQPtrListIterator it( toolBarIterator() ); for ( ; it.current() ; ++it ) { it.current()->positionYourself( force ); } d->settingsDirty = false; } void TDEMainWindow::saveWindowSize( TDEConfig * config ) const { int scnum = TQApplication::desktop()->screenNumber(parentWidget()); TQRect desk = TQApplication::desktop()->screenGeometry(scnum); int w, h; #if defined Q_WS_X11 // save maximalization as desktop size + 1 in that direction KWin::WindowInfo info = KWin::windowInfo( winId(), NET::WMState ); w = info.state() & NET::MaxHoriz ? desk.width() + 1 : width(); h = info.state() & NET::MaxVert ? desk.height() + 1 : height(); #else if (isMaximized()) { w = desk.width() + 1; h = desk.height() + 1; } //TODO: add "Maximized" property instead "+1" hack #endif TQRect size( desk.width(), w, desk.height(), h ); bool defaultSize = (size == d->defaultWindowSize); TQString widthString = TQString::fromLatin1("Width %1").arg(desk.width()); TQString heightString = TQString::fromLatin1("Height %1").arg(desk.height()); if (!config->hasDefault(widthString) && defaultSize) config->revertToDefault(widthString); else config->writeEntry(widthString, w ); if (!config->hasDefault(heightString) && defaultSize) config->revertToDefault(heightString); else config->writeEntry(heightString, h ); } void TDEMainWindow::restoreWindowSize( TDEConfig * config ) { if (d->care_about_geometry) { parseGeometry(true); } else { // restore the size int scnum = TQApplication::desktop()->screenNumber(parentWidget()); TQRect desk = TQApplication::desktop()->screenGeometry(scnum); if ( d->defaultWindowSize.isNull() ) // only once d->defaultWindowSize = TQRect(desk.width(), width(), desk.height(), height()); // store default values TQSize size( config->readNumEntry( TQString::fromLatin1("Width %1").arg(desk.width()), 0 ), config->readNumEntry( TQString::fromLatin1("Height %1").arg(desk.height()), 0 ) ); if (size.isEmpty()) { // try the KDE 2.0 way size = TQSize( config->readNumEntry( TQString::fromLatin1("Width"), 0 ), config->readNumEntry( TQString::fromLatin1("Height"), 0 ) ); if (!size.isEmpty()) { // make sure the other resolutions don't get old settings config->writeEntry( TQString::fromLatin1("Width"), 0 ); config->writeEntry( TQString::fromLatin1("Height"), 0 ); } } if ( !size.isEmpty() ) { #ifdef Q_WS_X11 int state = 0; if (size.width() > desk.width()) { state = state | NET::MaxHoriz; } if (size.height() > desk.height()) { state = state | NET::MaxVert; } if (( state & NET::Max ) == NET::Max ) { resize( desk.width(), desk.height()); } else if(( state & NET::MaxHoriz ) == NET::MaxHoriz ) { resize( width(), size.height()); } else if(( state & NET::MaxVert ) == NET::MaxVert ) { resize( size.width(), height()); } else { resize( size ); } // TQWidget::showMaximized() is both insufficient and broken KWin::setState( winId(), state ); #else if (size.width() > desk.width() || size.height() > desk.height()) setWindowState( WindowMaximized ); else resize( size ); #endif } } } bool TDEMainWindow::initialGeometrySet() const { return d->care_about_geometry; } void TDEMainWindow::ignoreInitialGeometry() { d->care_about_geometry = false; } void TDEMainWindow::setSettingsDirty() { //kdDebug(200) << "TDEMainWindow::setSettingsDirty" << endl; d->settingsDirty = true; if ( d->autoSaveSettings ) { // Use a timer to save "immediately" user-wise, but not too immediately // (to compress calls and save only once, in case of multiple changes) if ( !d->settingsTimer ) { d->settingsTimer = new TQTimer( this ); connect( d->settingsTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( saveAutoSaveSettings() ) ); } d->settingsTimer->start( 500, true ); } } bool TDEMainWindow::settingsDirty() const { return d->settingsDirty; } TQString TDEMainWindow::settingsGroup() const { return d->autoSaveGroup; } void TDEMainWindow::setAutoSaveSettings( const TQString & groupName, bool saveWindowSize ) { d->autoSaveSettings = true; d->autoSaveGroup = groupName; d->autoSaveWindowSize = saveWindowSize; // Get notified when the user moves a toolbar around disconnect( this, TQT_SIGNAL( dockWindowPositionChanged( TQDockWindow * ) ), this, TQT_SLOT( setSettingsDirty() ) ); connect( this, TQT_SIGNAL( dockWindowPositionChanged( TQDockWindow * ) ), this, TQT_SLOT( setSettingsDirty() ) ); // Now read the previously saved settings applyMainWindowSettings( TDEGlobal::config(), groupName ); } void TDEMainWindow::resetAutoSaveSettings() { d->autoSaveSettings = false; if ( d->settingsTimer ) d->settingsTimer->stop(); } bool TDEMainWindow::autoSaveSettings() const { return d->autoSaveSettings; } TQString TDEMainWindow::autoSaveGroup() const { return d->autoSaveGroup; } void TDEMainWindow::saveAutoSaveSettings() { Q_ASSERT( d->autoSaveSettings ); //kdDebug(200) << "TDEMainWindow::saveAutoSaveSettings -> saving settings" << endl; saveMainWindowSettings( TDEGlobal::config(), d->autoSaveGroup ); TDEGlobal::config()->sync(); d->settingsDirty = false; if ( d->settingsTimer ) d->settingsTimer->stop(); } void TDEMainWindow::resizeEvent( TQResizeEvent * ) { if ( d->autoSaveWindowSize ) setSettingsDirty(); } bool TDEMainWindow::hasMenuBar() { return (internalMenuBar()); } KMenuBar *TDEMainWindow::menuBar() { KMenuBar * mb = internalMenuBar(); if ( !mb ) { mb = new KMenuBar( this ); // trigger a re-layout and trigger a call to the private // setMenuBar method. TQMainWindow::menuBar(); } return mb; } KStatusBar *TDEMainWindow::statusBar() { KStatusBar * sb = internalStatusBar(); if ( !sb ) { sb = new KStatusBar( this ); // trigger a re-layout and trigger a call to the private // setStatusBar method. TQMainWindow::statusBar(); } return sb; } void TDEMainWindow::shuttingDown() { // Needed for Qt <= 3.0.3 at least to prevent reentrancy // when queryExit() shows a dialog. Check before removing! static bool reentrancy_protection = false; if (!reentrancy_protection) { reentrancy_protection = true; // call the virtual queryExit queryExit(); reentrancy_protection = false; } } KMenuBar *TDEMainWindow::internalMenuBar() { TQObjectList *l = queryList( "KMenuBar", 0, false, false ); if ( !l || !l->first() ) { delete l; return 0; } KMenuBar *m = (KMenuBar*)l->first(); delete l; return m; } KStatusBar *TDEMainWindow::internalStatusBar() { TQObjectList *l = queryList( "KStatusBar", 0, false, false ); if ( !l || !l->first() ) { delete l; return 0; } KStatusBar *s = (KStatusBar*)l->first(); delete l; return s; } void TDEMainWindow::childEvent( TQChildEvent* e) { TQMainWindow::childEvent( e ); } TDEToolBar *TDEMainWindow::toolBar( const char * name ) { if (!name) name = "mainToolBar"; TDEToolBar *tb = (TDEToolBar*)child( name, "TDEToolBar" ); if ( tb ) return tb; bool honor_mode = (!strcmp(name, "mainToolBar")); if ( builderClient() ) return new TDEToolBar(this, name, honor_mode); // XMLGUI constructor else return new TDEToolBar(this, DockTop, false, name, honor_mode ); // non-XMLGUI } TQPtrListIterator TDEMainWindow::toolBarIterator() { toolbarList.clear(); TQPtrList lst; for ( int i = (int)TQMainWindow::DockUnmanaged; i <= (int)DockMinimized; ++i ) { lst = toolBars( (ToolBarDock)i ); for ( TQToolBar *tb = lst.first(); tb; tb = lst.next() ) { if ( !tb->inherits( "TDEToolBar" ) ) continue; toolbarList.append( (TDEToolBar*)tb ); } } return TQPtrListIterator( toolbarList ); } TDEAccel * TDEMainWindow::accel() { if ( !d->tdeaccel ) d->tdeaccel = new TDEAccel( this, "kmw-tdeaccel" ); return d->tdeaccel; } void TDEMainWindow::paintEvent( TQPaintEvent * pe ) { TQMainWindow::paintEvent(pe); //Upcall to handle SH_MainWindow_SpaceBelowMenuBar rendering } TQSize TDEMainWindow::sizeForCentralWidgetSize(TQSize size) { TDEToolBar *tb = (TDEToolBar*)child( "mainToolBar", "TDEToolBar" ); if (tb && !tb->isHidden()) { switch( tb->barPos() ) { case TDEToolBar::Top: case TDEToolBar::Bottom: size += TQSize(0, tb->sizeHint().height()); break; case TDEToolBar::Left: case TDEToolBar::Right: size += TQSize(toolBar()->sizeHint().width(), 0); break; case TDEToolBar::Flat: size += TQSize(0, 3+kapp->style().pixelMetric( TQStyle::PM_DockWindowHandleExtent )); break; default: break; } } KMenuBar *mb = internalMenuBar(); if (mb && !mb->isHidden()) { size += TQSize(0,mb->heightForWidth(size.width())); if (style().styleHint(TQStyle::SH_MainWindow_SpaceBelowMenuBar, this)) size += TQSize( 0, dockWindowsMovable() ? 1 : 2); } TQStatusBar *sb = internalStatusBar(); if( sb && !sb->isHidden() ) size += TQSize(0, sb->sizeHint().height()); return size; } #if KDE_IS_VERSION( 3, 9, 0 ) #ifdef __GNUC__ #warning Remove, should be in Qt #endif #endif void TDEMainWindow::setIcon( const TQPixmap& p ) { TQMainWindow::setIcon( p ); #ifdef Q_WS_X11 // Qt3 doesn't support _NET_WM_ICON, but TDEApplication::setTopWidget(), which // is used by TDEMainWindow, sets it KWin::setIcons( winId(), p, TQPixmap()); #endif } TQPtrList* TDEMainWindow::getMemberList() { return memberList; } // why do we support old gcc versions? using KXMLGUIBuilder::finalizeGUI; // DF: because they compile KDE much faster :) void TDEMainWindow::finalizeGUI( KXMLGUIClient *client ) { KXMLGUIBuilder::finalizeGUI( client ); } void TDEMainWindow::virtual_hook( int id, void* data ) { KXMLGUIBuilder::virtual_hook( id, data ); KXMLGUIClient::virtual_hook( id, data ); } #include "tdemainwindow.moc"