rewrite formtatter* and customkeys* to share their code

This commit is contained in:
Evgenii Alekseev 2017-07-12 03:28:03 +03:00
parent 7ce3e8b1cf
commit 9d0a1bd70c
21 changed files with 595 additions and 712 deletions

View File

@ -0,0 +1,190 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awabstractpairconfig.h"
#include "ui_awabstractpairconfig.h"
#include <KI18n/KLocalizedString>
#include <QPushButton>
#include "awabstractselector.h"
#include "awdebug.h"
AWAbstractPairConfig::AWAbstractPairConfig(QWidget *_parent,
const bool _hasEdit,
const QStringList &_keys)
: QDialog(_parent)
, ui(new Ui::AWAbstractPairConfig)
, m_hasEdit(_hasEdit)
, m_keys(_keys)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
// edit feature
if (m_hasEdit) {
m_editButton = ui->buttonBox->addButton(i18n("Edit"),
QDialogButtonBox::ActionRole);
connect(m_editButton, SIGNAL(clicked(bool)), this, SLOT(edit()));
}
}
AWAbstractPairConfig::~AWAbstractPairConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clearSelectors();
delete m_helper;
delete ui;
}
void AWAbstractPairConfig::showDialog()
{
// update dialog
updateDialog();
// exec dialog
return execDialog();
}
void AWAbstractPairConfig::setEditable(const bool _first, const bool _second)
{
qCDebug(LOG_AW) << "Set editable" << _first << _second;
m_editable = {_first, _second};
}
void AWAbstractPairConfig::edit()
{
m_helper->editPairs();
updateDialog();
}
void AWAbstractPairConfig::updateUi()
{
QPair<QString, QString> current
= static_cast<AWAbstractSelector *>(sender())->current();
int index
= m_selectors.indexOf(static_cast<AWAbstractSelector *>(sender()));
if ((current.first.isEmpty()) && (current.second.isEmpty())) {
// remove current selector if it is empty and does not last
if (sender() == m_selectors.last())
return;
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
// add new selector if something changed
if (sender() != m_selectors.last())
return;
auto keys = initKeys();
addSelector(keys.first, keys.second, QPair<QString, QString>());
}
}
void AWAbstractPairConfig::addSelector(const QStringList &_keys,
const QStringList &_values,
const QPair<QString, QString> &_current)
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values
<< "and current ones" << _current;
AWAbstractSelector *selector
= new AWAbstractSelector(ui->scrollAreaWidgetContents, m_editable);
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWAbstractPairConfig::clearSelectors()
{
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this,
SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
m_selectors.clear();
}
void AWAbstractPairConfig::execDialog()
{
int ret = exec();
QHash<QString, QString> data;
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
}
// save configuration if required
switch (ret) {
case 0:
break;
case 1:
default:
m_helper->writeItems(data);
m_helper->removeUnusedKeys(data.keys());
break;
}
}
QPair<QStringList, QStringList> AWAbstractPairConfig::initKeys() const
{
// we are adding empty string at the start
QStringList left = {""};
left.append(m_helper->leftKeys().isEmpty() ? m_keys : m_helper->leftKeys());
left.sort();
QStringList right = {""};
right.append(m_helper->rightKeys().isEmpty() ? m_keys
: m_helper->rightKeys());
right.sort();
return QPair<QStringList, QStringList>(left, right);
}
void AWAbstractPairConfig::updateDialog()
{
clearSelectors();
auto pairs = m_helper->pairs();
auto keys = initKeys();
for (auto &key : m_helper->keys())
addSelector(keys.first, keys.second,
QPair<QString, QString>(key, m_helper->pairs()[key]));
// empty one
addSelector(keys.first, keys.second, QPair<QString, QString>());
}

View File

