(kaction);
+ if (action) {
+ const QStringList l = action->tool->mimetypes;
+ const bool b = (!l.count() || l.contains(mimeType));
+ action->setEnabled(b);
+ }
+ }
+ }
+}
+// END KateExternalToolsMenuAction
+
+// BEGIN ToolItem
+/**
+ * This is a QListBoxItem, that has a KateExternalTool. The text is the Name
+ * of the tool.
+ */
+class ToolItem : public QListWidgetItem
+{
+public:
+ ToolItem(QListWidget* lb, const QPixmap& icon, KateExternalTool* tool)
+ : QListWidgetItem(icon, tool->name, lb)
+ , tool(tool)
+ {
+ }
+
+ ~ToolItem() {}
+
+ KateExternalTool* tool;
+};
+// END ToolItem
+
+// BEGIN KateExternalToolServiceEditor
+KateExternalToolServiceEditor::KateExternalToolServiceEditor(KateExternalTool* tool, QWidget* parent)
+ : QDialog(parent)
+ , tool(tool)
+{
+ setWindowTitle(i18n("Edit External Tool"));
+
+ auto vbox = new QVBoxLayout(this);
+ auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &KateExternalToolServiceEditor::slotOKClicked);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+
+ // create a entry for each property
+ // fill in the values from the service if available
+ auto w = new QWidget(this);
+ vbox->addWidget(w);
+ vbox->addWidget(buttonBox);
+
+ auto lo = new QGridLayout(w);
+ lo->setContentsMargins(0, 0, 0, 0);
+
+ leName = new QLineEdit(w);
+ lo->addWidget(leName, 1, 2);
+ auto l = new QLabel(w);
+ l->setBuddy(leName);
+ l->setText(i18n("&Label:"));
+ l->setAlignment(l->alignment() | Qt::AlignRight);
+ lo->addWidget(l, 1, 1);
+ if (tool)
+ leName->setText(tool->name);
+ leName->setWhatsThis(i18n("The name will be displayed in the 'Tools->External Tools' menu"));
+
+ btnIcon = new KIconButton(w);
+ btnIcon->setIconSize(KIconLoader::SizeSmall);
+ lo->addWidget(btnIcon, 1, 3);
+ if (tool && !tool->icon.isEmpty())
+ btnIcon->setIcon(tool->icon);
+
+ teCommand = new QTextEdit(w);
+ lo->addWidget(teCommand, 2, 2, 1, 2);
+ l = new QLabel(w);
+ l->setBuddy(teCommand);
+ l->setText(i18n("S&cript:"));
+ l->setAlignment(Qt::AlignTop | Qt::AlignRight);
+ lo->addWidget(l, 2, 1);
+ if (tool)
+ teCommand->setText(tool->command);
+ teCommand->setWhatsThis(i18n("The script to execute to invoke the tool. The script is passed "
+ "to /bin/sh for execution. The following macros "
+ "will be expanded:
"
+ "%URL
- the URL of the current document. "
+ "%URLs
- a list of the URLs of all open documents. "
+ "%directory
- the URL of the directory containing "
+ "the current document. "
+ "%filename
- the filename of the current document. "
+ "%line
- the current line of the text cursor in the "
+ "current view. "
+ "%column
- the column of the text cursor in the "
+ "current view. "
+ "%selection
- the selected text in the current view. "
+ "%text
- the text of the current document.
"));
+
+ leExecutable = new QLineEdit(w);
+ lo->addWidget(leExecutable, 3, 2, 1, 2);
+ l = new QLabel(w);
+ l->setBuddy(leExecutable);
+ l->setText(i18n("&Executable:"));
+ l->setAlignment(l->alignment() | Qt::AlignRight);
+ lo->addWidget(l, 3, 1);
+ if (tool)
+ leExecutable->setText(tool->tryexec);
+ leExecutable->setWhatsThis(i18n("The executable used by the command. This is used to check if a tool "
+ "should be displayed; if not set, the first word of command "
+ "will be used."));
+
+ leMimetypes = new QLineEdit(w);
+ lo->addWidget(leMimetypes, 4, 2);
+ l = new QLabel(w);
+ l->setBuddy(leMimetypes);
+ l->setText(i18n("&Mime types:"));
+ l->setAlignment(l->alignment() | Qt::AlignRight);
+ lo->addWidget(l, 4, 1);
+ if (tool)
+ leMimetypes->setText(tool->mimetypes.join(QStringLiteral("; ")));
+ leMimetypes->setWhatsThis(i18n("A semicolon-separated list of mime types for which this tool should "
+ "be available; if this is left empty, the tool is always available. "
+ "To choose from known mimetypes, press the button on the right."));
+
+ auto btnMimetype = new QToolButton(w);
+ lo->addWidget(btnMimetype, 4, 3);
+ btnMimetype->setIcon(QIcon::fromTheme(QStringLiteral("tools-wizard")));
+ connect(btnMimetype, &QToolButton::clicked, this, &KateExternalToolServiceEditor::showMTDlg);
+ btnMimetype->setWhatsThis(i18n("Click for a dialog that can help you create a list of mimetypes."));
+
+ cmbSave = new QComboBox(w);
+ lo->addWidget(cmbSave, 5, 2, 1, 2);
+ l = new QLabel(w);
+ l->setBuddy(cmbSave);
+ l->setText(i18n("&Save:"));
+ l->setAlignment(l->alignment() | Qt::AlignRight);
+ lo->addWidget(l, 5, 1);
+ cmbSave->addItems({ i18n("None"), i18n("Current Document"), i18n("All Documents") });
+ if (tool)
+ cmbSave->setCurrentIndex(tool->save);
+ cmbSave->setWhatsThis(i18n("You can choose to save the current or all [modified] documents prior to "
+ "running the command. This is helpful if you want to pass URLs to "
+ "an application like, for example, an FTP client."));
+
+ leCmdLine = new QLineEdit(w);
+ lo->addWidget(leCmdLine, 6, 2, 1, 2);
+ l = new QLabel(i18n("&Command line name:"), w);
+ l->setBuddy(leCmdLine);
+ l->setAlignment(l->alignment() | Qt::AlignRight);
+ lo->addWidget(l, 6, 1);
+ if (tool)
+ leCmdLine->setText(tool->cmdname);
+ leCmdLine->setWhatsThis(i18n("If you specify a name here, you can invoke the command from the view "
+ "command line with exttool-the_name_you_specified_here. "
+ "Please do not use spaces or tabs in the name."));
+}
+
+void KateExternalToolServiceEditor::slotOKClicked()
+{
+ if (leName->text().isEmpty() || teCommand->document()->isEmpty()) {
+ QMessageBox::information(this, i18n("External Tool"), i18n("You must specify at least a name and a command"));
+ return;
+ }
+ accept();
+}
+
+void KateExternalToolServiceEditor::showMTDlg()
+{
+ QString text = i18n("Select the MimeTypes for which to enable this tool.");
+ QStringList list = leMimetypes->text().split(QRegExp(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts);
+ KMimeTypeChooserDialog d(i18n("Select Mime Types"), text, list, QStringLiteral("text"), this);
+ if (d.exec() == QDialog::Accepted) {
+ leMimetypes->setText(d.chooser()->mimeTypes().join(QStringLiteral(";")));
+ }
+}
+// END KateExternalToolServiceEditor
+
+// BEGIN KateExternalToolsConfigWidget
+KateExternalToolsConfigWidget::KateExternalToolsConfigWidget(QWidget* parent, KateExternalToolsPlugin* plugin)
+ : KTextEditor::ConfigPage(parent)
+ , m_changed(false)
+ , m_plugin(plugin)
+{
+ setupUi(this);
+
+ btnMoveUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
+ btnMoveDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
+
+ connect(lbTools, &QListWidget::itemSelectionChanged, this, &KateExternalToolsConfigWidget::slotSelectionChanged);
+ connect(lbTools, &QListWidget::itemDoubleClicked, this, &KateExternalToolsConfigWidget::slotEdit);
+ connect(btnNew, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotNew);
+ connect(btnRemove, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotRemove);
+ connect(btnEdit, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotEdit);
+ connect(btnSeparator, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotInsertSeparator);
+ connect(btnMoveUp, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotMoveUp);
+ connect(btnMoveDown, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotMoveDown);
+
+ config = new KConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
+ reset();
+ slotSelectionChanged();
+}
+
+KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
+{
+ delete config;
+}
+
+QString KateExternalToolsConfigWidget::name() const
+{
+ return i18n("External Tools");
+}
+
+QString KateExternalToolsConfigWidget::fullName() const
+{
+ return i18n("External Tools");
+}
+
+QIcon KateExternalToolsConfigWidget::icon() const
+{
+ return QIcon();
+}
+
+void KateExternalToolsConfigWidget::reset()
+{
+ // m_tools.clear();
+ lbTools->clear();
+
+ // load the files from a KConfig
+ const QStringList tools = config->group("Global").readEntry("tools", QStringList());
+
+ for (QStringList::const_iterator it = tools.begin(); it != tools.end(); ++it) {
+ if (*it == QStringLiteral("---")) {
+ new QListWidgetItem(QStringLiteral("---"), lbTools);
+ } else {
+ KConfigGroup cg(config, *it);
+
+ KateExternalTool* t
+ = new KateExternalTool(cg.readEntry("name", ""), cg.readEntry("command", ""), cg.readEntry("icon", ""),
+ cg.readEntry("executable", ""), cg.readEntry("mimetypes", QStringList()),
+ cg.readEntry("acname"), cg.readEntry("cmdname"), cg.readEntry("save", 0));
+
+ if (t->hasexec) // we only show tools that are also in the menu.
+ new ToolItem(lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t);
+ else
+ delete t;
+ }
+ }
+ m_changed = false;
+}
+
+QPixmap KateExternalToolsConfigWidget::blankIcon()
+{
+ QPixmap pm(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
+ pm.fill();
+ pm.setMask(pm.createHeuristicMask());
+ return pm;
+}
+
+void KateExternalToolsConfigWidget::apply()
+{
+ if (!m_changed)
+ return;
+ m_changed = false;
+
+ // save a new list
+ // save each item
+ QStringList tools;
+ for (int i = 0; i < lbTools->count(); i++) {
+ if (lbTools->item(i)->text() == QStringLiteral("---")) {
+ tools << QStringLiteral("---");
+ continue;
+ }
+ KateExternalTool* t = static_cast(lbTools->item(i))->tool;
+ // qDebug()<<"adding tool: "<name;
+ tools << t->acname;
+
+ KConfigGroup cg(config, t->acname);
+
+ cg.writeEntry("name", t->name);
+ cg.writeEntry("command", t->command);
+ cg.writeEntry("icon", t->icon);
+ cg.writeEntry("executable", t->tryexec);
+ cg.writeEntry("mimetypes", t->mimetypes);
+ cg.writeEntry("acname", t->acname);
+ cg.writeEntry("cmdname", t->cmdname);
+ cg.writeEntry("save", t->save);
+ }
+
+ config->group("Global").writeEntry("tools", tools);
+
+ // if any tools was removed, try to delete their groups, and
+ // add the group names to the list of removed items.
+ if (m_removed.count()) {
+ for (QStringList::iterator it = m_removed.begin(); it != m_removed.end(); ++it) {
+ if (config->hasGroup(*it))
+ config->deleteGroup(*it);
+ }
+ QStringList removed = config->group("Global").readEntry("removed", QStringList());
+ removed += m_removed;
+
+ // clean up the list of removed items, so that it does not contain
+ // non-existing groups (we can't remove groups from a non-owned global file).
+ config->sync();
+ QStringList::iterator it1 = removed.begin();
+ while (it1 != removed.end()) {
+ if (!config->hasGroup(*it1))
+ it1 = removed.erase(it1);
+ else
+ ++it1;
+ }
+ config->group("Global").writeEntry("removed", removed);
+ }
+
+ config->sync();
+ m_plugin->reload();
+}
+
+void KateExternalToolsConfigWidget::slotSelectionChanged()
+{
+ // update button state
+ bool hs = lbTools->currentItem() != nullptr;
+ btnEdit->setEnabled(hs && dynamic_cast(lbTools->currentItem()));
+ btnRemove->setEnabled(hs);
+ btnMoveUp->setEnabled((lbTools->currentRow() > 0) && hs);
+ btnMoveDown->setEnabled((lbTools->currentRow() < (int)lbTools->count() - 1) && hs);
+}
+
+void KateExternalToolsConfigWidget::slotNew()
+{
+ // display a editor, and if it is OK'd, create a new tool and
+ // create a listbox item for it
+ KateExternalToolServiceEditor editor(nullptr, this);
+
+ if (editor.exec()) {
+ KateExternalTool* t = new KateExternalTool(
+ editor.leName->text(), editor.teCommand->toPlainText(), editor.btnIcon->icon(), editor.leExecutable->text(),
+ editor.leMimetypes->text().split(QRegExp(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts));
+
+ // This is sticky, it does not change again, so that shortcuts sticks
+ // TODO check for dups
+ t->acname = QStringLiteral("externaltool_") + QString(t->name).remove(QRegExp(QStringLiteral("\\W+")));
+
+ new ToolItem(lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t);
+
+ emit changed();
+ m_changed = true;
+ }
+}
+
+void KateExternalToolsConfigWidget::slotRemove()
+{
+ // add the tool action name to a list of removed items,
+ // remove the current listbox item
+ if (lbTools->currentRow() > -1) {
+ ToolItem* i = dynamic_cast(lbTools->currentItem());
+ if (i)
+ m_removed << i->tool->acname;
+
+ delete lbTools->takeItem(lbTools->currentRow());
+ emit changed();
+ m_changed = true;
+ }
+}
+
+void KateExternalToolsConfigWidget::slotEdit()
+{
+ if (!dynamic_cast(lbTools->currentItem()))
+ return;
+ // show the item in an editor
+ KateExternalTool* t = static_cast(lbTools->currentItem())->tool;
+ KateExternalToolServiceEditor editor(t, this);
+ editor.resize(config->group("Editor").readEntry("Size", QSize()));
+ if (editor.exec() /*== KDialog::Ok*/) {
+
+ bool elementChanged = ((editor.btnIcon->icon() != t->icon) || (editor.leName->text() != t->name));
+
+ t->name = editor.leName->text();
+ t->cmdname = editor.leCmdLine->text();
+ t->command = editor.teCommand->toPlainText();
+ t->icon = editor.btnIcon->icon();
+ t->tryexec = editor.leExecutable->text();
+ t->mimetypes = editor.leMimetypes->text().split(QRegExp(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts);
+ t->save = editor.cmbSave->currentIndex();
+
+ // if the icon has changed or name changed, I have to renew the listbox item :S
+ if (elementChanged) {
+ int idx = lbTools->row(lbTools->currentItem());
+ delete lbTools->takeItem(idx);
+ lbTools->insertItem(idx, new ToolItem(nullptr, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t));
+ }
+
+ emit changed();
+ m_changed = true;
+ }
+
+ config->group("Editor").writeEntry("Size", editor.size());
+ config->sync();
+}
+
+void KateExternalToolsConfigWidget::slotInsertSeparator()
+{
+ lbTools->insertItem(lbTools->currentRow() + 1, QStringLiteral("---"));
+ emit changed();
+ m_changed = true;
+}
+
+void KateExternalToolsConfigWidget::slotMoveUp()
+{
+ // move the current item in the listbox upwards if possible
+ QListWidgetItem* item = lbTools->currentItem();
+ if (!item)
+ return;
+
+ int idx = lbTools->row(item);
+
+ if (idx < 1)
+ return;
+
+ if (dynamic_cast(item)) {
+ KateExternalTool* tool = static_cast(item)->tool;
+ delete lbTools->takeItem(idx);
+ lbTools->insertItem(idx - 1,
+ new ToolItem(nullptr, tool->icon.isEmpty() ? blankIcon() : SmallIcon(tool->icon), tool));
+ } else // a separator!
+ {
+ delete lbTools->takeItem(idx);
+ lbTools->insertItem(idx - 1, new QListWidgetItem(QStringLiteral("---")));
+ }
+
+ lbTools->setCurrentRow(idx - 1);
+ slotSelectionChanged();
+ emit changed();
+ m_changed = true;
+}
+
+void KateExternalToolsConfigWidget::slotMoveDown()
+{
+ // move the current item in the listbox downwards if possible
+ QListWidgetItem* item = lbTools->currentItem();
+ if (!item)
+ return;
+
+ int idx = lbTools->row(item);
+
+ if (idx > lbTools->count() - 1)
+ return;
+
+ if (dynamic_cast(item)) {
+ KateExternalTool* tool = static_cast(item)->tool;
+ delete lbTools->takeItem(idx);
+ lbTools->insertItem(idx + 1,
+ new ToolItem(nullptr, tool->icon.isEmpty() ? blankIcon() : SmallIcon(tool->icon), tool));
+ } else // a separator!
+ {
+ delete lbTools->takeItem(idx);
+ lbTools->insertItem(idx + 1, new QListWidgetItem(QStringLiteral("---")));
+ }
+
+ lbTools->setCurrentRow(idx + 1);
+ slotSelectionChanged();
+ emit changed();
+ m_changed = true;
+}
+// END KateExternalToolsConfigWidget
+// kate: space-indent on; indent-width 4; replace-tabs on;
diff --git a/addons/externaltools/externaltoolsplugin.h b/addons/externaltools/externaltoolsplugin.h
new file mode 100644
--- /dev/null
+++ b/addons/externaltools/externaltoolsplugin.h
@@ -0,0 +1,86 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann
+ Copyright (C) 2002 Joseph Wenninger
+ Copyright (C) 2002 Anders Lund
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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.
+*/
+
+#ifndef KTEXTEDITOR_EXTERNALTOOLS_PLUGIN_H
+#define KTEXTEDITOR_EXTERNALTOOLS_PLUGIN_H
+
+#include
+#include
+
+#include
+
+#include "externaltools.h"
+
+class KateExternalToolsPluginView;
+
+class KateExternalToolsPlugin : public KTextEditor::Plugin
+{
+ Q_OBJECT
+
+public:
+ explicit KateExternalToolsPlugin(QObject* parent = nullptr, const QList& = QList());
+ virtual ~KateExternalToolsPlugin();
+
+ int configPages() const override;
+ KTextEditor::ConfigPage* configPage(int number = 0, QWidget* parent = nullptr) override;
+
+ void reload();
+
+ QObject* createView(KTextEditor::MainWindow* mainWindow) override;
+ KateExternalToolsPluginView* extView(QWidget* widget);
+
+private:
+ QList m_views;
+ KateExternalToolsCommand* m_command = nullptr;
+private
+ Q_SLOT : void viewDestroyed(QObject* view);
+};
+
+class KateExternalToolsPluginView : public QObject, public KXMLGUIClient
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ */
+ KateExternalToolsPluginView(KTextEditor::MainWindow* mainWindow);
+
+ /**
+ * Virtual destructor.
+ */
+ ~KateExternalToolsPluginView();
+
+ /**
+ * Returns the associated mainWindow
+ */
+ KTextEditor::MainWindow* mainWindow() const;
+
+ void rebuildMenu();
+
+ KateExternalToolsMenuAction* externalTools = nullptr;
+
+private:
+ KTextEditor::MainWindow* m_mainWindow;
+};
+
+#endif
+
+// kate: space-indent on; indent-width 4; replace-tabs on;
diff --git a/addons/externaltools/externaltoolsplugin.cpp b/addons/externaltools/externaltoolsplugin.cpp
new file mode 100644
--- /dev/null
+++ b/addons/externaltools/externaltoolsplugin.cpp
@@ -0,0 +1,152 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann
+ Copyright (C) 2002 Joseph Wenninger
+ Copyright (C) 2002 Anders Lund
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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 "externaltoolsplugin.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+K_PLUGIN_FACTORY_WITH_JSON(KateExternalToolsFactory, "externaltoolsplugin.json",
+ registerPlugin();)
+
+KateExternalToolsPlugin::KateExternalToolsPlugin(QObject* parent, const QList&)
+ : KTextEditor::Plugin(parent)
+{
+ if (KAuthorized::authorizeAction(QStringLiteral("shell_access"))) {
+ m_command = new KateExternalToolsCommand(this);
+ }
+}
+
+KateExternalToolsPlugin::~KateExternalToolsPlugin()
+{
+ if (KAuthorized::authorizeAction(QStringLiteral("shell_access"))) {
+ if (m_command) {
+ delete m_command;
+ }
+ }
+}
+
+QObject* KateExternalToolsPlugin::createView(KTextEditor::MainWindow* mainWindow)
+{
+ KateExternalToolsPluginView* view = new KateExternalToolsPluginView(mainWindow);
+ connect(view, SIGNAL(destroyed(QObject*)), this, SLOT(viewDestroyed(QObject*)));
+ m_views.append(view);
+ return view;
+}
+
+KateExternalToolsPluginView* KateExternalToolsPlugin::extView(QWidget* widget)
+{
+ foreach (KateExternalToolsPluginView* view, m_views) {
+ if (view->mainWindow()->window() == widget)
+ return view;
+ }
+ return nullptr;
+}
+
+void KateExternalToolsPlugin::viewDestroyed(QObject* view)
+{
+ m_views.removeAll(dynamic_cast(view));
+}
+
+void KateExternalToolsPlugin::reload()
+{
+ if (KAuthorized::authorizeAction(QStringLiteral("shell_access"))) {
+ if (m_command)
+ m_command->reload();
+ }
+ foreach (KateExternalToolsPluginView* view, m_views) {
+ view->rebuildMenu();
+ }
+}
+
+int KateExternalToolsPlugin::configPages() const
+{
+ return 1;
+}
+
+KTextEditor::ConfigPage* KateExternalToolsPlugin::configPage(int number, QWidget* parent)
+{
+ if (number == 0) {
+ return new KateExternalToolsConfigWidget(parent, this);
+ }
+ return nullptr;
+}
+
+KateExternalToolsPluginView::KateExternalToolsPluginView(KTextEditor::MainWindow* mainWindow)
+ : QObject(mainWindow)
+ , m_mainWindow(mainWindow)
+{
+ KXMLGUIClient::setComponentName(QLatin1String("externaltools"), i18n("External Tools"));
+ setXMLFile(QLatin1String("ui.rc"));
+
+ if (KAuthorized::authorizeAction(QStringLiteral("shell_access"))) {
+ externalTools
+ = new KateExternalToolsMenuAction(i18n("External Tools"), actionCollection(), mainWindow, mainWindow);
+ actionCollection()->addAction(QStringLiteral("tools_external"), externalTools);
+ externalTools->setWhatsThis(i18n("Launch external helper applications"));
+ }
+
+ mainWindow->guiFactory()->addClient(this);
+}
+
+void KateExternalToolsPluginView::rebuildMenu()
+{
+ if (externalTools) {
+ KXMLGUIFactory* f = factory();
+ f->removeClient(this);
+ reloadXML();
+ externalTools->reload();
+ qDebug() << "has just returned from externalTools->reload()";
+ f->addClient(this);
+ }
+}
+
+KateExternalToolsPluginView::~KateExternalToolsPluginView()
+{
+ m_mainWindow->guiFactory()->removeClient(this);
+
+ delete externalTools;
+ externalTools = nullptr;
+}
+
+KTextEditor::MainWindow* KateExternalToolsPluginView::mainWindow() const
+{
+ return m_mainWindow;
+}
+
+#include "externaltoolsplugin.moc"
+
+// kate: space-indent on; indent-width 4; replace-tabs on;
diff --git a/addons/externaltools/externaltoolsplugin.desktop b/addons/externaltools/externaltoolsplugin.desktop
new file mode 100644
--- /dev/null
+++ b/addons/externaltools/externaltoolsplugin.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=KTextEditor/Plugin
+X-KDE-Library=externaltoolsplugin
+Name=External Tools
+Comment=External Tools
diff --git a/addons/externaltools/plugin.qrc b/addons/externaltools/plugin.qrc
new file mode 100644
--- /dev/null
+++ b/addons/externaltools/plugin.qrc
@@ -0,0 +1,6 @@
+
+
+
+ ui.rc
+
+
diff --git a/addons/externaltools/ui.rc b/addons/externaltools/ui.rc
new file mode 100644
--- /dev/null
+++ b/addons/externaltools/ui.rc
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+