QmlDesigner: Allow changing downloaded textures path

For now changing the path triggers the "restart needed" dialog. Some
refactoring (for future) is needed to make the change works right away.

Also added few missing ContentLibraryBackend uses.

Fixes: QDS-9233
Change-Id: I3a576d397b0452a70d9940edaaa38193c41af347
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2023-03-02 16:31:49 +02:00
parent db6046b456
commit a0df1fd61a
11 changed files with 325 additions and 248 deletions

View File

@@ -55,7 +55,7 @@ Item {
&& ContentLibraryBackend.rootView.hasMaterialLibrary
&& ContentLibraryBackend.materialsModel.hasRequiredQuick3DImport
} else { // Textures / Environments tabs
texturesModel.texBundleExists
ContentLibraryBackend.texturesModel.texBundleExists
}
}
@@ -106,7 +106,7 @@ Item {
id: texturesView
width: root.width
model: texturesModel
model: ContentLibraryBackend.texturesModel
searchBox: searchBox
}
@@ -115,7 +115,7 @@ Item {
id: environmentsView
width: root.width
model: environmentsModel
model: ContentLibraryBackend.environmentsModel
searchBox: searchBox
}

View File

@@ -4,36 +4,34 @@
#include "contentlibrarytexturesmodel.h"
#include "contentlibrarytexturescategory.h"
#include "qmldesignerplugin.h"
#include "utils/algorithm.h"
#include "utils/qtcassert.h"
#include "utils/filedownloader.h"
#include "utils/fileextractor.h"
#include <qmldesigner/utils/fileextractor.h>
#include <qmldesigner/utils/filedownloader.h>
#include <qmldesignerbase/qmldesignerbaseplugin.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QUrl>
#include <QQmlEngine>
#include <QSize>
#include <QStandardPaths>
#include <QUrl>
namespace QmlDesigner {
ContentLibraryTexturesModel::ContentLibraryTexturesModel(const QString &bundleSubPath, QObject *parent)
ContentLibraryTexturesModel::ContentLibraryTexturesModel(const QString &category, QObject *parent)
: QAbstractListModel(parent)
, m_bundleSubPath(bundleSubPath)
{
qmlRegisterType<QmlDesigner::FileDownloader>("WebFetcher", 1, 0, "FileDownloader");
qmlRegisterType<QmlDesigner::FileExtractor>("WebFetcher", 1, 0, "FileExtractor");
static const QString baseDownloadPath =
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)
+ "/QtDesignStudio/bundles";
m_downloadPath = baseDownloadPath + '/' + bundleSubPath;
m_category = category; // textures main category (ex: Textures, Environments)
}
int ContentLibraryTexturesModel::rowCount(const QModelIndex &) const
@@ -99,39 +97,50 @@ QHash<int, QByteArray> ContentLibraryTexturesModel::roleNames() const
return roles;
}
void ContentLibraryTexturesModel::loadTextureBundle(const QString &bundlePath, const QString &baseUrl,
const QVariantMap &metaData)
/**
* @brief Load the bundle categorized icons. Actual textures are downloaded on demand
*
* @param bundlePath local path to the bundle folder and icons
* @param metaData bundle textures metadata
*/
void ContentLibraryTexturesModel::loadTextureBundle(const QString &bundlePath, const QVariantMap &metaData)
{
QDir bundleDir = QDir(bundlePath);
if (!m_bundleCategories.isEmpty())
return;
QDir bundleDir = QString("%1/%2").arg(bundlePath, m_category);
if (!bundleDir.exists()) {
qWarning() << __FUNCTION__ << "textures bundle folder doesn't exist." << bundlePath;
return;
}
if (!m_bundleCategories.isEmpty())
return;
QString remoteBaseUrl = QmlDesignerPlugin::settings()
.value(DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL).toString()
+ '/' + m_category;
const QFileInfoList dirs = bundleDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QFileInfo &dir : dirs) {
auto category = new ContentLibraryTexturesCategory(this, dir.fileName());
const QFileInfoList texFiles = QDir(dir.filePath() + "/icon").entryInfoList(QDir::Files);
for (const QFileInfo &tex : texFiles) {
QString zipPath = '/' + dir.fileName() + '/' + tex.baseName() + ".zip";
QString urlPath = baseUrl + zipPath;
QString downloadPath = m_downloadPath + '/' + dir.fileName();
QString fullZipPath = m_bundleSubPath + zipPath;
QString fullRemoteUrl = QString("%1/%2/%3.zip").arg(remoteBaseUrl, dir.fileName(),
tex.baseName());
QString localDownloadPath = QString("%1/%2/%3").arg(QmlDesignerBasePlugin::bundlesPathSetting(),
m_category, dir.fileName());
QString key = QString("%1/%2/%3.zip").arg(m_category, dir.fileName(), tex.baseName());
QString fileExt;
QSize dimensions;
qint64 sizeInBytes = -1;
if (metaData.contains(fullZipPath)) {
QVariantMap dataMap = metaData[fullZipPath].toMap();
if (metaData.contains(key)) {
QVariantMap dataMap = metaData[key].toMap();
fileExt = '.' + dataMap.value("format").toString();
dimensions = QSize(dataMap.value("width").toInt(), dataMap.value("height").toInt());
sizeInBytes = dataMap.value("size").toLongLong();
}
category->addTexture(tex, downloadPath, urlPath, fileExt, dimensions, sizeInBytes);
category->addTexture(tex, localDownloadPath, fullRemoteUrl, fileExt, dimensions, sizeInBytes);
}
m_bundleCategories.append(category);
}

View File

@@ -18,7 +18,7 @@ class ContentLibraryTexturesModel : public QAbstractListModel
Q_PROPERTY(bool hasSceneEnv READ hasSceneEnv NOTIFY hasSceneEnvChanged)
public:
ContentLibraryTexturesModel(const QString &bundleSubpath, QObject *parent = nullptr);
ContentLibraryTexturesModel(const QString &category, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@@ -33,8 +33,7 @@ public:
void setHasSceneEnv(bool b);
void resetModel();
void loadTextureBundle(const QString &bundlePath, const QString &baseUrl,
const QVariantMap &metaData);
void loadTextureBundle(const QString &bundlePath, const QVariantMap &metaData);
signals:
void isEmptyChanged();
@@ -46,8 +45,7 @@ private:
void updateIsEmpty();
QString m_searchText;
QString m_downloadPath;
QString m_bundleSubPath;
QString m_category;
QList<ContentLibraryTexturesCategory *> m_bundleCategories;
bool m_isEmpty = true;

View File

@@ -106,19 +106,14 @@ ContentLibraryWidget::ContentLibraryWidget()
m_quickWidget->setClearColor(Theme::getColor(Theme::Color::DSpanelBackground));
QString textureBundlePath = findTextureBundlePath();
QString baseUrl = QmlDesignerPlugin::settings()
.value(DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL)
.toString();
QVariantMap metaData;
QFile jsonFile(textureBundlePath + "/texture_bundle.json");
if (jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
metaData = QJsonDocument::fromJson(jsonFile.readAll()).toVariant().toMap();
m_texturesModel->loadTextureBundle(textureBundlePath + "/Textures",
baseUrl + "/Textures", metaData);
m_environmentsModel->loadTextureBundle(textureBundlePath + "/Environments",
baseUrl + "/Environments", metaData);
m_texturesModel->loadTextureBundle(textureBundlePath, metaData);
m_environmentsModel->loadTextureBundle(textureBundlePath, metaData);
Theme::setupTheme(m_quickWidget->engine());
m_quickWidget->quickWidget()->installEventFilter(this);

View File

@@ -2,20 +2,21 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "qmldesignerplugin.h"
#include "coreplugin/iwizardfactory.h"
#include "designmodecontext.h"
#include "designmodewidget.h"
#include "dynamiclicensecheck.h"
#include "exception.h"
#include "generateresource.h"
#include "nodeinstanceview.h"
#include "openuiqmlfiledialog.h"
#include "qmldesignerconstants.h"
#include "qmldesignerexternaldependencies.h"
#include "qmldesignerprojectmanager.h"
#include "quick2propertyeditorview.h"
#include "settingspage.h"
#include <toolbar.h>
#include "shortcutmanager.h"
#include "toolbar.h"
#include <colortool/colortool.h>
#include <connectionview.h>

View File

@@ -5,7 +5,6 @@
#include "documentmanager.h"
#include "qmldesigner_global.h"
#include "shortcutmanager.h"
#include <designersettings.h>
#include <viewmanager.h>
@@ -13,6 +12,7 @@
#include <extensionsystem/iplugin.h>
#include <qmldesignerbase/qmldesignerbaseplugin.h>
#include <QElapsedTimer>
@@ -114,6 +114,7 @@ private: // variables
QmlDesignerPluginPrivate *d = nullptr;
static QmlDesignerPlugin *m_instance;
QElapsedTimer m_usageTimer;
StudioConfigSettingsPage m_settingsPage;
};
} // namespace QmlDesigner

View File

@@ -5,10 +5,27 @@
#include "utils/designersettings.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/dialogs/restartdialog.h>
#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/hostosinfo.h>
#include <QCheckBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSpacerItem>
#include <QStandardPaths>
#include <QVBoxLayout>
namespace QmlDesigner {
const char EXAMPLES_DOWNLOAD_PATH[] = "StudioConfig/ExamplesDownloadPath";
const char BUNDLES_DOWNLOAD_PATH[] = "StudioConfig/BundlesDownloadPath";
class QmlDesignerBasePlugin::Data
{
public:
@@ -24,6 +41,12 @@ QmlDesignerBasePlugin::QmlDesignerBasePlugin()
global = this;
};
QmlDesignerBasePlugin *QmlDesignerBasePlugin::instance()
{
return global;
};
QmlDesignerBasePlugin::~QmlDesignerBasePlugin() = default;
DesignerSettings &QmlDesignerBasePlugin::settings()
@@ -38,4 +61,212 @@ bool QmlDesignerBasePlugin::initialize(const QStringList &, QString *)
return true;
}
Utils::FilePath QmlDesignerBasePlugin::defaultExamplesPath()
{
QStandardPaths::StandardLocation location = Utils::HostOsInfo::isMacHost()
? QStandardPaths::HomeLocation
: QStandardPaths::DocumentsLocation;
return Utils::FilePath::fromString(QStandardPaths::writableLocation(location))
.pathAppended("QtDesignStudio/examples");
}
Utils::FilePath QmlDesignerBasePlugin::defaultBundlesPath()
{
QStandardPaths::StandardLocation location = Utils::HostOsInfo::isMacHost()
? QStandardPaths::HomeLocation
: QStandardPaths::DocumentsLocation;
return Utils::FilePath::fromString(QStandardPaths::writableLocation(location))
.pathAppended("QtDesignStudio/bundles");
}
QString QmlDesignerBasePlugin::examplesPathSetting()
{
return Core::ICore::settings()
->value(EXAMPLES_DOWNLOAD_PATH, defaultExamplesPath().toString())
.toString();
}
QString QmlDesignerBasePlugin::bundlesPathSetting()
{
return Core::ICore::settings()
->value(BUNDLES_DOWNLOAD_PATH, defaultBundlesPath().toString())
.toString();
}
static bool hideBuildMenuSetting()
{
return Core::ICore::settings()
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_BUILD, false)
.toBool();
}
static bool hideDebugMenuSetting()
{
return Core::ICore::settings()
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_DEBUG, false)
.toBool();
}
static bool hideAnalyzeMenuSetting()
{
return Core::ICore::settings()
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_ANALYZE, false)
.toBool();
}
static bool hideToolsMenuSetting()
{
return Core::ICore::settings()->value(Core::Constants::SETTINGS_MENU_HIDE_TOOLS, false).toBool();
}
void setSettingIfDifferent(const QString &key, bool value, bool &dirty)
{
QSettings *s = Core::ICore::settings();
if (s->value(key, false).toBool() != value) {
dirty = true;
s->setValue(key, value);
}
}
StudioSettingsPage::StudioSettingsPage()
: m_buildCheckBox(new QCheckBox(tr("Build")))
, m_debugCheckBox(new QCheckBox(tr("Debug")))
, m_analyzeCheckBox(new QCheckBox(tr("Analyze")))
, m_toolsCheckBox(new QCheckBox(tr("Tools")))
, m_pathChooserExamples(new Utils::PathChooser())
, m_pathChooserBundles(new Utils::PathChooser())
{
const QString toolTip = tr(
"Hide top-level menus with advanced functionality to simplify the UI. <b>Build</b> is "
"generally not required in the context of Qt Design Studio. <b>Debug</b> and "
"<b>Analyze</b> "
"are only required for debugging and profiling. <b>Tools</b> can be useful for bookmarks "
"and git integration.");
QVBoxLayout *boxLayout = new QVBoxLayout();
setLayout(boxLayout);
auto groupBox = new QGroupBox(tr("Hide Menu"));
groupBox->setToolTip(toolTip);
boxLayout->addWidget(groupBox);
auto verticalLayout = new QVBoxLayout();
groupBox->setLayout(verticalLayout);
m_buildCheckBox->setToolTip(toolTip);
m_debugCheckBox->setToolTip(toolTip);
m_analyzeCheckBox->setToolTip(toolTip);
m_toolsCheckBox->setToolTip(toolTip);
verticalLayout->addWidget(m_buildCheckBox);
verticalLayout->addWidget(m_debugCheckBox);
verticalLayout->addWidget(m_analyzeCheckBox);
verticalLayout->addWidget(m_toolsCheckBox);
verticalLayout->addSpacerItem(
new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum));
m_buildCheckBox->setChecked(hideBuildMenuSetting());
m_debugCheckBox->setChecked(hideDebugMenuSetting());
m_analyzeCheckBox->setChecked(hideAnalyzeMenuSetting());
m_toolsCheckBox->setChecked(hideToolsMenuSetting());
// Examples path setting
auto examplesGroupBox = new QGroupBox(tr("Examples"));
boxLayout->addWidget(examplesGroupBox);
auto examplesLayout = new QHBoxLayout(this);
examplesGroupBox->setLayout(examplesLayout);
auto examplesLabel = new QLabel(tr("Examples path:"));
m_pathChooserExamples->setFilePath(
Utils::FilePath::fromString(QmlDesignerBasePlugin::examplesPathSetting()));
auto examplesResetButton = new QPushButton(tr("Reset Path"));
connect(examplesResetButton, &QPushButton::clicked, this, [this]() {
m_pathChooserExamples->setFilePath(QmlDesignerBasePlugin::defaultExamplesPath());
});
examplesLayout->addWidget(examplesLabel);
examplesLayout->addWidget(m_pathChooserExamples);
examplesLayout->addWidget(examplesResetButton);
// Bundles path setting
auto bundlesGroupBox = new QGroupBox(tr("Bundles"));
boxLayout->addWidget(bundlesGroupBox);
auto bundlesLayout = new QHBoxLayout(this);
bundlesGroupBox->setLayout(bundlesLayout);
QLabel *bundlesLabel = new QLabel(tr("Bundles path:"));
m_pathChooserBundles->setFilePath(
Utils::FilePath::fromString(QmlDesignerBasePlugin::bundlesPathSetting()));
QPushButton *bundlesResetButton = new QPushButton(tr("Reset Path"));
connect(bundlesResetButton, &QPushButton::clicked, this, [this]() {
m_pathChooserBundles->setFilePath(QmlDesignerBasePlugin::defaultBundlesPath());
});
bundlesLayout->addWidget(bundlesLabel);
bundlesLayout->addWidget(m_pathChooserBundles);
bundlesLayout->addWidget(bundlesResetButton);
boxLayout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));
}
void StudioSettingsPage::apply()
{
bool dirty = false;
setSettingIfDifferent(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_BUILD,
m_buildCheckBox->isChecked(),
dirty);
setSettingIfDifferent(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_DEBUG,
m_debugCheckBox->isChecked(),
dirty);
setSettingIfDifferent(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_ANALYZE,
m_analyzeCheckBox->isChecked(),
dirty);
setSettingIfDifferent(Core::Constants::SETTINGS_MENU_HIDE_TOOLS,
m_toolsCheckBox->isChecked(),
dirty);
if (dirty) {
const QString restartText = tr("The menu visibility change will take effect after restart.");
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
restartDialog.exec();
}
QSettings *s = Core::ICore::settings();
const QString value = m_pathChooserExamples->filePath().toString();
if (s->value(EXAMPLES_DOWNLOAD_PATH, false).toString() != value) {
s->setValue(EXAMPLES_DOWNLOAD_PATH, value);
emit global->examplesDownloadPathChanged(value);
}
const QString bundlesPath = m_pathChooserBundles->filePath().toString();
if (s->value(BUNDLES_DOWNLOAD_PATH).toString() != bundlesPath) {
s->setValue(BUNDLES_DOWNLOAD_PATH, bundlesPath);
emit global->bundlesDownloadPathChanged(bundlesPath);
const QString restartText = tr("Changing bundle path will take effect after restart.");
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
restartDialog.exec();
}
}
StudioConfigSettingsPage::StudioConfigSettingsPage()
{
setId("Z.StudioConfig.Settings");
setDisplayName(tr("Qt Design Studio Configuration"));
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
setWidgetCreator([] { return new StudioSettingsPage; });
}
} // namespace QmlDesigner

