Vergelijk commits

...

5 Commits

Auteur SHA1 Bericht Datum
5076f044a6 Update README.md to document inheritance
Closes #4.
2020-09-06 21:45:43 +02:00
560e15d48d implement inheritance keyword for .qsrun entries 2020-09-06 21:37:15 +02:00
45d7b930f8 Refactoring to use new entryprovider and settingsprovider classes 2020-09-06 19:43:17 +02:00
2824f84f9f Introduce Settingsprovider to read settings
Previously, it was in the configprovider.cpp.

Now, it has been split to this file
2020-09-06 19:41:59 +02:00
f03e247bd8 merge configreader/configprovider into entryprovider
settings-related methods that don't have any relation
to entries will be moved to a seperate file
settingsprovider
2020-09-06 19:40:46 +02:00
13 gewijzigde bestanden met toevoegingen van 225 en 174 verwijderingen

Bestand weergeven

@ -62,6 +62,18 @@ col 0
key I key I
``` ```
Example with inheritance: qsrun will search for "vlc.desktop" inside the paths defined in sysAppsPaths:
```
inherit vlc.desktop
row 3
col 1
```
Therefore, there is no need to explicitly the entry a name or icon etc. However, values given here will overwrite the inherited values.
"key" means a shortcut key, you can launch those by pressing Ctrl + "key", so in "key" means a shortcut key, you can launch those by pressing Ctrl + "key", so in
the example above: CTRL + I. the example above: CTRL + I.

Bestand weergeven

