forked from qt-creator/qt-creator
Make Content Library Materials downloadable
Task-number: QDS-9267 Change-Id: Ib4da1871cd1d9f0bf52323793b7d8d1b028ae170 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -10,25 +10,34 @@ import QtQuick.Controls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import ContentLibraryBackend
|
||||
|
||||
import WebFetcher 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal showContextMenu()
|
||||
|
||||
// Download states: "" (ie default, not downloaded), "unavailable", "downloading", "downloaded",
|
||||
// "failed"
|
||||
property string downloadState: modelData.isDownloaded() ? "downloaded" : ""
|
||||
|
||||
visible: modelData.bundleMaterialVisible
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
enabled: root.downloadState !== "downloading"
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
onPressed: (mouse) => {
|
||||
if (mouse.button === Qt.LeftButton && !materialsModel.importerRunning)
|
||||
ContentLibraryBackend.rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
|
||||
else if (mouse.button === Qt.RightButton)
|
||||
if (mouse.button === Qt.LeftButton && !materialsModel.importerRunning) {
|
||||
if (root.downloadState === "downloaded")
|
||||
ContentLibraryBackend.rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
|
||||
} else if (mouse.button === Qt.RightButton && root.downloadState === "downloaded") {
|
||||
root.showContextMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +47,15 @@ Item {
|
||||
|
||||
Item { width: 1; height: 5 } // spacer
|
||||
|
||||
DownloadPane {
|
||||
id: downloadPane
|
||||
width: root.width - 10
|
||||
height: img.width
|
||||
visible: root.downloadState === "downloading"
|
||||
|
||||
onRequestCancel: downloader.cancel()
|
||||
}
|
||||
|
||||
Image {
|
||||
id: img
|
||||
|
||||
@@ -46,6 +64,7 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
source: modelData.bundleMaterialIcon
|
||||
cache: false
|
||||
visible: root.downloadState != "downloading"
|
||||
|
||||
Rectangle { // circular indicator for imported bundle materials
|
||||
width: 10
|
||||
@@ -83,13 +102,52 @@ Item {
|
||||
anchors.right: img.right
|
||||
anchors.bottom: img.bottom
|
||||
enabled: !ContentLibraryBackend.materialsModel.importerRunning
|
||||
visible: containsMouse || mouseArea.containsMouse
|
||||
visible: root.downloadState === "downloaded"
|
||||
&& (containsMouse || mouseArea.containsMouse)
|
||||
|
||||
onClicked: {
|
||||
ContentLibraryBackend.materialsModel.addToProject(modelData)
|
||||
}
|
||||
} // IconButton
|
||||
|
||||
Text { // download icon
|
||||
color: root.downloadState === "unavailable" || root.downloadState === "failed"
|
||||
? StudioTheme.Values.themeRedLight
|
||||
: StudioTheme.Values.themeTextColor
|
||||
|
||||
font.family: StudioTheme.Constants.iconFont.family
|
||||
text: root.downloadState === "unavailable"
|
||||
? StudioTheme.Constants.downloadUnavailable
|
||||
: StudioTheme.Constants.download
|
||||
|
||||
font.pixelSize: 22
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
anchors.bottomMargin: 0
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
style: Text.Outline
|
||||
styleColor: "black"
|
||||
|
||||
visible: root.downloadState !== "downloaded"
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (root.downloadState !== "" && root.downloadState !== "failed")
|
||||
return
|
||||
|
||||
downloadPane.beginDownload(Qt.binding(function() { return downloader.progress }))
|
||||
|
||||
root.downloadState = ""
|
||||
downloader.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Image
|
||||
|
||||
TextInput {
|
||||
id: matName
|
||||
@@ -110,5 +168,44 @@ Item {
|
||||
selectionColor: StudioTheme.Values.themeTextSelectionColor
|
||||
selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
|
||||
}
|
||||
}
|
||||
} // Column
|
||||
|
||||
MultiFileDownloader {
|
||||
id: downloader
|
||||
|
||||
baseUrl: modelData.bundleMaterialBaseWebUrl
|
||||
files: modelData.bundleMaterialFiles
|
||||
|
||||
targetDirPath: modelData.bundleMaterialParentPath
|
||||
|
||||
onDownloadStarting: {
|
||||
root.downloadState = "downloading"
|
||||
}
|
||||
|
||||
onFinishedChanged: {
|
||||
downloadPane.endDownload()
|
||||
|
||||
root.downloadState = "downloaded"
|
||||
}
|
||||
|
||||
onDownloadCanceled: {
|
||||
downloadPane.endDownload()
|
||||
|
||||
root.downloadState = ""
|
||||
}
|
||||
|
||||
onDownloadFailed: {
|
||||
downloadPane.endDownload()
|
||||
|
||||
root.downloadState = "failed"
|
||||
}
|
||||
|
||||
downloader: FileDownloader {
|
||||
id: fileDownloader
|
||||
url: downloader.nextUrl
|
||||
probeUrl: false
|
||||
downloadEnabled: true
|
||||
targetFilePath: downloader.nextTargetPath
|
||||
} // FileDownloader
|
||||
} // MultiFileDownloader
|
||||
}
|
||||
|
@@ -232,7 +232,7 @@ Item {
|
||||
FileExtractor {
|
||||
id: extractor
|
||||
archiveName: downloader.completeBaseName
|
||||
sourceFile: downloader.tempFile
|
||||
sourceFile: downloader.outputFile
|
||||
targetPath: modelData.textureParentPath
|
||||
alwaysCreateDir: false
|
||||
clearTargetPathContents: false
|
||||
|
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
color: StudioTheme.Values.themeThumbnailBackground
|
||||
border.color: "#00000000"
|
||||
|
||||
signal requestCancel
|
||||
|
||||
property alias allowCancel: progressBar.closeButtonVisible
|
||||
property alias progressValue: progressBar.value
|
||||
property alias progressLabel: progressLabel.text
|
||||
|
||||
function beginDownload(progressFunction)
|
||||
{
|
||||
progressBar.visible = true
|
||||
root.progressLabel = qsTr("Downloading...")
|
||||
root.allowCancel = true
|
||||
root.progressValue = progressFunction
|
||||
}
|
||||
|
||||
function endDownload()
|
||||
{
|
||||
root.allowCancel = false
|
||||
root.progressLabel = ""
|
||||
root.progressValue = 0
|
||||
}
|
||||
|
||||
TextureProgressBar {
|
||||
id: progressBar
|
||||
anchors.rightMargin: 10
|
||||
anchors.leftMargin: 10
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
visible: false
|
||||
|
||||
onCancelRequested: {
|
||||
root.requestCancel()
|
||||
}
|
||||
|
||||
Text {
|
||||
id: progressLabel
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
text: qsTr("Progress:")
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: 5
|
||||
anchors.left: parent.left
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.top: parent.bottom
|
||||
anchors.topMargin: 5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Text {
|
||||
id: progressAmount
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
text: progressBar.value.toFixed(1)
|
||||
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Text {
|
||||
id: percentSign
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
text: qsTr("%")
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
} // TextureProgressBar
|
||||
} // Rectangle
|
@@ -22,6 +22,7 @@ add_qtc_library(QmlDesignerUtils STATIC
|
||||
SOURCES
|
||||
asset.cpp asset.h
|
||||
filedownloader.cpp filedownloader.h
|
||||
multifiledownloader.cpp multifiledownloader.h
|
||||
fileextractor.cpp fileextractor.h
|
||||
hdrimage.cpp hdrimage.h
|
||||
ktximage.cpp ktximage.h
|
||||
|
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "contentlibrarymaterial.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ContentLibraryMaterial::ContentLibraryMaterial(QObject *parent,
|
||||
@@ -10,8 +12,15 @@ ContentLibraryMaterial::ContentLibraryMaterial(QObject *parent,
|
||||
const QString &qml,
|
||||
const TypeName &type,
|
||||
const QUrl &icon,
|
||||
const QStringList &files)
|
||||
: QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files) {}
|
||||
const QStringList &files,
|
||||
const QString &downloadPath,
|
||||
const QString &baseWebUrl)
|
||||
: QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files)
|
||||
, m_downloadPath(downloadPath), m_baseWebUrl(baseWebUrl)
|
||||
{
|
||||
m_allFiles = m_files;
|
||||
m_allFiles.push_back(m_qml);
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterial::filter(const QString &searchText)
|
||||
{
|
||||
@@ -64,4 +73,25 @@ bool ContentLibraryMaterial::imported() const
|
||||
return m_imported;
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterial::isDownloaded() const
|
||||
{
|
||||
QString fullPath = qmlFilePath();
|
||||
return QFileInfo(fullPath).isFile();
|
||||
}
|
||||
|
||||
QString ContentLibraryMaterial::qmlFilePath() const
|
||||
{
|
||||
return m_downloadPath + "/" + m_qml;
|
||||
}
|
||||
|
||||
QString ContentLibraryMaterial::parentDirPath() const
|
||||
{
|
||||
return m_downloadPath;
|
||||
}
|
||||
|
||||
QStringList ContentLibraryMaterial::allFiles() const
|
||||
{
|
||||
return m_allFiles;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -19,6 +19,9 @@ class ContentLibraryMaterial : public QObject
|
||||
Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT)
|
||||
Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged)
|
||||
Q_PROPERTY(bool bundleMaterialImported READ imported WRITE setImported NOTIFY materialImportedChanged)
|
||||
Q_PROPERTY(QString bundleMaterialBaseWebUrl MEMBER m_baseWebUrl CONSTANT)
|
||||
Q_PROPERTY(QString bundleMaterialParentPath READ parentDirPath CONSTANT)
|
||||
Q_PROPERTY(QStringList bundleMaterialFiles READ allFiles CONSTANT)
|
||||
|
||||
public:
|
||||
ContentLibraryMaterial(QObject *parent,
|
||||
@@ -26,18 +29,25 @@ public:
|
||||
const QString &qml,
|
||||
const TypeName &type,
|
||||
const QUrl &icon,
|
||||
const QStringList &files);
|
||||
const QStringList &files,
|
||||
const QString &downloadPath,
|
||||
const QString &baseWebUrl);
|
||||
|
||||
bool filter(const QString &searchText);
|
||||
|
||||
Q_INVOKABLE bool isDownloaded() const;
|
||||
|
||||
QUrl icon() const;
|
||||
QString qml() const;
|
||||
TypeName type() const;
|
||||
QStringList files() const;
|
||||
bool visible() const;
|
||||
QString qmlFilePath() const;
|
||||
|
||||
bool setImported(bool imported);
|
||||
bool imported() const;
|
||||
QString parentDirPath() const;
|
||||
QStringList allFiles() const;
|
||||
|
||||
signals:
|
||||
void materialVisibleChanged();
|
||||
@@ -52,6 +62,10 @@ private:
|
||||
|
||||
bool m_visible = true;
|
||||
bool m_imported = false;
|
||||
|
||||
QString m_downloadPath;
|
||||
QString m_baseWebUrl;
|
||||
QStringList m_allFiles;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -7,7 +7,11 @@
|
||||
#include "contentlibrarymaterial.h"
|
||||
#include "contentlibrarymaterialscategory.h"
|
||||
#include "contentlibrarywidget.h"
|
||||
#include "filedownloader.h"
|
||||
#include "fileextractor.h"
|
||||
#include "multifiledownloader.h"
|
||||
#include "qmldesignerconstants.h"
|
||||
#include "qmldesignerplugin.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
@@ -16,6 +20,8 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QQmlEngine>
|
||||
#include <QStandardPaths>
|
||||
#include <QUrl>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -24,7 +30,19 @@ ContentLibraryMaterialsModel::ContentLibraryMaterialsModel(ContentLibraryWidget
|
||||
: QAbstractListModel(parent)
|
||||
, m_widget(parent)
|
||||
{
|
||||
loadMaterialBundle();
|
||||
m_downloadPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)
|
||||
+ "/QtDesignStudio/bundles/Materials";
|
||||
|
||||
m_baseUrl = QmlDesignerPlugin::settings()
|
||||
.value(DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL)
|
||||
.toString() + "/materials/v1";
|
||||
|
||||
qmlRegisterType<QmlDesigner::FileDownloader>("WebFetcher", 1, 0, "FileDownloader");
|
||||
qmlRegisterType<QmlDesigner::MultiFileDownloader>("WebFetcher", 1, 0, "MultiFileDownloader");
|
||||
|
||||
QDir bundleDir{m_downloadPath};
|
||||
if (fetchBundleMetadata(bundleDir) && fetchBundleIcons(bundleDir))
|
||||
loadMaterialBundle(bundleDir);
|
||||
}
|
||||
|
||||
int ContentLibraryMaterialsModel::rowCount(const QModelIndex &) const
|
||||
@@ -91,30 +109,127 @@ QHash<int, QByteArray> ContentLibraryMaterialsModel::roleNames() const
|
||||
return roles;
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::loadMaterialBundle()
|
||||
bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir)
|
||||
{
|
||||
if (m_matBundleExists || m_probeMatBundleDir)
|
||||
QString iconsPath = bundleDir.filePath("icons");
|
||||
|
||||
QDir iconsDir(iconsPath);
|
||||
if (iconsDir.exists() && iconsDir.entryList().length() > 0)
|
||||
return true;
|
||||
|
||||
QString zipFileUrl = m_baseUrl + "/icons.zip";
|
||||
|
||||
FileDownloader *downloader = new FileDownloader(this);
|
||||
downloader->setUrl(zipFileUrl);
|
||||
downloader->setProbeUrl(false);
|
||||
downloader->setDownloadEnabled(true);
|
||||
|
||||
QObject::connect(downloader, &FileDownloader::finishedChanged, this, [=]() {
|
||||
FileExtractor *extractor = new FileExtractor(this);
|
||||
extractor->setArchiveName(downloader->completeBaseName());
|
||||
extractor->setSourceFile(downloader->outputFile());
|
||||
extractor->setTargetPath(bundleDir.absolutePath());
|
||||
extractor->setAlwaysCreateDir(false);
|
||||
extractor->setClearTargetPathContents(false);
|
||||
|
||||
QObject::connect(extractor, &FileExtractor::finishedChanged, this, [=]() {
|
||||
downloader->deleteLater();
|
||||
extractor->deleteLater();
|
||||
|
||||
loadMaterialBundle(bundleDir);
|
||||
});
|
||||
|
||||
extractor->extract();
|
||||
});
|
||||
|
||||
downloader->start();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterialsModel::fetchBundleMetadata(const QDir &bundleDir)
|
||||
{
|
||||
QString matBundlePath = bundleDir.filePath("material_bundle.json");
|
||||
|
||||
QFileInfo fi(matBundlePath);
|
||||
if (fi.exists() && fi.size() > 0)
|
||||
return true;
|
||||
|
||||
QString metaFileUrl = m_baseUrl + "/material_bundle.json";
|
||||
FileDownloader *downloader = new FileDownloader(this);
|
||||
downloader->setUrl(metaFileUrl);
|
||||
downloader->setProbeUrl(false);
|
||||
downloader->setDownloadEnabled(true);
|
||||
downloader->setTargetFilePath(matBundlePath);
|
||||
|
||||
QObject::connect(downloader, &FileDownloader::finishedChanged, this, [=]() {
|
||||
if (fetchBundleIcons(bundleDir))
|
||||
loadMaterialBundle(bundleDir);
|
||||
|
||||
downloader->deleteLater();
|
||||
});
|
||||
|
||||
downloader->start();
|
||||
return false;
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::downloadSharedFiles(const QDir &targetDir, const QStringList &files)
|
||||
{
|
||||
QString metaFileUrl = m_baseUrl + "/shared_files.zip";
|
||||
FileDownloader *downloader = new FileDownloader(this);
|
||||
downloader->setUrl(metaFileUrl);
|
||||
downloader->setProbeUrl(false);
|
||||
downloader->setDownloadEnabled(true);
|
||||
|
||||
QObject::connect(downloader, &FileDownloader::finishedChanged, this, [=]() {
|
||||
FileExtractor *extractor = new FileExtractor(this);
|
||||
extractor->setArchiveName(downloader->completeBaseName());
|
||||
extractor->setSourceFile(downloader->outputFile());
|
||||
extractor->setTargetPath(targetDir.absolutePath());
|
||||
extractor->setAlwaysCreateDir(false);
|
||||
extractor->setClearTargetPathContents(false);
|
||||
|
||||
QObject::connect(extractor, &FileExtractor::finishedChanged, this, [this, downloader, extractor]() {
|
||||
downloader->deleteLater();
|
||||
extractor->deleteLater();
|
||||
|
||||
createImporter(m_importerBundlePath, m_importerBundleId, m_importerSharedFiles);
|
||||
});
|
||||
|
||||
extractor->extract();
|
||||
});
|
||||
|
||||
downloader->start();
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::createImporter(const QString &bundlePath, const QString &bundleId,
|
||||
const QStringList &sharedFiles)
|
||||
{
|
||||
m_importer = new Internal::ContentLibraryBundleImporter(bundlePath, bundleId, sharedFiles);
|
||||
connect(m_importer, &Internal::ContentLibraryBundleImporter::importFinished, this,
|
||||
[&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||
m_importerRunning = false;
|
||||
emit importerRunningChanged();
|
||||
if (metaInfo.isValid())
|
||||
emit bundleMaterialImported(metaInfo);
|
||||
});
|
||||
|
||||
connect(m_importer, &Internal::ContentLibraryBundleImporter::unimportFinished, this,
|
||||
[&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||
Q_UNUSED(metaInfo)
|
||||
m_importerRunning = false;
|
||||
emit importerRunningChanged();
|
||||
emit bundleMaterialUnimported(metaInfo);
|
||||
});
|
||||
|
||||
resetModel();
|
||||
updateIsEmpty();
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &matBundleDir)
|
||||
{
|
||||
if (m_matBundleExists)
|
||||
return;
|
||||
|
||||
QDir matBundleDir;
|
||||
|
||||
if (!qEnvironmentVariable("MATERIAL_BUNDLE_PATH").isEmpty())
|
||||
matBundleDir.setPath(qEnvironmentVariable("MATERIAL_BUNDLE_PATH"));
|
||||
else if (Utils::HostOsInfo::isMacHost())
|
||||
matBundleDir.setPath(QCoreApplication::applicationDirPath() + "/../Resources/material_bundle");
|
||||
|
||||
// search for matBundleDir from exec dir and up
|
||||
if (matBundleDir.dirName() == ".") {
|
||||
m_probeMatBundleDir = true; // probe only once
|
||||
|
||||
matBundleDir.setPath(QCoreApplication::applicationDirPath());
|
||||
while (!matBundleDir.cd("material_bundle") && matBundleDir.cdUp())
|
||||
; // do nothing
|
||||
|
||||
if (matBundleDir.dirName() != "material_bundle") // bundlePathDir not found
|
||||
return;
|
||||
}
|
||||
|
||||
QString matBundlePath = matBundleDir.filePath("material_bundle.json");
|
||||
|
||||
if (m_matBundleObj.isEmpty()) {
|
||||
@@ -160,7 +275,8 @@ void ContentLibraryMaterialsModel::loadMaterialBundle()
|
||||
bundleId,
|
||||
qml.chopped(4)).toLatin1(); // chopped(4): remove .qml
|
||||
|
||||
auto bundleMat = new ContentLibraryMaterial(category, mat, qml, type, icon, files);
|
||||
auto bundleMat = new ContentLibraryMaterial(category, mat, qml, type, icon, files,
|
||||
m_downloadPath, m_baseUrl);
|
||||
|
||||
category->addBundleMaterial(bundleMat);
|
||||
}
|
||||
@@ -172,24 +288,22 @@ void ContentLibraryMaterialsModel::loadMaterialBundle()
|
||||
for (const auto /*QJson{Const,}ValueRef*/ &file : sharedFilesArr)
|
||||
sharedFiles.append(file.toString());
|
||||
|
||||
m_importer = new Internal::ContentLibraryBundleImporter(matBundleDir.path(), bundleId, sharedFiles);
|
||||
connect(m_importer, &Internal::ContentLibraryBundleImporter::importFinished, this,
|
||||
[&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||
m_importerRunning = false;
|
||||
emit importerRunningChanged();
|
||||
if (metaInfo.isValid())
|
||||
emit bundleMaterialImported(metaInfo);
|
||||
});
|
||||
QStringList missingSharedFiles;
|
||||
for (const QString &s : std::as_const(sharedFiles)) {
|
||||
const QString fullSharedFilePath = matBundleDir.filePath(s);
|
||||
|
||||
connect(m_importer, &Internal::ContentLibraryBundleImporter::unimportFinished, this,
|
||||
[&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||
Q_UNUSED(metaInfo)
|
||||
m_importerRunning = false;
|
||||
emit importerRunningChanged();
|
||||
emit bundleMaterialUnimported(metaInfo);
|
||||
});
|
||||
if (!QFile::exists(fullSharedFilePath))
|
||||
missingSharedFiles.push_back(s);
|
||||
}
|
||||
|
||||
updateIsEmpty();
|
||||
if (missingSharedFiles.length() > 0) {
|
||||
m_importerBundlePath = matBundleDir.path();
|
||||
m_importerBundleId = bundleId;
|
||||
m_importerSharedFiles = sharedFiles;
|
||||
downloadSharedFiles(matBundleDir, missingSharedFiles);
|
||||
} else {
|
||||
createImporter(matBundleDir.path(), bundleId, sharedFiles);
|
||||
}
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterialsModel::hasRequiredQuick3DImport() const
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "nodemetainfo.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QDir>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -70,8 +71,13 @@ signals:
|
||||
void matBundleExistsChanged();
|
||||
|
||||
private:
|
||||
void loadMaterialBundle();
|
||||
void loadMaterialBundle(const QDir &matBundleDir);
|
||||
bool fetchBundleIcons(const QDir &bundleDir);
|
||||
bool fetchBundleMetadata(const QDir &bundleDir);
|
||||
bool isValidIndex(int idx) const;
|
||||
void downloadSharedFiles(const QDir &targetDir, const QStringList &files);
|
||||
void createImporter(const QString &bundlePath, const QString &bundleId,
|
||||
const QStringList &sharedFiles);
|
||||
|
||||
ContentLibraryWidget *m_widget = nullptr;
|
||||
QString m_searchText;
|
||||
@@ -82,11 +88,17 @@ private:
|
||||
bool m_isEmpty = true;
|
||||
bool m_matBundleExists = false;
|
||||
bool m_hasModelSelection = false;
|
||||
bool m_probeMatBundleDir = false;
|
||||
bool m_importerRunning = false;
|
||||
|
||||
int m_quick3dMajorVersion = -1;
|
||||
int m_quick3dMinorVersion = -1;
|
||||
|
||||
QString m_downloadPath;
|
||||
QString m_baseUrl;
|
||||
|
||||
QString m_importerBundlePath;
|
||||
QString m_importerBundleId;
|
||||
QStringList m_importerSharedFiles;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -116,7 +116,7 @@ void ContentLibraryTexturesModel::loadTextureBundle(const QString &bundlePath, c
|
||||
|
||||
QString remoteBaseUrl = QmlDesignerPlugin::settings()
|
||||
.value(DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL).toString()
|
||||
+ '/' + m_category;
|
||||
+ "/textures/" + m_category;
|
||||
|
||||
const QFileInfoList dirs = bundleDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const QFileInfo &dir : dirs) {
|
||||
|
@@ -54,7 +54,8 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
if (m_materialToDrag) {
|
||||
QMouseEvent *me = static_cast<QMouseEvent *>(event);
|
||||
if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
|
||||
if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20
|
||||
&& m_materialToDrag->isDownloaded()) {
|
||||
QByteArray data;
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <private/qqmldata_p.h>
|
||||
#include <utils/networkaccessmanager.h>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QQmlEngine>
|
||||
@@ -12,33 +13,52 @@ namespace QmlDesigner {
|
||||
|
||||
FileDownloader::FileDownloader(QObject *parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
{
|
||||
QObject::connect(this, &FileDownloader::downloadFailed, this, [this]() {
|
||||
if (m_outputFile.exists())
|
||||
m_outputFile.remove();
|
||||
});
|
||||
|
||||
QObject::connect(this, &FileDownloader::downloadCanceled, this, [this]() {
|
||||
if (m_outputFile.exists())
|
||||
m_outputFile.remove();
|
||||
});
|
||||
}
|
||||
|
||||
FileDownloader::~FileDownloader()
|
||||
{
|
||||
if (m_tempFile.exists())
|
||||
m_tempFile.remove();
|
||||
// Delete the temp file only if a target Path was set (i.e. file will be moved)
|
||||
if (deleteFileAtTheEnd() && m_outputFile.exists())
|
||||
m_outputFile.remove();
|
||||
}
|
||||
|
||||
bool FileDownloader::deleteFileAtTheEnd() const
|
||||
{
|
||||
return m_targetFilePath.isEmpty();
|
||||
}
|
||||
|
||||
void FileDownloader::start()
|
||||
{
|
||||
emit downloadStarting();
|
||||
|
||||
m_tempFile.setFileName(QDir::tempPath() + "/" + name() + ".XXXXXX" + ".zip");
|
||||
m_tempFile.open(QIODevice::WriteOnly);
|
||||
QString tempFileName = QDir::tempPath() + "/.qds_download_" + url().fileName();
|
||||
|
||||
m_outputFile.setFileName(tempFileName);
|
||||
m_outputFile.open(QIODevice::WriteOnly);
|
||||
|
||||
auto request = QNetworkRequest(m_url);
|
||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
|
||||
QNetworkRequest::UserVerifiedRedirectPolicy);
|
||||
m_reply = Utils::NetworkAccessManager::instance()->get(request);
|
||||
QNetworkReply *reply = Utils::NetworkAccessManager::instance()->get(request);
|
||||
m_reply = reply;
|
||||
|
||||
QNetworkReply::connect(m_reply, &QNetworkReply::readyRead, this, [this]() {
|
||||
QNetworkReply::connect(reply, &QNetworkReply::readyRead, this, [this, reply]() {
|
||||
bool isDownloadingFile = false;
|
||||
QString contentType;
|
||||
if (!m_reply->hasRawHeader("Content-Type")) {
|
||||
if (!reply->hasRawHeader("Content-Type")) {
|
||||
isDownloadingFile = true;
|
||||
} else {
|
||||
contentType = QString::fromUtf8(m_reply->rawHeader("Content-Type"));
|
||||
contentType = QString::fromUtf8(reply->rawHeader("Content-Type"));
|
||||
|
||||
if (contentType.startsWith("application/")
|
||||
|| contentType.startsWith("image/")
|
||||
@@ -50,12 +70,12 @@ void FileDownloader::start()
|
||||
}
|
||||
|
||||
if (isDownloadingFile)
|
||||
m_tempFile.write(m_reply->readAll());
|
||||
m_outputFile.write(reply->readAll());
|
||||
else
|
||||
m_reply->close();
|
||||
reply->close();
|
||||
});
|
||||
|
||||
QNetworkReply::connect(m_reply,
|
||||
QNetworkReply::connect(reply,
|
||||
&QNetworkReply::downloadProgress,
|
||||
this,
|
||||
[this](qint64 current, qint64 max) {
|
||||
@@ -66,33 +86,44 @@ void FileDownloader::start()
|
||||
}
|
||||
|
||||
m_progress = current * 100 / max;
|
||||
|
||||
emit progressChanged();
|
||||
});
|
||||
|
||||
QNetworkReply::connect(m_reply, &QNetworkReply::redirected, [this](const QUrl &) {
|
||||
emit m_reply->redirectAllowed();
|
||||
QNetworkReply::connect(reply, &QNetworkReply::redirected, [reply](const QUrl &) {
|
||||
emit reply->redirectAllowed();
|
||||
});
|
||||
|
||||
QNetworkReply::connect(m_reply, &QNetworkReply::finished, this, [this]() {
|
||||
if (m_reply->error()) {
|
||||
if (m_tempFile.exists())
|
||||
m_tempFile.remove();
|
||||
|
||||
if (m_reply->error() != QNetworkReply::OperationCanceledError) {
|
||||
qWarning() << Q_FUNC_INFO << m_url << m_reply->errorString();
|
||||
QNetworkReply::connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
if (reply->error()) {
|
||||
if (reply->error() != QNetworkReply::OperationCanceledError) {
|
||||
qWarning() << Q_FUNC_INFO << m_url << reply->errorString();
|
||||
emit downloadFailed();
|
||||
} else {
|
||||
emit downloadCanceled();
|
||||
}
|
||||
} else {
|
||||
m_tempFile.flush();
|
||||
m_tempFile.close();
|
||||
m_outputFile.flush();
|
||||
m_outputFile.close();
|
||||
|
||||
QString dirPath = QFileInfo(m_targetFilePath).dir().absolutePath();
|
||||
if (!deleteFileAtTheEnd()) {
|
||||
if (!QDir{}.mkpath(dirPath)) {
|
||||
emit downloadFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QFileInfo().exists(m_targetFilePath) && !m_outputFile.rename(m_targetFilePath)) {
|
||||
emit downloadFailed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_finished = true;
|
||||
emit tempFileChanged();
|
||||
emit outputFileChanged();
|
||||
emit finishedChanged();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
m_reply = nullptr;
|
||||
});
|
||||
}
|
||||
@@ -176,9 +207,9 @@ int FileDownloader::progress() const
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
QString FileDownloader::tempFile() const
|
||||
QString FileDownloader::outputFile() const
|
||||
{
|
||||
return QFileInfo(m_tempFile).canonicalFilePath();
|
||||
return QFileInfo(m_outputFile).canonicalFilePath();
|
||||
}
|
||||
|
||||
QDateTime FileDownloader::lastModified() const
|
||||
@@ -242,4 +273,14 @@ void FileDownloader::doProbeUrl()
|
||||
});
|
||||
}
|
||||
|
||||
void FileDownloader::setTargetFilePath(const QString &path)
|
||||
{
|
||||
m_targetFilePath = path;
|
||||
}
|
||||
|
||||
QString FileDownloader::targetFilePath() const
|
||||
{
|
||||
return m_targetFilePath;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -15,13 +15,14 @@ class FileDownloader : public QObject
|
||||
|
||||
Q_PROPERTY(bool downloadEnabled WRITE setDownloadEnabled READ downloadEnabled NOTIFY downloadEnabledChanged)
|
||||
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
|
||||
Q_PROPERTY(QString targetFilePath READ targetFilePath WRITE setTargetFilePath NOTIFY targetFilePathChanged)
|
||||
Q_PROPERTY(bool probeUrl READ probeUrl WRITE setProbeUrl NOTIFY probeUrlChanged)
|
||||
Q_PROPERTY(bool finished READ finished NOTIFY finishedChanged)
|
||||
Q_PROPERTY(bool error READ error NOTIFY errorChanged)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString completeBaseName READ completeBaseName NOTIFY nameChanged)
|
||||
Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
|
||||
Q_PROPERTY(QString tempFile READ tempFile NOTIFY tempFileChanged)
|
||||
Q_PROPERTY(QString outputFile READ outputFile NOTIFY outputFileChanged)
|
||||
Q_PROPERTY(QDateTime lastModified READ lastModified NOTIFY lastModifiedChanged)
|
||||
Q_PROPERTY(bool available READ available NOTIFY availableChanged)
|
||||
|
||||
@@ -32,12 +33,14 @@ public:
|
||||
|
||||
void setUrl(const QUrl &url);
|
||||
QUrl url() const;
|
||||
void setTargetFilePath(const QString &path);
|
||||
QString targetFilePath() const;
|
||||
bool finished() const;
|
||||
bool error() const;
|
||||
QString name() const;
|
||||
QString completeBaseName() const;
|
||||
int progress() const;
|
||||
QString tempFile() const;
|
||||
QString outputFile() const;
|
||||
QDateTime lastModified() const;
|
||||
bool available() const;
|
||||
void setDownloadEnabled(bool value);
|
||||
@@ -55,7 +58,7 @@ signals:
|
||||
void nameChanged();
|
||||
void urlChanged();
|
||||
void progressChanged();
|
||||
void tempFileChanged();
|
||||
void outputFileChanged();
|
||||
void downloadFailed();
|
||||
void lastModifiedChanged();
|
||||
void availableChanged();
|
||||
@@ -64,21 +67,24 @@ signals:
|
||||
void downloadStarting();
|
||||
void downloadCanceled();
|
||||
void probeUrlChanged();
|
||||
void targetFilePathChanged();
|
||||
|
||||
private:
|
||||
void doProbeUrl();
|
||||
bool deleteFileAtTheEnd() const;
|
||||
|
||||
QUrl m_url;
|
||||
bool m_probeUrl = false;
|
||||
bool m_finished = false;
|
||||
bool m_error = false;
|
||||
int m_progress = 0;
|
||||
QFile m_tempFile;
|
||||
QFile m_outputFile;
|
||||
QDateTime m_lastModified;
|
||||
bool m_available = false;
|
||||
|
||||
QNetworkReply *m_reply = nullptr;
|
||||
bool m_downloadEnabled = false;
|
||||
QString m_targetFilePath;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -104,13 +104,13 @@ void FileExtractor::browse()
|
||||
emit targetFolderExistsChanged();
|
||||
}
|
||||
|
||||
void FileExtractor::setSourceFile(QString &sourceFilePath)
|
||||
void FileExtractor::setSourceFile(const QString &sourceFilePath)
|
||||
{
|
||||
m_sourceFile = Utils::FilePath::fromString(sourceFilePath);
|
||||
emit targetFolderExistsChanged();
|
||||
}
|
||||
|
||||
void FileExtractor::setArchiveName(QString &filePath)
|
||||
void FileExtractor::setArchiveName(const QString &filePath)
|
||||
{
|
||||
m_archiveName = filePath;
|
||||
emit targetFolderExistsChanged();
|
||||
|
@@ -36,8 +36,8 @@ public:
|
||||
|
||||
QString targetPath() const;
|
||||
void setTargetPath(const QString &path);
|
||||
void setSourceFile(QString &sourceFilePath);
|
||||
void setArchiveName(QString &filePath);
|
||||
void setSourceFile(const QString &sourceFilePath);
|
||||
void setArchiveName(const QString &filePath);
|
||||
const QString detailedText() const;
|
||||
bool finished() const;
|
||||
QString currentFile() const;
|
||||
|
132
src/plugins/qmldesigner/utils/multifiledownloader.cpp
Normal file
132
src/plugins/qmldesigner/utils/multifiledownloader.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright (C) 2023 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 "multifiledownloader.h"
|
||||
#include "filedownloader.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
MultiFileDownloader::MultiFileDownloader(QObject *parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
MultiFileDownloader::~MultiFileDownloader()
|
||||
{}
|
||||
|
||||
void MultiFileDownloader::setDownloader(FileDownloader *downloader)
|
||||
{
|
||||
m_downloader = downloader;
|
||||
|
||||
QObject::connect(this, &MultiFileDownloader::downloadStarting, [this]() {
|
||||
m_nextFile = 0;
|
||||
if (m_files.length() > 0)
|
||||
m_downloader->start();
|
||||
});
|
||||
|
||||
QObject::connect(m_downloader, &FileDownloader::progressChanged, this, [this]() {
|
||||
m_progress = (m_nextFile + m_downloader->progress()) / m_files.count();
|
||||
});
|
||||
|
||||
QObject::connect(m_downloader, &FileDownloader::downloadFailed, this, [this]() {
|
||||
m_failed = true;
|
||||
emit downloadFailed();
|
||||
});
|
||||
|
||||
QObject::connect(m_downloader, &FileDownloader::downloadCanceled, this, [this]() {
|
||||
m_canceled = true;
|
||||
emit downloadCanceled();
|
||||
});
|
||||
|
||||
QObject::connect(m_downloader, &FileDownloader::finishedChanged, this, [this]() {
|
||||
switchToNextFile();
|
||||
});
|
||||
}
|
||||
|
||||
void MultiFileDownloader::start()
|
||||
{
|
||||
emit downloadStarting();
|
||||
}
|
||||
|
||||
void MultiFileDownloader::cancel()
|
||||
{
|
||||
m_canceled = true;
|
||||
m_downloader->cancel();
|
||||
}
|
||||
|
||||
void MultiFileDownloader::setBaseUrl(const QUrl &baseUrl)
|
||||
{
|
||||
if (m_baseUrl != baseUrl) {
|
||||
m_baseUrl = baseUrl;
|
||||
emit baseUrlChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QUrl MultiFileDownloader::baseUrl() const
|
||||
{
|
||||
return m_baseUrl;
|
||||
}
|
||||
|
||||
bool MultiFileDownloader::finished() const
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
int MultiFileDownloader::progress() const
|
||||
{
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
void MultiFileDownloader::setTargetDirPath(const QString &path)
|
||||
{
|
||||
m_targetDirPath = path;
|
||||
}
|
||||
|
||||
QString MultiFileDownloader::targetDirPath() const
|
||||
{
|
||||
return m_targetDirPath;
|
||||
}
|
||||
|
||||
QString MultiFileDownloader::nextUrl() const
|
||||
{
|
||||
if (m_nextFile >= m_files.length())
|
||||
return {};
|
||||
|
||||
return m_baseUrl.toString() + "/" + m_files[m_nextFile];
|
||||
}
|
||||
|
||||
QString MultiFileDownloader::nextTargetPath() const
|
||||
{
|
||||
if (m_nextFile >= m_files.length())
|
||||
return {};
|
||||
|
||||
return m_targetDirPath + "/" + m_files[m_nextFile];
|
||||
}
|
||||
|
||||
void MultiFileDownloader::setFiles(const QStringList &files)
|
||||
{
|
||||
m_files = files;
|
||||
}
|
||||
|
||||
QStringList MultiFileDownloader::files() const
|
||||
{
|
||||
return m_files;
|
||||
}
|
||||
|
||||
void MultiFileDownloader::switchToNextFile()
|
||||
{
|
||||
++m_nextFile;
|
||||
|
||||
if (m_nextFile < m_files.length()) {
|
||||
if (m_canceled) {
|
||||
emit downloadCanceled();
|
||||
} else {
|
||||
emit nextUrlChanged();
|
||||
emit nextTargetPathChanged();
|
||||
m_downloader->start();
|
||||
}
|
||||
} else {
|
||||
m_finished = true;
|
||||
emit finishedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
77
src/plugins/qmldesigner/utils/multifiledownloader.h
Normal file
77
src/plugins/qmldesigner/utils/multifiledownloader.h
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2023 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 <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class FileDownloader;
|
||||
|
||||
class MultiFileDownloader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(FileDownloader *downloader WRITE setDownloader)
|
||||
Q_PROPERTY(bool finished READ finished NOTIFY finishedChanged)
|
||||
Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
|
||||
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged)
|
||||
Q_PROPERTY(QString targetDirPath READ targetDirPath WRITE setTargetDirPath NOTIFY targetDirPathChanged)
|
||||
|
||||
Q_PROPERTY(QString nextUrl READ nextUrl NOTIFY nextUrlChanged)
|
||||
Q_PROPERTY(QString nextTargetPath READ nextTargetPath NOTIFY nextTargetPathChanged)
|
||||
Q_PROPERTY(QStringList files READ files WRITE setFiles NOTIFY filesChanged)
|
||||
|
||||
public:
|
||||
explicit MultiFileDownloader(QObject *parent = nullptr);
|
||||
|
||||
~MultiFileDownloader();
|
||||
|
||||
void setBaseUrl(const QUrl &url);
|
||||
QUrl baseUrl() const;
|
||||
|
||||
void setTargetDirPath(const QString &path);
|
||||
QString targetDirPath() const;
|
||||
void setDownloader(FileDownloader *downloader);
|
||||
|
||||
bool finished() const;
|
||||
int progress() const;
|
||||
|
||||
QString nextUrl() const;
|
||||
QString nextTargetPath() const;
|
||||
|
||||
void setFiles(const QStringList &files);
|
||||
QStringList files() const;
|
||||
void switchToNextFile();
|
||||
|
||||
Q_INVOKABLE void start();
|
||||
Q_INVOKABLE void cancel();
|
||||
|
||||
signals:
|
||||
void finishedChanged();
|
||||
void baseUrlChanged();
|
||||
void progressChanged();
|
||||
void downloadFailed();
|
||||
|
||||
void downloadStarting();
|
||||
void downloadCanceled();
|
||||
void targetDirPathChanged();
|
||||
void nextUrlChanged();
|
||||
void filesChanged();
|
||||
void nextTargetPathChanged();
|
||||
|
||||
private:
|
||||
QUrl m_baseUrl;
|
||||
bool m_finished = false;
|
||||
int m_progress = 0;
|
||||
QString m_targetDirPath;
|
||||
FileDownloader *m_downloader = nullptr;
|
||||
bool m_canceled = false;
|
||||
bool m_failed = false;
|
||||
QStringList m_files;
|
||||
int m_nextFile = 0;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -89,7 +89,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
|
||||
restoreValue(settings, DesignerSettingsKey::EDITOR_ZOOM_FACTOR, 1.0);
|
||||
restoreValue(settings, DesignerSettingsKey::ACTIONS_MERGE_TEMPLATE_ENABLED, false);
|
||||
restoreValue(settings, DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL,
|
||||
"https://cdn.qt.io/designstudio/bundles/textures");
|
||||
"https://cdn.qt.io/designstudio/bundles");
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
|
@@ -60,7 +60,7 @@ inline constexpr char SMOOTH_RENDERING[] = "SmoothRendering";
|
||||
inline constexpr char OLD_STATES_EDITOR[] = "ForceOldStatesEditor";
|
||||
inline constexpr char EDITOR_ZOOM_FACTOR[] = "EditorZoomFactor";
|
||||
inline constexpr char ACTIONS_MERGE_TEMPLATE_ENABLED[] = "ActionsMergeTemplateEnabled";
|
||||
inline constexpr char DOWNLOADABLE_BUNDLES_URL[] = "DownloadableBundlesUrl";
|
||||
inline constexpr char DOWNLOADABLE_BUNDLES_URL[] = "DownloadableBundlesLocation";
|
||||
}
|
||||
|
||||
class QMLDESIGNERBASE_EXPORT DesignerSettings
|
||||
|
@@ -117,7 +117,7 @@ DataModelDownloader::DataModelDownloader(QObject * /* parent */)
|
||||
|
||||
if (m_fileDownloader.finished()) {
|
||||
const Utils::FilePath archiveFile = Utils::FilePath::fromString(
|
||||
m_fileDownloader.tempFile());
|
||||
m_fileDownloader.outputFile());
|
||||
QTC_ASSERT(Utils::Archive::supportsFile(archiveFile), return );
|
||||
auto archive = new Utils::Archive(archiveFile, tempFilePath());
|
||||
QTC_ASSERT(archive->isValid(), delete archive; return );
|
||||
|
@@ -40,7 +40,7 @@ Rectangle {
|
||||
FileExtractor {
|
||||
id: fileExtractor
|
||||
archiveName: root.completeBaseName.length === 0 ? downloader.completeBaseName : root.completeBaseName
|
||||
sourceFile: root.tempFile.length === 0 ? downloader.tempFile : root.tempFile
|
||||
sourceFile: root.tempFile.length === 0 ? downloader.outputFile : root.tempFile
|
||||
}
|
||||
|
||||
FileDownloader {
|
||||
|
Reference in New Issue
Block a user