Implement config checking (#1859)
* Add error handling functions to ConfigHandler Refurbished functions setValue and value which were previously unused. These functions now set/get a setting with error handling. Currently recognizes only errors recognizable by QSettings. * Make use of value and setValue in ConfigHandler Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add checker for unrecognized general options Extraneous config options in [General] will be reported as errors. Added some placeholder functions to be implemented in future commits. * Introduce keysFromGroup function Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Check shortcut names for duplicates Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix notification spam Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Implement shortcut conflict checking Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix reading of fallbacks on error If there is a config error, some values would not be loaded correctly. Using the newly implemented function ConfigHandler::contains instead of QSettings::contains solves this issue. These changes reveal u bug that causes a crash on startup. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix crashes introduced in previous commit Because ConfigHandler is a dependency of most other classes, calling functions from those classes inside ConfigHandler caused infinite recursions in some cases. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add config file watcher Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add missing config options Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix bug in shortcut conflict detection Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add error resolved notification Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add GUI error message overlay Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add indicator in config window Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Use ConfigHandler::fileChanged in ConfigWindow Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix watcher sometimes not firing Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Improve config file watching performance Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add new way to handle config This is only a fundamental implementation. Future commits will replace everything with this new paradigm. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix getButtons and related functions Also refactored related code to use QList instead of QVector because QSettings does not work well with QVector. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Make good use of the new way * Implement proper checking for basic types Everything is covered, apart from KeySequence. * Move fallback path to ExistingDir value handler Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Use consistent naming scheme in ConfigHandler Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Implement config getters/setters via macro Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Surround text with tr and clang-format Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix colors being saved obfuscated Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add ValueHandler::represenation Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Move ValueHandler to separate files Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * confighandler.cpp: rename macro CUSTOM to OPTION Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix bug with shortcut conflict checker Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Update docs and fix setAllTheButtons Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Handle filenamePattern properly Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix failing build due to wrong function name Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix QSet error due to Qt version mismatch Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Replace QSharedPointer::get with data for older Qt versions Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix failing build on MacOS and ubuntu 18.04 Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add column headers to recognizedGeneralOptions map Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix ubuntu 18.04 error Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix false positive when shortcuts empty Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix wrong shortcut group prefix Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Implement proper shortcut checking Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add shortcut map in ConfigHandler Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Move ConfigShortcuts functions to ShortcutsWidget Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix minor bugs Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add fallback scheme: Pictures, HOME, TMP Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add config --check CLI option Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add config error log to GUI Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Rename ValueHandler::description to expected * Convert Qt's #AARRGGBB to #RRGGBBAA and vice versa Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Remove obsolete `saveAfterCopyPath` Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix errors in example config Also added an additional ; in front of actual comments to differentiate them from commented options. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Allow special value 'picker' in userColors Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Allow only name, #RRGGBB, and #RRGGBBAA color formats Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com>
This commit is contained in:
197
src/utils/valuehandler.h
Normal file
197
src/utils/valuehandler.h
Normal file
@@ -0,0 +1,197 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/widgets/capture/capturetoolbutton.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
class QVariant;
|
||||
|
||||
/**
|
||||
* @brief Handles the value of a configuration option (abstract class).
|
||||
*
|
||||
* Each configuration option is represented as a `QVariant`. If the option was
|
||||
* not specified in a config file, the `QVariant` will be invalid.
|
||||
*
|
||||
* Each option will usually be handled in three different ways:
|
||||
* - have its value checked for semantic errors (type, format, etc).
|
||||
* @see ValueHandler::check
|
||||
* - have its value (that was taken from the config file) adapted for proper
|
||||
* use.
|
||||
* @see ValueHandler::value
|
||||
* - provided a fallback value in case: the config does not explicitly specify
|
||||
* it, or the config contains an error and is globally falling back to
|
||||
* defaults.
|
||||
* @see ValueHandler::fallback.
|
||||
* - some options may want to be stored in the config file in a different way
|
||||
* than the default one provided by `QVariant`.
|
||||
* @see ValueHandler::representation
|
||||
*
|
||||
* @note Please see the documentation of the functions to learn when you should
|
||||
* override each.
|
||||
*
|
||||
*/
|
||||
class ValueHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Check the value semantically.
|
||||
* @param val The value that was read from the config file
|
||||
* @return Whether the value is correct
|
||||
* @note The function should presume that `val.isValid()` is true.
|
||||
*/
|
||||
virtual bool check(const QVariant& val) = 0;
|
||||
/**
|
||||
* @brief Adapt the value for proper use.
|
||||
* @param val The value that was read from the config file
|
||||
* @return The modified value
|
||||
*
|
||||
* If the value is invalid (unspecified in the config) or does not pass
|
||||
* `check`, the fallback will be returned. Otherwise the value is processed
|
||||
* by `process` and then returned.
|
||||
*
|
||||
* @note Cannot be overriden
|
||||
* @see fallback, process
|
||||
*/
|
||||
QVariant value(const QVariant& val);
|
||||
/**
|
||||
* @brief Fallback value (default value).
|
||||
*/
|
||||
virtual QVariant fallback();
|
||||
/**
|
||||
* @brief Return the representaion of the value in the config file.
|
||||
*
|
||||
* Override this if you want to write the value in a different format than
|
||||
* the one provided by `QVariant`.
|
||||
*/
|
||||
virtual QVariant representation(const QVariant& val);
|
||||
/**
|
||||
* @brief The expected value (descriptive).
|
||||
* Used when reporting configuration errors.
|
||||
*/
|
||||
virtual QString expected();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Process a value, presuming it is a valid `QVariant`.
|
||||
* @param val The value that was read from the config file
|
||||
* @return The processed value
|
||||
* @note You will usually want to override this. In rare cases, you may want
|
||||
* to override `value`.
|
||||
*/
|
||||
virtual QVariant process(const QVariant& val);
|
||||
};
|
||||
|
||||
class Bool : public ValueHandler
|
||||
{
|
||||
public:
|
||||
Bool(bool def);
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
|
||||
private:
|
||||
bool m_def;
|
||||
};
|
||||
|
||||
class String : public ValueHandler
|
||||
{
|
||||
public:
|
||||
String(const QString& def);
|
||||
bool check(const QVariant&) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
|
||||
private:
|
||||
QString m_def;
|
||||
};
|
||||
|
||||
class Color : public ValueHandler
|
||||
{
|
||||
public:
|
||||
Color(const QColor& def);
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant process(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QVariant representation(const QVariant& val) override;
|
||||
QString expected() override;
|
||||
|
||||
private:
|
||||
QColor m_def;
|
||||
};
|
||||
|
||||
class BoundedInt : public ValueHandler
|
||||
{
|
||||
public:
|
||||
BoundedInt(int min, int max, int def);
|
||||
|
||||
bool check(const QVariant& val) override;
|
||||
virtual QVariant fallback() override;
|
||||
QString expected() override;
|
||||
|
||||
private:
|
||||
int m_min, m_max, m_def;
|
||||
};
|
||||
|
||||
class LowerBoundedInt : public ValueHandler
|
||||
{
|
||||
public:
|
||||
LowerBoundedInt(int min, int def);
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
|
||||
private:
|
||||
int m_min, m_def;
|
||||
};
|
||||
|
||||
class KeySequence : public ValueHandler
|
||||
{
|
||||
public:
|
||||
KeySequence(const QKeySequence& fallback = {});
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
|
||||
private:
|
||||
QKeySequence m_fallback;
|
||||
};
|
||||
|
||||
class ExistingDir : public ValueHandler
|
||||
{
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
};
|
||||
|
||||
class FilenamePattern : public ValueHandler
|
||||
{
|
||||
bool check(const QVariant&) override;
|
||||
QVariant fallback() override;
|
||||
QVariant process(const QVariant&) override;
|
||||
QString expected() override;
|
||||
};
|
||||
|
||||
class ButtonList : public ValueHandler
|
||||
{
|
||||
public:
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant process(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QVariant representation(const QVariant& val) override;
|
||||
QString expected() override;
|
||||
|
||||
// UTILITY FUNCTIONS
|
||||
static QList<CaptureToolButton::ButtonType> fromIntList(const QList<int>&);
|
||||
static QList<int> toIntList(const QList<CaptureToolButton::ButtonType>& l);
|
||||
static bool normalizeButtons(QList<int>& buttons);
|
||||
};
|
||||
|
||||
class UserColors : public ValueHandler
|
||||
{
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant process(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
};
|
||||
Reference in New Issue
Block a user