diff --git a/src/kmenumenuhandler_p.cpp b/src/kmenumenuhandler_p.cpp index 84bc2b0..91363d2 100644 --- a/src/kmenumenuhandler_p.cpp +++ b/src/kmenumenuhandler_p.cpp @@ -1,249 +1,249 @@ /* This file is part of the KDE project Copyright (C) 2006 Olivier Goffart This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 "kmenumenuhandler_p.h" #include "kxmlguibuilder.h" #include "kxmlguiclient.h" #include "kxmlguifactory.h" #include "kactioncollection.h" #include "kmainwindow.h" #include "ktoolbar.h" #include "kshortcutwidget.h" #include "debug.h" #include #include #include #include #include #include #include #include #include #include #include namespace KDEPrivate { KMenuMenuHandler::KMenuMenuHandler(KXMLGUIBuilder *builder) : QObject(), m_builder(builder), m_popupMenu(nullptr), m_popupAction(nullptr), m_contextMenu(nullptr) { m_toolbarAction = new KSelectAction(i18n("Add to Toolbar"), this); connect(m_toolbarAction, SIGNAL(triggered(int)), this, SLOT(slotAddToToolBar(int))); } void KMenuMenuHandler::insertMenu(QMenu *popup) { popup->installEventFilter(this); } bool KMenuMenuHandler::eventFilter(QObject *watched, QEvent *event) { switch (event->type()) { case QEvent::MouseButtonPress: if (m_contextMenu && m_contextMenu->isVisible()) { m_contextMenu->hide(); return true; } break; case QEvent::MouseButtonRelease: if (m_contextMenu && m_contextMenu->isVisible()) { return true; } break; case QEvent::ContextMenu: { QContextMenuEvent *e = static_cast(event); QMenu *menu = static_cast(watched); if (e->reason() == QContextMenuEvent::Mouse) { showContextMenu(menu, e->pos()); } else if (menu->activeAction()) { showContextMenu(menu, menu->actionGeometry(menu->activeAction()).center()); } } event->accept(); return true; default: break; } return false; } void KMenuMenuHandler::buildToolbarAction() { KMainWindow *window = qobject_cast(m_builder->widget()); if (!window) { return; } QStringList toolbarlist; foreach (KToolBar *b, window->toolBars()) { toolbarlist << (b->windowTitle().isEmpty() ? b->objectName() : b->windowTitle()); } m_toolbarAction->setItems(toolbarlist); } static KActionCollection *findParentCollection(KXMLGUIFactory *factory, QAction *action) { foreach (KXMLGUIClient *client, factory->clients()) { KActionCollection *collection = client->actionCollection(); // if the call to actions() is too slow, add KActionCollection::contains(QAction*). if (collection->actions().contains(action)) { return collection; } } return nullptr; } void KMenuMenuHandler::slotSetShortcut() { if (!m_popupMenu || !m_popupAction) { return; } QDialog dialog(m_builder->widget()); dialog.setLayout(new QVBoxLayout); KShortcutWidget swidget(&dialog); swidget.setShortcut(m_popupAction->shortcuts()); dialog.layout()->addWidget(&swidget); QDialogButtonBox box(&dialog); box.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(&box, SIGNAL(accepted()), &dialog, SLOT(accept())); connect(&box, SIGNAL(rejected()), &dialog, SLOT(reject())); dialog.layout()->addWidget(&box); KActionCollection *parentCollection = nullptr; if (dynamic_cast(m_builder)) { QList checkCollections; KXMLGUIFactory *factory = dynamic_cast(m_builder)->factory(); parentCollection = findParentCollection(factory, m_popupAction); foreach (KXMLGUIClient *client, factory->clients()) { checkCollections += client->actionCollection(); } swidget.setCheckActionCollections(checkCollections); } if (dialog.exec()) { m_popupAction->setShortcuts(swidget.shortcut()); swidget.applyStealShortcut(); if (parentCollection) { parentCollection->writeSettings(); } } } void KMenuMenuHandler::slotAddToToolBar(int tb) { KMainWindow *window = qobject_cast(m_builder->widget()); if (!window) { return; } if (!m_popupMenu || !m_popupAction) { return; } KXMLGUIFactory *factory = dynamic_cast(m_builder)->factory(); QString actionName = m_popupAction->objectName(); // set by KActionCollection::addAction KActionCollection *collection = nullptr; if (factory) { collection = findParentCollection(factory, m_popupAction); } if (!collection) { qCWarning(DEBUG_KXMLGUI) << "Cannot find the action collection for action " << actionName; return; } KToolBar *toolbar = window->toolBars().at(tb); toolbar->addAction(m_popupAction); const KXMLGUIClient *client = collection->parentGUIClient(); QString xmlFile = client->localXMLFile(); QDomDocument document; document.setContent(KXMLGUIFactory::readConfigFile(client->xmlFile(), client->componentName())); QDomElement elem = document.documentElement().toElement(); const QLatin1String tagToolBar("ToolBar"); const QLatin1String attrNoEdit("noEdit"); const QLatin1String attrName("name"); QDomElement toolbarElem; QDomNode n = elem.firstChild(); for (; !n.isNull(); n = n.nextSibling()) { QDomElement elem = n.toElement(); if (!elem.isNull() && elem.tagName() == tagToolBar && elem.attribute(attrName) == toolbar->objectName()) { if (elem.attribute(attrNoEdit) == QStringLiteral("true")) { qCWarning(DEBUG_KXMLGUI) << "The toolbar is not editable"; return; } toolbarElem = elem; break; } } if (toolbarElem.isNull()) { toolbarElem = document.createElement(tagToolBar); toolbarElem.setAttribute(attrName, toolbar->objectName()); elem.appendChild(toolbarElem); } KXMLGUIFactory::findActionByName(toolbarElem, actionName, true); KXMLGUIFactory::saveConfigFile(document, xmlFile); } void KMenuMenuHandler::showContextMenu(QMenu *menu, const QPoint &pos) { Q_ASSERT(!m_popupMenu); Q_ASSERT(!m_popupAction); Q_ASSERT(!m_contextMenu); - m_popupAction = menu->actionAt(pos); - - if (!m_popupAction) { + auto *action = menu->actionAt(pos); + if (!action || action->isSeparator()) { return; } m_popupMenu = menu; + m_popupAction = action; m_contextMenu = new QMenu; m_contextMenu->addAction(i18n("Configure Shortcut..."), this, SLOT(slotSetShortcut())); KMainWindow *window = qobject_cast(m_builder->widget()); if (window) { m_contextMenu->addAction(m_toolbarAction); buildToolbarAction(); } m_contextMenu->exec(menu->mapToGlobal(pos)); delete m_contextMenu; m_contextMenu = nullptr; m_popupAction = nullptr; m_popupMenu = nullptr; } } //END namespace KDEPrivate