// Copyright (C) 2020 Alexis Jeandet. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include #include #include #include #include #include #include #include namespace MesonProjectManager::Internal { struct ComboData { QString value() const { return m_choices.at(m_currentIndex != -1 ? m_currentIndex : 0); } void setValue(const QString &value) { m_currentIndex = m_choices.indexOf(value); } ComboData(const QStringList &choices, const QString &value) : m_choices{choices} { setValue(value); } ComboData() = default; const QStringList &choices() const { return m_choices; } int currentIndex() const { return m_currentIndex; } private: QStringList m_choices; int m_currentIndex = 0; }; struct FeatureData : ComboData { FeatureData() : ComboData({"enabled", "disabled", "auto"}, "disabled") {} FeatureData(const QString &value) : ComboData({"enabled", "disabled", "auto"}, value) {} }; } // namespace MesonProjectManager::Internal Q_DECLARE_METATYPE(MesonProjectManager::Internal::FeatureData); Q_DECLARE_METATYPE(MesonProjectManager::Internal::ComboData); namespace MesonProjectManager::Internal { struct BuildOption { enum class Type { integer, string, feature, combo, array, boolean, unknown }; const QString name; const QString section; const QString description; const std::optional subproject; virtual ~BuildOption() {} virtual QVariant value() const = 0; virtual QString valueStr() const = 0; virtual void setValue(const QVariant &) = 0; virtual Type type() const = 0; virtual BuildOption *copy() const = 0; inline QString fullName() const { if (subproject) return QString("%1:%2").arg(*subproject).arg(name); return name; } inline virtual QString mesonArg() const { return QString("-D%1=%2").arg(fullName()).arg(valueStr()); } BuildOption(const QString &name, const QString §ion, const QString &description) : name{name.contains(":") ? name.split(":").last() : name} , section{section} , description{description} , subproject{name.contains(":") ? std::optional(name.split(":").first()) : std::nullopt} {} }; // namespace Internal struct IntegerBuildOption final : BuildOption { QVariant value() const override { return m_currentValue; } QString valueStr() const override { return QString::number(m_currentValue); } void setValue(const QVariant &value) override { m_currentValue = value.toInt(); } Type type() const override { return Type::integer; } BuildOption *copy() const override { return new IntegerBuildOption{*this}; } IntegerBuildOption(const QString &name, const QString §ion, const QString &description, const QVariant &value) : BuildOption(name, section, description) , m_currentValue{value.toInt()} {} protected: int m_currentValue; }; struct StringBuildOption : BuildOption { QVariant value() const override { return m_currentValue; } QString valueStr() const override { return m_currentValue; } void setValue(const QVariant &value) override { m_currentValue = value.toString(); } Type type() const override { return Type::string; } BuildOption *copy() const override { return new StringBuildOption{*this}; } StringBuildOption(const QString &name, const QString §ion, const QString &description, const QVariant &value) : BuildOption(name, section, description) , m_currentValue{value.toString()} {} protected: QString m_currentValue; }; struct FeatureBuildOption final : BuildOption { QVariant value() const override { return QVariant::fromValue(m_currentValue); } QString valueStr() const override { return m_currentValue.value(); } void setValue(const QVariant &value) override { m_currentValue.setValue(value.toString()); } Type type() const override { return Type::feature; } BuildOption *copy() const override { return new FeatureBuildOption{*this}; } FeatureBuildOption(const QString &name, const QString §ion, const QString &description, const QVariant &value) : BuildOption(name, section, description) { setValue(value); } protected: FeatureData m_currentValue; }; struct ComboBuildOption : BuildOption { const QStringList &choices() const { return m_currentValue.choices(); } QVariant value() const override { return QVariant::fromValue(m_currentValue); } QString valueStr() const override { return m_currentValue.value(); } void setValue(const QVariant &value) override { m_currentValue.setValue(value.toString()); } Type type() const override { return Type::combo; } BuildOption *copy() const override { return new ComboBuildOption{*this}; } ComboBuildOption(const QString &name, const QString §ion, const QString &description, const QStringList &choices, const QVariant &value) : BuildOption(name, section, description) , m_currentValue{choices, value.toString()} {} protected: ComboData m_currentValue; }; static inline QStringList quoteAll(const QStringList &values) { QStringList quoted; std::transform(std::cbegin(values), std::cend(values), std::back_inserter(quoted), [](const QString &v) { if (v.front() == '\'' && v.back() == '\'') return v; return QString("\'%1\'").arg(v); }); return quoted; } struct ArrayBuildOption : BuildOption { QVariant value() const override { return m_currentValue; } QString valueStr() const override { return m_currentValue.join(" "); } void setValue(const QVariant &value) override { m_currentValue = quoteAll(value.toStringList()); } Type type() const override { return Type::array; } BuildOption *copy() const override { return new ArrayBuildOption{*this}; } inline QString mesonArg() const override { return QString("-D%1=[%2]").arg(fullName()).arg(quoteAll(m_currentValue).join(',')); } ArrayBuildOption(const QString &name, const QString §ion, const QString &description, const QVariant &value) : BuildOption(name, section, description) , m_currentValue{quoteAll(value.toStringList())} {} protected: QStringList m_currentValue; }; struct BooleanBuildOption final : BuildOption { QVariant value() const override { return m_currentValue; } QString valueStr() const override { return m_currentValue ? QString{"true"} : QString{"false"}; } void setValue(const QVariant &value) override { m_currentValue = value.toBool(); } Type type() const override { return Type::boolean; } BuildOption *copy() const override { return new BooleanBuildOption{*this}; } BooleanBuildOption(const QString &name, const QString §ion, const QString &description, const QVariant &value) : BuildOption(name, section, description) { setValue(value); } protected: bool m_currentValue; }; struct UnknownBuildOption : BuildOption { QVariant value() const override { return {"Unknown option"}; } QString valueStr() const override { return {"Unknown option"}; } void setValue(const QVariant &) override {} Type type() const override { return Type::unknown; } BuildOption *copy() const override { return new UnknownBuildOption{*this}; } UnknownBuildOption(const QString &name, const QString §ion, const QString &description) : BuildOption(name, section, description) {} }; using BuildOptionsList = std::vector>; } // namespace MesonProjectManager::Internal