1/*
2 SPDX-FileCopyrightText: 2010-2018 Dominik Haumann <dhaumann@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "katescriptaction.h"
8#include "kateabstractinputmode.h"
9#include "katecmd.h"
10#include "katedocument.h"
11#include "kateglobal.h"
12#include "katepartdebug.h"
13#include "katescriptmanager.h"
14#include "kateview.h"
15#include "kateviewhelpers.h"
16
17#include <QJsonObject>
18#include <QMenu>
19
20#include <KActionCollection>
21#include <KLocalizedString>
22#include <KXMLGUIFactory>
23
24// BEGIN KateScriptAction
25KateScriptAction::KateScriptAction(const QString &cmd, const QJsonObject &action, KTextEditor::ViewPrivate *view)
26 : QAction(i18nc("Script command name", action.value(QStringLiteral("name")).toString().toUtf8().data()), view)
27 , m_view(view)
28 , m_command(cmd)
29 , m_interactive(action.value(QStringLiteral("interactive")).toBool())
30{
31 const QString icon = action.value(QStringLiteral("icon")).toString();
32 if (!icon.isEmpty()) {
33 setIcon(QIcon::fromTheme(name: icon));
34 }
35
36 connect(sender: this, signal: &KateScriptAction::triggered, context: this, slot: &KateScriptAction::exec);
37}
38
39void KateScriptAction::exec()
40{
41 if (m_interactive) {
42 m_view->currentInputMode()->launchInteractiveCommand(command: m_command + QLatin1Char(' '));
43 } else {
44 KTextEditor::Command *p = KateCmd::self()->queryCommand(cmd: m_command);
45 if (p) {
46 QString msg;
47 p->exec(view: m_view, cmd: m_command, msg);
48 }
49 }
50}
51// END KateScriptAction
52
53// BEGIN KateScriptActionMenu
54KateScriptActionMenu::KateScriptActionMenu(KTextEditor::ViewPrivate *view, const QString &text)
55 : KActionMenu(QIcon::fromTheme(QStringLiteral("code-context")), text, view)
56 , m_view(view)
57{
58 repopulate();
59 setPopupMode(QToolButton::InstantPopup);
60
61 // on script-reload signal, repopulate script menu
62 connect(sender: KTextEditor::EditorPrivate::self()->scriptManager(), signal: &KateScriptManager::reloaded, context: this, slot: &KateScriptActionMenu::repopulate);
63}
64
65KateScriptActionMenu::~KateScriptActionMenu()
66{
67 cleanup();
68}
69
70void KateScriptActionMenu::cleanup()
71{
72 // delete menus and actions for real
73 qDeleteAll(c: m_menus);
74 m_menus.clear();
75
76 qDeleteAll(c: m_actions);
77 m_actions.clear();
78}
79
80void KateScriptActionMenu::repopulate()
81{
82 // if the view is already hooked into the GUI, first remove it
83 // now and add it later, so that the changes we do here take effect
84 KXMLGUIFactory *viewFactory = m_view->factory();
85 if (viewFactory) {
86 viewFactory->removeClient(client: m_view);
87 }
88
89 // remove existing menu actions
90 cleanup();
91
92 // now add all command line script commands
93 QHash<QString, QMenu *> menus;
94 const auto scripts = KTextEditor::EditorPrivate::self()->scriptManager()->commandLineScripts();
95 for (KateCommandLineScript *script : scripts) {
96 // traverse actions
97 const auto &actions = script->commandHeader().actions();
98 for (const auto &value : actions) {
99 // action is a value
100 const auto action = value.toObject();
101
102 // get command
103 const QString cmd = action.value(QStringLiteral("function")).toString();
104
105 // show in a category submenu?
106 QMenu *m = menu();
107 QString category = action.value(QStringLiteral("category")).toString();
108 if (!category.isEmpty()) {
109 m = menus[category];
110 if (!m) {
111 m = menu()->addMenu(i18nc("Script command category", category.toUtf8().data()));
112 menus.insert(key: category, value: m);
113 m_menus.append(t: m);
114 m_view->actionCollection()->addAction(name: QLatin1String("tools_scripts_") + category, action: m->menuAction());
115 }
116 }
117
118 // create action + add to menu
119 QAction *a = new KateScriptAction(cmd, action, m_view);
120 m->addAction(action: a);
121 m_view->actionCollection()->addAction(name: QLatin1String("tools_scripts_") + cmd, action: a);
122 const QString shortcut = action.value(QStringLiteral("shortcut")).toString();
123 if (!shortcut.isEmpty()) {
124 m_view->actionCollection()->setDefaultShortcut(action: a, shortcut: QKeySequence(shortcut, QKeySequence::PortableText));
125 }
126
127 m_actions.append(t: a);
128 }
129 }
130
131 // finally add the view to the xml factory again, if it initially was there
132 if (viewFactory) {
133 viewFactory->addClient(client: m_view);
134 }
135}
136
137// END KateScriptActionMenu
138

source code of ktexteditor/src/script/katescriptaction.cpp