@ -0,0 +1,75 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWABSTRACTPAIRCONFIG_H
#define AWABSTRACTPAIRCONFIG_H
#include <QDialog>
#include "awabstractpairhelper.h"
class AWAbstractSelector;
namespace Ui
{
class AWAbstractPairConfig;
}
class AWAbstractPairConfig : public QDialog
{
Q_OBJECT
public:
explicit AWAbstractPairConfig(QWidget *_parent = nullptr,
const bool _hasEdit = false,
const QStringList &_keys = QStringList());
virtual ~AWAbstractPairConfig();
template <class T> void initHelper()
{
if (m_helper)
delete m_helper;
m_helper = new T(this);
}
void showDialog();
// properties
void setEditable(const bool _first, const bool _second);
private slots:
void edit();
void updateUi();
private:
QPushButton *m_editButton = nullptr;
Ui::AWAbstractPairConfig *ui = nullptr;
AWAbstractPairHelper *m_helper = nullptr;
QList<AWAbstractSelector *> m_selectors;
// properties
QPair<bool, bool> m_editable = {false, false};
bool m_hasEdit = false;
QStringList m_keys;
// methods
void addSelector(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current);
void clearSelectors();
void execDialog();
QPair<QStringList, QStringList> initKeys() const;
void updateDialog();
};
#endif /* AWABSTRACTPAIRCONFIG_H */

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AWCustomKeysConfig</class>
<widget class="QDialog" name="AWCustomKeysConfig">
<class>AWAbstractPairConfig</class>
<widget class="QDialog" name="AWAbstractPairConfig">
<property name="geometry">
<rect>
<x>0</x>
@ -60,7 +60,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AWCustomKeysConfig</receiver>
<receiver>AWAbstractPairConfig</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -76,7 +76,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AWCustomKeysConfig</receiver>
<receiver>AWAbstractPairConfig</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

View File

@ -0,0 +1,135 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awabstractpairhelper.h"
#include <QSettings>
#include <QStandardPaths>
#include "awdebug.h"
AWAbstractPairHelper::AWAbstractPairHelper(const QString &_filePath,
const QString &_section)
: m_filePath(_filePath)
, m_section(_section)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
initItems();
}
AWAbstractPairHelper::~AWAbstractPairHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QStringList AWAbstractPairHelper::keys() const
{
return m_pairs.keys();
}
QHash<QString, QString> AWAbstractPairHelper::pairs() const
{
return m_pairs;
}
QStringList AWAbstractPairHelper::values() const
{
return m_pairs.values();
}
void AWAbstractPairHelper::initItems()
{
m_pairs.clear();
QStringList configs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, m_filePath);
for (auto &fileName : configs) {
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup(m_section);
QStringList keys = settings.childKeys();
for (auto &key : keys) {
QString value = settings.value(key).toString();
qCInfo(LOG_AW) << "Found key" << key << "for value" << value << "in"
<< settings.fileName();
if (value.isEmpty()) {
qCInfo(LOG_AW) << "Skip empty value for" << key;
continue;
}
m_pairs[key] = value;
}
settings.endGroup();
}
}
bool AWAbstractPairHelper::writeItems(
const QHash<QString, QString> &_configuration) const
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup(m_section);
for (auto &key : _configuration.keys())
settings.setValue(key, _configuration[key]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
bool AWAbstractPairHelper::removeUnusedKeys(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove keys" << _keys;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup(m_section);
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
}
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}

View File

@ -0,0 +1,52 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWABSTRACTPAIRHELPER_H
#define AWABSTRACTPAIRHELPER_H
#include <QHash>
class AWAbstractPairHelper
{
public:
explicit AWAbstractPairHelper(const QString &_filePath = "",
const QString &_section = "");
virtual ~AWAbstractPairHelper();
QStringList keys() const;
QHash<QString, QString> pairs() const;
QStringList values() const;
// read-write methods
virtual void initItems();
virtual bool
writeItems(const QHash<QString, QString> &_configuration) const;
virtual bool removeUnusedKeys(const QStringList &_keys) const;
// configuration related
virtual void editPairs() = 0;
virtual QStringList leftKeys() = 0;
virtual QStringList rightKeys() = 0;
private:
// properties
QHash<QString, QString> m_pairs;
QString m_filePath;
QString m_section;
};
#endif /* AWABSTRACTPAIRHELPER_H */

View File

