#include "valuehandler.h" #include "capturetool.h" #include "confighandler.h" #include #include #include #include // VALUE HANDLER QVariant ValueHandler::value(const QVariant& val) { if (!val.isValid() || !check(val)) { return fallback(); } else { return process(val); } } QVariant ValueHandler::fallback() { return QVariant(); } QVariant ValueHandler::representation(const QVariant& val) { return val.toString(); } QString ValueHandler::expected() { return {}; } QVariant ValueHandler::process(const QVariant& val) { return val; } // BOOL Bool::Bool(bool def) : m_def(def) {} bool Bool::check(const QVariant& val) { QString str = val.toString(); if (str != "true" && str != "false") { return false; } return true; } QVariant Bool::fallback() { return m_def; } QString Bool::expected() { return QStringLiteral("true or false"); } // STRING String::String(const QString& def) : m_def(def) {} bool String::check(const QVariant&) { return true; } QVariant String::fallback() { return m_def; } QString String::expected() { return QStringLiteral("string"); } // COLOR Color::Color(const QColor& def) : m_def(def) {} bool Color::check(const QVariant& val) { QString str = val.toString(); // Disable #RGB, #RRRGGGBBB and #RRRRGGGGBBBB formats that QColor supports return QColor::isValidColor(str) && (str[0] != '#' || (str.length() != 4 && str.length() != 10 && str.length() != 13)); } QVariant Color::process(const QVariant& val) { QString str = val.toString(); QColor color(str); if (str.length() == 9 && str[0] == '#') { // Convert #RRGGBBAA (flameshot) to #AARRGGBB (QColor) int blue = color.blue(); color.setBlue(color.green()); color.setGreen(color.red()); color.setRed(color.alpha()); color.setAlpha(blue); } return color; } QVariant Color::fallback() { return m_def; } QVariant Color::representation(const QVariant& val) { QString str = val.toString(); QColor color(str); if (str.length() == 9 && str[0] == '#') { // Convert #AARRGGBB (QColor) to #RRGGBBAA (flameshot) int alpha = color.alpha(); color.setAlpha(color.red()); color.setRed(color.green()); color.setGreen(color.blue()); color.setBlue(alpha); } return color.name(); } QString Color::expected() { return QStringLiteral("color name or hex value"); } // BOUNDED INT BoundedInt::BoundedInt(int min, int max, int def) : m_min(min) , m_max(max) , m_def(def) {} bool BoundedInt::check(const QVariant& val) { QString str = val.toString(); bool conversionOk; int num = str.toInt(&conversionOk); return conversionOk && (m_max < m_min || num <= m_max); } QVariant BoundedInt::fallback() { return m_def; } QString BoundedInt::expected() { return QStringLiteral("number between %1 and %2").arg(m_min).arg(m_max); } // LOWER BOUNDED INT LowerBoundedInt::LowerBoundedInt(int min, int def) : m_min(min) , m_def(def) {} bool LowerBoundedInt::check(const QVariant& val) { QString str = val.toString(); bool conversionOk; int num = str.toInt(&conversionOk); return conversionOk && num >= m_min; } QVariant LowerBoundedInt::fallback() { return m_def; } QString LowerBoundedInt::expected() { return QStringLiteral("number >= %1").arg(m_min); } // KEY SEQUENCE KeySequence::KeySequence(const QKeySequence& fallback) : m_fallback(fallback) {} bool KeySequence::check(const QVariant& val) { QString str = val.toString(); if (!str.isEmpty() && QKeySequence(str).toString().isEmpty()) { return false; } return true; } QVariant KeySequence::fallback() { return m_fallback; } QString KeySequence::expected() { return QStringLiteral("keyboard shortcut"); } // EXISTING DIR bool ExistingDir::check(const QVariant& val) { if (!val.canConvert(QVariant::String) || val.toString().isEmpty()) { return false; } QFileInfo info(val.toString()); return info.isDir() && info.exists(); } QVariant ExistingDir::fallback() { using SP = QStandardPaths; for (auto location : { SP::PicturesLocation, SP::HomeLocation, SP::TempLocation }) { QString path = SP::writableLocation(location); if (QFileInfo(path).isDir()) { return path; } } return {}; } QString ExistingDir::expected() { return QStringLiteral("existing directory"); } // FILENAME PATTERN bool FilenamePattern::check(const QVariant&) { return true; } QVariant FilenamePattern::fallback() { return ConfigHandler().filenamePatternDefault(); } QVariant FilenamePattern::process(const QVariant& val) { QString str = val.toString(); return !str.isEmpty() ? val : fallback(); } QString FilenamePattern::expected() { return QStringLiteral("please edit using the GUI"); } // BUTTON LIST using BType = CaptureTool::Type; using BList = QList; bool ButtonList::check(const QVariant& val) { // TODO stop using CTB using CTB = CaptureToolButton; auto allButtons = CTB::getIterableButtonTypes(); for (int btn : val.value>()) { if (!allButtons.contains(static_cast(btn))) { return false; } } return true; } // Helper void sortButtons(BList& buttons) { std::sort(buttons.begin(), buttons.end(), [](BType a, BType b) { return CaptureToolButton::getPriorityByButton(a) < CaptureToolButton::getPriorityByButton(b); }); } QVariant ButtonList::process(const QVariant& val) { QList intButtons = val.value>(); auto buttons = ButtonList::fromIntList(intButtons); sortButtons(buttons); return QVariant::fromValue(buttons); } QVariant ButtonList::fallback() { auto buttons = CaptureToolButton::getIterableButtonTypes(); buttons.removeOne(CaptureTool::TYPE_SIZEDECREASE); buttons.removeOne(CaptureTool::TYPE_SIZEINCREASE); sortButtons(buttons); return QVariant::fromValue(buttons); } QVariant ButtonList::representation(const QVariant& val) { auto intList = toIntList(val.value()); normalizeButtons(intList); return QVariant::fromValue(intList); } QString ButtonList::expected() { return QStringLiteral("please don't edit by hand"); } QList ButtonList::fromIntList(const QList& l) { QList buttons; buttons.reserve(l.size()); for (auto const i : l) buttons << static_cast(i); return buttons; } QList ButtonList::toIntList(const QList& l) { QList buttons; buttons.reserve(l.size()); for (auto const i : l) buttons << static_cast(i); return buttons; } bool ButtonList::normalizeButtons(QList& buttons) { QList listTypesInt = toIntList(CaptureToolButton::getIterableButtonTypes()); bool hasChanged = false; for (int i = 0; i < buttons.size(); i++) { if (!listTypesInt.contains(buttons.at(i))) { buttons.removeAt(i); hasChanged = true; } } return hasChanged; } // USER COLORS bool UserColors::check(const QVariant& val) { if (!val.isValid()) { return true; } if (!val.canConvert(QVariant::StringList)) { return false; } for (const QString& str : val.toStringList()) { if (!QColor::isValidColor(str) && str != "picker") { return false; } } return true; } QVariant UserColors::process(const QVariant& val) { QStringList strColors = val.toStringList(); if (strColors.isEmpty()) { return fallback(); } QVector colors; colors.reserve(strColors.size()); for (const QString& str : strColors) { if (str != "picker") { colors.append(QColor(str)); } else { colors.append(QColor()); } } return QVariant::fromValue(colors); } QVariant UserColors::fallback() { return QVariant::fromValue(QVector{ Qt::darkRed, Qt::red, Qt::yellow, Qt::green, Qt::darkGreen, Qt::cyan, Qt::blue, Qt::magenta, Qt::darkMagenta, QColor() }); } QString UserColors::expected() { return QStringLiteral("list of colors separated by comma"); }