diff --git a/src/kxmlguiwindow.cpp b/src/kxmlguiwindow.cpp index 519fb26..9e0d64d 100644 --- a/src/kxmlguiwindow.cpp +++ b/src/kxmlguiwindow.cpp @@ -1,393 +1,437 @@ /* 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) (C) 2005-2006 Hamish Rodda (rodda@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 "kxmlguiwindow.h" #include "kmainwindow_p.h" +#include "kmessagebox.h" #include "kactioncollection.h" #include "kmainwindowiface_p.h" #include "ktoolbarhandler_p.h" #include "kxmlguifactory.h" #include "kedittoolbar.h" #include "khelpmenu.h" #include "ktoolbar.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KXmlGuiWindowPrivate : public KMainWindowPrivate { public: void _k_slotFactoryMakingChanges(bool b) { // While the GUI factory is adding/removing clients, // don't let KMainWindow think those are changes made by the user // #105525 letDirtySettings = !b; } bool showHelpMenu: 1; QSize defaultSize; KDEPrivate::ToolBarHandler *toolBarHandler; KToggleAction *showStatusBarAction; QPointer toolBarEditor; KXMLGUIFactory *factory; }; KXmlGuiWindow::KXmlGuiWindow(QWidget *parent, Qt::WindowFlags f) : KMainWindow(*new KXmlGuiWindowPrivate, parent, f), KXMLGUIBuilder(this) { K_D(KXmlGuiWindow); d->showHelpMenu = true; d->toolBarHandler = 0; d->showStatusBarAction = 0; d->factory = 0; new KMainWindowInterface(this); } QAction *KXmlGuiWindow::toolBarMenuAction() { K_D(KXmlGuiWindow); if (!d->toolBarHandler) { return 0; } return d->toolBarHandler->toolBarMenuAction(); } void KXmlGuiWindow::setupToolbarMenuActions() { K_D(KXmlGuiWindow); if (d->toolBarHandler) { d->toolBarHandler->setupActions(); } } KXmlGuiWindow::~KXmlGuiWindow() { K_D(KXmlGuiWindow); delete d->factory; } bool KXmlGuiWindow::event(QEvent *ev) { bool ret = KMainWindow::event(ev); if (ev->type() == QEvent::Polish) { QDBusConnection::sessionBus().registerObject(dbusName() + QStringLiteral("/actions"), actionCollection(), QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportScriptableProperties | QDBusConnection::ExportNonScriptableSlots | QDBusConnection::ExportNonScriptableProperties | QDBusConnection::ExportChildObjects); } return ret; } void KXmlGuiWindow::setHelpMenuEnabled(bool showHelpMenu) { K_D(KXmlGuiWindow); d->showHelpMenu = showHelpMenu; } bool KXmlGuiWindow::isHelpMenuEnabled() const { K_D(const KXmlGuiWindow); return d->showHelpMenu; } KXMLGUIFactory *KXmlGuiWindow::guiFactory() { K_D(KXmlGuiWindow); if (!d->factory) { d->factory = new KXMLGUIFactory(this, this); connect(d->factory, SIGNAL(makingChanges(bool)), this, SLOT(_k_slotFactoryMakingChanges(bool))); } return d->factory; } void KXmlGuiWindow::configureToolbars() { K_D(KXmlGuiWindow); KConfigGroup cg(KSharedConfig::openConfig(), ""); saveMainWindowSettings(cg); if (!d->toolBarEditor) { d->toolBarEditor = new KEditToolBar(guiFactory(), this); d->toolBarEditor->setAttribute(Qt::WA_DeleteOnClose); connect(d->toolBarEditor, SIGNAL(newToolBarConfig()), SLOT(saveNewToolbarConfig())); } d->toolBarEditor->show(); } void KXmlGuiWindow::saveNewToolbarConfig() { // createGUI(xmlFile()); // this loses any plugged-in guiclients, so we use remove+add instead. guiFactory()->removeClient(this); guiFactory()->addClient(this); KConfigGroup cg(KSharedConfig::openConfig(), ""); applyMainWindowSettings(cg); } void KXmlGuiWindow::setupGUI(StandardWindowOptions options, const QString &xmlfile) { setupGUI(QSize(), options, xmlfile); } void KXmlGuiWindow::setupGUI(const QSize &defaultSize, StandardWindowOptions options, const QString &xmlfile) { K_D(KXmlGuiWindow); if (options & Keys) { KStandardAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), actionCollection()); } if ((options & StatusBar) && statusBar()) { createStandardStatusBarAction(); } if (options & ToolBar) { setStandardToolBarMenuEnabled(true); KStandardAction::configureToolbars(this, SLOT(configureToolbars()), actionCollection()); } d->defaultSize = defaultSize; if (options & Create) { createGUI(xmlfile); } if (d->defaultSize.isValid()) { resize(d->defaultSize); } else if (isHidden()) { adjustSize(); } if (options & Save) { const KConfigGroup cg(autoSaveConfigGroup()); if (cg.isValid()) { setAutoSaveSettings(cg); } else { setAutoSaveSettings(); } } } void KXmlGuiWindow::createGUI(const QString &xmlfile) { K_D(KXmlGuiWindow); // 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 QMenuBar *mb = menuBar(); if (mb) { mb->clear(); } qDeleteAll(toolBars()); // delete all toolbars // don't build a help menu unless the user ask for it if (d->showHelpMenu) { delete d->helpMenu; // we always want a help menu d->helpMenu = new KHelpMenu(this, KAboutData::applicationData(), true); KActionCollection *actions = actionCollection(); QAction *helpContentsAction = d->helpMenu->action(KHelpMenu::menuHelpContents); QAction *whatsThisAction = d->helpMenu->action(KHelpMenu::menuWhatsThis); QAction *reportBugAction = d->helpMenu->action(KHelpMenu::menuReportBug); QAction *switchLanguageAction = d->helpMenu->action(KHelpMenu::menuSwitchLanguage); QAction *aboutAppAction = d->helpMenu->action(KHelpMenu::menuAboutApp); QAction *aboutKdeAction = d->helpMenu->action(KHelpMenu::menuAboutKDE); QAction *donateAction = d->helpMenu->action(KHelpMenu::menuDonate); if (helpContentsAction) { actions->addAction(helpContentsAction->objectName(), helpContentsAction); } if (whatsThisAction) { actions->addAction(whatsThisAction->objectName(), whatsThisAction); } if (reportBugAction) { actions->addAction(reportBugAction->objectName(), reportBugAction); } if (switchLanguageAction) { actions->addAction(switchLanguageAction->objectName(), switchLanguageAction); } if (aboutAppAction) { actions->addAction(aboutAppAction->objectName(), aboutAppAction); } if (aboutKdeAction) { actions->addAction(aboutKdeAction->objectName(), aboutKdeAction); } if (donateAction) { actions->addAction(donateAction->objectName(), donateAction); } } const QString windowXmlFile = xmlfile.isNull() ? componentName() + QStringLiteral("ui.rc") : xmlfile; // Help beginners who call setXMLFile and then setupGUI... if (!xmlFile().isEmpty() && xmlFile() != windowXmlFile) { qWarning() << "You called setXMLFile(" << xmlFile() << ") and then createGUI or setupGUI," << "which also calls setXMLFile and will overwrite the file you have previously set.\n" << "You should call createGUI(" << xmlFile() << ") or setupGUI(," << xmlFile() << ") instead."; } // we always want to load in our global standards file loadStandardsXmlFile(); // now, merge in our local xml file. setXMLFile(windowXmlFile, true); // make sure we don't have any state saved already setXMLGUIBuildDocument(QDomDocument()); // do the actual GUI building guiFactory()->reset(); guiFactory()->addClient(this); + checkAmbiguousShortcuts(); + // setUpdatesEnabled( true ); } void KXmlGuiWindow::slotStateChanged(const QString &newstate) { stateChanged(newstate, KXMLGUIClient::StateNoReverse); } void KXmlGuiWindow::slotStateChanged(const QString &newstate, bool reverse) { stateChanged(newstate, reverse ? KXMLGUIClient::StateReverse : KXMLGUIClient::StateNoReverse); } void KXmlGuiWindow::setStandardToolBarMenuEnabled(bool enable) { K_D(KXmlGuiWindow); 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 KXmlGuiWindow::isStandardToolBarMenuEnabled() const { K_D(const KXmlGuiWindow); return (d->toolBarHandler); } void KXmlGuiWindow::createStandardStatusBarAction() { K_D(KXmlGuiWindow); if (!d->showStatusBarAction) { d->showStatusBarAction = KStandardAction::showStatusbar(this, SLOT(setSettingsDirty()), actionCollection()); QStatusBar *sb = statusBar(); // Creates statusbar if it doesn't exist already. connect(d->showStatusBarAction, SIGNAL(toggled(bool)), sb, SLOT(setVisible(bool))); d->showStatusBarAction->setChecked(sb->isHidden()); } else { // If the language has changed, we'll need to grab the new text and whatsThis QAction *tmpStatusBar = KStandardAction::showStatusbar(NULL, NULL, NULL); d->showStatusBarAction->setText(tmpStatusBar->text()); d->showStatusBarAction->setWhatsThis(tmpStatusBar->whatsThis()); delete tmpStatusBar; } } void KXmlGuiWindow::finalizeGUI(bool /*force*/) { // FIXME: this really needs to be removed with a code more like the one we had on KDE3. // what we need to do here is to position correctly toolbars so they don't overlap. // Also, take in count plugins could provide their own toolbars and those also need to // be restored. if (autoSaveSettings() && autoSaveConfigGroup().isValid()) { applyMainWindowSettings(autoSaveConfigGroup()); } } void KXmlGuiWindow::applyMainWindowSettings(const KConfigGroup &config) { K_D(KXmlGuiWindow); KMainWindow::applyMainWindowSettings(config); QStatusBar *sb = findChild(); if (sb && d->showStatusBarAction) { d->showStatusBarAction->setChecked(!sb->isHidden()); } } // KDE5 TODO: change it to "using KXMLGUIBuilder::finalizeGUI;" in the header // and remove the reimplementation void KXmlGuiWindow::finalizeGUI(KXMLGUIClient *client) { KXMLGUIBuilder::finalizeGUI(client); } +void KXmlGuiWindow::checkAmbiguousShortcuts() +{ + QMap shortcuts; + QAction *editCutAction = actionCollection()->action(QStringLiteral("edit_cut")); + QAction *deleteFileAction = actionCollection()->action(QStringLiteral("deletefile")); + foreach (QAction *action, actionCollection()->actions()) { + if (action->isEnabled()) { + foreach (const QKeySequence &shortcut, action->shortcuts()) { + const QString portableShortcutText = shortcut.toString(); + const QAction *existingShortcutAction = shortcuts.value(portableShortcutText); + if (existingShortcutAction) { + // If the shortcut is already in use we give a warning, so that hopefully the developer will find it + // There is one exception, if the conflicting shortcut is a non primary shortcut of "edit_cut" + // and "deleteFileAction" is the other action since Shift+Delete is used for both in our default code + bool showWarning = true; + if ((action == editCutAction && existingShortcutAction == deleteFileAction) || + (action == deleteFileAction && existingShortcutAction == editCutAction)) { + QList editCutActionShortcuts = editCutAction->shortcuts(); + if (editCutActionShortcuts.indexOf(shortcut) > 0) // alternate shortcut + { + editCutActionShortcuts.removeAll(shortcut); + editCutAction->setShortcuts(editCutActionShortcuts); + + showWarning = false; + } + } + + if (showWarning) { + const QString actionName = KLocalizedString::removeAcceleratorMarker(action->text()); + const QString existingShortcutActionName = KLocalizedString::removeAcceleratorMarker(existingShortcutAction->text()); + const QString dontShowAgainString = existingShortcutActionName + actionName + shortcut.toString(); + KMessageBox::information(this, i18n("There are two actions (%1, %2) that want to use the same shortcut (%3). This is most probably a bug. Please report it in bugs.kde.org", existingShortcutActionName, actionName, shortcut.toString(QKeySequence::NativeText)), i18n("Ambiguous Shortcuts"), dontShowAgainString, KMessageBox::Notify | KMessageBox::AllowLink); + } + } else { + shortcuts.insert(portableShortcutText, action); + } + } + } + } +} + #include "moc_kxmlguiwindow.cpp" diff --git a/src/kxmlguiwindow.h b/src/kxmlguiwindow.h index 3c61939..11e8418 100644 --- a/src/kxmlguiwindow.h +++ b/src/kxmlguiwindow.h @@ -1,348 +1,355 @@ /* 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) (C) 2005-2006 Hamish Rodda (rodda@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. */ #ifndef KXMLGUIWINDOW_H #define KXMLGUIWINDOW_H #include "kxmlguiclient.h" #include "kxmlguibuilder.h" #include "kmainwindow.h" #include class KMenu; class KXMLGUIFactory; class KConfig; class KConfigGroup; class KToolBar; class KXmlGuiWindowPrivate; #define KDE_DEFAULT_WINDOWFLAGS 0 /** * @short %KDE top level main window with predefined action layout * * Instead of creating a KMainWindow manually and assigning menus, menu entries, * toolbar buttons and actions to it by hand, this class can be used to load an * rc file to manage the main window's actions. * * See http://techbase.kde.org/Development/Tutorials/Using_KActions#XMLGUI * for essential information on the XML file format and usage of this class. * * @see KMainWindow * @author Reginald Stadlbauer (reggie@kde.org) Stephan Kulow (coolo@kde.org), Matthias Ettrich (ettrich@kde.org), Chris Schlaeger (cs@kde.org), Sven Radej (radej@kde.org). Maintained by Sven Radej (radej@kde.org) */ class KXMLGUI_EXPORT KXmlGuiWindow : public KMainWindow, public KXMLGUIBuilder, virtual public KXMLGUIClient { XMLGUI_DECLARE_PRIVATE(KXmlGuiWindow) Q_OBJECT Q_PROPERTY(bool hasMenuBar READ hasMenuBar) Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings) Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup) Q_PROPERTY(bool standardToolBarMenuEnabled READ isStandardToolBarMenuEnabled WRITE setStandardToolBarMenuEnabled) Q_FLAGS(StandardWindowOption) public: /** * Construct a main window. * * @param parent The widget parent. This is usually 0 but it may also be the window * group leader. In that case, the KMainWindow becomes sort of a * secondary window. * * @param f Specify the widget flags. The default is * Qt::Window and Qt::WA_DeleteOnClose. Qt::Window indicates that a * main window is a toplevel window, regardless of whether it has a * parent or not. Qt::WA_DeleteOnClose indicates that a main window is * automatically destroyed when its window is closed. Pass 0 if * you do not want this behavior. * * @see http://doc.trolltech.com/qt.html#WindowType-enum * * KMainWindows must be created on the heap with 'new', like: * \code * KMainWindow *kmw = new KMainWindow(...); * kmw->setObjectName(...); * \endcode * * IMPORTANT: For session management and window management to work * properly, all main windows in the application should have a * different name. If you don't do it, KMainWindow will create * a unique name, but it's recommended to explicitly pass a window name that will * also describe the type of the window. If there can be several windows of the same * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make * the names unique. For example, for a mail client which has one main window showing * the mails and folders, and which can also have one or more windows for composing * mails, the name for the folders window should be e.g. "mainwindow" and * for the composer windows "composer#". * */ explicit KXmlGuiWindow(QWidget *parent = 0, Qt::WindowFlags f = KDE_DEFAULT_WINDOWFLAGS); /** * \brief Destructor. * * Will also destroy the toolbars, and menubar if * needed. */ virtual ~KXmlGuiWindow(); /** * Enables the build of a standard help menu when calling createGUI/setupGUI(). * * The default behavior is to build one, you must call this function * to disable it */ void setHelpMenuEnabled(bool showHelpMenu = true); /** * Return @p true when the help menu is enabled */ bool isHelpMenuEnabled() const; virtual KXMLGUIFactory *guiFactory(); /** * Create a GUI given a local XML file. In a regular app you usually want to use * setupGUI() instead of this one since it does more things for free * like setting up the toolbar/shortcut edit actions, etc. * * If @p xmlfile is NULL, * then it will try to construct a local XML filename like * appnameui.rc where 'appname' is your app's name. If that file * does not exist, then the XML UI code will only use the global * (standard) XML file for the layout purposes. * * @param xmlfile The local xmlfile (relative or absolute) */ void createGUI(const QString &xmlfile = QString()); /** * Sets whether KMainWindow should provide a menu that allows showing/hiding * the available toolbars ( using KToggleToolBarAction ) . In case there * is only one toolbar configured a simple 'Show \' menu item * is shown. * * The menu / menu item is implemented using xmlgui. It will be inserted in your * menu structure in the 'Settings' menu. * * If your application uses a non-standard xmlgui resource file then you can * specify the exact position of the menu / menu item by adding a * <Merge name="StandardToolBarMenuHandler" /> * line to the settings menu section of your resource file ( usually appname.rc ). * * Note that you should enable this feature before calling createGUI() ( or similar ) . */ void setStandardToolBarMenuEnabled(bool enable); bool isStandardToolBarMenuEnabled() const; /** * Sets whether KMainWindow should provide a menu that allows showing/hiding * of the statusbar ( using KToggleStatusBarAction ). * * The menu / menu item is implemented using xmlgui. It will be inserted * in your menu structure in the 'Settings' menu. * * Note that you should enable this feature before calling createGUI() * ( or similar ). * * If an application maintains the action on its own (i.e. never calls * this function) a connection needs to be made to let KMainWindow * know when that status (hidden/shown) of the statusbar has changed. * For example: * connect(action, SIGNAL(activated()), * kmainwindow, SLOT(setSettingsDirty())); * Otherwise the status (hidden/show) of the statusbar might not be saved * by KMainWindow. */ void createStandardStatusBarAction(); /** * @see setupGUI() */ enum StandardWindowOption { /** * adds action to show/hide the toolbar(s) and adds * action to configure the toolbar(s). * @see setStandardToolBarMenuEnabled */ ToolBar = 1, /** * adds action to show the key configure action. */ Keys = 2, /** * adds action to show/hide the statusbar if the * statusbar exists. @see createStandardStatusBarAction */ StatusBar = 4, /** * auto-saves (and loads) the toolbar/menubar/statusbar settings and * window size using the default name. @see setAutoSaveSettings * * Typically you want to let the default window size be determined by * the widgets size hints. Make sure that setupGUI() is called after * all the widgets are created ( including setCentralWidget ) so the * default size's will be correct. @see setAutoSaveSettings for * more information on this topic. */ Save = 8, /** * calls createGUI() once ToolBar, Keys and Statusbar have been * taken care of. @see createGUI * * NOTE: when using KParts::MainWindow, remove this flag from the * setupGUI call, since you'll be using createGUI(part) instead. * @code * setupGUI(ToolBar | Keys | StatusBar | Save); * @endcode */ Create = 16, /** * All the above option * (this is the default) */ Default = ToolBar | Keys | StatusBar | Save | Create }; Q_DECLARE_FLAGS(StandardWindowOptions, StandardWindowOption) /** * Configures the current windows and its actions in the typical KDE * fashion. The options are all enabled by default but can be turned * off if desired through the params or if the prereqs don't exists. * * Typically this function replaces createGUI(). * * @see StandardWindowOptions * @note Since this method will restore the state of the application (toolbar, dockwindows * positions...), you need to have added all your actions to your toolbars etc before * calling to this method. (This note is only applicable if you are using the Default or * Save flag). * @warning If you are calling createGUI yourself, remember to remove the Create flag from * the @p options parameter. * */ void setupGUI(StandardWindowOptions options = Default, const QString &xmlfile = QString()); /** * Configures the current windows and its actions in the typical KDE * fashion. The options are all enabled by default but can be turned * off if desired through the params or if the prereqs don't exists. * * @p defaultSize The default size of the window * * Typically this function replaces createGUI(). * * @see StandardWindowOptions * @note Since this method will restore the state of the application (toolbar, dockwindows * positions...), you need to have added all your actions to your toolbars etc before * calling to this method. (This note is only applicable if you are using the Default or * Save flag). * @warning If you are calling createGUI yourself, remember to remove the Create flag from * the @p options parameter. Also, call setupGUI always after you call createGUI. */ void setupGUI(const QSize &defaultSize, StandardWindowOptions options = Default, const QString &xmlfile = QString()); /** * Returns a pointer to the mainwindows action responsible for the toolbars menu */ QAction *toolBarMenuAction(); /** * @internal for KToolBar */ void setupToolbarMenuActions(); // KDE5 TODO: change it to "using KXMLGUIBuilder::finalizeGUI;" void finalizeGUI(KXMLGUIClient *client) Q_DECL_OVERRIDE; /** * @internal */ void finalizeGUI(bool force); // reimplemented for internal reasons void applyMainWindowSettings(const KConfigGroup &config) Q_DECL_OVERRIDE; public Q_SLOTS: /** * Show a standard configure toolbar dialog. * * This slot can be connected directly to the action to configure toolbar. * This is very simple to do that by adding a single line * \code * KStandardAction::configureToolbars( this, SLOT( configureToolbars() ), * actionCollection() ); * \endcode */ virtual void configureToolbars(); /** * Apply a state change * * Enable and disable actions as defined in the XML rc file */ virtual void slotStateChanged(const QString &newstate); /** * Apply a state change * * Enable and disable actions as defined in the XML rc file, * can "reverse" the state (disable the actions which should be * enabled, and vice-versa) if specified. */ void slotStateChanged(const QString &newstate, bool reverse); protected: /** * Reimplemented to catch QEvent::Polish in order to adjust the object name * if needed, once all constructor code for the main window has run. * Also reimplemented to catch when a QDockWidget is added or removed. */ bool event(QEvent *event) Q_DECL_OVERRIDE; + /** + * Checks if there are actions using the same shortcut. This is called + * automatically from createGUI. + * @since 5.30 + */ + void checkAmbiguousShortcuts(); + protected Q_SLOTS: /** * Rebuilds the GUI after KEditToolbar changed the toolbar layout. * @see configureToolbars() */ virtual void saveNewToolbarConfig(); private: Q_PRIVATE_SLOT(k_func(), void _k_slotFactoryMakingChanges(bool)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KXmlGuiWindow::StandardWindowOptions) #endif