@ -16,158 +16,23 @@
***************************************************************************/
#include "awcustomkeysconfig.h"
#include "ui_awcustomkeysconfig.h"
#include <KI18n/KLocalizedString>
#include <QPushButton>
#include "awabstractselector.h"
#include "awdebug.h"
#include "awcustomkeyshelper.h"
#include "awdebug.h"
AWCustomKeysConfig::AWCustomKeysConfig(QWidget *_parent, const QStringList &_keys)
: QDialog(_parent)
, ui(new Ui::AWCustomKeysConfig)
, m_keys(_keys)
AWCustomKeysConfig::AWCustomKeysConfig(QWidget *_parent,
const QStringList &_keys)
: AWAbstractPairConfig(_parent, false, _keys)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this);
init();
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
setEditable(true, false);
initHelper<AWCustomKeysHelper>();
}
AWCustomKeysConfig::~AWCustomKeysConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clearSelectors();
delete m_helper;
delete ui;
}
void AWCustomKeysConfig::showDialog()
{
// update dialog
updateDialog();
// exec dialog
return execDialog();
}
void AWCustomKeysConfig::updateUi()
{
QPair<QString, QString> current
= static_cast<AWAbstractSelector *>(sender())->current();
int index
= m_selectors.indexOf(static_cast<AWAbstractSelector *>(sender()));
if ((current.first.isEmpty()) && (current.second.isEmpty())) {
// remove current selector if it is empty and does not last
if (sender() == m_selectors.last())
return;
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
// add new selector if something changed
if (sender() != m_selectors.last())
return;
auto keys = initKeys();
addSelector(keys.first, keys.second, QPair<QString, QString>());
}
}
void AWCustomKeysConfig::addSelector(const QStringList &_keys,
const QStringList &_values,
const QPair<QString, QString> &_current)
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values
<< "and current ones" << _current;
AWAbstractSelector *selector
= new AWAbstractSelector(ui->scrollAreaWidgetContents, {true, false});
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWCustomKeysConfig::clearSelectors()
{
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this,
SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
m_selectors.clear();
}
void AWCustomKeysConfig::execDialog()
{
int ret = exec();
QHash<QString, QString> data;
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
}
// save configuration if required
switch (ret) {
case 0:
break;
case 1:
default:
m_helper->writeItems(data);
m_helper->removeUnusedKeys(data.keys());
break;
}
}
void AWCustomKeysConfig::init()
{
delete m_helper;
m_helper = new AWCustomKeysHelper(this);
}
QPair<QStringList, QStringList> AWCustomKeysConfig::initKeys() const
{
// we are adding empty string at the start
QStringList keys = QStringList() << "";
keys.append(m_keys);
keys.sort();
QStringList userKeys = QStringList() << "";
userKeys.append(m_helper->keys());
userKeys.sort();
return QPair<QStringList, QStringList>(userKeys, keys);
}
void AWCustomKeysConfig::updateDialog()
{
clearSelectors();
auto userKeys = m_helper->getUserKeys();
auto keys = initKeys();
for (auto &key : userKeys.keys())
addSelector(keys.first, keys.second,
QPair<QString, QString>(key, userKeys[key]));
// empty one
addSelector(keys.first, keys.second, QPair<QString, QString>());
}

View File

@ -19,17 +19,10 @@
#ifndef AWCUSTOMKEYSCONFIG_H
#define AWCUSTOMKEYSCONFIG_H
#include <QDialog>
#include "awabstractpairconfig.h"
class AWAbstractSelector;
class AWCustomKeysHelper;
namespace Ui
{
class AWCustomKeysConfig;
}
class AWCustomKeysConfig : public QDialog
class AWCustomKeysConfig : public AWAbstractPairConfig
{
Q_OBJECT
@ -37,25 +30,6 @@ public:
explicit AWCustomKeysConfig(QWidget *_parent = nullptr,
const QStringList &_keys = QStringList());
virtual ~AWCustomKeysConfig();
Q_INVOKABLE void showDialog();
private slots:
void updateUi();
private:
Ui::AWCustomKeysConfig *ui = nullptr;
AWCustomKeysHelper *m_helper = nullptr;
QList<AWAbstractSelector *> m_selectors;
// properties
QStringList m_keys;
// methods
void addSelector(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current);
void clearSelectors();
void execDialog();
void init();
QPair<QStringList, QStringList> initKeys() const;
void updateDialog();
};

