forked from qt-creator/qt-creator
QmlDesigner: Refactor out ContentLibraryMaterial from user bundle
Some tweaks and refactoring to get rid of ContentLibraryMaterial in the user section of the content library. The end goal is to unify the code for handling all Qml components in the user section (materials, 3d components, effects, 2D components. etc). Change-Id: I99d4fb64dae0b52265994ce478525e574e4bc658 Reviewed-by: Ali Kianian <ali.kianian@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -19,7 +19,6 @@
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
@@ -33,7 +32,7 @@ ContentLibraryMaterialsModel::ContentLibraryMaterialsModel(ContentLibraryWidget
|
||||
: QAbstractListModel(parent)
|
||||
, m_widget(parent)
|
||||
{
|
||||
m_downloadPath = Paths::bundlesPathSetting() + "/Materials";
|
||||
m_bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/Materials");
|
||||
|
||||
m_baseUrl = QmlDesignerPlugin::settings()
|
||||
.value(DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL)
|
||||
@@ -45,9 +44,8 @@ ContentLibraryMaterialsModel::ContentLibraryMaterialsModel(ContentLibraryWidget
|
||||
|
||||
void ContentLibraryMaterialsModel::loadBundle()
|
||||
{
|
||||
QDir bundleDir{m_downloadPath};
|
||||
if (fetchBundleMetadata(bundleDir) && fetchBundleIcons(bundleDir))
|
||||
loadMaterialBundle(bundleDir);
|
||||
if (fetchBundleMetadata() && fetchBundleIcons())
|
||||
loadMaterialBundle();
|
||||
}
|
||||
|
||||
int ContentLibraryMaterialsModel::rowCount(const QModelIndex &) const
|
||||
@@ -114,13 +112,14 @@ QHash<int, QByteArray> ContentLibraryMaterialsModel::roleNames() const
|
||||
return roles;
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir)
|
||||
bool ContentLibraryMaterialsModel::fetchBundleIcons()
|
||||
{
|
||||
QString iconsPath = bundleDir.filePath("icons");
|
||||
Utils::FilePath iconsFilePath = m_bundlePath.pathAppended("icons");
|
||||
|
||||
QDir iconsDir(iconsPath);
|
||||
if (iconsDir.exists() && iconsDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).length() > 0)
|
||||
if (iconsFilePath.exists() && iconsFilePath.dirEntries(QDir::Files | QDir::Dirs
|
||||
| QDir::NoDotAndDotDot).length() > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString zipFileUrl = m_baseUrl + "/icons.zip";
|
||||
|
||||
@@ -130,20 +129,20 @@ bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir)
|
||||
downloader->setDownloadEnabled(true);
|
||||
|
||||
QObject::connect(downloader, &FileDownloader::finishedChanged, this,
|
||||
[this, downloader, bundleDir] {
|
||||
[this, downloader] {
|
||||
FileExtractor *extractor = new FileExtractor(this);
|
||||
extractor->setArchiveName(downloader->completeBaseName());
|
||||
extractor->setSourceFile(downloader->outputFile());
|
||||
extractor->setTargetPath(bundleDir.absolutePath());
|
||||
extractor->setTargetPath(m_bundlePath.toFSPathString());
|
||||
extractor->setAlwaysCreateDir(false);
|
||||
extractor->setClearTargetPathContents(false);
|
||||
|
||||
QObject::connect(extractor, &FileExtractor::finishedChanged, this,
|
||||
[this, downloader, bundleDir, extractor] {
|
||||
[this, downloader, extractor] {
|
||||
downloader->deleteLater();
|
||||
extractor->deleteLater();
|
||||
|
||||
loadMaterialBundle(bundleDir);
|
||||
loadMaterialBundle();
|
||||
});
|
||||
|
||||
extractor->extract();
|
||||
@@ -153,12 +152,11 @@ bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterialsModel::fetchBundleMetadata(const QDir &bundleDir)
|
||||
bool ContentLibraryMaterialsModel::fetchBundleMetadata()
|
||||
{
|
||||
QString matBundlePath = bundleDir.filePath("material_bundle.json");
|
||||
Utils::FilePath jsonFilePath = m_bundlePath.pathAppended("material_bundle.json");
|
||||
|
||||
QFileInfo fi(matBundlePath);
|
||||
if (fi.exists() && fi.size() > 0)
|
||||
if (jsonFilePath.exists() && jsonFilePath.fileSize() > 0)
|
||||
return true;
|
||||
|
||||
QString metaFileUrl = m_baseUrl + "/material_bundle.json";
|
||||
@@ -166,12 +164,12 @@ bool ContentLibraryMaterialsModel::fetchBundleMetadata(const QDir &bundleDir)
|
||||
downloader->setUrl(metaFileUrl);
|
||||
downloader->setProbeUrl(false);
|
||||
downloader->setDownloadEnabled(true);
|
||||
downloader->setTargetFilePath(matBundlePath);
|
||||
downloader->setTargetFilePath(m_bundlePath.toFSPathString());
|
||||
|
||||
QObject::connect(downloader, &FileDownloader::finishedChanged, this,
|
||||
[this, downloader, bundleDir] {
|
||||
if (fetchBundleIcons(bundleDir))
|
||||
loadMaterialBundle(bundleDir);
|
||||
[this, downloader] {
|
||||
if (fetchBundleIcons())
|
||||
loadMaterialBundle();
|
||||
downloader->deleteLater();
|
||||
});
|
||||
|
||||
@@ -179,7 +177,7 @@ bool ContentLibraryMaterialsModel::fetchBundleMetadata(const QDir &bundleDir)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::downloadSharedFiles(const QDir &targetDir, const QStringList &)
|
||||
void ContentLibraryMaterialsModel::downloadSharedFiles()
|
||||
{
|
||||
QString metaFileUrl = m_baseUrl + "/shared_files.zip";
|
||||
FileDownloader *downloader = new FileDownloader(this);
|
||||
@@ -188,11 +186,11 @@ void ContentLibraryMaterialsModel::downloadSharedFiles(const QDir &targetDir, co
|
||||
downloader->setDownloadEnabled(true);
|
||||
|
||||
QObject::connect(downloader, &FileDownloader::finishedChanged, this,
|
||||
[this, downloader, targetDir] {
|
||||
[this, downloader] {
|
||||
FileExtractor *extractor = new FileExtractor(this);
|
||||
extractor->setArchiveName(downloader->completeBaseName());
|
||||
extractor->setSourceFile(downloader->outputFile());
|
||||
extractor->setTargetPath(targetDir.absolutePath());
|
||||
extractor->setTargetPath(m_bundlePath.toFSPathString());
|
||||
extractor->setAlwaysCreateDir(false);
|
||||
extractor->setClearTargetPathContents(false);
|
||||
|
||||
@@ -212,7 +210,7 @@ QString ContentLibraryMaterialsModel::bundleId() const
|
||||
return m_bundleId;
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir)
|
||||
void ContentLibraryMaterialsModel::loadMaterialBundle()
|
||||
{
|
||||
auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils();
|
||||
|
||||
@@ -227,18 +225,18 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir)
|
||||
m_bundleObj = {};
|
||||
m_bundleId.clear();
|
||||
|
||||
QString bundlePath = bundleDir.filePath("material_bundle.json");
|
||||
Utils::FilePath jsonFilePath = m_bundlePath.pathAppended("material_bundle.json");
|
||||
|
||||
QFile bundleFile(bundlePath);
|
||||
if (!bundleFile.open(QIODevice::ReadOnly)) {
|
||||
qWarning("Couldn't open material_bundle.json");
|
||||
Utils::expected_str<QByteArray> jsonContents = jsonFilePath.fileContents();
|
||||
if (!jsonContents.has_value()) {
|
||||
qWarning() << __FUNCTION__ << jsonContents.error();
|
||||
resetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(bundleFile.readAll());
|
||||
QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(jsonContents.value());
|
||||
if (bundleJsonDoc.isNull()) {
|
||||
qWarning("Invalid material_bundle.json file");
|
||||
qWarning() << __FUNCTION__ << "Invalid json file" << jsonFilePath;
|
||||
resetModel();
|
||||
return;
|
||||
}
|
||||
@@ -263,33 +261,25 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir)
|
||||
for (const QJsonValueConstRef &asset : assetsArr)
|
||||
files.append(asset.toString());
|
||||
|
||||
QUrl icon = QUrl::fromLocalFile(bundleDir.filePath(matObj.value("icon").toString()));
|
||||
QUrl icon = m_bundlePath.pathAppended(matObj.value("icon").toString()).toUrl();
|
||||
QString qml = matObj.value("qml").toString();
|
||||
TypeName type = QLatin1String("%1.%2")
|
||||
.arg(bundleType, qml.chopped(4)).toLatin1(); // chopped(4): remove .qml
|
||||
TypeName type = QLatin1String("%1.%2").arg(bundleType, qml.chopped(4)).toLatin1(); // chopped(4): remove .qml
|
||||
|
||||
auto bundleMat = new ContentLibraryMaterial(category, matName, qml, type, icon, files,
|
||||
m_downloadPath, m_baseUrl);
|
||||
auto bundleMat = new ContentLibraryMaterial(category, matName, qml, type, icon, files);
|
||||
|
||||
category->addBundleMaterial(bundleMat);
|
||||
}
|
||||
m_bundleCategories.append(category);
|
||||
}
|
||||
|
||||
m_bundleSharedFiles.clear();
|
||||
const QJsonArray sharedFilesArr = m_bundleObj.value("sharedFiles").toArray();
|
||||
for (const QJsonValueConstRef &file : sharedFilesArr)
|
||||
m_bundleSharedFiles.append(file.toString());
|
||||
|
||||
QStringList missingSharedFiles;
|
||||
for (const QString &s : std::as_const(m_bundleSharedFiles)) {
|
||||
if (!QFileInfo::exists(bundleDir.filePath(s)))
|
||||
missingSharedFiles.push_back(s);
|
||||
m_bundleSharedFiles = m_bundleObj.value("sharedFiles").toVariant().toStringList();
|
||||
for (const QString &file : std::as_const(m_bundleSharedFiles)) {
|
||||
if (!m_bundlePath.pathAppended(file).exists()) {
|
||||
downloadSharedFiles();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (missingSharedFiles.length() > 0)
|
||||
downloadSharedFiles(bundleDir, missingSharedFiles);
|
||||
|
||||
m_bundleExists = true;
|
||||
updateIsEmpty();
|
||||
resetModel();
|
||||
@@ -305,6 +295,11 @@ bool ContentLibraryMaterialsModel::matBundleExists() const
|
||||
return m_bundleExists;
|
||||
}
|
||||
|
||||
QString ContentLibraryMaterialsModel::bundlePath() const
|
||||
{
|
||||
return m_bundlePath.toFSPathString();
|
||||
}
|
||||
|
||||
void ContentLibraryMaterialsModel::setSearchText(const QString &searchText)
|
||||
{
|
||||
QString lowerSearchText = searchText.toLower();
|
||||
@@ -364,8 +359,8 @@ void ContentLibraryMaterialsModel::applyToSelected(ContentLibraryMaterial *mat,
|
||||
|
||||
void ContentLibraryMaterialsModel::addToProject(ContentLibraryMaterial *mat)
|
||||
{
|
||||
QString err = m_widget->importer()->importComponent(mat->dirPath(), mat->type(), mat->qml(),
|
||||
mat->files() + m_bundleSharedFiles);
|
||||
QString err = m_widget->importer()->importComponent(m_bundlePath.toFSPathString(), mat->type(),
|
||||
mat->qml(), mat->files() + m_bundleSharedFiles);
|
||||
|
||||
if (err.isEmpty())
|
||||
m_widget->setImporterRunning(true);
|
||||
@@ -383,4 +378,9 @@ void ContentLibraryMaterialsModel::removeFromProject(ContentLibraryMaterial *mat
|
||||
qWarning() << __FUNCTION__ << err;
|
||||
}
|
||||
|
||||
bool ContentLibraryMaterialsModel::isMaterialDownloaded(ContentLibraryMaterial *mat) const
|
||||
{
|
||||
return m_bundlePath.pathAppended(mat->qml()).exists();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
Reference in New Issue
Block a user