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 |
25 | KateScriptAction::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 | |
39 | void 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 |
54 | 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 | |
65 | KateScriptActionMenu::() |
66 | { |
67 | cleanup(); |
68 | } |
69 | |
70 | void KateScriptActionMenu::() |
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 | |
80 | void KateScriptActionMenu::() |
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 *> ; |
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 | |