View File

@ -18,19 +18,15 @@
#include "awcustomkeyshelper.h"
#include <QSet>
#include <QSettings>
#include <QStandardPaths>
#include "awdebug.h"
AWCustomKeysHelper::AWCustomKeysHelper(QObject *_parent)
: QObject(_parent)
, AWAbstractPairHelper("awesomewidgets/custom.ini", "Custom")
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_filePath = "awesomewidgets/custom.ini";
initItems();
}
@ -40,120 +36,43 @@ AWCustomKeysHelper::~AWCustomKeysHelper()
}
void AWCustomKeysHelper::initItems()
{
m_keys.clear();
QStringList configs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, m_filePath);
for (auto &fileName : configs) {
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup("Custom");
QStringList keys = settings.childKeys();
for (auto &key : keys) {
QString source = settings.value(key).toString();
qCInfo(LOG_AW) << "Found custom key" << key << "for source"
<< source << "in" << settings.fileName();
if (source.isEmpty()) {
qCInfo(LOG_AW) << "Skip empty source for" << key;
continue;
}
m_keys[key] = source;
}
settings.endGroup();
}
}
bool AWCustomKeysHelper::writeItems(
const QHash<QString, QString> &_configuration) const
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup("Custom");
for (auto &key : _configuration.keys())
settings.setValue(key, _configuration[key]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
bool AWCustomKeysHelper::removeUnusedKeys(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove keys" << _keys;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup("Custom");
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
}
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
QHash<QString, QString> AWCustomKeysHelper::getUserKeys() const
{
return m_keys;
}
QStringList AWCustomKeysHelper::keys() const
{
return m_keys.keys();
}
QString AWCustomKeysHelper::source(const QString &_key) const
{
qCDebug(LOG_AW) << "Get source by key" << _key;
return m_keys[_key];
return pairs()[_key];
}
QStringList AWCustomKeysHelper::sources() const
{
return QSet<QString>::fromList(m_keys.values()).toList();
return QSet<QString>::fromList(values()).toList();
}
QStringList AWCustomKeysHelper::refinedSources() const
{
auto allSources = QSet<QString>::fromList(m_keys.values());
auto allSources = QSet<QString>::fromList(pairs().values());
QSet<QString> output;
while (output != allSources) {
output.clear();
for (auto &src : allSources)
output.insert(m_keys.contains(src) ? source(src) : src);
output.insert(pairs().contains(src) ? source(src) : src);
allSources = output;
}
return output.toList();
}
QStringList AWCustomKeysHelper::leftKeys()
{
return keys();
}
QStringList AWCustomKeysHelper::rightKeys()
{
return QStringList();
}

View File

@ -22,29 +22,26 @@
#include <QHash>
#include <QObject>
#include "awabstractpairhelper.h"
class AWCustomKeysHelper : public QObject
class AWCustomKeysHelper : public QObject, public AWAbstractPairHelper
{
Q_OBJECT
public:
explicit AWCustomKeysHelper(QObject *_parent = nullptr);
virtual ~AWCustomKeysHelper();
// read-write methods
void initItems();
bool writeItems(const QHash<QString, QString> &_configuration) const;
bool removeUnusedKeys(const QStringList &_keys) const;
// get
QHash<QString, QString> getUserKeys() const;
QStringList keys() const;
QString source(const QString &_key) const;
QStringList sources() const;
QStringList refinedSources() const;
// configuration related
virtual void editPairs(){};
virtual QStringList leftKeys();
virtual QStringList rightKeys();
private:
// properties
QString m_filePath;
QHash<QString, QString> m_keys;
};

View File

@ -16,168 +16,22 @@
***************************************************************************/
#include "awformatterconfig.h"
#include "ui_awformatterconfig.h"
#include <KI18n/KLocalizedString>
#include <QPushButton>
#include "awabstractselector.h"
#include "awdebug.h"
#include "awformatterhelper.h"
AWFormatterConfig::AWFormatterConfig(QWidget *_parent, const QStringList &_keys)
: QDialog(_parent)
, ui(new Ui::AWFormatterConfig)
, m_keys(_keys)
: AWAbstractPairConfig(_parent, true, _keys)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this);
m_editButton
= ui->buttonBox->addButton(i18n("Edit"), QDialogButtonBox::ActionRole);
init();
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(m_editButton, SIGNAL(clicked(bool)), this, SLOT(editFormatters()));
setEditable(false, false);
initHelper<AWFormatterHelper>();
}
AWFormatterConfig::~AWFormatterConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clearSelectors();
delete m_helper;
delete ui;
}
void AWFormatterConfig::showDialog()
{
// update dialog
updateDialog();
// exec dialog
return execDialog();
}
void AWFormatterConfig::editFormatters()
{
m_helper->editItems();
updateDialog();
}
void AWFormatterConfig::updateUi()
{
QPair<QString, QString> current
= static_cast<AWAbstractSelector *>(sender())->current();
int index
= m_selectors.indexOf(static_cast<AWAbstractSelector *>(sender()));
if ((current.first.isEmpty()) && (current.second.isEmpty())) {
// remove current selector if it is empty and does not last
if (sender() == m_selectors.last())
return;
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
// add new selector if something changed
if (sender() != m_selectors.last())
return;
auto keys = initKeys();
addSelector(keys.first, keys.second, QPair<QString, QString>());
}
}
void AWFormatterConfig::addSelector(const QStringList &_keys,
const QStringList &_values,
const QPair<QString, QString> &_current)
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values
<< "and current ones" << _current;
AWAbstractSelector *selector
= new AWAbstractSelector(ui->scrollAreaWidgetContents);
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWFormatterConfig::clearSelectors()
{
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this,
SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
m_selectors.clear();
}
void AWFormatterConfig::execDialog()
{
int ret = exec();
QHash<QString, QString> data;
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
}
// save configuration if required
switch (ret) {
case 0:
break;
case 1:
default:
m_helper->writeItems(data);
m_helper->removeUnusedFormatters(data.keys());
break;
}
}
void AWFormatterConfig::init()
{
delete m_helper;
m_helper = new AWFormatterHelper(this);
}
QPair<QStringList, QStringList> AWFormatterConfig::initKeys() const
{
// we are adding empty string at the start
QStringList keys = QStringList() << "";
keys.append(m_keys);
keys.sort();
QStringList knownFormatters = QStringList() << "";
knownFormatters.append(m_helper->knownFormatters());
knownFormatters.sort();
return QPair<QStringList, QStringList>(keys, knownFormatters);
}
void AWFormatterConfig::updateDialog()
{
clearSelectors();
QHash<QString, QString> appliedFormatters = m_helper->getFormatters();
auto keys = initKeys();
for (auto &key : appliedFormatters.keys())
addSelector(keys.first, keys.second,
QPair<QString, QString>(key, appliedFormatters[key]));
// empty one
addSelector(keys.first, keys.second, QPair<QString, QString>());
}

