diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 9e040dba0e6..8018e76044d 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -22,6 +22,7 @@ add_qtc_library(QmlDesignerUtils STATIC SOURCES designersettings.cpp designersettings.h hdrimage.cpp hdrimage.h + imageutils.cpp imageutils.h qmldesignerutils_global.h ) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp index f348580937d..9972a446227 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp @@ -3,8 +3,8 @@ #include "materialbrowsertexturesmodel.h" -#include "designeractionmanager.h" #include "designmodewidget.h" +#include "imageutils.h" #include "qmldesignerplugin.h" #include "qmlobjectnode.h" #include "variantproperty.h" @@ -52,24 +52,18 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role) return m_textureList.at(index.row()).internalId(); if (role == RoleTexToolTip) { - QString source = QmlObjectNode(m_textureList.at(index.row())).modelValue("source").toString(); + QString source = data(index, RoleTexSource).toString(); // absolute path if (source.isEmpty()) return tr("Texture has no source image."); - const QString noData = tr("Texture has no data."); + ModelNode texNode = m_textureList.at(index.row()); + QString info = ImageUtils::imageInfo(source); - auto op = QmlDesignerPlugin::instance()->viewManager().designerActionManager() - .modelNodePreviewOperation(m_textureList.at(index.row())); - if (!op) - return noData; + if (info.isEmpty()) + return tr("Texture has no data."); - QVariantMap imgMap = op(m_textureList.at(index.row())).toMap(); - if (imgMap.isEmpty()) - return noData; - - return QLatin1String("%1\n%2\n%3").arg(imgMap.value("id").toString(), - source.split('/').last(), - imgMap.value("info").toString()); + QString sourceRelative = QmlObjectNode(texNode).modelValue("source").toString(); + return QLatin1String("%1\n%2\n%3").arg(texNode.id(), sourceRelative, info); } return {}; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index a1025cc9aa4..c715b659787 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -25,6 +25,7 @@ #include "createscenecommand.h" #include "debugoutputcommand.h" #include "informationchangedcommand.h" +#include "imageutils.h" #include "inputeventcommand.h" #include "nodeabstractproperty.h" #include "nodeinstanceserverproxy.h" @@ -83,6 +84,8 @@ #include #include +#include +#include #include #include #include @@ -135,13 +138,13 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager // related to a single event to be received before we act. m_resetTimer.setSingleShot(true); m_resetTimer.setInterval(100); - QObject::connect(&m_resetTimer, &QTimer::timeout, [this] { + QObject::connect(&m_resetTimer, &QTimer::timeout, this, [this] { if (isAttached()) resetPuppet(); }); m_updateWatcherTimer.setSingleShot(true); m_updateWatcherTimer.setInterval(100); - QObject::connect(&m_updateWatcherTimer, &QTimer::timeout, [this] { + QObject::connect(&m_updateWatcherTimer, &QTimer::timeout, this, [this] { for (const auto &path : std::as_const(m_pendingUpdateDirs)) updateWatcher(path); m_pendingUpdateDirs.clear(); @@ -152,11 +155,11 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager // unnecessary generation when project with multiple shaders is opened. m_generateQsbFilesTimer.setSingleShot(true); m_generateQsbFilesTimer.setInterval(100); - QObject::connect(&m_generateQsbFilesTimer, &QTimer::timeout, [this] { + QObject::connect(&m_generateQsbFilesTimer, &QTimer::timeout, this, [this] { handleShaderChanges(); }); - connect(m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, + connect(m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, [this](const QString &path) { const QSet pendingDirs = m_pendingUpdateDirs; for (const auto &pendingPath : pendingDirs) { @@ -172,7 +175,7 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager m_updateWatcherTimer.start(); }); - connect(m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, [this](const QString &path) { + connect(m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, this, [this](const QString &path) { if (m_qsbTargets.contains(path)) { m_qsbTargets.insert(path, true); m_generateQsbFilesTimer.start(); @@ -1910,23 +1913,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio); imageData.pixmap.setDevicePixelRatio(ratio); imageData.time = modified; - - double imgSize = double(imageFi.size()); - static QStringList units({::QmlDesigner::NodeInstanceView::tr("B"), - ::QmlDesigner::NodeInstanceView::tr("KB"), - ::QmlDesigner::NodeInstanceView::tr("MB"), - ::QmlDesigner::NodeInstanceView::tr("GB")}); - int unitIndex = 0; - while (imgSize > 1024. && unitIndex < units.size() - 1) { - ++unitIndex; - imgSize /= 1024.; - } - imageData.info = QStringLiteral("%1 x %2\n%3%4 (%5)") - .arg(originalPixmap.width()) - .arg(originalPixmap.height()) - .arg(QString::number(imgSize, 'g', 3)) - .arg(units[unitIndex]) - .arg(imageFi.suffix()); + imageData.info = ImageUtils::imageInfo(imageSource); m_imageDataMap.insert(imageData.id, imageData); } } diff --git a/src/plugins/qmldesigner/utils/imageutils.cpp b/src/plugins/qmldesigner/utils/imageutils.cpp new file mode 100644 index 00000000000..c1e3b8f4950 --- /dev/null +++ b/src/plugins/qmldesigner/utils/imageutils.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "imageutils.h" + +#include +#include +#include + +namespace QmlDesigner { + +QString QmlDesigner::ImageUtils::imageInfo(const QString &path) +{ + QFileInfo info(path); + if (!info.exists()) + return {}; + + int width = 0; + int height = 0; + if (info.suffix() == "hdr") { + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return {}; + + while (!file.atEnd()) { + QByteArray line = file.readLine(); + if (sscanf(line.constData(), "-Y %d +X %d", &height, &width)) + break; + } + } else { + QSize size = QImageReader(path).size(); + width = size.width(); + height = size.height(); + } + + if (width == 0 && height == 0) + return {}; + + return QLatin1String("%1 x %2\n%3 (%4)") + .arg(QString::number(width), + QString::number(height), + QLocale::system().formattedDataSize(info.size(), 2, QLocale::DataSizeTraditionalFormat), + info.suffix()); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/utils/imageutils.h b/src/plugins/qmldesigner/utils/imageutils.h new file mode 100644 index 00000000000..3b740b76b1e --- /dev/null +++ b/src/plugins/qmldesigner/utils/imageutils.h @@ -0,0 +1,17 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#pragma once + +#include + +namespace QmlDesigner { + +class ImageUtils +{ +public: + ImageUtils(); + + static QString imageInfo(const QString &path); +}; + +} // namespace QmlDesigner