diff --git a/addons/externaltools/configwidget.ui b/addons/externaltools/configwidget.ui
index a9d065417..4b21bd833 100644
--- a/addons/externaltools/configwidget.ui
+++ b/addons/externaltools/configwidget.ui
@@ -1,118 +1,118 @@
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.
diff --git a/addons/externaltools/kateexternaltoolsconfigwidget.cpp b/addons/externaltools/kateexternaltoolsconfigwidget.cpp
index 32223562f..5b75ba5b7 100644
--- a/addons/externaltools/kateexternaltoolsconfigwidget.cpp
+++ b/addons/externaltools/kateexternaltoolsconfigwidget.cpp
@@ -1,374 +1,381 @@
/* 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
#include
#include
// BEGIN ToolItem
/**
- * This is a QListBoxItem, that has a KateExternalTool. The text is the Name
- * of the tool.
+ * This is a QStandardItem, that has a KateExternalTool.
+ * The text is the Name of the tool.
*/
-class ToolItem : public QListWidgetItem
+class ToolItem : public QStandardItem
{
public:
- ToolItem(QListWidget* lb, const QPixmap& icon, KateExternalTool* tool)
- : QListWidgetItem(icon, tool->name, lb)
- , tool(tool)
+ ToolItem(const QPixmap& icon, KateExternalTool* tool)
+ : QStandardItem(icon, tool->name)
{
+ setData(QVariant::fromValue(tool));
}
- ~ToolItem() {}
-
- KateExternalTool* tool;
+ KateExternalTool * tool() {
+ return qvariant_cast(data());
+ }
};
// END ToolItem
// BEGIN KateExternalToolServiceEditor
KateExternalToolServiceEditor::KateExternalToolServiceEditor(KateExternalTool* tool, QWidget* parent)
: QDialog(parent)
, 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);
if (tool) {
ui->edtName->setText(tool->name);
if (!tool->icon.isEmpty())
ui->btnIcon->setIcon(tool->icon);
ui->edtExecutable->setText(tool->executable);
ui->edtArgs->setText(tool->arguments);
ui->edtInput->setText(tool->input);
ui->edtCommand->setText(tool->cmdname);
ui->edtWorkingDir->setText(tool->workingDir);
ui->edtMimeType->setText(tool->mimetypes.join(QStringLiteral("; ")));
ui->cmbSave->setCurrentIndex(static_cast(tool->saveMode));
ui->chkIncludeStderr->setChecked(tool->includeStderr);
}
}
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, &QListWidget::itemSelectionChanged, this, &KateExternalToolsConfigWidget::slotSelectionChanged);
- connect(lbTools, &QListWidget::itemDoubleClicked, this, &KateExternalToolsConfigWidget::slotEdit);
+// 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();
slotSelectionChanged();
}
KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
{
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();
}
void KateExternalToolsConfigWidget::reset()
{
- // m_tools.clear();
- lbTools->clear();
-
- // load the files from a KConfig
- const QStringList tools = m_config->group("Global").readEntry("tools", QStringList());
-
- for (int i = 0; i < tools.size(); ++i) {
- const QString& toolSection = tools[i];
- KConfigGroup cg(m_config, toolSection);
- KateExternalTool* t = new KateExternalTool();
- t->load(cg);
-
- 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;
+ // clear list
+ m_toolsModel.clear();
+
+ // 2 steps: 1st step: create categories
+ 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);
+ qDebug() << "HANEDLED" << clone->name;
}
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;
QStringList tools;
- for (int i = 0; i < lbTools->count(); i++) {
- const QString toolSection = QStringLiteral("Tool ") + QString::number(i);
- tools << toolSection;
-
- KConfigGroup cg(m_config, toolSection);
- KateExternalTool* t = static_cast(lbTools->item(i))->tool;
- t->save(cg);
- }
+// for (int i = 0; i < lbTools->count(); i++) {
+// const QString toolSection = QStringLiteral("Tool ") + QString::number(i);
+// tools << toolSection;
+//
+// KConfigGroup cg(m_config, toolSection);
+// KateExternalTool* t = static_cast(lbTools->item(i))->tool;
+// t->save(cg);
+// }
m_config->group("Global").writeEntry("tools", tools);
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);
+// 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::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() == QDialog::Accepted) {
KateExternalTool* t = new KateExternalTool();
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->includeStderr = editor.ui->chkIncludeStderr->isChecked();
// This is sticky, it does not change again, so that shortcuts sticks
// TODO check for dups
- t->actionName = QStringLiteral("externaltool_") + QString(t->name).remove(QRegExp(QStringLiteral("\\W+")));
+ t->actionName = QStringLiteral("externaltool_") + QString(t->name).remove(QRegularExpression(QStringLiteral("\\W+")));
- new ToolItem(lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t);
+ 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;
}
}
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 (lbTools->currentRow() > -1) {
- ToolItem* i = dynamic_cast(lbTools->currentItem());
- if (i)
- m_removed << i->tool->actionName;
+ if (toolItem) {
+ m_removed << toolItem->tool()->actionName;
- delete lbTools->takeItem(lbTools->currentRow());
+ toolItem->parent()->removeRow(toolItem->index().row());
+ delete toolItem;;
emit changed();
m_changed = true;
}
}
void KateExternalToolsConfigWidget::slotEdit()
{
- if (!dynamic_cast(lbTools->currentItem()))
+ auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
+ auto toolItem = dynamic_cast(item);
+ if (!toolItem)
return;
// show the item in an editor
- KateExternalTool* t = static_cast(lbTools->currentItem())->tool;
+ KateExternalTool* t = toolItem->tool();
KateExternalToolServiceEditor editor(t, this);
editor.resize(m_config->group("Editor").readEntry("Size", QSize()));
if (editor.exec() /*== KDialog::Ok*/) {
- bool elementChanged = ((editor.ui->btnIcon->icon() != t->icon) || (editor.ui->edtName->text() != t->name));
+ 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->cmdname = editor.ui->edtCommand->text();
t->workingDir = editor.ui->edtWorkingDir->text();
- t->mimetypes
- = editor.ui->edtMimeType->text().split(QRegExp(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts);
+ t->mimetypes = editor.ui->edtMimeType->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts);
t->saveMode = static_cast(editor.ui->cmbSave->currentIndex());
t->includeStderr = editor.ui->chkIncludeStderr->isChecked();
- // if the icon has changed or name changed, I have to renew the listbox item :S
+ // if the icon or name name changed, renew the item
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));
+ 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
- QListWidgetItem* item = lbTools->currentItem();
+ auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
+// auto toolItem = dynamic_cast(item);
if (!item)
return;
- int idx = lbTools->row(item);
+ 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;
- 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));
- }
+ bool moved = m_toolsModel.moveRow(srcParent, srcRow, dstParent, dstRow);
+ qDebug() << "Moving up succesful?" << moved;
- lbTools->setCurrentRow(idx - 1);
- slotSelectionChanged();
+// slotSelectionChanged();
emit changed();
m_changed = true;
}
void KateExternalToolsConfigWidget::slotMoveDown()
{
// move the current item in the listbox downwards if possible
- QListWidgetItem* item = lbTools->currentItem();
+ auto item = m_toolsModel.itemFromIndex(lbTools->currentIndex());
+// auto toolItem = dynamic_cast(item);
if (!item)
return;
- int idx = lbTools->row(item);
+// int idx = lbTools->row(item);
+// if (idx > lbTools->count() - 1)
+// return;
- 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;
- 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));
- }
-
- lbTools->setCurrentRow(idx + 1);
- slotSelectionChanged();
+// 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 42e0ca9dd..04520b335 100644
--- a/addons/externaltools/kateexternaltoolsconfigwidget.h
+++ b/addons/externaltools/kateexternaltoolsconfigwidget.h
@@ -1,114 +1,118 @@
/* 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(); } // double sigh
+ void defaults() override { reset(); }
private Q_SLOTS:
void slotNew();
void slotEdit();
void slotRemove();
void slotMoveUp();
void slotMoveDown();
void slotSelectionChanged();
+ QStandardItem * addCategory(const QString & category);
+
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* tool;
};
#endif // KTEXTEDITOR_EXTERNALTOOLS_CONFIGWIDGET_H
// kate: space-indent on; indent-width 4; replace-tabs on;