View File

@ -19,17 +19,10 @@
#ifndef AWFORMATTERCONFIG_H
#define AWFORMATTERCONFIG_H
#include <QDialog>
#include "awabstractpairconfig.h"
class AWAbstractSelector;
class AWFormatterHelper;
namespace Ui
{
class AWFormatterConfig;
}
class AWFormatterConfig : public QDialog
class AWFormatterConfig : public AWAbstractPairConfig
{
Q_OBJECT
@ -37,27 +30,6 @@ public:
explicit AWFormatterConfig(QWidget *_parent = nullptr,
const QStringList &_keys = QStringList());
virtual ~AWFormatterConfig();
Q_INVOKABLE void showDialog();
private slots:
void editFormatters();
void updateUi();
private:
QPushButton *m_editButton = nullptr;
Ui::AWFormatterConfig *ui = nullptr;
AWFormatterHelper *m_helper = nullptr;
QList<AWAbstractSelector *> m_selectors;
// properties
QStringList m_keys;
// methods
void addSelector(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current);
void clearSelectors();
void execDialog();
void init();
QPair<QStringList, QStringList> initKeys() const;
void updateDialog();
};

View File

@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AWFormatterConfig</class>
<widget class="QDialog" name="AWFormatterConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>249</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AWFormatterConfig</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AWFormatterConfig</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -17,9 +17,9 @@
#include "awformatterconfigfactory.h"
#include "awcustomkeysconfig.h"
#include "awdebug.h"
#include "awformatterconfig.h"
#include "awcustomkeysconfig.h"
AWFormatterConfigFactory::AWFormatterConfigFactory(QObject *_parent)

