forked from qt-creator/qt-creator
QmlDesigner: Optimize requesting an image info for tooltips
Avoid loading an image for the sole purpose of getting the dimensions. Also small relevant tweaks. Change-Id: I3d11175340cb77d3634fe7e69481ad26db8a74ef Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -22,6 +22,7 @@ add_qtc_library(QmlDesignerUtils STATIC
|
|||||||
SOURCES
|
SOURCES
|
||||||
designersettings.cpp designersettings.h
|
designersettings.cpp designersettings.h
|
||||||
hdrimage.cpp hdrimage.h
|
hdrimage.cpp hdrimage.h
|
||||||
|
imageutils.cpp imageutils.h
|
||||||
qmldesignerutils_global.h
|
qmldesignerutils_global.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "materialbrowsertexturesmodel.h"
|
#include "materialbrowsertexturesmodel.h"
|
||||||
|
|
||||||
#include "designeractionmanager.h"
|
|
||||||
#include "designmodewidget.h"
|
#include "designmodewidget.h"
|
||||||
|
#include "imageutils.h"
|
||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "qmlobjectnode.h"
|
#include "qmlobjectnode.h"
|
||||||
#include "variantproperty.h"
|
#include "variantproperty.h"
|
||||||
@@ -52,24 +52,18 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role)
|
|||||||
return m_textureList.at(index.row()).internalId();
|
return m_textureList.at(index.row()).internalId();
|
||||||
|
|
||||||
if (role == RoleTexToolTip) {
|
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())
|
if (source.isEmpty())
|
||||||
return tr("Texture has no source image.");
|
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()
|
if (info.isEmpty())
|
||||||
.modelNodePreviewOperation(m_textureList.at(index.row()));
|
return tr("Texture has no data.");
|
||||||
if (!op)
|
|
||||||
return noData;
|
|
||||||
|
|
||||||
QVariantMap imgMap = op(m_textureList.at(index.row())).toMap();
|
QString sourceRelative = QmlObjectNode(texNode).modelValue("source").toString();
|
||||||
if (imgMap.isEmpty())
|
return QLatin1String("%1\n%2\n%3").arg(texNode.id(), sourceRelative, info);
|
||||||
return noData;
|
|
||||||
|
|
||||||
return QLatin1String("%1\n%2\n%3").arg(imgMap.value("id").toString(),
|
|
||||||
source.split('/').last(),
|
|
||||||
imgMap.value("info").toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "createscenecommand.h"
|
#include "createscenecommand.h"
|
||||||
#include "debugoutputcommand.h"
|
#include "debugoutputcommand.h"
|
||||||
#include "informationchangedcommand.h"
|
#include "informationchangedcommand.h"
|
||||||
|
#include "imageutils.h"
|
||||||
#include "inputeventcommand.h"
|
#include "inputeventcommand.h"
|
||||||
#include "nodeabstractproperty.h"
|
#include "nodeabstractproperty.h"
|
||||||
#include "nodeinstanceserverproxy.h"
|
#include "nodeinstanceserverproxy.h"
|
||||||
@@ -83,6 +84,8 @@
|
|||||||
|
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QLocale>
|
||||||
#include <QMultiHash>
|
#include <QMultiHash>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPicture>
|
#include <QPicture>
|
||||||
@@ -135,13 +138,13 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager
|
|||||||
// related to a single event to be received before we act.
|
// related to a single event to be received before we act.
|
||||||
m_resetTimer.setSingleShot(true);
|
m_resetTimer.setSingleShot(true);
|
||||||
m_resetTimer.setInterval(100);
|
m_resetTimer.setInterval(100);
|
||||||
QObject::connect(&m_resetTimer, &QTimer::timeout, [this] {
|
QObject::connect(&m_resetTimer, &QTimer::timeout, this, [this] {
|
||||||
if (isAttached())
|
if (isAttached())
|
||||||
resetPuppet();
|
resetPuppet();
|
||||||
});
|
});
|
||||||
m_updateWatcherTimer.setSingleShot(true);
|
m_updateWatcherTimer.setSingleShot(true);
|
||||||
m_updateWatcherTimer.setInterval(100);
|
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))
|
for (const auto &path : std::as_const(m_pendingUpdateDirs))
|
||||||
updateWatcher(path);
|
updateWatcher(path);
|
||||||
m_pendingUpdateDirs.clear();
|
m_pendingUpdateDirs.clear();
|
||||||
@@ -152,11 +155,11 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager
|
|||||||
// unnecessary generation when project with multiple shaders is opened.
|
// unnecessary generation when project with multiple shaders is opened.
|
||||||
m_generateQsbFilesTimer.setSingleShot(true);
|
m_generateQsbFilesTimer.setSingleShot(true);
|
||||||
m_generateQsbFilesTimer.setInterval(100);
|
m_generateQsbFilesTimer.setInterval(100);
|
||||||
QObject::connect(&m_generateQsbFilesTimer, &QTimer::timeout, [this] {
|
QObject::connect(&m_generateQsbFilesTimer, &QTimer::timeout, this, [this] {
|
||||||
handleShaderChanges();
|
handleShaderChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged,
|
connect(m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this,
|
||||||
[this](const QString &path) {
|
[this](const QString &path) {
|
||||||
const QSet<QString> pendingDirs = m_pendingUpdateDirs;
|
const QSet<QString> pendingDirs = m_pendingUpdateDirs;
|
||||||
for (const auto &pendingPath : pendingDirs) {
|
for (const auto &pendingPath : pendingDirs) {
|
||||||
@@ -172,7 +175,7 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager
|
|||||||
m_updateWatcherTimer.start();
|
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)) {
|
if (m_qsbTargets.contains(path)) {
|
||||||
m_qsbTargets.insert(path, true);
|
m_qsbTargets.insert(path, true);
|
||||||
m_generateQsbFilesTimer.start();
|
m_generateQsbFilesTimer.start();
|
||||||
@@ -1910,23 +1913,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
|
|||||||
imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio);
|
imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio);
|
||||||
imageData.pixmap.setDevicePixelRatio(ratio);
|
imageData.pixmap.setDevicePixelRatio(ratio);
|
||||||
imageData.time = modified;
|
imageData.time = modified;
|
||||||
|
imageData.info = ImageUtils::imageInfo(imageSource);
|
||||||
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());
|
|
||||||
m_imageDataMap.insert(imageData.id, imageData);
|
m_imageDataMap.insert(imageData.id, imageData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
src/plugins/qmldesigner/utils/imageutils.cpp
Normal file
46
src/plugins/qmldesigner/utils/imageutils.cpp
Normal file
@@ -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 <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QImageReader>
|
||||||
|
|
||||||
|
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
|
17
src/plugins/qmldesigner/utils/imageutils.h
Normal file
17
src/plugins/qmldesigner/utils/imageutils.h
Normal file
@@ -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 <QString>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ImageUtils
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageUtils();
|
||||||
|
|
||||||
|
static QString imageInfo(const QString &path);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
Reference in New Issue
Block a user