diff --git a/addons/externaltools/configwidget.ui b/addons/externaltools/configwidget.ui
index 4b21bd833..d3f53fe12 100644
--- a/addons/externaltools/configwidget.ui
+++ b/addons/externaltools/configwidget.ui
@@ -1,118 +1,121 @@
ExternalToolsConfigWidget
0
0
504
296
0
0
0
0
-
-
Qt::Vertical
20
98
-
Qt::Vertical
17
108
-
-
&New...
-
Edit&...
-
&Remove
-
Qt::Horizontal
40
20
-
New &Category
-
-
-
This list shows all the configured tools, represented by their menu text.
+
+ true
+
diff --git a/addons/externaltools/kateexternaltoolsconfigwidget.cpp b/addons/externaltools/kateexternaltoolsconfigwidget.cpp
index 9d08399a3..74ae3e179 100644
--- a/addons/externaltools/kateexternaltoolsconfigwidget.cpp
+++ b/addons/externaltools/kateexternaltoolsconfigwidget.cpp
@@ -1,407 +1,419 @@
/* This file is part of the KDE project
*
* Copyright 2019 Dominik Haumann
*
* 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.
*/
// TODO
// Icons
// Direct shortcut setting
#include "kateexternaltoolsconfigwidget.h"
#include "externaltoolsplugin.h"
#include "kateexternaltool.h"
#include "katemacroexpander.h"
#include "katetoolrunner.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// BEGIN ToolItem
/**
* This is a QStandardItem, that has a KateExternalTool.
* The text is the Name of the tool.
*/
class ToolItem : public QStandardItem
{
public:
ToolItem(const QPixmap& icon, KateExternalTool* tool)
: QStandardItem(icon, tool->name)
{
setData(QVariant::fromValue(tool));
}
KateExternalTool * tool() {
return qvariant_cast(data());
}
};
// END ToolItem
// BEGIN KateExternalToolServiceEditor
KateExternalToolServiceEditor::KateExternalToolServiceEditor(KateExternalTool* tool, QWidget* parent)
: QDialog(parent)
, m_tool(tool)
{
setWindowTitle(i18n("Edit External Tool"));
ui = new Ui::ToolDialog();
ui->setupUi(this);
ui->btnIcon->setIconSize(KIconLoader::SizeSmall);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &KateExternalToolServiceEditor::slotOKClicked);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(ui->btnMimeType, &QToolButton::clicked, this, &KateExternalToolServiceEditor::showMTDlg);
Q_ASSERT(m_tool != nullptr);
ui->edtName->setText(m_tool->name);
if (!m_tool->icon.isEmpty())
ui->btnIcon->setIcon(m_tool->icon);
ui->edtExecutable->setText(m_tool->executable);
ui->edtArgs->setText(m_tool->arguments);
ui->edtInput->setText(m_tool->input);
ui->edtWorkingDir->setText(m_tool->workingDir);
ui->edtMimeType->setText(m_tool->mimetypes.join(QStringLiteral("; ")));
ui->cmbSave->setCurrentIndex(static_cast(m_tool->saveMode));
ui->chkReload->setChecked(m_tool->reload);
ui->cmbOutput->setCurrentIndex(static_cast(m_tool->outputMode));
ui->chkIncludeStderr->setChecked(m_tool->includeStderr);
ui->edtCommand->setText(m_tool->cmdname);
}
void KateExternalToolServiceEditor::slotOKClicked()
{
if (ui->edtName->text().isEmpty() || ui->edtExecutable->text().isEmpty()) {
QMessageBox::information(this, i18n("External Tool"),
i18n("You must specify at least a name and an executable"));
return;
}
accept();
}
void KateExternalToolServiceEditor::showMTDlg()
{
QString text = i18n("Select the MimeTypes for which to enable this tool.");
QStringList list
= ui->edtMimeType->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts);
KMimeTypeChooserDialog d(i18n("Select Mime Types"), text, list, QStringLiteral("text"), this);
if (d.exec() == QDialog::Accepted) {
ui->edtMimeType->setText(d.chooser()->mimeTypes().join(QStringLiteral(";")));
}
}
// END KateExternalToolServiceEditor
// BEGIN KateExternalToolsConfigWidget
KateExternalToolsConfigWidget::KateExternalToolsConfigWidget(QWidget* parent, KateExternalToolsPlugin* plugin)
: KTextEditor::ConfigPage(parent)
, m_plugin(plugin)
{
setupUi(this);
lbTools->setModel(&m_toolsModel);
btnMoveUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
btnMoveDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
// connect(lbTools, &QTreeView::itemSelectionChanged, this, &KateExternalToolsConfigWidget::slotSelectionChanged);
// connect(lbTools, &QTreeView::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(btnMoveUp, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotMoveUp);
connect(btnMoveDown, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotMoveDown);
m_config = new KConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
// reset triggers a reload of the exisint tools
reset();
slotSelectionChanged();
}
KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
{
+ clearTools();
+
delete m_config;
}
QString KateExternalToolsConfigWidget::name() const
{
return i18n("External Tools");
}
QString KateExternalToolsConfigWidget::fullName() const
{
return i18n("External Tools");
}
QIcon KateExternalToolsConfigWidget::icon() const
{
return QIcon::fromTheme(QStringLiteral("system-run"));
}
void KateExternalToolsConfigWidget::reset()
{
- // clear list
- m_toolsModel.clear();
+ clearTools();
- // 2 steps: 1st step: create categories
+ // create categories
+ addCategory(i18n("Uncategorized"));
const auto tools = m_plugin->tools();
for (auto tool : tools) {
auto clone = new KateExternalTool(*tool);
auto item = new ToolItem(clone->icon.isEmpty() ? blankIcon() : SmallIcon(clone->icon), clone);
auto category = addCategory(clone->category.isEmpty() ? i18n("Uncategorized") : clone->category);
category->appendRow(item);
}
+ lbTools->expandAll();
m_changed = false;
}
QPixmap KateExternalToolsConfigWidget::blankIcon()
{
QPixmap pm(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
pm.fill();
pm.setMask(pm.createHeuristicMask());
return pm;
}
static std::vector childItems(const QStandardItem * item)
{
// collect all KateExternalTool items
std::vector children;
for (int i = 0; i < item->rowCount(); ++i) {
children.push_back(item->child(i));
}
return children;
}
static std::vector collectTools(const QStandardItemModel & model)
{
std::vector tools;
for (auto categoryItem : childItems(model.invisibleRootItem())) {
for (auto child : childItems(categoryItem)) {
auto toolItem = static_cast(child);
tools.push_back(toolItem->tool());
}
}
return tools;
}
void KateExternalToolsConfigWidget::apply()
{
if (!m_changed)
return;
m_changed = false;
// collect all KateExternalTool items
const std::vector tools = collectTools(m_toolsModel);
m_config->group("Global").writeEntry("tools", static_cast(tools.size()));
for (size_t i = 0; i < tools.size(); i++) {
const QString section = QStringLiteral("Tool ") + QString::number(i);
KConfigGroup cg(m_config, section);
tools[i]->save(cg);
}
m_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);
}
QStandardItem * KateExternalToolsConfigWidget::addCategory(const QString & category)
{
// searach for existing category
auto items = m_toolsModel.findItems(category);
if (!items.empty()) {
return items.front();
}
// ...otherwise, create it
auto item = new QStandardItem(category);
m_toolsModel.appendRow(item);
return item;
}
+void KateExternalToolsConfigWidget::clearTools()
+{
+ // collect all KateExternalTool items and delete them, since they are copies
+ std::vector tools = collectTools(m_toolsModel);
+ qDeleteAll(tools);
+ tools.clear();
+ m_toolsModel.clear();
+}
+
void KateExternalToolsConfigWidget::slotNew()
{
// display a editor, and if it is OK'd, create a new tool and
// create a listbox item for it
auto t = new KateExternalTool();
KateExternalToolServiceEditor editor(t, this);
if (editor.exec() == QDialog::Accepted) {
t->name = editor.ui->edtName->text();
t->icon = editor.ui->btnIcon->icon();
t->executable = editor.ui->edtExecutable->text();
t->arguments = editor.ui->edtArgs->text();
t->input = editor.ui->edtInput->toPlainText();
t->workingDir = editor.ui->edtWorkingDir->text();
t->mimetypes = editor.ui->edtMimeType->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")),
QString::SkipEmptyParts);
t->saveMode = static_cast(editor.ui->cmbSave->currentIndex());
t->reload = editor.ui->chkReload->isChecked();
t->outputMode = static_cast(editor.ui->cmbOutput->currentIndex());
t->includeStderr = editor.ui->chkIncludeStderr->isChecked();
t->cmdname = editor.ui->edtCommand->text();
// This is sticky, it does not change again, so that shortcuts sticks
// TODO check for dups
t->actionName = QStringLiteral("externaltool_") + QString(t->name).remove(QRegularExpression(QStringLiteral("\\W+")));
auto item = new ToolItem(t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t);
auto category = addCategory(item->tool()->category);
category->appendRow(item);
emit changed();
m_changed = true;
} else {
delete t;
}
}
void KateExternalToolsConfigWidget::slotRemove()
{
auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
auto toolItem = dynamic_cast(item);
// add the tool action name to a list of removed items,
// remove the current listbox item
if (toolItem) {
m_removed << toolItem->tool()->actionName;
toolItem->parent()->removeRow(toolItem->index().row());
delete toolItem;;
emit changed();
m_changed = true;
}
}
void KateExternalToolsConfigWidget::slotEdit()
{
auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
auto toolItem = dynamic_cast(item);
if (!toolItem)
return;
// show the item in an editor
KateExternalTool* t = toolItem->tool();
KateExternalToolServiceEditor editor(t, this);
editor.resize(m_config->group("Editor").readEntry("Size", QSize()));
if (editor.exec() == QDialog::Accepted) {
const bool elementChanged = ((editor.ui->btnIcon->icon() != t->icon) || (editor.ui->edtName->text() != t->name));
t->name = editor.ui->edtName->text();
t->icon = editor.ui->btnIcon->icon();
t->executable = editor.ui->edtExecutable->text();
t->arguments = editor.ui->edtArgs->text();
t->input = editor.ui->edtInput->toPlainText();
t->workingDir = editor.ui->edtWorkingDir->text();
t->mimetypes = editor.ui->edtMimeType->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts);
t->saveMode = static_cast(editor.ui->cmbSave->currentIndex());
t->reload = editor.ui->chkReload->isChecked();
t->outputMode = static_cast(editor.ui->cmbOutput->currentIndex());
t->includeStderr = editor.ui->chkIncludeStderr->isChecked();
t->cmdname = editor.ui->edtCommand->text();
// if the icon or name name changed, renew the item
if (elementChanged) {
toolItem->setText(t->name);
toolItem->setIcon(t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon));
}
emit changed();
m_changed = true;
}
m_config->group("Editor").writeEntry("Size", editor.size());
m_config->sync();
}
void KateExternalToolsConfigWidget::slotMoveUp()
{
// move the current item in the listbox upwards if possible
auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
// auto toolItem = dynamic_cast(item);
if (!item)
return;
QModelIndex srcParent = item->parent() ? item->parent()->index() : m_toolsModel.invisibleRootItem()->index();
int srcRow = item->index().row();
QModelIndex dstParent = (item->index().row() > 0) ? srcParent : QModelIndex();
int dstRow = item->index().row() > 0 ? (item->index().row() - 1) : 0;
bool moved = m_toolsModel.moveRow(srcParent, srcRow, dstParent, dstRow);
// slotSelectionChanged();
emit changed();
m_changed = true;
}
void KateExternalToolsConfigWidget::slotMoveDown()
{
// move the current item in the listbox downwards if possible
auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
// auto toolItem = dynamic_cast(item);
if (!item)
return;
// int idx = lbTools->row(item);
// if (idx > lbTools->count() - 1)
// return;
QModelIndex srcParent = item->parent() ? item->parent()->index() : m_toolsModel.invisibleRootItem()->index();
int srcRow = item->index().row();
QModelIndex dstParent = srcParent;
int dstRow = item->index().row() + 1;
// slotSelectionChanged();
emit changed();
m_changed = true;
}
// END KateExternalToolsConfigWidget
// kate: space-indent on; indent-width 4; replace-tabs on;
diff --git a/addons/externaltools/kateexternaltoolsconfigwidget.h b/addons/externaltools/kateexternaltoolsconfigwidget.h
index c34b25825..44aa28d96 100644
--- a/addons/externaltools/kateexternaltoolsconfigwidget.h
+++ b/addons/externaltools/kateexternaltoolsconfigwidget.h
@@ -1,118 +1,119 @@
/* This file is part of the KDE project
*
* Copyright 2019 Dominik Haumann
*
* 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.
*/
#ifndef KTEXTEDITOR_EXTERNALTOOLS_CONFIGWIDGET_H
#define KTEXTEDITOR_EXTERNALTOOLS_CONFIGWIDGET_H
#include "ui_configwidget.h"
#include "ui_tooldialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class KActionCollection;
class KateExternalToolsPlugin;
class KateExternalTool;
/**
* The config widget.
* The config widget allows the user to view a list of services of the type
* "Kate/ExternalTool" and add, remove or edit them.
*/
class KateExternalToolsConfigWidget : public KTextEditor::ConfigPage, public Ui::ExternalToolsConfigWidget
{
Q_OBJECT
public:
KateExternalToolsConfigWidget(QWidget* parent, KateExternalToolsPlugin* plugin);
virtual ~KateExternalToolsConfigWidget();
QString name() const override;
QString fullName() const override;
QIcon icon() const override;
public Q_SLOTS:
void apply() override;
void reset() override;
void defaults() override { reset(); }
private Q_SLOTS:
void slotNew();
void slotEdit();
void slotRemove();
void slotMoveUp();
void slotMoveDown();
void slotSelectionChanged();
QStandardItem * addCategory(const QString & category);
+ void clearTools();
private:
QPixmap blankIcon();
QStringList m_removed;
class KConfig* m_config = nullptr;
bool m_changed = false;
KateExternalToolsPlugin* m_plugin;
QStandardItemModel m_toolsModel;
};
/**
* A Dialog to edit a single KateExternalTool object
*/
class KateExternalToolServiceEditor : public QDialog
{
Q_OBJECT
public:
explicit KateExternalToolServiceEditor(KateExternalTool* tool = nullptr, QWidget* parent = nullptr);
private Q_SLOTS:
/**
* Run when the OK button is clicked, to ensure critical values are provided.
*/
void slotOKClicked();
/**
* show a mimetype chooser dialog
*/
void showMTDlg();
public:
Ui::ToolDialog* ui;
private:
KateExternalTool* m_tool;
};
#endif // KTEXTEDITOR_EXTERNALTOOLS_CONFIGWIDGET_H
// kate: space-indent on; indent-width 4; replace-tabs on;