File indexing completed on 2024-04-21 03:57:38
0001 /* 0002 SPDX-FileCopyrightText: 2010-2018 Dominik Haumann <dhaumann@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "katescriptaction.h" 0008 #include "kateabstractinputmode.h" 0009 #include "katecmd.h" 0010 #include "katedocument.h" 0011 #include "kateglobal.h" 0012 #include "katepartdebug.h" 0013 #include "katescriptmanager.h" 0014 #include "kateview.h" 0015 #include "kateviewhelpers.h" 0016 0017 #include <QJsonObject> 0018 #include <QMenu> 0019 0020 #include <KActionCollection> 0021 #include <KLocalizedString> 0022 #include <KXMLGUIFactory> 0023 0024 // BEGIN KateScriptAction 0025 KateScriptAction::KateScriptAction(const QString &cmd, const QJsonObject &action, KTextEditor::ViewPrivate *view) 0026 : QAction(i18nc("Script command name", action.value(QStringLiteral("name")).toString().toUtf8().data()), view) 0027 , m_view(view) 0028 , m_command(cmd) 0029 , m_interactive(action.value(QStringLiteral("interactive")).toBool()) 0030 { 0031 const QString icon = action.value(QStringLiteral("icon")).toString(); 0032 if (!icon.isEmpty()) { 0033 setIcon(QIcon::fromTheme(icon)); 0034 } 0035 0036 connect(this, &KateScriptAction::triggered, this, &KateScriptAction::exec); 0037 } 0038 0039 void KateScriptAction::exec() 0040 { 0041 if (m_interactive) { 0042 m_view->currentInputMode()->launchInteractiveCommand(m_command + QLatin1Char(' ')); 0043 } else { 0044 KTextEditor::Command *p = KateCmd::self()->queryCommand(m_command); 0045 if (p) { 0046 QString msg; 0047 p->exec(m_view, m_command, msg); 0048 } 0049 } 0050 } 0051 // END KateScriptAction 0052 0053 // BEGIN KateScriptActionMenu 0054 KateScriptActionMenu::KateScriptActionMenu(KTextEditor::ViewPrivate *view, const QString &text) 0055 : KActionMenu(QIcon::fromTheme(QStringLiteral("code-context")), text, view) 0056 , m_view(view) 0057 { 0058 repopulate(); 0059 setPopupMode(QToolButton::InstantPopup); 0060 0061 // on script-reload signal, repopulate script menu 0062 connect(KTextEditor::EditorPrivate::self()->scriptManager(), &KateScriptManager::reloaded, this, &KateScriptActionMenu::repopulate); 0063 } 0064 0065 KateScriptActionMenu::~KateScriptActionMenu() 0066 { 0067 cleanup(); 0068 } 0069 0070 void KateScriptActionMenu::cleanup() 0071 { 0072 // delete menus and actions for real 0073 qDeleteAll(m_menus); 0074 m_menus.clear(); 0075 0076 qDeleteAll(m_actions); 0077 m_actions.clear(); 0078 } 0079 0080 void KateScriptActionMenu::repopulate() 0081 { 0082 // if the view is already hooked into the GUI, first remove it 0083 // now and add it later, so that the changes we do here take effect 0084 KXMLGUIFactory *viewFactory = m_view->factory(); 0085 if (viewFactory) { 0086 viewFactory->removeClient(m_view); 0087 } 0088 0089 // remove existing menu actions 0090 cleanup(); 0091 0092 // now add all command line script commands 0093 QHash<QString, QMenu *> menus; 0094 const auto scripts = KTextEditor::EditorPrivate::self()->scriptManager()->commandLineScripts(); 0095 for (KateCommandLineScript *script : scripts) { 0096 // traverse actions 0097 const auto &actions = script->commandHeader().actions(); 0098 for (const auto &value : actions) { 0099 // action is a value 0100 const auto action = value.toObject(); 0101 0102 // get command 0103 const QString cmd = action.value(QStringLiteral("function")).toString(); 0104 0105 // show in a category submenu? 0106 QMenu *m = menu(); 0107 QString category = action.value(QStringLiteral("category")).toString(); 0108 if (!category.isEmpty()) { 0109 m = menus[category]; 0110 if (!m) { 0111 m = menu()->addMenu(i18nc("Script command category", category.toUtf8().data())); 0112 menus.insert(category, m); 0113 m_menus.append(m); 0114 m_view->actionCollection()->addAction(QLatin1String("tools_scripts_") + category, m->menuAction()); 0115 } 0116 } 0117 0118 // create action + add to menu 0119 QAction *a = new KateScriptAction(cmd, action, m_view); 0120 m->addAction(a); 0121 m_view->actionCollection()->addAction(QLatin1String("tools_scripts_") + cmd, a); 0122 const QString shortcut = action.value(QStringLiteral("shortcut")).toString(); 0123 if (!shortcut.isEmpty()) { 0124 m_view->actionCollection()->setDefaultShortcut(a, QKeySequence(shortcut, QKeySequence::PortableText)); 0125 } 0126 0127 m_actions.append(a); 0128 } 0129 } 0130 0131 // finally add the view to the xml factory again, if it initially was there 0132 if (viewFactory) { 0133 viewFactory->addClient(m_view); 0134 } 0135 } 0136 0137 // END KateScriptActionMenu