View File

@@ -5,12 +5,42 @@
#include "qmldesignerbase_global.h"
#include <coreplugin/dialogs/ioptionspage.h>
#include <extensionsystem/iplugin.h>
#include <utils/pathchooser.h>
#include <memory>
QT_FORWARD_DECLARE_CLASS(QCheckBox)
namespace QmlDesigner {
class StudioSettingsPage : public Core::IOptionsPageWidget
{
Q_OBJECT
public:
void apply() final;
StudioSettingsPage();
private:
QCheckBox *m_buildCheckBox;
QCheckBox *m_debugCheckBox;
QCheckBox *m_analyzeCheckBox;
QCheckBox *m_toolsCheckBox;
Utils::PathChooser *m_pathChooserExamples;
Utils::PathChooser *m_pathChooserBundles;
};
class QMLDESIGNERBASE_EXPORT StudioConfigSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
StudioConfigSettingsPage();
};
class QMLDESIGNERBASE_EXPORT QmlDesignerBasePlugin final : public ExtensionSystem::IPlugin
{
Q_OBJECT
@@ -20,8 +50,19 @@ public:
QmlDesignerBasePlugin();
~QmlDesignerBasePlugin();
static QmlDesignerBasePlugin *instance();
static Utils::FilePath defaultExamplesPath();
static Utils::FilePath defaultBundlesPath();
static QString examplesPathSetting();
static QString bundlesPathSetting();
static class DesignerSettings &settings();
signals:
void examplesDownloadPathChanged(const QString &path);
void bundlesDownloadPathChanged(const QString &path);
private:
bool initialize(const QStringList &arguments, QString *errorMessage) override;

View File

@@ -7,6 +7,8 @@
#include <coreplugin/documentmanager.h>
#include <coreplugin/icore.h>
#include <qmldesignerbase/qmldesignerbaseplugin.h>
#include <utils/archive.h>
#include <utils/algorithm.h>
#include <utils/networkaccessmanager.h>
@@ -60,7 +62,7 @@ bool DataModelDownloader::downloadEnabled() const
QString DataModelDownloader::targetPath() const
{
return StudioWelcome::Internal::StudioWelcomePlugin::examplesPathSetting();
return QmlDesigner::QmlDesignerBasePlugin::examplesPathSetting();
}
static Utils::FilePath tempFilePath()
@@ -104,8 +106,8 @@ DataModelDownloader::DataModelDownloader(QObject * /* parent */)
auto studioWelcomePlugin = qobject_cast<StudioWelcome::Internal::StudioWelcomePlugin *>(plugin);
if (studioWelcomePlugin) {
QObject::connect(studioWelcomePlugin,
&StudioWelcome::Internal::StudioWelcomePlugin::examplesDownloadPathChanged,
QObject::connect(QmlDesigner::QmlDesignerBasePlugin::instance(),
&QmlDesigner::QmlDesignerBasePlugin::examplesDownloadPathChanged,
this,
&DataModelDownloader::targetPathMustChange);
}

View File

@@ -4,15 +4,14 @@
#include "studiowelcomeplugin.h"
#include "examplecheckout.h"
#include "projectexplorer/target.h"
#include "qdsnewdialog.h"
#include <app/app_version.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/dialogs/restartdialog.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/helpmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/imode.h>
@@ -20,8 +19,8 @@
#include <projectexplorer/jsonwizard/jsonwizardfactory.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmanager.h>
#include "projectexplorer/target.h"
#include <qmlprojectmanager/projectfilecontenttools.h>
#include <qmlprojectmanager/qmlproject.h>
@@ -40,14 +39,11 @@
#include <QAbstractListModel>
#include <QApplication>
#include <QCheckBox>
#include <QDesktopServices>
#include <QFileInfo>
#include <QFontDatabase>
#include <QGroupBox>
#include <QMainWindow>
#include <QPointer>
#include <QPushButton>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickItem>
@@ -92,8 +88,6 @@ const char STATISTICS_COLLECTION_MODE[] = "StatisticsCollectionMode";
const char NO_TELEMETRY[] = "NoTelemetry";
const char CRASH_REPORTER_SETTING[] = "CrashReportingEnabled";
const char EXAMPLES_DOWNLOAD_PATH[] = "StudioWelcome/ExamplesDownloadPath";
QPointer<QQuickView> s_viewWindow = nullptr;
QPointer<QQuickWidget> s_viewWidget = nullptr;
static StudioWelcomePlugin *s_pluginInstance = nullptr;
@@ -647,23 +641,6 @@ bool StudioWelcomePlugin::delayedInitialize()
return true;
}
Utils::FilePath StudioWelcomePlugin::defaultExamplesPath()
{
QStandardPaths::StandardLocation location = Utils::HostOsInfo::isMacHost()
? QStandardPaths::HomeLocation
: QStandardPaths::DocumentsLocation;
return Utils::FilePath::fromString(QStandardPaths::writableLocation(location))
.pathAppended("QtDesignStudio/examples");
}
QString StudioWelcomePlugin::examplesPathSetting()
{
return Core::ICore::settings()
->value(EXAMPLES_DOWNLOAD_PATH, defaultExamplesPath().toString())
.toString();
}
WelcomeMode::WelcomeMode()
{
setDisplayName(tr("Welcome"));
@@ -748,41 +725,6 @@ WelcomeMode::WelcomeMode()
[](const QString &path) { return QFileInfo::exists(path); }));
}
static bool hideBuildMenuSetting()
{
return Core::ICore::settings()
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_BUILD, false)
.toBool();
}
static bool hideDebugMenuSetting()
{
return Core::ICore::settings()
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_DEBUG, false)
.toBool();
}
static bool hideAnalyzeMenuSetting()
{
return Core::ICore::settings()
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_ANALYZE, false)
.toBool();
}
static bool hideToolsMenuSetting()
{
return Core::ICore::settings()->value(Core::Constants::SETTINGS_MENU_HIDE_TOOLS, false).toBool();
}
void setSettingIfDifferent(const QString &key, bool value, bool &dirty)
{
QSettings *s = Core::ICore::settings();
if (s->value(key, false).toBool() != value) {
dirty = true;
s->setValue(key, value);
}
}
WelcomeMode::~WelcomeMode()
{
delete m_modeWidget;
@@ -836,114 +778,6 @@ void WelcomeMode::createQuickWidget()
m_quickWidget->engine()->setOutputWarningsToStandardError(false);
}
StudioSettingsPage::StudioSettingsPage()
: m_buildCheckBox(new QCheckBox(tr("Build")))
, m_debugCheckBox(new QCheckBox(tr("Debug")))
, m_analyzeCheckBox(new QCheckBox(tr("Analyze")))
, m_toolsCheckBox(new QCheckBox(tr("Tools")))
, m_pathChooser(new Utils::PathChooser())
{
const QString toolTip = tr(
"Hide top-level menus with advanced functionality to simplify the UI. <b>Build</b> is "
"generally not required in the context of Qt Design Studio. <b>Debug</b> and "
"<b>Analyze</b> "
"are only required for debugging and profiling. <b>Tools</b> can be useful for bookmarks "
"and git integration.");
QVBoxLayout *boxLayout = new QVBoxLayout();
setLayout(boxLayout);
auto groupBox = new QGroupBox(tr("Hide Menu"));
groupBox->setToolTip(toolTip);
boxLayout->addWidget(groupBox);
auto verticalLayout = new QVBoxLayout();
groupBox->setLayout(verticalLayout);
m_buildCheckBox->setToolTip(toolTip);
m_debugCheckBox->setToolTip(toolTip);
m_analyzeCheckBox->setToolTip(toolTip);
m_toolsCheckBox->setToolTip(toolTip);
verticalLayout->addWidget(m_buildCheckBox);
verticalLayout->addWidget(m_debugCheckBox);
verticalLayout->addWidget(m_analyzeCheckBox);
verticalLayout->addWidget(m_toolsCheckBox);
verticalLayout->addSpacerItem(
new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum));
m_buildCheckBox->setChecked(hideBuildMenuSetting());
m_debugCheckBox->setChecked(hideDebugMenuSetting());
m_analyzeCheckBox->setChecked(hideAnalyzeMenuSetting());
m_toolsCheckBox->setChecked(hideToolsMenuSetting());
auto examplesGroupBox = new QGroupBox(tr("Examples"));
boxLayout->addWidget(examplesGroupBox);
auto horizontalLayout = new QHBoxLayout();
examplesGroupBox->setLayout(horizontalLayout);
auto label = new QLabel(tr("Examples path:"));
m_pathChooser->setFilePath(
Utils::FilePath::fromString(StudioWelcomePlugin::examplesPathSetting()));
auto resetButton = new QPushButton(tr("Reset Path"));
connect(resetButton, &QPushButton::clicked, this, [this]() {
m_pathChooser->setFilePath(StudioWelcomePlugin::defaultExamplesPath());
});
horizontalLayout->addWidget(label);
horizontalLayout->addWidget(m_pathChooser);
horizontalLayout->addWidget(resetButton);
boxLayout->addSpacerItem(
new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));
}
void StudioSettingsPage::apply()
{
bool dirty = false;
setSettingIfDifferent(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_BUILD,
m_buildCheckBox->isChecked(),
dirty);
setSettingIfDifferent(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_DEBUG,
m_debugCheckBox->isChecked(),
dirty);
setSettingIfDifferent(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_ANALYZE,
m_analyzeCheckBox->isChecked(),
dirty);
setSettingIfDifferent(Core::Constants::SETTINGS_MENU_HIDE_TOOLS,
m_toolsCheckBox->isChecked(),
dirty);
if (dirty) {
const QString restartText = tr("The menu visibility change will take effect after restart.");
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
restartDialog.exec();
}
QSettings *s = Core::ICore::settings();
const QString value = m_pathChooser->filePath().toString();
if (s->value(EXAMPLES_DOWNLOAD_PATH, false).toString() != value) {
s->setValue(EXAMPLES_DOWNLOAD_PATH, value);
emit s_pluginInstance->examplesDownloadPathChanged(value);
}
}
StudioWelcomeSettingsPage::StudioWelcomeSettingsPage()
{
setId("Z.StudioWelcome.Settings");
setDisplayName(tr("Qt Design Studio Configuration"));
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
setWidgetCreator([] { return new StudioSettingsPage; });
}
} // namespace Internal
} // namespace StudioWelcome