@ -1,59 +0,0 @@
/*
* Copyright (c) 2018-2019 Albert S. <mail at quitesimple dot org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <exception>
#include <QFile>
#include <QDir>
#include <QString>
#include <QStringList>
#include <QIcon>
#include <QKeySequence>
class EntryConfig
{
public:
QString key;
QString name;
QString command;
QStringList arguments;
QIcon icon;
int row=0;
int col=0;
};
class ConfigReader
{
private:
QStringList configPaths;
EntryConfig readFromFile(const QString &path);
EntryConfig readFromDesktopFile(const QString &path);
QStringList desktopIgnoreArgs;
public:
ConfigReader(QStringList paths);
QVector<EntryConfig> readConfig();
};
class ConfigFormatException : public std::runtime_error
{
public:
ConfigFormatException() : std::runtime_error("Error in configuration file, misformated line?") {};
ConfigFormatException(const std::string &str) : std::runtime_error(str) {};
};
#endif

Bestand weergeven

@ -1,25 +0,0 @@
#include "configprovider.h"
ConfigProvider::ConfigProvider(QString configDirPath, QSettings &settings)
{
this->settings = &settings;
this->configDirPath = configDirPath;
}
QVector<EntryConfig> ConfigProvider::getUserEntries()
{
ConfigReader reader({this->configDirPath});
return reader.readConfig();
}
QVector<EntryConfig> ConfigProvider::getSystemEntries()
{
QStringList systemApplicationsPaths = settings->value("sysAppsPaths", "/usr/share/applications/").toStringList();
ConfigReader systemConfigReader(systemApplicationsPaths);
return systemConfigReader.readConfig();
}
bool ConfigProvider::singleInstanceMode()
{
return settings->value("singleInstance", true).toBool();
}

Bestand weergeven

@ -1,18 +0,0 @@
#ifndef CONFIGPROVIDER_H
#define CONFIGPROVIDER_H
#include <QSettings>
#include "config.h"
class ConfigProvider
{
private:
QSettings *settings;
QString configDirPath;
public:
ConfigProvider(QString configDirPath, QSettings &settings);
QVector<EntryConfig> getUserEntries();
QVector<EntryConfig> getSystemEntries();
bool singleInstanceMode();
};
#endif // CONFIGPROVIDER_H

Bestand weergeven

@ -1,48 +1,35 @@
/* #include "entryprovider.h"
* Copyright (c) 2018-2020 Albert S. <mail at quitesimple dot org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <QDirIterator>
#include <QDebug> #include <QDebug>
#include <QDirIterator>
#include <QTextStream> #include <QTextStream>
EntryProvider::EntryProvider(QStringList userEntriesDirsPaths, QStringList systemEntriesDirsPaths)
ConfigReader::ConfigReader(QStringList paths)
{ {
this->configPaths = paths; this->userEntriesDirsPaths = userEntriesDirsPaths;
desktopIgnoreArgs << "%F" << "%f" << "%U" << "%u"; this->systemEntriesDirsPaths = systemEntriesDirsPaths;
_desktopIgnoreArgs << "%F"
<< "%f"
<< "%U"
<< "%u";
} }
EntryConfig EntryProvider::readFromDesktopFile(const QString &path)
EntryConfig ConfigReader::readFromDesktopFile(const QString &path)
{ {
EntryConfig result; EntryConfig result;
QFile file(path); QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{ {
//TODO: better exception class // TODO: better exception class
throw new std::runtime_error("Failed to open file"); throw new std::runtime_error("Failed to open file");
} }
QTextStream stream(&file); QTextStream stream(&file);
//There should be nothing preceding this group in the desktop entry file but possibly one or more comments. // There should be nothing preceding this group in the desktop entry file but possibly one or more comments.
//https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s03.html#group-header // https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s03.html#group-header
QString firstLine; QString firstLine;
do do
{ {
firstLine = stream.readLine().trimmed(); firstLine = stream.readLine().trimmed();
} while(!stream.atEnd() && ( firstLine.isEmpty() || firstLine[0] == '#') ); } while(!stream.atEnd() && (firstLine.isEmpty() || firstLine[0] == '#'));
if(firstLine != "[Desktop Entry]") if(firstLine != "[Desktop Entry]")
{ {
@ -52,13 +39,13 @@ EntryConfig ConfigReader::readFromDesktopFile(const QString &path)
while(!stream.atEnd()) while(!stream.atEnd())
{ {
QString line = stream.readLine(); QString line = stream.readLine();
//new group, so we are finished with [Desktop Entry] // new group, so we are finished with [Desktop Entry]
if(line.startsWith("[") && line.endsWith("]")) if(line.startsWith("[") && line.endsWith("]"))
{ {
return result; return result;
} }
QString key = line.section('=',0,0).toLower(); QString key = line.section('=', 0, 0).toLower();
QString args = line.section('=', 1); QString args = line.section('=', 1);
if(key == "name") if(key == "name")
{ {
@ -81,7 +68,7 @@ EntryConfig ConfigReader::readFromDesktopFile(const QString &path)
{ {
for(QString &arg : arguments) for(QString &arg : arguments)
{ {
if(!desktopIgnoreArgs.contains(arg)) if(!_desktopIgnoreArgs.contains(arg))
{ {
result.arguments.append(arg); result.arguments.append(arg);
} }
@ -93,13 +80,14 @@ EntryConfig ConfigReader::readFromDesktopFile(const QString &path)
} }
/* qsrun own's config file */ /* qsrun own's config file */
EntryConfig ConfigReader::readFromFile(const QString &path) EntryConfig EntryProvider::readFromFile(const QString &path)
{ {
EntryConfig result; EntryConfig result;
EntryConfig inheritedConfig;
QFile file(path); QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{ {
//TODO: better exception class // TODO: better exception class
throw new std::runtime_error("Failed to open file"); throw new std::runtime_error("Failed to open file");
} }
QTextStream stream(&file); QTextStream stream(&file);
@ -165,18 +153,45 @@ EntryConfig ConfigReader::readFromFile(const QString &path)
} }
if(key == "key") if(key == "key")
{ {
//QKeySequence sequence(splitted[1]); // QKeySequence sequence(splitted[1]);
//result.keySequence = sequence; // result.keySequence = sequence;
result.key = splitted[1].toLower(); result.key = splitted[1].toLower();
} }
if(key == "inherit")
{
inheritedConfig = readFromDesktopFile(resolveEntryPath(splitted[1]));
} }
return result; }
return result.update(inheritedConfig);
} }
QVector<EntryConfig> ConfigReader::readConfig() QString EntryProvider::resolveEntryPath(QString path)
{
if(path.trimmed().isEmpty())
{
return {};
}
if(path[0] == '/')
{
return path;
}
QStringList paths = this->userEntriesDirsPaths + this->systemEntriesDirsPaths;
for(QString &configPath : paths)
{
QDir dir(configPath);
QString desktopFilePath = dir.absoluteFilePath(path);
if(QFileInfo::exists(desktopFilePath))
{
return desktopFilePath;
}
}
return {};
}
QVector<EntryConfig> EntryProvider::readConfig(QStringList paths)
{ {
QVector<EntryConfig> result; QVector<EntryConfig> result;
for(QString &configPath : configPaths) for(QString &configPath : paths)
{ {
QDirIterator it(configPath, QDirIterator::Subdirectories); QDirIterator it(configPath, QDirIterator::Subdirectories);
while(it.hasNext()) while(it.hasNext())
@ -189,7 +204,6 @@ QVector<EntryConfig> ConfigReader::readConfig()
if(suffix == "desktop") if(suffix == "desktop")
{ {
result.append(readFromDesktopFile(path)); result.append(readFromDesktopFile(path));
} }
if(suffix == "qsrun") if(suffix == "qsrun")
{ {
@ -197,8 +211,39 @@ QVector<EntryConfig> ConfigReader::readConfig()
} }
} }
} }
} }
return result; return result;
} }
QVector<EntryConfig> EntryProvider::getUserEntries()
{
return readConfig(this->userEntriesDirsPaths);
}
QVector<EntryConfig> EntryProvider::getSystemEntries()
{
return readConfig(this->systemEntriesDirsPaths);
}
template <class T> void assignIfDestDefault(T &dest, const T &source)
{
if(dest == T())
{
dest = source;
}
}
EntryConfig &EntryConfig::update(const EntryConfig &o)
{
assignIfDestDefault(this->arguments, o.arguments);
assignIfDestDefault(this->col, o.col);
assignIfDestDefault(this->command, o.command);
if(this->icon.isNull())
{
this->icon = o.icon;
}
assignIfDestDefault(this->key, o.key);
assignIfDestDefault(this->name, o.name);
assignIfDestDefault(this->row, o.row);
return *this;
}

