// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "devicesupport/idevicefwd.h" #include "projectexplorer_export.h" #include "task.h" #include #include #include #include #include QT_BEGIN_NAMESPACE class QAction; class QComboBox; QT_END_NAMESPACE namespace Utils { class Environment; class MacroExpander; class OutputLineParser; } // namespace Utils namespace ProjectExplorer { class Kit; class KitAspect; using LogCallback = std::function; class PROJECTEXPLORER_EXPORT DetectionSource { public: enum DetectionType { Manual, FromSystem, FromSdk, Temporary, Uninitialized, }; DetectionSource() = default; DetectionSource(DetectionType type, const QString &id = {}) : type(type), id(id) {} bool isAutoDetected() const { return type == FromSystem || type == FromSdk || type == Temporary; } bool isTemporary() const { return type == Temporary; } bool isSdkProvided() const { return type == FromSdk; } bool isSystemDetected() const { return type == FromSystem; } bool operator==(const DetectionSource &other) const { return type == other.type && id == other.id; } void fromMap(const Utils::Store &); void toMap(Utils::Store &) const; static std::optional createFromMap(const Utils::Store &); DetectionType type = Uninitialized; QString id; private: PROJECTEXPLORER_EXPORT friend QDebug operator<<(QDebug dbg, const DetectionSource &source); }; PROJECTEXPLORER_EXPORT QtTaskTree::Group kitDetectionRecipe( const IDeviceConstPtr &device, DetectionSource::DetectionType detectionType, const LogCallback &logCallback); PROJECTEXPLORER_EXPORT QtTaskTree::Group removeDetectedKitsRecipe( const IDeviceConstPtr &device, const LogCallback &logCallback); PROJECTEXPLORER_EXPORT void listAutoDetected( const IDeviceConstPtr &device, const LogCallback &logCallback); /** * @brief The KitAspectFactory class * * A KitAspectFactory can create instances of one type of KitAspect. * A KitAspect handles a specific piece of information stored in the kit. * * They auto-register with the \a KitManager for their life time */ class PROJECTEXPLORER_EXPORT KitAspectFactory : public QObject { public: using Item = QPair; using ItemList = QList; Utils::Id id() const { return m_id; } QList jsonKeys() const { return m_jsonKeys; } int priority() const { return m_priority; } QString displayName() const { return m_displayName; } QString description() const { return m_description; } bool isEssential() const { return m_essential; } // called to find issues with the kit virtual Tasks validate(const Kit *) const = 0; // called after restoring a kit, so upgrading of kit information settings can be done virtual void upgrade(Kit *) { return; } // called to fix issues with this kitinformation. Does not modify the rest of the kit. virtual void fix(Kit *) { return; } // called on initial setup of a kit. virtual void setup(Kit *) { return; } virtual int weight(const Kit *k) const; virtual QVariant getInfo(const Kit *k, Utils::Id request, const QVariant &input) const; virtual ItemList toUserOutput(const Kit *) const = 0; virtual KitAspect *createKitAspect(Kit *) const = 0; virtual void addToBuildEnvironment(const Kit *k, Utils::Environment &env) const; virtual void addToRunEnvironment(const Kit *k, Utils::Environment &env) const; virtual QList createOutputParsers(const Kit *k) const; virtual QSet supportedPlatforms(const Kit *k) const; virtual QSet availableFeatures(const Kit *k) const; QList embeddableAspects() const { return m_embeddableAspects; } virtual void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const; virtual void onKitsLoaded() {} static void handleKitsLoaded(); static const QList kitAspectFactories(); virtual std::optional autoDetect( Kit *kit, const Utils::FilePaths &searchPaths, const DetectionSource &detectionSource, const LogCallback &logCallback) const; virtual std::optional removeAutoDetected( const QString &detectionSourceId, const LogCallback &logCallback) const; virtual void listAutoDetected( const QString &detectionSourceId, const LogCallback &logCallback) const; virtual Utils::Result createAspectFromJson( const DetectionSource &detectionSource, const Utils::FilePath &rootPath, Kit *kit, const QJsonValue &json, const LogCallback &logCallback) const; protected: KitAspectFactory(); ~KitAspectFactory(); void setId(Utils::Id id) { m_id = id; } void setJsonKeys(const QList &ids) { m_jsonKeys = ids; } void setDisplayName(const QString &name) { m_displayName = name; } void setDescription(const QString &desc) { m_description = desc; } void makeEssential() { m_essential = true; } void setPriority(int priority) { m_priority = priority; } void setEmbeddableAspects(const QList &aspects) { m_embeddableAspects = aspects; } void notifyAboutUpdate(Kit *k); private: QString m_displayName; QString m_description; Utils::Id m_id; QList m_jsonKeys; QList m_embeddableAspects; int m_priority = 0; // The higher the closer to the top. bool m_essential = false; }; class PROJECTEXPLORER_EXPORT KitAspect : public Utils::BaseAspect { Q_OBJECT public: enum ItemRole { IdRole = Qt::UserRole + 100, IsNoneRole, TypeRole, QualityRole }; KitAspect(Kit *kit, const KitAspectFactory *factory); ~KitAspect(); virtual void refresh(); void addToLayoutImpl(Layouting::Layout &layout) override; static QString msgManage(); Kit *kit() const; const KitAspectFactory *factory() const; QAction *mutableAction() const; void addMutableAction(QWidget *child); void setManagingPage(Utils::Id pageId); void setAspectsToEmbed(const QList &aspects); QList aspectsToEmbed() const; void makeStickySubWidgetsReadOnly(); // For layouting purposes only. QList comboBoxes() const; virtual void addToInnerLayout(Layouting::Layout &layout); protected: virtual void makeReadOnly(); virtual Utils::Id settingsPageItemToPreselect() const { return {}; } void addLabelToLayout(Layouting::Layout &layout); void addListAspectsToLayout(Layouting::Layout &layout); void addManageButtonToLayout(Layouting::Layout &layout); // Convenience for aspects that provide a list model from which one value can be chosen. // It will be exposed via a QComboBox. class ListAspectSpec { public: using Getter = std::function; using Setter = std::function; using ResetModel = std::function; ListAspectSpec( QAbstractItemModel *model, Getter &&getter, Setter &&setter, ResetModel &&resetModel) : model(model) , getter(std::move(getter)) , setter(std::move(setter)) , resetModel(std::move(resetModel)) {} QAbstractItemModel *model; Getter getter; Setter setter; ResetModel resetModel; }; void addListAspectSpec(const ListAspectSpec &listAspectSpec); private: class Private; Private * const d; }; } // namespace ProjectExplorer