View File

@@ -5,40 +5,12 @@
#include <extensionsystem/iplugin.h>
#include <coreplugin/dialogs/ioptionspage.h>
#include <utils/pathchooser.h>
#include <QTimer>
QT_FORWARD_DECLARE_CLASS(QCheckBox)
namespace StudioWelcome {
namespace Internal {
class StudioSettingsPage : public Core::IOptionsPageWidget
{
Q_OBJECT
public:
void apply() final;
StudioSettingsPage();
private:
QCheckBox *m_buildCheckBox;
QCheckBox *m_debugCheckBox;
QCheckBox *m_analyzeCheckBox;
QCheckBox *m_toolsCheckBox;
Utils::PathChooser *m_pathChooser;
};
class StudioWelcomeSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
StudioWelcomeSettingsPage();
};
class StudioWelcomePlugin final : public ExtensionSystem::IPlugin
{
Q_OBJECT
@@ -55,15 +27,8 @@ public:
void extensionsInitialized() override;
bool delayedInitialize() override;
static Utils::FilePath defaultExamplesPath();
static QString examplesPathSetting();
signals:
void examplesDownloadPathChanged(const QString &path);
private:
class WelcomeMode *m_welcomeMode = nullptr;
StudioWelcomeSettingsPage m_settingsPage;
};
} // namespace Internal