diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2024-04-20 00:25:43 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2024-04-23 09:51:51 +0000 |
commit | a369d075ad6f042823e5a3742162cd3858cc055a (patch) | |
tree | 607a43fb5006bd3ede2a6e71186f7ab7a354b674 /src | |
parent | cbc617d2ad1d881fd9c40445e65bce83f2689b8e (diff) |
QmlDesigner: Implement adding an image to the content library
Also some cleanups in same files.
Fixes: QDS-12506
Change-Id: I0c211206b6b7c29857a30f18d6077c2ddd76849c
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Diffstat (limited to 'src')
12 files changed, 134 insertions, 48 deletions
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp index dc5a1c9741..b821cc6595 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "assetslibraryiconprovider.h" -#include "asset.h" -#include "modelnodeoperations.h" +#include <modelnodeoperations.h> #include <theme.h> #include <utils/hdrimage.h> #include <utils/ktximage.h> diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h index fb38605ea6..d52779232f 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h @@ -3,12 +3,11 @@ #pragma once +#include <asset.h> #include <synchronousimagecache.h> #include <QQuickImageProvider> -#include "asset.h" - namespace QmlDesigner { struct Thumbnail diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index c2359409eb..9d09f52d8f 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -1,21 +1,19 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include <QCheckBox> -#include <QFileInfo> -#include <QFileSystemModel> -#include <QMessageBox> -#include <QSortFilterProxyModel> - -#include "asset.h" #include "assetslibrarymodel.h" +#include <asset.h> #include <modelnodeoperations.h> #include <qmldesignerplugin.h> #include <coreplugin/icore.h> #include <utils/algorithm.h> -#include <utils/qtcassert.h> +#include <utils/filesystemwatcher.h> + +#include <QFileInfo> +#include <QFileSystemModel> +#include <QMessageBox> namespace QmlDesigner { @@ -38,7 +36,7 @@ void AssetsLibraryModel::createBackendModel() QObject::connect(m_sourceFsModel, &QFileSystemModel::directoryLoaded, this, [this]([[maybe_unused]] const QString &dir) { - syncHaveFiles(); + syncHasFiles(); }); m_fileWatcher = new Utils::FileSystemWatcher(parent()); @@ -207,7 +205,7 @@ bool AssetsLibraryModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour } } -bool AssetsLibraryModel::checkHaveFiles(const QModelIndex &parentIdx) const +bool AssetsLibraryModel::checkHasFiles(const QModelIndex &parentIdx) const { if (!parentIdx.isValid()) return false; @@ -218,30 +216,30 @@ bool AssetsLibraryModel::checkHaveFiles(const QModelIndex &parentIdx) const if (!isDirectory(newIdx)) return true; - if (checkHaveFiles(newIdx)) + if (checkHasFiles(newIdx)) return true; } return false; } -void AssetsLibraryModel::setHaveFiles(bool value) +void AssetsLibraryModel::setHasFiles(bool value) { - if (m_haveFiles != value) { - m_haveFiles = value; - emit haveFilesChanged(); + if (m_hasFiles != value) { + m_hasFiles = value; + emit hasFilesChanged(); } } -bool AssetsLibraryModel::checkHaveFiles() const +bool AssetsLibraryModel::checkHasFiles() const { auto rootIdx = indexForPath(m_rootPath); - return checkHaveFiles(rootIdx); + return checkHasFiles(rootIdx); } -void AssetsLibraryModel::syncHaveFiles() +void AssetsLibraryModel::syncHasFiles() { - setHaveFiles(checkHaveFiles()); + setHasFiles(checkHasFiles()); } QString AssetsLibraryModel::getUniqueName(const QString &oldName) { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index 9334e86e9b..2516be787f 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -3,12 +3,13 @@ #pragma once -#include <QFileInfo> -#include <QFileSystemModel> #include <QSortFilterProxyModel> -#include <utils/filesystemwatcher.h> -#include <utils/qtcassert.h> +namespace Utils { +class FileSystemWatcher; +} + +QT_FORWARD_DECLARE_CLASS(QFileSystemModel) namespace QmlDesigner { @@ -22,7 +23,7 @@ public: void setRootPath(const QString &newPath); void setSearchText(const QString &searchText); - Q_PROPERTY(bool haveFiles READ haveFiles NOTIFY haveFilesChanged); + Q_PROPERTY(bool hasFiles READ hasFiles NOTIFY hasFilesChanged) Q_INVOKABLE QString rootPath() const; Q_INVOKABLE QString filePath(const QModelIndex &index) const; @@ -35,7 +36,7 @@ public: Q_INVOKABLE QModelIndex parentDirIndex(const QString &path) const; Q_INVOKABLE QModelIndex parentDirIndex(const QModelIndex &index) const; Q_INVOKABLE QString parentDirPath(const QString &path) const; - Q_INVOKABLE void syncHaveFiles(); + Q_INVOKABLE void syncHasFiles(); Q_INVOKABLE QList<QModelIndex> parentIndices(const QModelIndex &index) const; Q_INVOKABLE bool indexIsValid(const QModelIndex &index) const; @@ -55,30 +56,30 @@ public: return std::min(result, 1); } - bool haveFiles() const { return m_haveFiles; } + bool hasFiles() const { return m_hasFiles; } QString getUniqueName(const QString &oldName); signals: void directoryLoaded(const QString &path); void rootPathChanged(); - void haveFilesChanged(); + void hasFilesChanged(); void fileChanged(const QString &path); void effectsDeleted(const QStringList &effectNames); private: - void setHaveFiles(bool value); + void setHasFiles(bool value); bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; void resetModel(); void createBackendModel(); void destroyBackendModel(); - bool checkHaveFiles(const QModelIndex &parentIdx) const; - bool checkHaveFiles() const; + bool checkHasFiles(const QModelIndex &parentIdx) const; + bool checkHasFiles() const; QString m_searchText; QString m_rootPath; QFileSystemModel *m_sourceFsModel = nullptr; - bool m_haveFiles = false; + bool m_hasFiles = false; Utils::FileSystemWatcher *m_fileWatcher = nullptr; }; diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index bcaa5351fd..4b270c8902 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -3,20 +3,22 @@ #include "assetslibrarywidget.h" -#include "asset.h" #include "assetslibraryiconprovider.h" #include "assetslibrarymodel.h" #include "assetslibraryview.h" -#include "designeractionmanager.h" -#include "import.h" -#include "modelnodeoperations.h" -#include "nodemetainfo.h" -#include "qmldesignerconstants.h" -#include "qmldesignerplugin.h" -#include "theme.h" -#include <utils3d.h> +#include <asset.h> +#include <designeractionmanager.h> +#include <designerpaths.h> +#include <hdrimage.h> +#include <import.h> +#include <modelnodeoperations.h> +#include <nodemetainfo.h> +#include <qmldesignerconstants.h> +#include <qmldesignerplugin.h> #include <studioquickwidget.h> +#include <theme.h> +#include <utils3d.h> #include <coreplugin/fileutils.h> #include <coreplugin/icore.h> @@ -376,7 +378,7 @@ QList<QToolButton *> AssetsLibraryWidget::createToolBarWidgets() void AssetsLibraryWidget::handleSearchFilterChanged(const QString &filterText) { - if (filterText == m_filterText || (!m_assetsModel->haveFiles() + if (filterText == m_filterText || (!m_assetsModel->hasFiles() && filterText.contains(m_filterText, Qt::CaseInsensitive))) return; @@ -645,4 +647,15 @@ void AssetsLibraryWidget::addResources(const QStringList &files, bool showDialog } } +bool AssetsLibraryWidget::userBundleEnabled() const +{ + // TODO: this method is to be removed after user bundle implementation is complete + return Core::ICore::settings()->value("QML/Designer/UseExperimentalFeatures45", false).toBool(); +} + +void AssetsLibraryWidget::addAssetsToContentLibrary(const QStringList &assetPaths) +{ + m_assetsView->emitCustomNotification("add_assets_to_content_lib", {}, {assetPaths}); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h index ed987d14de..8b59ae0785 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h @@ -98,6 +98,8 @@ public: Q_INVOKABLE void showInGraphicalShell(const QString &path); Q_INVOKABLE QString showInGraphicalShellMsg() const; + Q_INVOKABLE bool userBundleEnabled() const; + Q_INVOKABLE void addAssetsToContentLibrary(const QStringList &assetPaths); signals: void itemActivated(const QString &itemName); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp index 243e0d9662..18d6e45fa8 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp @@ -94,7 +94,30 @@ void ContentLibraryUserModel::addMaterial(const QString &name, const QString &qm m_userMaterials.append(libMat); int matSectionIdx = 0; - emit dataChanged(index(matSectionIdx, 0), index(matSectionIdx, 0)); + emit dataChanged(index(matSectionIdx), index(matSectionIdx)); +} + +void ContentLibraryUserModel::addTextures(const QStringList &paths) +{ + QDir bundleDir{Paths::bundlesPathSetting() + "/User/textures"}; + bundleDir.mkpath("."); + bundleDir.mkdir("icons"); + + for (const QString &path : paths) { + QFileInfo fileInfo(path); + QString suffix = '.' + fileInfo.suffix(); + auto iconFileInfo = QFileInfo(fileInfo.path().append("/icons/").append(fileInfo.baseName() + ".png")); + QPair<QSize, qint64> info = ImageUtils::imageInfo(path); + QString dirPath = fileInfo.path(); + QSize imgDims = info.first; + qint64 imgFileSize = info.second; + + auto tex = new ContentLibraryTexture(this, iconFileInfo, dirPath, suffix, imgDims, imgFileSize); + m_userTextures.append(tex); + } + + int texSectionIdx = 1; + emit dataChanged(index(texSectionIdx), index(texSectionIdx)); } // returns unique library material's name and qml component @@ -273,10 +296,10 @@ void ContentLibraryUserModel::loadTextureBundle() const QFileInfoList fileInfos = bundleDir.entryInfoList(QDir::Files); for (const QFileInfo &fileInfo : fileInfos) { - auto iconFileInfo = QFileInfo(fileInfo.path().append("/icons/").append(fileInfo.fileName())); + QString suffix = '.' + fileInfo.suffix(); + auto iconFileInfo = QFileInfo(fileInfo.path().append("/icons/").append(fileInfo.baseName() + ".png")); QPair<QSize, qint64> info = ImageUtils::imageInfo(fileInfo.path()); QString dirPath = fileInfo.path(); - QString suffix = '.' + fileInfo.suffix(); QSize imgDims = info.first; qint64 imgFileSize = info.second; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h index 26edbf5ec3..3e9a96fd9d 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h @@ -62,6 +62,7 @@ public: void updateIsEmpty(); void addMaterial(const QString &name, const QString &qml, const QUrl &icon, const QStringList &files); + void addTextures(const QStringList &paths); void setBundleObj(const QJsonObject &newBundleObj); QJsonObject &bundleJsonObjectRef(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 91e402116a..dd8a4d9919 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -397,6 +397,8 @@ void ContentLibraryView::customNotification(const AbstractView *view, QTC_ASSERT(nodeList.size() == 1 && data.size() == 1, return); addLibMaterial(nodeList.first(), data.first().value<QPixmap>()); + } else if (identifier == "add_assets_to_content_lib") { + addLibAssets(data.first().toStringList()); } } @@ -655,6 +657,33 @@ QPair<QString, QSet<QString>> ContentLibraryView::modelNodeToQmlString(const Mod return {qml, assets}; } +void ContentLibraryView::addLibAssets(const QStringList &paths) +{ + auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/textures"); + QStringList pathsInBundle; + + for (const QString &path : paths) { + Asset asset(path); + auto assetPath = Utils::FilePath::fromString(path); + + // save icon + QString iconSavePath = bundlePath.pathAppended("icons/" + assetPath.baseName() + ".png").toString(); + QPixmap icon = asset.pixmap({120, 120}); + bool iconSaved = icon.save(iconSavePath); + if (!iconSaved) + qWarning() << __FUNCTION__ << "icon save failed"; + + // save asset + auto result = assetPath.copyFile(bundlePath.pathAppended(asset.fileName())); + if (!result) + qWarning() << __FUNCTION__ << result.error(); + + pathsInBundle.append(bundlePath.pathAppended(asset.fileName()).toString()); + } + + m_widget->userModel()->addTextures(pathsInBundle); +} + ModelNode ContentLibraryView::getBundleMaterialDefaultInstance(const TypeName &type) { ModelNode matLib = Utils3D::materialLibraryNode(this); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index d6ce50ed0e..03d42fa8bc 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -55,6 +55,7 @@ private: void updateBundleEffectsImportedState(); void updateBundlesQuick3DVersion(); void addLibMaterial(const ModelNode &mat, const QPixmap &icon); + void addLibAssets(const QStringList &paths); QStringList writeLibMaterialQml(const ModelNode &mat, const QString &qml); QPair<QString, QSet<QString>> modelNodeToQmlString(const ModelNode &node, QStringList &depListIds, int depth = 0); diff --git a/src/plugins/qmldesigner/utils/asset.cpp b/src/plugins/qmldesigner/utils/asset.cpp index f6753dc004..ec1e4312e4 100644 --- a/src/plugins/qmldesigner/utils/asset.cpp +++ b/src/plugins/qmldesigner/utils/asset.cpp @@ -3,7 +3,10 @@ #include "asset.h" +#include "hdrimage.h" + #include <QImageReader> +#include <QPixmap> namespace QmlDesigner { @@ -106,6 +109,19 @@ bool Asset::isSupported(const QString &path) return supportedSuffixes().contains(path); } +QPixmap Asset::pixmap(const QSize &size) const +{ + if (!isImage() && !isHdrFile()) + return {}; + + QPixmap icon = isHdrFile() ? HdrImage{m_filePath}.toPixmap() : QPixmap{m_filePath}; + + if (size.isValid()) + icon = icon.scaled(size, Qt::KeepAspectRatio); + + return icon; +} + Asset::Type Asset::type() const { return m_type; diff --git a/src/plugins/qmldesigner/utils/asset.h b/src/plugins/qmldesigner/utils/asset.h index 1b548a1c73..a5c5899f34 100644 --- a/src/plugins/qmldesigner/utils/asset.h +++ b/src/plugins/qmldesigner/utils/asset.h @@ -3,8 +3,11 @@ #pragma once +#include <QSize> #include <QString> +QT_FORWARD_DECLARE_CLASS(QPixmap) + namespace QmlDesigner { class Asset @@ -39,6 +42,7 @@ public: const QString id() const; const QString fileName() const; bool hasSuffix() const; + QPixmap pixmap(const QSize &size = {}) const; Type type() const; bool isImage() const; |