48
entryprovider.h Normal file
Bestand weergeven

@ -0,0 +1,48 @@
#ifndef ENTRYPROVIDER_H
#define ENTRYPROVIDER_H
#include <QIcon>
#include <QSettings>
class ConfigFormatException : public std::runtime_error
{
public:
ConfigFormatException() : std::runtime_error("Error in configuration file, misformated line?")
{
}
ConfigFormatException(const std::string &str) : std::runtime_error(str)
{
}
};
class EntryConfig
{
public:
QString key;
QString name;
QString command;
QStringList arguments;
QIcon icon;
int row = 0;
int col = 0;
EntryConfig &update(const EntryConfig &o);
};
class EntryProvider
{
protected:
QStringList _desktopIgnoreArgs;
QStringList userEntriesDirsPaths;
QStringList systemEntriesDirsPaths;
EntryConfig readFromFile(const QString &path);
EntryConfig readFromDesktopFile(const QString &path);
QVector<EntryConfig> readConfig(QStringList paths);
QString resolveEntryPath(QString path);
public:
EntryProvider(QStringList userEntriesDirsPaths, QStringList systemEntriesDirsPaths);
QVector<EntryConfig> getUserEntries();
QVector<EntryConfig> getSystemEntries();
};
#endif // ENTRYPROVIDER_H

Bestand weergeven

