KDEUI
kxmlguiwindow.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 (C) 2005-2006 Hamish Rodda (rodda@kde.org) 00010 00011 This library is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU Library General Public 00013 License version 2 as published by the Free Software Foundation. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Library General Public License for more details. 00019 00020 You should have received a copy of the GNU Library General Public License 00021 along with this library; see the file COPYING.LIB. If not, write to 00022 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00023 Boston, MA 02110-1301, USA. 00024 */ 00025 00026 #include "kxmlguiwindow.h" 00027 #include "kmainwindow_p.h" 00028 #include "kactioncollection.h" 00029 #include "kmainwindowiface_p.h" 00030 #include "ktoolbarhandler_p.h" 00031 #include "kxmlguifactory.h" 00032 #include "kcmdlineargs.h" 00033 #include "ktoggleaction.h" 00034 #include "ksessionmanager.h" 00035 #include "kstandardaction.h" 00036 00037 #include <config.h> 00038 00039 #include <QCloseEvent> 00040 #include <QDesktopWidget> 00041 #include <QDockWidget> 00042 #include <QtXml/QDomDocument> 00043 #include <QtGui/QLayout> 00044 #include <QtCore/QObject> 00045 #include <QtGui/QSessionManager> 00046 #include <QtGui/QStyle> 00047 #include <QtCore/QTimer> 00048 #include <QtGui/QWidget> 00049 #include <QtCore/QList> 00050 #include <kaction.h> 00051 #include <kapplication.h> 00052 #include <kauthorized.h> 00053 #include <kconfig.h> 00054 #include <kdebug.h> 00055 #include <kedittoolbar.h> 00056 #include <khelpmenu.h> 00057 #include <klocale.h> 00058 #include <kmenubar.h> 00059 #include <kstandarddirs.h> 00060 #include <kstatusbar.h> 00061 #include <ktoolbar.h> 00062 #include <kwindowsystem.h> 00063 #include <kconfiggroup.h> 00064 00065 #include <stdlib.h> 00066 #include <ctype.h> 00067 #include <assert.h> 00068 00069 class KXmlGuiWindowPrivate : public KMainWindowPrivate { 00070 public: 00071 void _k_slotFactoryMakingChanges(bool b) 00072 { 00073 // While the GUI factory is adding/removing clients, 00074 // don't let KMainWindow think those are changes made by the user 00075 // #105525 00076 letDirtySettings = !b; 00077 } 00078 00079 bool showHelpMenu:1; 00080 QSize defaultSize; 00081 00082 KDEPrivate::ToolBarHandler *toolBarHandler; 00083 KToggleAction *showStatusBarAction; 00084 QPointer<KEditToolBar> toolBarEditor; 00085 KXMLGUIFactory *factory; 00086 }; 00087 00088 KXmlGuiWindow::KXmlGuiWindow( QWidget* parent, Qt::WFlags f ) 00089 : KMainWindow(*new KXmlGuiWindowPrivate, parent, f), KXMLGUIBuilder( this ) 00090 { 00091 K_D(KXmlGuiWindow); 00092 d->showHelpMenu = true; 00093 d->toolBarHandler = 0; 00094 d->showStatusBarAction = 0; 00095 d->factory = 0; 00096 new KMainWindowInterface(this); 00097 } 00098 00099 00100 QAction *KXmlGuiWindow::toolBarMenuAction() 00101 { 00102 K_D(KXmlGuiWindow); 00103 if ( !d->toolBarHandler ) 00104 return 0; 00105 00106 return d->toolBarHandler->toolBarMenuAction(); 00107 } 00108 00109 00110 void KXmlGuiWindow::setupToolbarMenuActions() 00111 { 00112 K_D(KXmlGuiWindow); 00113 if ( d->toolBarHandler ) 00114 d->toolBarHandler->setupActions(); 00115 } 00116 00117 00118 KXmlGuiWindow::~KXmlGuiWindow() 00119 { 00120 K_D(KXmlGuiWindow); 00121 delete d->factory; 00122 } 00123 00124 bool KXmlGuiWindow::event( QEvent* ev ) 00125 { 00126 bool ret = KMainWindow::event(ev); 00127 if (ev->type()==QEvent::Polish) { 00128 QDBusConnection::sessionBus().registerObject(dbusName() + "/actions", actionCollection(), 00129 QDBusConnection::ExportScriptableSlots | 00130 QDBusConnection::ExportScriptableProperties | 00131 QDBusConnection::ExportNonScriptableSlots | 00132 QDBusConnection::ExportNonScriptableProperties | 00133 QDBusConnection::ExportChildObjects); 00134 } 00135 return ret; 00136 } 00137 00138 void KXmlGuiWindow::setHelpMenuEnabled(bool showHelpMenu) 00139 { 00140 K_D(KXmlGuiWindow); 00141 d->showHelpMenu = showHelpMenu; 00142 } 00143 00144 bool KXmlGuiWindow::isHelpMenuEnabled() const 00145 { 00146 K_D(const KXmlGuiWindow); 00147 return d->showHelpMenu; 00148 } 00149 00150 KXMLGUIFactory *KXmlGuiWindow::guiFactory() 00151 { 00152 K_D(KXmlGuiWindow); 00153 if (!d->factory) { 00154 d->factory = new KXMLGUIFactory( this, this ); 00155 connect(d->factory, SIGNAL(makingChanges(bool)), 00156 this, SLOT(_k_slotFactoryMakingChanges(bool))); 00157 } 00158 return d->factory; 00159 } 00160 00161 void KXmlGuiWindow::configureToolbars() 00162 { 00163 K_D(KXmlGuiWindow); 00164 KConfigGroup cg(KGlobal::config(), QString()); 00165 saveMainWindowSettings(cg); 00166 if (!d->toolBarEditor) { 00167 d->toolBarEditor = new KEditToolBar(guiFactory(), this); 00168 d->toolBarEditor->setAttribute(Qt::WA_DeleteOnClose); 00169 connect(d->toolBarEditor, SIGNAL(newToolBarConfig()), SLOT(saveNewToolbarConfig())); 00170 } 00171 d->toolBarEditor->show(); 00172 } 00173 00174 void KXmlGuiWindow::saveNewToolbarConfig() 00175 { 00176 // createGUI(xmlFile()); // this loses any plugged-in guiclients, so we use remove+add instead. 00177 00178 guiFactory()->removeClient(this); 00179 guiFactory()->addClient(this); 00180 00181 KConfigGroup cg(KGlobal::config(), QString()); 00182 applyMainWindowSettings(cg); 00183 } 00184 00185 void KXmlGuiWindow::setupGUI( StandardWindowOptions options, const QString & xmlfile ) { 00186 setupGUI(QSize(), options, xmlfile); 00187 } 00188 00189 void KXmlGuiWindow::setupGUI( const QSize & defaultSize, StandardWindowOptions options, const QString & xmlfile ) { 00190 K_D(KXmlGuiWindow); 00191 00192 if( options & Keys ){ 00193 KStandardAction::keyBindings(guiFactory(), 00194 SLOT(configureShortcuts()), actionCollection()); 00195 } 00196 00197 if( (options & StatusBar) && statusBar() ){ 00198 createStandardStatusBarAction(); 00199 } 00200 00201 if( options & ToolBar ){ 00202 setStandardToolBarMenuEnabled( true ); 00203 KStandardAction::configureToolbars(this, 00204 SLOT(configureToolbars() ), actionCollection()); 00205 } 00206 00207 d->defaultSize = defaultSize; 00208 00209 if( options & Create ){ 00210 createGUI(xmlfile); 00211 } 00212 00213 if (initialGeometrySet()) { 00214 // Do nothing... 00215 } 00216 else if (d->defaultSize.isValid()) { 00217 resize(d->defaultSize); 00218 } 00219 else if (isHidden()) { 00220 adjustSize(); 00221 } 00222 00223 if( options & Save ){ 00224 const KConfigGroup cg(autoSaveConfigGroup()); 00225 if (cg.isValid()) { 00226 setAutoSaveSettings(cg); 00227 } else { 00228 setAutoSaveSettings(); 00229 } 00230 } 00231 } 00232 void KXmlGuiWindow::createGUI( const QString &xmlfile ) 00233 { 00234 K_D(KXmlGuiWindow); 00235 // disabling the updates prevents unnecessary redraws 00236 //setUpdatesEnabled( false ); 00237 00238 // just in case we are rebuilding, let's remove our old client 00239 guiFactory()->removeClient( this ); 00240 00241 // make sure to have an empty GUI 00242 QMenuBar* mb = menuBar(); 00243 if ( mb ) 00244 mb->clear(); 00245 00246 qDeleteAll( toolBars() ); // delete all toolbars 00247 00248 // don't build a help menu unless the user ask for it 00249 if (d->showHelpMenu) { 00250 delete d->helpMenu; 00251 // we always want a help menu 00252 d->helpMenu = new KHelpMenu(this, componentData().aboutData(), true, actionCollection()); 00253 } 00254 00255 const QString windowXmlFile = xmlfile.isNull() ? componentData().componentName() + "ui.rc" : xmlfile; 00256 00257 // Help beginners who call setXMLFile and then setupGUI... 00258 if (!xmlFile().isEmpty() && xmlFile() != windowXmlFile) { 00259 kWarning() << "You called setXMLFile(" << xmlFile() << ") and then createGUI or setupGUI," 00260 << "which also calls setXMLFile and will overwrite the file you have previously set.\n" 00261 << "You should call createGUI("<<xmlFile()<<") or setupGUI(<options>,"<<xmlFile()<<") instead."; 00262 } 00263 00264 // we always want to load in our global standards file 00265 loadStandardsXmlFile(); 00266 00267 // now, merge in our local xml file. 00268 setXMLFile(windowXmlFile, true); 00269 00270 // make sure we don't have any state saved already 00271 setXMLGUIBuildDocument( QDomDocument() ); 00272 00273 // do the actual GUI building 00274 guiFactory()->addClient( this ); 00275 00276 // setUpdatesEnabled( true ); 00277 } 00278 00279 void KXmlGuiWindow::slotStateChanged(const QString &newstate) 00280 { 00281 stateChanged(newstate, KXMLGUIClient::StateNoReverse); 00282 } 00283 00284 void KXmlGuiWindow::slotStateChanged(const QString &newstate, 00285 bool reverse) 00286 { 00287 stateChanged(newstate, 00288 reverse ? KXMLGUIClient::StateReverse : KXMLGUIClient::StateNoReverse); 00289 } 00290 00291 void KXmlGuiWindow::setStandardToolBarMenuEnabled( bool enable ) 00292 { 00293 K_D(KXmlGuiWindow); 00294 if ( enable ) { 00295 if ( d->toolBarHandler ) 00296 return; 00297 00298 d->toolBarHandler = new KDEPrivate::ToolBarHandler( this ); 00299 00300 if ( factory() ) 00301 factory()->addClient( d->toolBarHandler ); 00302 } else { 00303 if ( !d->toolBarHandler ) 00304 return; 00305 00306 if ( factory() ) 00307 factory()->removeClient( d->toolBarHandler ); 00308 00309 delete d->toolBarHandler; 00310 d->toolBarHandler = 0; 00311 } 00312 } 00313 00314 bool KXmlGuiWindow::isStandardToolBarMenuEnabled() const 00315 { 00316 K_D(const KXmlGuiWindow); 00317 return ( d->toolBarHandler ); 00318 } 00319 00320 void KXmlGuiWindow::createStandardStatusBarAction(){ 00321 K_D(KXmlGuiWindow); 00322 if(!d->showStatusBarAction){ 00323 d->showStatusBarAction = KStandardAction::showStatusbar(this, SLOT(setSettingsDirty()), actionCollection()); 00324 KStatusBar *sb = statusBar(); // Creates statusbar if it doesn't exist already. 00325 connect(d->showStatusBarAction, SIGNAL(toggled(bool)), sb, SLOT(setVisible(bool))); 00326 d->showStatusBarAction->setChecked(sb->isHidden()); 00327 } else { 00328 // If the language has changed, we'll need to grab the new text and whatsThis 00329 KAction *tmpStatusBar = KStandardAction::showStatusbar(NULL, NULL, NULL); 00330 d->showStatusBarAction->setText(tmpStatusBar->text()); 00331 d->showStatusBarAction->setWhatsThis(tmpStatusBar->whatsThis()); 00332 delete tmpStatusBar; 00333 } 00334 } 00335 00336 void KXmlGuiWindow::finalizeGUI( bool /*force*/ ) 00337 { 00338 // FIXME: this really needs to be removed with a code more like the one we had on KDE3. 00339 // what we need to do here is to position correctly toolbars so they don't overlap. 00340 // Also, take in count plugins could provide their own toolbars and those also need to 00341 // be restored. 00342 if (autoSaveSettings() && autoSaveConfigGroup().isValid()) { 00343 applyMainWindowSettings(autoSaveConfigGroup()); 00344 } 00345 } 00346 00347 void KXmlGuiWindow::applyMainWindowSettings(const KConfigGroup &config, bool force) 00348 { 00349 K_D(KXmlGuiWindow); 00350 KMainWindow::applyMainWindowSettings(config, force); 00351 KStatusBar *sb = qFindChild<KStatusBar *>(this); 00352 if (sb && d->showStatusBarAction) 00353 d->showStatusBarAction->setChecked(!sb->isHidden()); 00354 } 00355 00356 // KDE5 TODO: change it to "using KXMLGUIBuilder::finalizeGUI;" in the header 00357 // and remove the reimplementation 00358 void KXmlGuiWindow::finalizeGUI( KXMLGUIClient *client ) 00359 { KXMLGUIBuilder::finalizeGUI( client ); } 00360 00361 #include "kxmlguiwindow.moc" 00362
KDE 4.6 API Reference