View File

@ -35,10 +35,11 @@
AWFormatterHelper::AWFormatterHelper(QWidget *_parent)
: AbstractExtItemAggregator(_parent, "formatters")
, AWAbstractPairHelper("awesomewidgets/formatters/formatters.ini",
"Formatters")
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_filePath = "awesomewidgets/formatters/formatters.ini";
initItems();
}
@ -54,32 +55,21 @@ AWFormatterHelper::~AWFormatterHelper()
void AWFormatterHelper::initItems()
{
installDirectories();
initFormatters();
initKeys();
AWAbstractPairHelper::initItems();
// assign internal storage
m_formatters.clear();
for (auto &key : pairs().keys()) {
auto name = pairs()[key];
if (!m_formattersClasses.contains(name)) {
qCWarning(LOG_AW)
<< "Invalid formatter" << name << "found in" << key;
continue;
}
bool AWFormatterHelper::writeItems(
const QHash<QString, QString> &_configuration) const
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup("Formatters");
for (auto &key : _configuration.keys())
settings.setValue(key, _configuration[key]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
m_formatters[key] = m_formattersClasses[name];
}
}
@ -99,16 +89,6 @@ QStringList AWFormatterHelper::definedFormatters() const
}
QHash<QString, QString> AWFormatterHelper::getFormatters() const
{
QHash<QString, QString> map;
for (auto &tag : m_formatters.keys())
map[tag] = m_formatters[tag]->name();
return map;
}
QList<AbstractExtItem *> AWFormatterHelper::items() const
{
QList<AbstractExtItem *> converted;
@ -119,38 +99,24 @@ QList<AbstractExtItem *> AWFormatterHelper::items() const
}
QStringList AWFormatterHelper::knownFormatters() const
void AWFormatterHelper::editPairs()
{
return editItems();
}
QStringList AWFormatterHelper::leftKeys()
{
return QStringList();
}
QStringList AWFormatterHelper::rightKeys()
{
return m_formattersClasses.keys();
}
bool AWFormatterHelper::removeUnusedFormatters(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove formatters" << _keys;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup("Formatters");
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
}
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
void AWFormatterHelper::editItems()
{
repaintList();
@ -191,47 +157,52 @@ void AWFormatterHelper::initFormatters()
{
m_formattersClasses.clear();
for (int i = m_directories.count() - 1; i >= 0; i--) {
QStringList files
= QDir(m_directories.at(i)).entryList(QDir::Files, QDir::Name);
auto dirs = directories();
for (auto &dir : dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
for (auto &file : files) {
// check filename
if (!file.endsWith(".desktop"))
continue;
qCInfo(LOG_AW) << "Found file" << file << "in"
<< m_directories.at(i);
QString filePath
= QString("%1/%2").arg(m_directories.at(i)).arg(file);
auto metadata = readMetadata(filePath);
QString name = metadata.first;
if (m_formattersClasses.contains(name))
qCInfo(LOG_AW) << "Found file" << file << "in" << dir;
QString filePath = QString("%1/%2").arg(dir).arg(file);
// check if already exists
auto values = m_formattersClasses.values();
if (std::any_of(values.cbegin(), values.cend(),
[&filePath](const AWAbstractFormatter *item) {
return (item->fileName() == filePath);
}))
continue;
auto metadata = readMetadata(filePath);
switch (metadata.second) {
case AWAbstractFormatter::FormatterClass::DateTime:
m_formattersClasses[name]
m_formattersClasses[metadata.first]
= new AWDateTimeFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::Float:
m_formattersClasses[name]
m_formattersClasses[metadata.first]
= new AWFloatFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::List:
m_formattersClasses[name] = new AWListFormatter(this, filePath);
m_formattersClasses[metadata.first]
= new AWListFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::Script:
m_formattersClasses[name]
m_formattersClasses[metadata.first]
= new AWScriptFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::String:
m_formattersClasses[name]
m_formattersClasses[metadata.first]
= new AWStringFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::Json:
m_formattersClasses[name] = new AWJsonFormatter(this, filePath);
m_formattersClasses[metadata.first]
= new AWJsonFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::NoFormat:
m_formattersClasses[name] = new AWNoFormatter(this, filePath);
m_formattersClasses[metadata.first]
= new AWNoFormatter(this, filePath);
break;
}
}
@ -239,55 +210,6 @@ void AWFormatterHelper::initFormatters()
}
void AWFormatterHelper::initKeys()
{
m_formatters.clear();
QStringList configs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, m_filePath);
for (auto &fileName : configs) {
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup("Formatters");
QStringList keys = settings.childKeys();
for (auto &key : keys) {
QString name = settings.value(key).toString();
qCInfo(LOG_AW) << "Found formatter" << name << "for key" << key
<< "in" << settings.fileName();
if (name.isEmpty()) {
qCInfo(LOG_AW) << "Skip empty formatter for" << key;
continue;
}
if (!m_formattersClasses.contains(name)) {
qCWarning(LOG_AW)
<< "Invalid formatter" << name << "found in" << key;
continue;
}
m_formatters[key] = m_formattersClasses[name];
}
settings.endGroup();
}
}
void AWFormatterHelper::installDirectories()
{
// create directory at $HOME
QString localDir = QString("%1/awesomewidgets/formatters")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_AW) << "Created directory" << localDir;
m_directories = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, "awesomewidgets/formatters",
QStandardPaths::LocateDirectory);
}
QPair<QString, AWAbstractFormatter::FormatterClass>
AWFormatterHelper::readMetadata(const QString &_filePath) const
{
@ -306,13 +228,8 @@ AWFormatterHelper::readMetadata(const QString &_filePath) const
void AWFormatterHelper::doCreateItem()
{
QStringList selection = QStringList() << "NoFormat"
<< "DateTime"
<< "Float"
<< "List"
<< "Script"
<< "String"
<< "Json";
QStringList selection
= {"NoFormat", "DateTime", "Float", "List", "Script", "String", "Json"};
bool ok;
QString select = QInputDialog::getItem(
this, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok);

View File

@ -20,11 +20,12 @@
#define AWFORMATTERHELPER_H
#include "abstractextitemaggregator.h"
#include "awabstractformatter.h"
#include "awabstractpairhelper.h"
class AWFormatterHelper : public AbstractExtItemAggregator
class AWFormatterHelper : public AbstractExtItemAggregator,
public AWAbstractPairHelper
{
Q_OBJECT
@ -33,14 +34,14 @@ public:
virtual ~AWFormatterHelper();
// read-write methods
void initItems();
bool writeItems(const QHash<QString, QString> &_configuration) const;
// methods
QString convert(const QVariant &_value, const QString &_name) const;
QStringList definedFormatters() const;
QHash<QString, QString> getFormatters() const;
QList<AbstractExtItem *> items() const;
QStringList knownFormatters() const;
bool removeUnusedFormatters(const QStringList &_keys) const;
// configuration related
virtual void editPairs();
virtual QStringList leftKeys();
virtual QStringList rightKeys();
public slots:
void editItems();
@ -50,15 +51,11 @@ private:
AWAbstractFormatter::FormatterClass
defineFormatterClass(const QString &_stringType) const;
void initFormatters();
void initKeys();
void installDirectories();
QPair<QString, AWAbstractFormatter::FormatterClass>
readMetadata(const QString &_filePath) const;
// parent methods
void doCreateItem();
// properties
QStringList m_directories;
QString m_filePath;
QHash<QString, AWAbstractFormatter *> m_formatters;
QHash<QString, AWAbstractFormatter *> m_formattersClasses;
};

View File

@ -161,6 +161,9 @@ QStringList AWKeys::dictKeys(const bool _sorted, const QString &_regexp) const
// check if functions asked
if (_regexp == "functions")
return QString(STATIC_FUNCTIONS).split(',');
// check if user defined keys asked
if (_regexp == "userdefined")
return m_keyOperator->userKeys();
QStringList allKeys = m_keyOperator->dictKeys();
// sort if required

View File

@ -20,6 +20,7 @@
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QFileInfo>
#include <QInputDialog>
#include <QPushButton>
@ -33,6 +34,15 @@ AbstractExtItemAggregator::AbstractExtItemAggregator(QWidget *_parent,
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
// create directory at $HOME
QString localDir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(type());
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_LIB) << "Created directory" << localDir;
ui->setupUi(this);
copyButton
= ui->buttonBox->addButton(i18n("Copy"), QDialogButtonBox::ActionRole);
@ -182,6 +192,17 @@ QVariant AbstractExtItemAggregator::configArgs() const
}
QStringList AbstractExtItemAggregator::directories() const
{
auto dirs
= QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(type()),
QStandardPaths::LocateDirectory);
return dirs;
}
QString AbstractExtItemAggregator::type() const
{
return m_type;

View File

@ -73,6 +73,7 @@ public:
int uniqNumber() const;
// get methods
QVariant configArgs() const;
QStringList directories() const;
virtual QList<AbstractExtItem *> items() const = 0;
QString type() const;
// set methods

View File

@ -127,29 +127,23 @@ private:
QList<AbstractExtItem *> getItems()
{
// create directory at $HOME
QString localDir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(type());
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_LIB) << "Created directory" << localDir;
QStringList dirs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(type()),
QStandardPaths::LocateDirectory);
QStringList names;
QList<AbstractExtItem *> items;
auto dirs = directories();
for (auto &dir : dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
for (auto &file : files) {
if ((!file.endsWith(".desktop")) || (names.contains(file)))
// check filename
if (!file.endsWith(".desktop"))
continue;
qCInfo(LOG_LIB) << "Found file" << file << "in" << dir;
names.append(file);
QString filePath = QString("%1/%2").arg(dir).arg(file);
// check if already exists
if (std::any_of(items.cbegin(), items.cend(),
[&filePath](AbstractExtItem *item) {
return (item->fileName() == filePath);
}))
continue;
items.append(new T(this, filePath));
}
}

