File indexing completed on 2024-12-22 04:14:09
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2002 Simon Hausmann <hausmann@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #include "ktoolbarhandler_p.h" 0008 #include "config-xmlgui.h" 0009 #include <QDomDocument> 0010 #include <QAction> 0011 #include <QMenu> 0012 0013 #include <kactionmenu.h> 0014 #include <klocalizedstring.h> 0015 0016 #include "kxmlguiwindow.h" 0017 #include "ktoggletoolbaraction.h" 0018 #include "ktoolbar.h" 0019 #include "kxmlguifactory.h" 0020 #include "kactioncollection.h" 0021 0022 #if defined(KCONFIG_BEFORE_5_24) 0023 # define authorizeAction authorizeKAction 0024 #endif 0025 0026 namespace 0027 { 0028 const char actionListName[] = "show_menu_and_toolbar_actionlist"; 0029 0030 const char guiDescription[] = "" 0031 "<!DOCTYPE kpartgui><kpartgui name=\"StandardToolBarMenuHandler\">" 0032 "<MenuBar>" 0033 " <Menu name=\"settings\">" 0034 " <ActionList name=\"%1\" />" 0035 " </Menu>" 0036 "</MenuBar>" 0037 "</kpartgui>"; 0038 0039 class BarActionBuilder 0040 { 0041 public: 0042 BarActionBuilder(KisKActionCollection *actionCollection, KXmlGuiWindow *mainWindow, 0043 QLinkedList<KisToolBar *> &oldToolBarList) 0044 : m_actionCollection(actionCollection), m_mainWindow(mainWindow), m_needsRebuild(false) 0045 { 0046 QList<KisToolBar *> toolBars = m_mainWindow->findChildren<KisToolBar *>(); 0047 0048 Q_FOREACH (KisToolBar *toolBar, toolBars) { 0049 if (toolBar->mainWindow() != m_mainWindow) { 0050 continue; 0051 } 0052 0053 if (!oldToolBarList.contains(toolBar)) { 0054 m_needsRebuild = true; 0055 } 0056 0057 m_toolBars.append(toolBar); 0058 } 0059 0060 if (!m_needsRebuild) { 0061 m_needsRebuild = (oldToolBarList.count() != m_toolBars.count()); 0062 } 0063 } 0064 0065 bool needsRebuild() const 0066 { 0067 return m_needsRebuild; 0068 } 0069 0070 QList<QAction *> create() 0071 { 0072 QList<QAction *> actions; 0073 0074 if (!m_needsRebuild) { 0075 return actions; 0076 } 0077 0078 Q_FOREACH (KisToolBar *bar, m_toolBars) { 0079 handleToolBar(bar); 0080 } 0081 0082 if (m_toolBarActions.count() == 0) { 0083 return actions; 0084 } 0085 0086 if (m_toolBarActions.count() == 1) { 0087 KToggleToolBarAction *action = static_cast<KToggleToolBarAction *>(m_toolBarActions.first()); 0088 action->setText(KStandardShortcut::label(KStandardShortcut::ShowToolbar)); 0089 return m_toolBarActions; 0090 } 0091 0092 KActionMenu *menuAction = new KActionMenu(i18n("Toolbars Shown"), m_actionCollection); 0093 m_actionCollection->addAction(QStringLiteral("toolbars_submenu_action"), menuAction); 0094 0095 Q_FOREACH (QAction *action, m_toolBarActions) { 0096 menuAction->menu()->addAction(action); 0097 } 0098 0099 actions.append(menuAction); 0100 0101 return actions; 0102 } 0103 0104 const QLinkedList<KisToolBar *> &toolBars() const 0105 { 0106 return m_toolBars; 0107 } 0108 0109 private: 0110 void handleToolBar(KisToolBar *toolBar) 0111 { 0112 KToggleToolBarAction *action = new KToggleToolBarAction( 0113 toolBar, 0114 toolBar->windowTitle(), 0115 m_actionCollection); 0116 m_actionCollection->addAction(toolBar->objectName(), action); 0117 0118 // ## tooltips, whatsthis? 0119 m_toolBarActions.append(action); 0120 } 0121 0122 KisKActionCollection *m_actionCollection; 0123 KXmlGuiWindow *m_mainWindow; 0124 0125 QLinkedList<KisToolBar *> m_toolBars; 0126 QList<QAction *> m_toolBarActions; 0127 0128 bool m_needsRebuild : 1; 0129 }; 0130 } 0131 0132 using namespace KDEPrivate; 0133 0134 class ToolBarHandler::Private 0135 { 0136 public: 0137 Private(ToolBarHandler *_parent) 0138 : parent(_parent) 0139 { 0140 } 0141 0142 void clientAdded(KisKXMLGUIClient *client) 0143 { 0144 Q_UNUSED(client); 0145 parent->setupActions(); 0146 } 0147 0148 void init(KXmlGuiWindow *mainWindow); 0149 void connectToActionContainers(); 0150 void connectToActionContainer(QAction *action); 0151 void connectToActionContainer(QWidget *container); 0152 0153 ToolBarHandler *parent; 0154 QPointer<KXmlGuiWindow> mainWindow; 0155 QList<QAction *> actions; 0156 QLinkedList<KisToolBar *> toolBars; 0157 }; 0158 0159 void ToolBarHandler::Private::init(KXmlGuiWindow *mw) 0160 { 0161 mainWindow = mw; 0162 0163 QObject::connect(mainWindow->guiFactory(), SIGNAL(clientAdded(KisKXMLGUIClient*)), 0164 parent, SLOT(clientAdded(KisKXMLGUIClient*))); 0165 0166 if (parent->domDocument().documentElement().isNull()) { 0167 0168 QString completeDescription = QString::fromLatin1(guiDescription) 0169 .arg(QLatin1String(actionListName)); 0170 0171 parent->setXML(completeDescription, false /*merge*/); 0172 } 0173 } 0174 0175 void ToolBarHandler::Private::connectToActionContainers() 0176 { 0177 Q_FOREACH (QAction *action, actions) { 0178 connectToActionContainer(action); 0179 } 0180 } 0181 0182 void ToolBarHandler::Private::connectToActionContainer(QAction *action) 0183 { 0184 uint containerCount = action->associatedWidgets().count(); 0185 0186 for (uint i = 0; i < containerCount; ++i) { 0187 connectToActionContainer(action->associatedWidgets().value(i)); 0188 } 0189 } 0190 0191 void ToolBarHandler::Private::connectToActionContainer(QWidget *container) 0192 { 0193 QMenu *popupMenu = qobject_cast<QMenu *>(container); 0194 if (!popupMenu) { 0195 return; 0196 } 0197 0198 connect(popupMenu, SIGNAL(aboutToShow()), 0199 parent, SLOT(setupActions())); 0200 } 0201 0202 ToolBarHandler::ToolBarHandler(KXmlGuiWindow *mainWindow) 0203 : QObject(mainWindow), KisKXMLGUIClient(mainWindow), 0204 d(new Private(this)) 0205 { 0206 d->init(mainWindow); 0207 } 0208 0209 ToolBarHandler::ToolBarHandler(KXmlGuiWindow *mainWindow, QObject *parent) 0210 : QObject(parent), KisKXMLGUIClient(mainWindow), 0211 d(new Private(this)) 0212 { 0213 d->init(mainWindow); 0214 } 0215 0216 ToolBarHandler::~ToolBarHandler() 0217 { 0218 qDeleteAll(d->actions); 0219 d->actions.clear(); 0220 0221 delete d; 0222 } 0223 0224 QAction *ToolBarHandler::toolBarMenuAction() 0225 { 0226 Q_ASSERT(d->actions.count() == 1); 0227 return d->actions.first(); 0228 } 0229 0230 void ToolBarHandler::setupActions() 0231 { 0232 if (!factory() || !d->mainWindow) { 0233 return; 0234 } 0235 0236 BarActionBuilder builder(actionCollection(), d->mainWindow, d->toolBars); 0237 0238 if (!builder.needsRebuild()) { 0239 return; 0240 } 0241 0242 unplugActionList(QLatin1String(actionListName)); 0243 0244 qDeleteAll(d->actions); 0245 d->actions.clear(); 0246 0247 d->actions = builder.create(); 0248 0249 d->toolBars = builder.toolBars(); 0250 0251 // We have no XML file associated with our action collection, so load settings from KConfig 0252 actionCollection()->readSettings(); // #233712 0253 0254 plugActionList(QLatin1String(actionListName), d->actions); 0255 0256 d->connectToActionContainers(); 0257 } 0258 0259 #include "moc_ktoolbarhandler_p.cpp"