@ -18,7 +18,7 @@
#include <QWidget> #include <QWidget>
#include <QPushButton> #include <QPushButton>
#include "config.h" #include "entryprovider.h"
class EntryPushButton : public QPushButton class EntryPushButton : public QPushButton
{ {
Q_OBJECT Q_OBJECT
@ -44,8 +44,8 @@ public:
void setRow(int row); void setRow(int row);
void setCol(int col); void setCol(int col);
void setShortcutKey(QString key); void setShortcutKey(QString key);
}; };
#endif // ENTRYPUSHBUTTON_H #endif // ENTRYPUSHBUTTON_H

Bestand weergeven

@ -19,13 +19,12 @@
#include <QtConcurrent/QtConcurrentRun> #include <QtConcurrent/QtConcurrentRun>
#include <QSettings> #include <QSettings>
#include <QLocalSocket> #include <QLocalSocket>
#include "configprovider.h" #include <QDir>
#include "settingsprovider.h"
#include "entryprovider.h"
#include "window.h" #include "window.h"
#include "singleinstanceserver.h" #include "singleinstanceserver.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
@ -58,7 +57,8 @@ int main(int argc, char *argv[])
QSettings settings(configDirectoryPath + "qsrun.config", QSettings::NativeFormat); QSettings settings(configDirectoryPath + "qsrun.config", QSettings::NativeFormat);
ConfigProvider configProvider(configDirectoryPath, settings); SettingsProvider settingsProvider { settings };
EntryProvider entryProvider(settingsProvider.userEntriesPaths(), settingsProvider.systemApplicationsEntriesPaths());
//TODO if setting single instance mode //TODO if setting single instance mode
QLocalSocket localSocket; QLocalSocket localSocket;
localSocket.connectToServer("/tmp/qsrun.socket"); localSocket.connectToServer("/tmp/qsrun.socket");
@ -78,7 +78,7 @@ int main(int argc, char *argv[])
{ {
qDebug() << "Failed to listen on socket!"; qDebug() << "Failed to listen on socket!";
} }
Window *w = new Window { configProvider }; Window *w = new Window { entryProvider, settingsProvider };
QObject::connect(&server, &SingleInstanceServer::receivedMaximizationRequest, [&w]{ QObject::connect(&server, &SingleInstanceServer::receivedMaximizationRequest, [&w]{
if(w != nullptr) if(w != nullptr)
{ {

Bestand weergeven

@ -7,19 +7,21 @@ TARGET = qsrun
INCLUDEPATH += . INCLUDEPATH += .
# Input # Input
HEADERS += config.h window.h \ HEADERS += calculationengine.h \
entryprovider.h \
entrypushbutton.h \ entrypushbutton.h \
calculationengine.h \ settingsprovider.h \
singleinstanceserver.h \ singleinstanceserver.h \
configprovider.h window.h
SOURCES += config.cpp main.cpp window.cpp \ SOURCES += calculationengine.cpp \
entryprovider.cpp \
entrypushbutton.cpp \ entrypushbutton.cpp \
calculationengine.cpp \ main.cpp \
settingsprovider.cpp \
singleinstanceserver.cpp \ singleinstanceserver.cpp \
configprovider.cpp window.cpp
QT += widgets sql network QT += widgets sql network
QT_CONFIG -= no-pkg-config QT_CONFIG -= no-pkg-config
LIBS += -lcln LIBS += -lcln
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
PKGCONFIG += libqalculate PKGCONFIG += libqalculate

27
settingsprovider.cpp Normal file
Bestand weergeven

@ -0,0 +1,27 @@
#include "settingsprovider.h"
#include <QFileInfo>
#include <QDir>
SettingsProvider::SettingsProvider(QSettings &settings)
{
this->settings = &settings;
}
QStringList SettingsProvider::userEntriesPaths() const
{
//TODO: make it configurable, but we stick with this for now.
QFileInfo fi(this->settings->fileName());
return { fi.absoluteDir().absolutePath() };
}
QStringList SettingsProvider::systemApplicationsEntriesPaths() const
{
return settings->value("sysAppsPaths", "/usr/share/applications/").toStringList();
}
bool SettingsProvider::singleInstanceMode() const
{
return settings->value("singleInstance", true).toBool();
}

18
settingsprovider.h Normal file
Bestand weergeven

@ -0,0 +1,18 @@
#ifndef SETTINGSPROVIDER_H
#define SETTINGSPROVIDER_H
#include <stdexcept>
#include <QSettings>
class SettingsProvider
{
private:
QSettings *settings;
public:
SettingsProvider(QSettings &settings);
virtual QStringList userEntriesPaths() const;
virtual QStringList systemApplicationsEntriesPaths() const;
virtual bool singleInstanceMode() const;
};
#endif // SETTINGSPROVIDER_H

Bestand weergeven

@ -28,10 +28,11 @@
#include <QClipboard> #include <QClipboard>
#include <QScrollArea> #include <QScrollArea>
#include "window.h" #include "window.h"
#include "configprovider.h" #include "entryprovider.h"
Window::Window(ConfigProvider &configProvider) Window::Window(EntryProvider &entryProvider, SettingsProvider &configProvider)
{ {
this->configProvider = &configProvider; this->entryProvider = &entryProvider;
this->settingsProvider = &configProvider;
createGui(); createGui();
initFromConfig(); initFromConfig();
this->lineEdit->installEventFilter(this); this->lineEdit->installEventFilter(this);
@ -55,8 +56,8 @@ void Window::initFromConfig()
{ {
try try
{ {
this->userEntryButtons = generateEntryButtons(configProvider->getUserEntries()); this->userEntryButtons = generateEntryButtons(entryProvider->getUserEntries());
this->systemEntryButtons = generateEntryButtons(configProvider->getSystemEntries()); this->systemEntryButtons = generateEntryButtons(entryProvider->getSystemEntries());
} }
catch(const ConfigFormatException &e) catch(const ConfigFormatException &e)
{ {
@ -124,7 +125,7 @@ void Window::buttonClick(const EntryPushButton &config)
void Window::closeWindow() void Window::closeWindow()
{ {
if(configProvider->singleInstanceMode()) if(settingsProvider->singleInstanceMode())
{ {
this->lineEdit->setText(""); this->lineEdit->setText("");
hide(); hide();

Bestand weergeven

@ -30,16 +30,16 @@
#include <QThread> #include <QThread>
#include <QTreeWidget> #include <QTreeWidget>
#include <QLabel> #include <QLabel>
#include "config.h"
#include "entrypushbutton.h" #include "entrypushbutton.h"
#include "calculationengine.h" #include "calculationengine.h"
#include "configprovider.h" #include "settingsprovider.h"
class Window : public QWidget class Window : public QWidget
{ {
Q_OBJECT Q_OBJECT
private: private:
ConfigProvider *configProvider; EntryProvider *entryProvider;
SettingsProvider *settingsProvider;
CalculationEngine calcEngine; CalculationEngine calcEngine;
QString calculationresult; QString calculationresult;
QVector<EntryPushButton*> userEntryButtons; QVector<EntryPushButton*> userEntryButtons;
@ -71,7 +71,7 @@ private slots:
void lineEditReturnPressed(); void lineEditReturnPressed();
void showCalculationResultContextMenu(const QPoint &point); void showCalculationResultContextMenu(const QPoint &point);
public: public:
Window(ConfigProvider &configProvider); Window(EntryProvider &entryProvider, SettingsProvider &settingsProvider);
void setSystemConfig(const QVector<EntryConfig> &config); void setSystemConfig(const QVector<EntryConfig> &config);
bool eventFilter(QObject *obj, QEvent *event); bool eventFilter(QObject *obj, QEvent *event);
void focusInput(); void focusInput();