diff --git a/share/qtcreator/qmldesigner/workspacePresets/Advanced-3D.wrk b/share/qtcreator/qmldesigner/workspacePresets/Advanced-3D.wrk index 24eace89b8c..f7f232dc603 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Advanced-3D.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Advanced-3D.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Animation-2D.wrk b/share/qtcreator/qmldesigner/workspacePresets/Animation-2D.wrk index 346856dd507..c7045549fc8 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Animation-2D.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Animation-2D.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Animation-3D.wrk b/share/qtcreator/qmldesigner/workspacePresets/Animation-3D.wrk index 8f1d59119cd..2481c365b9f 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Animation-3D.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Animation-3D.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Basic.wrk b/share/qtcreator/qmldesigner/workspacePresets/Basic.wrk index b1edb18677f..ca1ef341109 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Basic.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Basic.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Code.wrk b/share/qtcreator/qmldesigner/workspacePresets/Code.wrk index 82f734432fc..828b930c5fd 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Code.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Code.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Essentials-3D.wrk b/share/qtcreator/qmldesigner/workspacePresets/Essentials-3D.wrk index 74215ffd456..2117c61db06 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Essentials-3D.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Essentials-3D.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Essentials.wrk b/share/qtcreator/qmldesigner/workspacePresets/Essentials.wrk index e11f39ec940..c71b377d8c9 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Essentials.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Essentials.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/UX-Design.wrk b/share/qtcreator/qmldesigner/workspacePresets/UX-Design.wrk index 5e973366629..f6c1329a7d3 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/UX-Design.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/UX-Design.wrk @@ -1,5 +1,5 @@ - + diff --git a/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk b/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk index 6dc95483470..011ead83a65 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk @@ -1,5 +1,5 @@ - + diff --git a/src/libs/advanceddockingsystem/dockmanager.cpp b/src/libs/advanceddockingsystem/dockmanager.cpp index a30ffb42e1d..3f148393a04 100644 --- a/src/libs/advanceddockingsystem/dockmanager.cpp +++ b/src/libs/advanceddockingsystem/dockmanager.cpp @@ -1578,6 +1578,55 @@ bool DockManager::writeDisplayName(const FilePath &filePath, const QString &disp return true; } +QString DockManager::readMcusEnabled(const FilePath &filePath) +{ + auto data = loadFile(filePath); + + if (data.isEmpty()) + return {}; + + auto tmp = data.startsWith(" content = filePath.fileContents(); + + QTC_ASSERT_EXPECTED(content, return false); + + QDomDocument doc; + QString error_msg; + int error_line, error_col; + if (!doc.setContent(*content, &error_msg, &error_line, &error_col)) { + qWarning() << QString("XML error on line %1, col %2: %3") + .arg(error_line) + .arg(error_col) + .arg(error_msg); + return false; + } + + QDomElement docElem = doc.documentElement(); + docElem.setAttribute(workspaceMcusEnabledAttribute.toString(), mcusEnabled); + + const expected_str result = write(filePath, doc.toByteArray(workspaceXmlFormattingIndent)); + if (!result) { + qWarning() << "Could not write mcusEnabled" << mcusEnabled << "to" << filePath << ":" + << result.error(); + return false; + } + + return true; +} + expected_str DockManager::write(const FilePath &filePath, const QByteArray &data) { qCInfo(adsLog) << "Write" << filePath; @@ -1638,6 +1687,11 @@ void DockManager::syncWorkspacePresets() const QString name = readDisplayName(userFile); if (name.isEmpty()) writeDisplayName(userFile, name); + + const QString presetMcusEnabled = readMcusEnabled(filePath); + const QString mcusEnabled = readMcusEnabled(userFile); + if (mcusEnabled.isEmpty() || mcusEnabled != presetMcusEnabled) + writeMcusEnabled(userFile, presetMcusEnabled); } continue; @@ -1694,4 +1748,12 @@ void DockManager::saveLockWorkspace() d->m_settings->setValue(Constants::LOCK_WORKSPACE_SETTINGS_KEY, d->m_workspaceLocked); } +void DockManager::setMcusProject(bool value) { + m_mcusProject = value; +} + +bool DockManager::mcusProject() const { + return m_mcusProject; +} + } // namespace ADS diff --git a/src/libs/advanceddockingsystem/dockmanager.h b/src/libs/advanceddockingsystem/dockmanager.h index 53117b93e6b..23aa21a5781 100644 --- a/src/libs/advanceddockingsystem/dockmanager.h +++ b/src/libs/advanceddockingsystem/dockmanager.h @@ -57,6 +57,7 @@ inline constexpr QStringView workspaceFolderName{u"workspaces"}; inline constexpr QStringView workspaceFileExtension{u"wrk"}; inline constexpr QStringView workspaceOrderFileName{u"order.json"}; inline constexpr QStringView workspaceDisplayNameAttribute{u"displayName"}; +inline constexpr QStringView workspaceMcusEnabledAttribute{u"mcusEnabled"}; inline const int workspaceXmlFormattingIndent = 2; /** @@ -760,6 +761,8 @@ public: static QByteArray loadFile(const Utils::FilePath &filePath); static QString readDisplayName(const Utils::FilePath &filePath); static bool writeDisplayName(const Utils::FilePath &filePath, const QString &displayName); + static QString readMcusEnabled(const Utils::FilePath &filePath); + static bool writeMcusEnabled(const Utils::FilePath &filePath, const QString &mcusEnabled); /** * This is used to limit saving of workspaces to only when they were actually presented ones, @@ -768,6 +771,9 @@ public: */ void aboutToShow(); + void setMcusProject(bool value); + bool mcusProject() const; + signals: void aboutToUnloadWorkspace(QString fileName); void aboutToLoadWorkspace(QString fileName); @@ -789,6 +795,8 @@ private: void saveStartupWorkspace(); void saveLockWorkspace(); + + bool m_mcusProject = false; }; // class DockManager } // namespace ADS diff --git a/src/libs/advanceddockingsystem/workspace.cpp b/src/libs/advanceddockingsystem/workspace.cpp index d3b0785d90b..8022b36f173 100644 --- a/src/libs/advanceddockingsystem/workspace.cpp +++ b/src/libs/advanceddockingsystem/workspace.cpp @@ -28,6 +28,12 @@ Workspace::Workspace(const Utils::FilePath &filePath, bool isPreset) } else { m_name = name; } + + QString mcusEnabled = DockManager::readMcusEnabled(m_filePath); + if (mcusEnabled.isEmpty()) + setMcusEnabled(true); + else + m_mcusEnabled = QVariant::fromValue(mcusEnabled).toBool(); } void Workspace::setName(const QString &name) @@ -84,6 +90,18 @@ bool Workspace::isPreset() const return m_preset; } +void Workspace::setMcusEnabled(bool enabled) +{ + QString mcusEnabled = QVariant::fromValue(enabled).toString(); + if (DockManager::writeMcusEnabled(filePath(), mcusEnabled)) + m_mcusEnabled = enabled; +} + +bool Workspace::isMcusEnabled() const +{ + return m_mcusEnabled; +} + Workspace::operator QString() const { return QString("Workspace %1 Preset[%2] %3") diff --git a/src/libs/advanceddockingsystem/workspace.h b/src/libs/advanceddockingsystem/workspace.h index c23db55d6b6..e89edb5539a 100644 --- a/src/libs/advanceddockingsystem/workspace.h +++ b/src/libs/advanceddockingsystem/workspace.h @@ -30,6 +30,9 @@ public: void setPreset(bool value); bool isPreset() const; + void setMcusEnabled(bool value); + bool isMcusEnabled() const; + friend bool operator==(const Workspace &a, const Workspace &b) { return a.fileName() == b.fileName(); @@ -50,6 +53,7 @@ private: QString m_name; Utils::FilePath m_filePath; bool m_preset = false; + bool m_mcusEnabled = true; }; } // namespace ADS diff --git a/src/libs/advanceddockingsystem/workspacemodel.cpp b/src/libs/advanceddockingsystem/workspacemodel.cpp index 99d3bd1473e..2748d85fc69 100644 --- a/src/libs/advanceddockingsystem/workspacemodel.cpp +++ b/src/libs/advanceddockingsystem/workspacemodel.cpp @@ -22,7 +22,7 @@ WorkspaceModel::WorkspaceModel(DockManager *manager, QObject *parent) connect(m_manager, &DockManager::workspaceLoaded, this, &WorkspaceModel::resetWorkspaces); } -int WorkspaceModel::indexOfWorkspace(const QString &fileName) +int WorkspaceModel::indexOfWorkspace(const QString &fileName) const { return m_manager->workspaceIndex(fileName); } @@ -134,6 +134,10 @@ Qt::ItemFlags WorkspaceModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = QAbstractTableModel::flags(index); + Workspace *workspace = m_manager->workspace(workspaceAt(index.row())); + if (m_manager->mcusProject() && !workspace->isMcusEnabled()) + defaultFlags &= ~Qt::ItemIsEnabled; + if (index.isValid()) return Qt::ItemIsDragEnabled | defaultFlags; diff --git a/src/libs/advanceddockingsystem/workspacemodel.h b/src/libs/advanceddockingsystem/workspacemodel.h index fe868f71f5b..2d6e0ef16b2 100644 --- a/src/libs/advanceddockingsystem/workspacemodel.h +++ b/src/libs/advanceddockingsystem/workspacemodel.h @@ -21,7 +21,7 @@ public: explicit WorkspaceModel(DockManager *manager, QObject *parent = nullptr); - int indexOfWorkspace(const QString &fileName); + int indexOfWorkspace(const QString &fileName) const; QString workspaceAt(int row) const; int rowCount(const QModelIndex &parent = QModelIndex()) const override; diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp index e42d71d24bb..c3073d58e54 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp @@ -149,6 +149,14 @@ WorkspaceModel::WorkspaceModel(QObject *) }; if (!connectDockManager()) connect(designModeWidget(), &Internal::DesignModeWidget::initialized, this, connectDockManager); + + connect(ProjectExplorer::ProjectManager::instance(), + &ProjectExplorer::ProjectManager::projectFinishedParsing, + this, + [this]() { + beginResetModel(); + endResetModel(); + }); } int WorkspaceModel::rowCount(const QModelIndex &) const @@ -162,7 +170,8 @@ int WorkspaceModel::rowCount(const QModelIndex &) const QHash WorkspaceModel::roleNames() const { static QHash roleNames{{DisplayNameRole, "displayName"}, - {FileNameRole, "fileName"}}; + {FileNameRole, "fileName"}, + {Enabled, "enabled"}}; return roleNames; } @@ -176,6 +185,9 @@ QVariant WorkspaceModel::data(const QModelIndex &index, int role) const return workspace.name(); } else if (role == FileNameRole) { return workspace.fileName(); + } else if (role == Enabled) { + if (QmlProjectManager::QmlProject::isMCUs()) + return workspace.isMcusEnabled(); } else { qWarning() << Q_FUNC_INFO << "invalid role"; } diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h index 307704d63a0..eb258f9ab75 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h @@ -29,7 +29,8 @@ public: class WorkspaceModel : public QAbstractListModel { Q_OBJECT - enum { DisplayNameRole = Qt::DisplayRole, FileNameRole = Qt::UserRole }; + + enum { DisplayNameRole = Qt::DisplayRole, FileNameRole = Qt::UserRole, Enabled }; public: explicit WorkspaceModel(QObject *parent = nullptr); diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index fdbcb670b76..98112515ca7 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -219,6 +220,13 @@ void DesignModeWidget::setup() QString sheet = QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/dockwidgets.css")); m_dockManager->setStyleSheet(Theme::replaceCssColors(sheet)); + connect(ProjectExplorer::ProjectManager::instance(), + &ProjectExplorer::ProjectManager::projectFinishedParsing, + m_dockManager, + [this]() { + this->m_dockManager->setMcusProject(QmlProjectManager::QmlProject::isMCUs()); + }); + // Setup icons const QString closeUnicode = Theme::getIconUnicode(Theme::Icon::close_small); const QString maximizeUnicode = Theme::getIconUnicode(Theme::Icon::maxBar_small); @@ -273,6 +281,7 @@ void DesignModeWidget::setup() Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW); // View > Views Core::ActionContainer *mviews = Core::ActionManager::createMenu(Core::Constants::M_VIEW_VIEWS); + connect(mviews->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowViews); mviews->menu()->addSeparator(); // View > Workspaces Core::ActionContainer *mworkspaces = Core::ActionManager::createMenu(QmlDesigner::Constants::M_VIEW_WORKSPACES); @@ -482,6 +491,29 @@ void DesignModeWidget::setup() show(); } +static bool isMcuDisabledView(const QString viewId) +{ + static const QStringList mcuDisabledViews = {"Editor3D", "MaterialEditor", "MaterialBrowser", "TextureEditor"}; + return mcuDisabledViews.contains(viewId); +} + +void DesignModeWidget::aboutToShowViews() +{ + for (const WidgetInfo &widgetInfo : viewManager().widgetInfos()) { + QString id = widgetInfo.uniqueId; + ADS::DockWidget *dockWidget = m_dockManager->findDockWidget(id); + QAction *action = dockWidget->toggleViewAction(); + + bool isMcuProject = currentDesignDocument() && currentDesignDocument()->isQtForMCUsProject(); + if (isMcuProject && isMcuDisabledView(id) && action->isEnabled()) { + action->setChecked(false); + action->setEnabled(false); + } else if (!isMcuProject && !action->isEnabled()) { + action->setEnabled(true); + } + } +} + void DesignModeWidget::aboutToShowWorkspaces() { Core::ActionContainer *aci = Core::ActionManager::actionContainer( @@ -520,6 +552,9 @@ void DesignModeWidget::aboutToShowWorkspaces() action->setCheckable(true); if (workspace == *m_dockManager->activeWorkspace()) action->setChecked(true); + + if (currentDesignDocument() && currentDesignDocument()->isQtForMCUsProject()) + action->setEnabled(workspace.isMcusEnabled()); } menu->addActions(ag->actions()); } diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 432549e694d..464994b7e34 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -93,6 +93,7 @@ private: QWidget *createCenterWidget(); QWidget *createCrumbleBarFrame(); + void aboutToShowViews(); void aboutToShowWorkspaces(); QPointer m_bottomSideBar; diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 360595e8fa4..818fffcdadc 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -238,4 +238,17 @@ bool QmlProject::allowOnlySingleProject() return !settings->value(key, false).toBool(); } +bool QmlProject::isMCUs() +{ + if (!ProjectExplorer::ProjectManager::startupTarget()) + return false; + + const QmlProjectManager::QmlBuildSystem *buildSystem + = qobject_cast( + ProjectExplorer::ProjectManager::startupTarget()->buildSystem()); + QTC_ASSERT(buildSystem, return false); + + return buildSystem && buildSystem->qtForMCUs(); +} + } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h index a41b05e57bb..0091d77d6c6 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.h +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -24,6 +24,8 @@ public: ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final; + static bool isMCUs(); + protected: RestoreResult fromMap(const Utils::Store &map, QString *errorMessage) override;