View File

@ -70,6 +70,10 @@ QtObject {
"label": i18n("Network"),
"regexp": "^(netdev|(down|up(?!time)).*)"
},
{
"label": i18n("Network request"),
"regexp": "^response.*"
},
{
"label": i18n("Music player"),
"regexp": "(^|d|s)(album|artist|duration|progress|title)"
@ -97,6 +101,10 @@ QtObject {
{
"label": i18n("Functions"),
"regexp": "functions"
},
{
"label": i18n("User defined"),
"regexp": "userdefined"
}
]
property variant dpTagRegexp: [

View File

@ -42,7 +42,8 @@ foreach (TEST_MODULE ${TEST_MODULES})
elseif (TEST_MODULE MATCHES "awkeycache")
set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awkeycache.cpp)
elseif (TEST_MODULE MATCHES "awkeys")
set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awactions.cpp
set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awabstractpairhelper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awactions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awcustomkeyshelper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awdataaggregator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awdataengineaggregator.cpp
@ -56,7 +57,8 @@ foreach (TEST_MODULE ${TEST_MODULES})
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awupdatehelper.cpp
${PROJECT_TRDPARTY_DIR}/fontdialog/fontdialog.cpp)
elseif (TEST_MODULE MATCHES "awpatternfunctions")
set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awformatterhelper.cpp
set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awabstractpairhelper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awformatterhelper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awkeysaggregator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awpatternfunctions.cpp)
elseif (TEST_MODULE MATCHES "awtelemetryhandler")