Commit 5cf2b5c2 authored by Ahmad Samir's avatar Ahmad Samir
Browse files

ExternalToolsPlugin: a config file per tool

The old config file was saved in ~/.local/share/application/externaltools,
and used for all the tools. Now the config file for each tool is saved in
~/.config/kate/externaltools/, and the plugin global config file is
~/.config/kate-externaltoolspluginrc.
parent 1042dffe
......@@ -30,19 +30,27 @@
#include <QClipboard>
#include <QGuiApplication>
static QString toolsConfigDir()
{
static const QString dir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/kate/externaltools/");
return dir;
}
static QVector<KateExternalTool> readDefaultTools()
{
QDir dir(QStringLiteral(":/kconfig/externaltools-config/"));
const QStringList entries = dir.entryList(QDir::NoDotAndDotDot | QDir::Files);
QVector<KateExternalTool> tools;
KConfig systemConfig(QStringLiteral("defaultexternaltoolsrc"));
KConfigGroup config(&systemConfig, "Global");
const int toolCount = config.readEntry("tools", 0);
for (int i = 0; i < toolCount; ++i) {
config = KConfigGroup(&systemConfig, QStringLiteral("Tool %1").arg(i));
KateExternalTool t;
t.load(config);
tools.push_back(t);
for (const auto &file : entries) {
KConfig config(dir.absoluteFilePath(file));
KConfigGroup cg = config.group("General");
KateExternalTool tool;
tool.load(cg);
tools.push_back(tool);
}
return tools;
}
......@@ -51,6 +59,11 @@ K_PLUGIN_FACTORY_WITH_JSON(KateExternalToolsFactory, "externaltoolsplugin.json",
KateExternalToolsPlugin::KateExternalToolsPlugin(QObject *parent, const QList<QVariant> &)
: KTextEditor::Plugin(parent)
{
m_config = KSharedConfig::openConfig(QStringLiteral("kate-externaltoolspluginrc"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation);
QDir().mkdir(toolsConfigDir());
migrateConfig();
// read built-in external tools from compiled-in resource file
m_defaultTools = readDefaultTools();
......@@ -63,6 +76,37 @@ KateExternalToolsPlugin::~KateExternalToolsPlugin()
clearTools();
}
void KateExternalToolsPlugin::migrateConfig()
{
const QString oldFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QStringLiteral("externaltools"));
if (!oldFile.isEmpty()) {
KConfig oldConf(oldFile);
KConfigGroup oldGroup(&oldConf, "Global");
const bool isFirstRun = oldGroup.readEntry("firststart", true);
m_config->group("Global").writeEntry("firststart", isFirstRun);
m_config->sync();
const int toolCount = oldGroup.readEntry("tools", 0);
for (int i = 0; i < toolCount; ++i) {
oldGroup = oldConf.group(QStringLiteral("Tool %1").arg(i));
const QString name = KateExternalTool::configFileName(oldGroup.readEntry("name"));
const QString newConfPath = toolsConfigDir() + name;
if (QFileInfo::exists(newConfPath)) { // Already migrated ?
continue;
}
KConfig newConfig(newConfPath);
KConfigGroup newGroup = newConfig.group("General");
oldGroup.copyTo(&newGroup, KConfigBase::Persistent);
newConfig.sync();
}
QFile::remove(oldFile);
}
}
QObject *KateExternalToolsPlugin::createView(KTextEditor::MainWindow *mainWindow)
{
KateExternalToolsPluginView *view = new KateExternalToolsPluginView(mainWindow, this);
......@@ -79,22 +123,61 @@ void KateExternalToolsPlugin::clearTools()
m_tools.clear();
}
void KateExternalToolsPlugin::reload()
void KateExternalToolsPlugin::addNewTool(KateExternalTool *tool)
{
clearTools();
m_tools.push_back(tool);
if (tool->hasexec && !tool->cmdname.isEmpty()) {
m_commands.push_back(tool->cmdname);
}
if (KAuthorized::authorizeAction(QStringLiteral("shell_access"))) {
m_command = new KateExternalToolsCommand(this);
}
}
KConfig _config(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
KConfigGroup config(&_config, "Global");
const int toolCount = config.readEntry("tools", 0);
const bool firstStart = config.readEntry("firststart", true);
void KateExternalToolsPlugin::removeTools(const std::vector<KateExternalTool *> &toRemove)
{
for (auto *tool : toRemove) {
if (!tool) {
continue;
}
QString configFile = KateExternalTool::configFileName(tool->name);
if (!configFile.isEmpty()) {
QFile::remove(toolsConfigDir() + configFile);
}
delete tool;
}
if (!firstStart || toolCount > 0) {
auto it = std::remove_if(m_tools.begin(), m_tools.end(), [&toRemove](KateExternalTool *tool) {
return std::find(toRemove.cbegin(), toRemove.cend(), tool) != toRemove.cend();
});
m_tools.erase(it, m_tools.end());
}
void KateExternalToolsPlugin::save(KateExternalTool *tool) const
{
const QString name = KateExternalTool::configFileName(tool->name);
KConfig config(toolsConfigDir() + name);
KConfigGroup cg = config.group("General");
tool->save(cg);
config.sync();
}
void KateExternalToolsPlugin::reload()
{
KConfigGroup group(m_config, "Global");
const bool firstStart = group.readEntry("firststart", true);
if (!firstStart) {
// read user config
for (int i = 0; i < toolCount; ++i) {
config = KConfigGroup(&_config, QStringLiteral("Tool %1").arg(i));
QDir dir(toolsConfigDir());
const QStringList entries = dir.entryList(QDir::NoDotAndDotDot | QDir::Files);
for (const auto &file : entries) {
KConfig config(dir.absoluteFilePath(file));
KConfigGroup cg = config.group("General");
auto t = new KateExternalTool();
t->load(config);
t->load(cg);
m_tools.push_back(t);
}
} else {
......@@ -105,7 +188,7 @@ void KateExternalToolsPlugin::reload()
}
// FIXME test for a command name first!
for (auto tool : m_tools) {
for (auto *tool : m_tools) {
if (tool->hasexec && (!tool->cmdname.isEmpty())) {
m_commands.push_back(tool->cmdname);
}
......
......@@ -10,6 +10,8 @@
#include <KTextEditor/Plugin>
#include <QVector>
#include <KSharedConfig>
namespace KTextEditor
{
class View;
......@@ -29,6 +31,15 @@ public:
explicit KateExternalToolsPlugin(QObject *parent = nullptr, const QList<QVariant> & = QList<QVariant>());
virtual ~KateExternalToolsPlugin();
/**
* Returns the global config object for the plugin (on Linux
* this is ~/.config/kateexternaltoolspluginrc).
*/
KSharedConfigPtr config()
{
return m_config;
}
/**
* Reimplemented to return the number of config pages, in this case 1.
*/
......@@ -50,7 +61,7 @@ public:
void clearTools();
/**
* Reloads the external tools from disk.
* Reloads the external tools configuration from disk.
*/
void reload();
......@@ -106,7 +117,23 @@ public:
*/
KateExternalToolsPluginView *viewForMainWindow(KTextEditor::MainWindow *mainWindow) const;
void addNewTool(KateExternalTool *tool);
/**
* Removes the tools in @p toRemove, this includes removing the relevant
* config file from disk.
*/
void removeTools(const std::vector<KateExternalTool *> &toRemove);
/**
* Saves the configuration of @p tool to that tool's config file.
*/
void save(KateExternalTool *tool) const;
private:
void migrateConfig();
KSharedConfigPtr m_config;
QVector<KateExternalTool> m_defaultTools;
QVector<KateExternalToolsPluginView *> m_views;
QVector<KateExternalTool *> m_tools;
......
......@@ -109,6 +109,20 @@ public:
* Returns the translated category if possible.
*/
QString translatedCategory() const;
/**
* Returns the config file name for this tool, created based on the tool "name", e.g.
* "Clang Format Full File" -> clang_format_full_file
* this will be the name of the config file in e.g. ~/.config/kate/externaltools/
*/
static QString configFileName(QString name)
{
name.replace(QLatin1Char(' '), QLatin1Char('_'));
// '(' and ')' are problematic as file names in the .qrc file
name.replace(QLatin1Char('('), QLatin1Char('_'));
name.replace(QLatin1Char(')'), QLatin1Char('_'));
return name.toLower();
}
};
/**
......
......@@ -260,8 +260,6 @@ KateExternalToolsConfigWidget::KateExternalToolsConfigWidget(QWidget *parent, Ka
});
connect(lbTools, &QTreeView::doubleClicked, this, &KateExternalToolsConfigWidget::slotEdit);
m_config = new KConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
// reset triggers a reload of the existing tools
reset();
slotSelectionChanged();
......@@ -275,8 +273,6 @@ KateExternalToolsConfigWidget::KateExternalToolsConfigWidget(QWidget *parent, Ka
KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
{
clearTools();
delete m_config;
}
QString KateExternalToolsConfigWidget::name() const
......@@ -335,16 +331,17 @@ void KateExternalToolsConfigWidget::apply()
}
}
KSharedConfigPtr config = m_plugin->config();
// write tool configuration to disk
m_config->group("Global").writeEntry("firststart", false);
m_config->group("Global").writeEntry("tools", static_cast<int>(tools.size()));
config->group("Global").writeEntry("firststart", false);
config->group("Global").writeEntry("tools", static_cast<int>(tools.size()));
for (size_t i = 0; i < tools.size(); i++) {
const QString section = QStringLiteral("Tool ") + QString::number(i);
KConfigGroup cg(m_config, section);
KConfigGroup cg(config, section);
tools[i]->save(cg);
}
m_config->sync();
config->sync();
m_plugin->reload();
}
......@@ -362,9 +359,12 @@ void KateExternalToolsConfigWidget::slotSelectionChanged()
bool KateExternalToolsConfigWidget::editTool(KateExternalTool *tool)
{
bool changed = false;
KSharedConfigPtr config = m_plugin->config();
KateExternalToolServiceEditor editor(tool, m_plugin, this);
editor.resize(m_config->group("Editor").readEntry("Size", QSize()));
KConfigGroup editorGroup = config->group("Editor");
editor.resize(editorGroup.readEntry("Size", QSize()));
if (editor.exec() == QDialog::Accepted) {
tool->name = editor.ui.edtName->text().trimmed();
tool->icon = editor.ui.btnIcon->icon();
......@@ -387,11 +387,12 @@ bool KateExternalToolsConfigWidget::editTool(KateExternalTool *tool)
makeActionNameUnique(tool, tools);
makeEditorCommandUnique(tool, tools);
m_plugin->save(tool);
changed = true;
}
m_config->group("Editor").writeEntry("Size", editor.size());
m_config->sync();
editorGroup.writeEntry("Size", editor.size());
config->sync();
return changed;
}
......@@ -447,6 +448,8 @@ void KateExternalToolsConfigWidget::addNewTool(KateExternalTool *tool)
category->appendRow(item);
lbTools->setCurrentIndex(item->index());
m_plugin->addNewTool(tool);
Q_EMIT changed();
m_changed = true;
}
......
......@@ -79,7 +79,6 @@ private Q_SLOTS:
void clearTools();
private:
KConfig *m_config = nullptr;
bool m_changed = false;
KateExternalToolsPlugin *m_plugin;
QStandardItemModel m_toolsModel;
......
......@@ -100,10 +100,10 @@ void KateExternalToolsMenuAction::reload()
connect(cfgAction, &QAction::triggered, this, &KateExternalToolsMenuAction::showConfigPage, Qt::QueuedConnection);
// load shortcuts
KSharedConfig::Ptr pConfig = KSharedConfig::openConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
KConfigGroup config(pConfig, "Global");
config = KConfigGroup(pConfig, "Shortcuts");
m_actionCollection->readSettings(&config);
KSharedConfigPtr pConfig = m_plugin->config();
KConfigGroup group(pConfig, "Global");
group = KConfigGroup(pConfig, "Shortcuts");
m_actionCollection->readSettings(&group);
slotViewChanged(m_mainwindow->activeView());
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment