aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2024-04-03 16:38:23 +0200
committerMarco Bubke <marco.bubke@qt.io>2024-04-22 15:34:53 +0000
commite262ec1ebbb51402fdd8583e51f131ee5f04e3a6 (patch)
tree1c272053c53e84cf0e29aef9886f5a3511e2b4e5 /src
parente9ee1c6b567eb9a68be887254733ec5c1080c169 (diff)
QmlDesigner: Integrate item library entries from project storage
Task-number: QDS-12102 Change-Id: Id6fbfcfb44d3b8c290f5e5d74addf33ef4d9a5e5 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/libs/languageutils/componentversion.cpp63
-rw-r--r--src/libs/languageutils/componentversion.h59
-rw-r--r--src/libs/sqlite/sqlitevalue.h38
-rw-r--r--src/libs/utils/smallstring.h8
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp5
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h2
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp4
-rw-r--r--src/plugins/qmldesigner/designercore/include/projectstorageids.h2
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h123
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h2
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h7
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp136
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h24
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp14
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h4
-rw-r--r--src/plugins/qmldesigner/qmldesignerprojectmanager.cpp11
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/quick.metainfo2
17 files changed, 386 insertions, 118 deletions
diff --git a/src/libs/languageutils/componentversion.cpp b/src/libs/languageutils/componentversion.cpp
index 6c599e300b..f041740d3b 100644
--- a/src/libs/languageutils/componentversion.cpp
+++ b/src/libs/languageutils/componentversion.cpp
@@ -10,27 +10,17 @@
namespace LanguageUtils {
-const int ComponentVersion::NoVersion = -1;
-const int ComponentVersion::MaxVersion = std::numeric_limits<int>::max();
+// QTC_TEMP
-ComponentVersion::ComponentVersion()
- : _major(NoVersion), _minor(NoVersion)
+ComponentVersion::ComponentVersion(QStringView versionString)
+ : _major(NoVersion)
+ , _minor(NoVersion)
{
-}
-
-ComponentVersion::ComponentVersion(int major, int minor)
- : _major(major), _minor(minor)
-{
-}
-
-ComponentVersion::ComponentVersion(const QString &versionString)
- : _major(NoVersion), _minor(NoVersion)
-{
- int dotIdx = versionString.indexOf(QLatin1Char('.'));
+ auto dotIdx = versionString.indexOf(QLatin1Char('.'));
if (dotIdx == -1)
return;
bool ok = false;
- int maybeMajor = versionString.left(dotIdx).toInt(&ok);
+ auto maybeMajor = versionString.left(dotIdx).toInt(&ok);
if (!ok)
return;
int maybeMinor = versionString.mid(dotIdx + 1).toInt(&ok);
@@ -40,15 +30,6 @@ ComponentVersion::ComponentVersion(const QString &versionString)
_minor = maybeMinor;
}
-ComponentVersion::~ComponentVersion()
-{
-}
-
-bool ComponentVersion::isValid() const
-{
- return _major >= 0 && _minor >= 0;
-}
-
QString ComponentVersion::toString() const
{
QByteArray temp;
@@ -65,36 +46,4 @@ void ComponentVersion::addToHash(QCryptographicHash &hash) const
hash.addData(reinterpret_cast<const char *>(&_minor), sizeof(_minor));
}
-bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs)
-{
- return lhs.majorVersion() < rhs.majorVersion()
- || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() < rhs.minorVersion());
-}
-
-bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs)
-{
- return lhs.majorVersion() < rhs.majorVersion()
- || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() <= rhs.minorVersion());
-}
-
-bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs)
-{
- return rhs < lhs;
-}
-
-bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs)
-{
- return rhs <= lhs;
-}
-
-bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs)
-{
- return lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() == rhs.minorVersion();
-}
-
-bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs)
-{
- return !(lhs == rhs);
-}
-
} // namespace LanguageUtils
diff --git a/src/libs/languageutils/componentversion.h b/src/libs/languageutils/componentversion.h
index 4b39e8402a..0ba332103a 100644
--- a/src/libs/languageutils/componentversion.h
+++ b/src/libs/languageutils/componentversion.h
@@ -9,6 +9,8 @@ QT_BEGIN_NAMESPACE
class QCryptographicHash;
QT_END_NAMESPACE
+#include <QStringView>
+
namespace LanguageUtils {
class LANGUAGEUTILS_EXPORT ComponentVersion
@@ -17,25 +19,56 @@ class LANGUAGEUTILS_EXPORT ComponentVersion
int _minor;
public:
- static const int NoVersion;
- static const int MaxVersion;
+ static const int NoVersion = -1;
+ static const int MaxVersion = -1;
+
+ ComponentVersion()
+ : _major(NoVersion)
+ , _minor(NoVersion)
+ {}
- ComponentVersion();
- ComponentVersion(int major, int minor);
- explicit ComponentVersion(const QString &versionString);
- ~ComponentVersion();
+ ComponentVersion(int major, int minor)
+ : _major(major)
+ , _minor(minor)
+ {}
+
+ explicit ComponentVersion(QStringView versionString);
+ ~ComponentVersion() = default;
int majorVersion() const { return _major; }
int minorVersion() const { return _minor; }
- friend bool LANGUAGEUTILS_EXPORT operator<(const ComponentVersion &lhs, const ComponentVersion &rhs);
- friend bool LANGUAGEUTILS_EXPORT operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs);
- friend bool LANGUAGEUTILS_EXPORT operator>(const ComponentVersion &lhs, const ComponentVersion &rhs);
- friend bool LANGUAGEUTILS_EXPORT operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs);
- friend bool LANGUAGEUTILS_EXPORT operator==(const ComponentVersion &lhs, const ComponentVersion &rhs);
- friend bool LANGUAGEUTILS_EXPORT operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs);
+ friend bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs)
+ {
+ return std::tie(lhs._major, lhs._minor) < std::tie(rhs._major, rhs._minor);
+ }
+
+ friend bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs)
+ {
+ return std::tie(lhs._major, lhs._minor) <= std::tie(rhs._major, rhs._minor);
+ }
+
+ friend bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs)
+ {
+ return rhs < lhs;
+ }
+
+ friend bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs)
+ {
+ return rhs <= lhs;
+ }
+
+ friend bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs)
+ {
+ return lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() == rhs.minorVersion();
+ }
+
+ friend bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs)
+ {
+ return !(lhs == rhs);
+ }
- bool isValid() const;
+ bool isValid() const { return _major >= 0 && _minor >= 0; }
QString toString() const;
void addToHash(QCryptographicHash &hash) const;
};
diff --git a/src/libs/sqlite/sqlitevalue.h b/src/libs/sqlite/sqlitevalue.h
index ec4120139a..725682494b 100644
--- a/src/libs/sqlite/sqlitevalue.h
+++ b/src/libs/sqlite/sqlitevalue.h
@@ -34,7 +34,7 @@ public:
explicit ValueBase(NullValue) {}
explicit ValueBase(VariantType &&value)
- : value(value)
+ : value(std::move(value))
{}
explicit ValueBase(const char *value)
@@ -44,6 +44,7 @@ public:
explicit ValueBase(long long value)
: value(value)
{}
+
explicit ValueBase(int value)
: value(static_cast<long long>(value))
{}
@@ -61,11 +62,6 @@ public:
{}
- explicit ValueBase(StringType &&value)
- : value(std::move(value))
-
- {}
-
explicit ValueBase(BlobView value)
: value(value)
@@ -230,14 +226,42 @@ public:
class ValueView : public ValueBase<Utils::SmallStringView, BlobView>
{
public:
+ ValueView() = default;
+
+ explicit ValueView(NullValue) {}
+
explicit ValueView(ValueBase &&base)
: ValueBase(std::move(base))
{}
+ explicit ValueView(Utils::SmallStringView value)
+ : ValueBase(value)
+ {}
+
+ explicit ValueView(BlobView value)
+ : ValueBase(value)
+ {}
+
+ explicit ValueView(long long value)
+ : ValueBase(value)
+ {}
+
+ explicit ValueView(int value)
+ : ValueBase(static_cast<long long>(value))
+ {}
+
+ explicit ValueView(uint value)
+ : ValueBase(static_cast<long long>(value))
+ {}
+
+ explicit ValueView(double value)
+ : ValueBase(value)
+ {}
+
template<typename Type>
static ValueView create(Type &&value_)
{
- return ValueView{ValueBase{value_}};
+ return ValueView(std::forward<Type>(value_));
}
};
diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h
index a8869b4ccf..52dd10602c 100644
--- a/src/libs/utils/smallstring.h
+++ b/src/libs/utils/smallstring.h
@@ -356,6 +356,14 @@ public:
return false;
}
+ bool startsWith(QStringView subStringToSearch) const noexcept
+ {
+ if (size() >= Utils::usize(subStringToSearch))
+ return subStringToSearch == QLatin1StringView{data(), subStringToSearch.size()};
+
+ return false;
+ }
+
bool startsWith(char characterToSearch) const noexcept
{
return data()[0] == characterToSearch;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
index 50bb01a5bb..3bff210520 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
@@ -296,15 +296,16 @@ void ItemLibraryModel::setSearchText(const QString &searchText)
Import ItemLibraryModel::entryToImport(const ItemLibraryEntry &entry)
{
+#ifndef QDS_USE_PROJECTSTORAGE
if (entry.majorVersion() == -1 && entry.minorVersion() == -1)
return Import::createFileImport(entry.requiredImport());
-
+#endif
return Import::createLibraryImport(entry.requiredImport(), QString::number(entry.majorVersion()) + QLatin1Char('.') +
QString::number(entry.minorVersion()));
}
-void ItemLibraryModel::update([[maybe_unused]] ItemLibraryInfo *itemLibraryInfo, Model *model)
+void ItemLibraryModel::update(Model *model)
{
if (!model)
return;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
index 212ddf8e04..b04ea492d2 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
@@ -37,7 +37,7 @@ public:
QString searchText() const;
ItemLibraryImport *importByUrl(const QString &importName) const;
- void update(ItemLibraryInfo *itemLibraryInfo, Model *model);
+ void update(Model *model);
void updateUsedImports(const Imports &usedImports);
QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry);
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
index 587489bc8c..ffefc43178 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
@@ -333,9 +333,7 @@ void ItemLibraryWidget::updateModel()
m_compressionTimer.stop();
}
-#ifndef QDS_USE_PROJECTSTORAGE
- m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data());
-#endif
+ m_itemLibraryModel->update(m_model.data());
if (m_itemLibraryModel->rowCount() == 0 && !m_updateRetry) {
m_updateRetry = true; // Only retry once to avoid endless loops
diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/designercore/include/projectstorageids.h
index 90c174e04e..0b157e55e7 100644
--- a/src/plugins/qmldesigner/designercore/include/projectstorageids.h
+++ b/src/plugins/qmldesigner/designercore/include/projectstorageids.h
@@ -51,6 +51,8 @@ using SourceContextIds = std::vector<SourceContextId>;
using SourceId = Sqlite::BasicId<BasicIdType::Source, int>;
using SourceIds = std::vector<SourceId>;
+template<std::size_t size>
+using SmallSourceIds = QVarLengthArray<SourceId, size>;
using ModuleId = Sqlite::BasicId<BasicIdType::Module, int>;
using ModuleIds = std::vector<ModuleId>;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
index ad606bcb90..70d5e92b25 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
@@ -484,6 +484,34 @@ public:
return typeHints;
}
+ SmallSourceIds<4> typeAnnotationSourceIds(SourceId directoryId) const override
+ {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type annotaion source ids"_t,
+ projectStorageCategory(),
+ keyValue("source id", directoryId)};
+
+ auto sourceIds = selectTypeAnnotationSourceIdsStatement
+ .template valuesWithTransaction<SmallSourceIds<4>>(directoryId);
+
+ tracer.end(keyValue("source ids", sourceIds));
+
+ return sourceIds;
+ }
+
+ SmallSourceIds<64> typeAnnotationDirectorySourceIds() const override
+ {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type annotaion source ids"_t, projectStorageCategory()};
+
+ auto sourceIds = selectTypeAnnotationDirectorySourceIdsStatement
+ .template valuesWithTransaction<SmallSourceIds<64>>();
+
+ tracer.end(keyValue("source ids", sourceIds));
+
+ return sourceIds;
+ }
+
Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const override
{
using NanotraceHR::keyValue;
@@ -518,6 +546,40 @@ public:
return entries;
}
+ Storage::Info::ItemLibraryEntries itemLibraryEntries(ImportId importId) const
+ {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get item library entries by import id"_t,
+ projectStorageCategory(),
+ keyValue("import id", importId)};
+
+ using Storage::Info::ItemLibraryProperties;
+ Storage::Info::ItemLibraryEntries entries;
+
+ auto callback = [&](TypeId typeId_,
+ Utils::SmallStringView name,
+ Utils::SmallStringView iconPath,
+ Utils::SmallStringView category,
+ Utils::SmallStringView import,
+ Utils::SmallStringView toolTip,
+ Utils::SmallStringView properties,
+ Utils::SmallStringView extraFilePaths,
+ Utils::SmallStringView templatePath) {
+ auto &last = entries.emplace_back(
+ typeId_, name, iconPath, category, import, toolTip, templatePath);
+ if (properties.size())
+ selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
+ if (extraFilePaths.size())
+ selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
+ };
+
+ selectItemLibraryEntriesByTypeIdStatement.readCallbackWithTransaction(callback, importId);
+
+ tracer.end(keyValue("item library entries", entries));
+
+ return entries;
+ }
+
Storage::Info::ItemLibraryEntries itemLibraryEntries(SourceId sourceId) const override
{
using NanotraceHR::keyValue;
@@ -1479,6 +1541,28 @@ private:
annotation.typeId = fetchTypeIdByModuleIdAndExportedName(annotation.moduleId,
annotation.typeName);
}
+
+ for (auto &annotation : typeAnnotations) {
+ if (!annotation.typeId)
+ qWarning() << moduleName(annotation.moduleId).toQString()
+ << annotation.typeName.toQString();
+ }
+
+ typeAnnotations.erase(std::remove_if(typeAnnotations.begin(),
+ typeAnnotations.end(),
+ [](const auto &annotation) {
+ return !annotation.typeId;
+ }),
+ typeAnnotations.end());
+ }
+
+ template<typename Value>
+ static Sqlite::ValueView createEmptyAsNull(const Value &value)
+ {
+ if (value.size())
+ return Sqlite::ValueView::create(value);
+
+ return Sqlite::ValueView{};
}
void synchronizeTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations,
@@ -1512,9 +1596,10 @@ private:
insertTypeAnnotationStatement.write(annotation.typeId,
annotation.sourceId,
+ annotation.directorySourceId,
annotation.iconPath,
- annotation.itemLibraryJson,
- annotation.hintsJson);
+ createEmptyAsNull(annotation.itemLibraryJson),
+ createEmptyAsNull(annotation.hintsJson));
};
auto update = [&](const TypeAnnotationView &annotationFromDatabase,
@@ -1533,8 +1618,8 @@ private:
updateTypeAnnotationStatement.write(annotation.typeId,
annotation.iconPath,
- annotation.itemLibraryJson,
- annotation.hintsJson);
+ createEmptyAsNull(annotation.itemLibraryJson),
+ createEmptyAsNull(annotation.hintsJson));
return Sqlite::UpdateChange::Update;
}
@@ -4285,11 +4370,15 @@ private:
Sqlite::StrictColumnType::Integer,
{Sqlite::PrimaryKey{}});
auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
+ auto &directorySourceIdColumn = table.addColumn("directorySourceId",
+ Sqlite::StrictColumnType::Integer);
+
table.addColumn("iconPath", Sqlite::StrictColumnType::Text);
table.addColumn("itemLibrary", Sqlite::StrictColumnType::Text);
table.addColumn("hints", Sqlite::StrictColumnType::Text);
table.addUniqueIndex({sourceIdColumn, typeIdColumn});
+ table.addIndex({directorySourceIdColumn});
table.initialize(database);
}
@@ -4926,9 +5015,10 @@ public:
"SELECT typeId, iconPath, itemLibrary, hints FROM typeAnnotations WHERE "
"sourceId IN carray(?1) ORDER BY typeId",
database};
- WriteStatement<5> insertTypeAnnotationStatement{
- "INSERT INTO typeAnnotations(typeId, sourceId, iconPath, itemLibrary, hints) VALUES(?1, "
- "?2, ?3, ?4, ?5)",
+ WriteStatement<6> insertTypeAnnotationStatement{
+ "INSERT INTO "
+ " typeAnnotations(typeId, sourceId, directorySourceId, iconPath, itemLibrary, hints) "
+ "VALUES(?1, ?2, ?3, ?4, ?5, ?6)",
database};
WriteStatement<4> updateTypeAnnotationStatement{
"UPDATE typeAnnotations SET iconPath=?2, itemLibrary=?3, hints=?4 WHERE typeId=?1", database};
@@ -4939,28 +5029,35 @@ public:
mutable ReadStatement<2, 1> selectTypeHintsStatement{
"SELECT hints.key, hints.value "
"FROM typeAnnotations, json_each(typeAnnotations.hints) AS hints "
- "WHERE typeId=?1",
+ "WHERE typeId=?1 AND hints IS NOT NULL",
database};
+ mutable ReadStatement<1, 1> selectTypeAnnotationSourceIdsStatement{
+ "SELECT sourceId FROM typeAnnotations WHERE directorySourceId=?1 ORDER BY sourceId", database};
+ mutable ReadStatement<1, 0> selectTypeAnnotationDirectorySourceIdsStatement{
+ "SELECT DISTINCT directorySourceId FROM typeAnnotations ORDER BY directorySourceId", database};
mutable ReadStatement<9> selectItemLibraryEntriesStatement{
"SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', i.value->>'$.category', "
" i.value->>'$.import', i.value->>'$.toolTip', i.value->>'$.properties', "
" i.value->>'$.extraFilePaths', i.value->>'$.templatePath' "
- "FROM typeAnnotations, json_each(typeAnnotations.itemLibrary) AS i",
+ "FROM typeAnnotations AS ta , json_each(ta.itemLibrary) AS i "
+ "WHERE ta.itemLibrary IS NOT NULL",
database};
mutable ReadStatement<9, 1> selectItemLibraryEntriesByTypeIdStatement{
"SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', i.value->>'$.category', "
" i.value->>'$.import', i.value->>'$.toolTip', i.value->>'$.properties', "
" i.value->>'$.extraFilePaths', i.value->>'$.templatePath' "
- "FROM typeAnnotations, json_each(typeAnnotations.itemLibrary) AS i "
- "WHERE typeId=?1",
+ "FROM typeAnnotations AS ta, json_each(ta.itemLibrary) AS i "
+ "WHERE typeId=?1 AND ta.itemLibrary IS NOT NULL",
database};
mutable ReadStatement<9, 1> selectItemLibraryEntriesBySourceIdStatement{
- "SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', i.value->>'$.category', "
+ "SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', "
+ "i.value->>'$.category', "
" i.value->>'$.import', i.value->>'$.toolTip', i.value->>'$.properties', "
" i.value->>'$.extraFilePaths', i.value->>'$.templatePath' "
"FROM typeAnnotations, json_each(typeAnnotations.itemLibrary) AS i "
"WHERE typeId IN (SELECT DISTINCT typeId "
- " FROM documentImports AS di JOIN exportedTypeNames USING(moduleId) "
+ " FROM documentImports AS di JOIN exportedTypeNames "
+ " USING(moduleId) "
" WHERE di.sourceId=?)",
database};
mutable ReadStatement<3, 1> selectItemLibraryPropertiesStatement{
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
index a67b629608..20d988f7aa 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
@@ -57,6 +57,8 @@ public:
= 0;
virtual PropertyDeclarationId defaultPropertyDeclarationId(TypeId typeId) const = 0;
virtual std::optional<Storage::Info::Type> type(TypeId typeId) const = 0;
+ virtual SmallSourceIds<4> typeAnnotationSourceIds(SourceId directoryId) const = 0;
+ virtual SmallSourceIds<64> typeAnnotationDirectorySourceIds() const = 0;
virtual Utils::PathString typeIconPath(TypeId typeId) const = 0;
virtual Storage::Info::TypeHints typeHints(TypeId typeId) const = 0;
virtual Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const = 0;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h
index 5f80505da3..8d810d94bd 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h
@@ -1202,10 +1202,13 @@ using ProjectDatas = std::vector<ProjectData>;
class TypeAnnotation
{
public:
- TypeAnnotation(SourceId sourceId)
+ TypeAnnotation(SourceId sourceId, SourceId directorySourceId)
: sourceId{sourceId}
+ , directorySourceId{directorySourceId}
{}
+
TypeAnnotation(SourceId sourceId,
+ SourceId directorySourceId,
Utils::SmallStringView typeName,
ModuleId moduleId,
Utils::SmallStringView iconPath,
@@ -1219,6 +1222,7 @@ public:
, sourceId{sourceId}
, moduleId{moduleId}
, traits{traits}
+ , directorySourceId{directorySourceId}
{}
template<typename String>
@@ -1247,6 +1251,7 @@ public:
SourceId sourceId;
ModuleId moduleId;
TypeTraits traits;
+ SourceId directorySourceId;
};
using TypeAnnotations = std::vector<TypeAnnotation>;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp
index 6948117db6..761d6371ef 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp
@@ -11,6 +11,7 @@
#include "qmltypesparserinterface.h"
#include "sourcepath.h"
#include "sourcepathcache.h"
+#include "typeannotationreader.h"
#include <tracing/qmldesignertracing.h>
@@ -246,7 +247,8 @@ std::vector<IdPaths> createIdPaths(ProjectStorageUpdater::WatchedSourceIdsIds wa
void ProjectStorageUpdater::update(QStringList directories,
QStringList qmlTypesPaths,
- const QString &propertyEditorResourcesPath)
+ const QString &propertyEditorResourcesPath,
+ const QStringList &typeAnnotationPaths)
{
NanotraceHR::Tracer tracer{"update"_t,
category(),
@@ -260,6 +262,7 @@ void ProjectStorageUpdater::update(QStringList directories,
updateDirectories(directories, package, notUpdatedSourceIds, watchedSourceIds);
updateQmlTypes(qmlTypesPaths, package, notUpdatedSourceIds, watchedSourceIds);
updatePropertyEditorPaths(propertyEditorResourcesPath, package, notUpdatedSourceIds);
+ updateTypeAnnotations(typeAnnotationPaths, package, notUpdatedSourceIds);
package.updatedSourceIds = filterNotUpdatedSourceIds(std::move(package.updatedSourceIds),
std::move(notUpdatedSourceIds.sourceIds));
@@ -511,12 +514,134 @@ void ProjectStorageUpdater::updatePropertyEditorPaths(
}
}
+namespace {
+
+template<typename SourceIds1, typename SourceIds2>
+SmallSourceIds<16> mergedSourceIds(const SourceIds1 &sourceIds1, const SourceIds2 &sourceIds2)
+{
+ SmallSourceIds<16> mergedSourceIds;
+
+ std::set_union(sourceIds1.begin(),
+ sourceIds1.end(),
+ sourceIds2.begin(),
+ sourceIds2.end(),
+ std::back_inserter(mergedSourceIds));
+
+ return mergedSourceIds;
+}
+} // namespace
+
+void ProjectStorageUpdater::updateTypeAnnotations(const QStringList &directoryPaths,
+ Storage::Synchronization::SynchronizationPackage &package,
+ NotUpdatedSourceIds &notUpdatedSourceIds)
+{
+ NanotraceHR::Tracer tracer("update type annotations"_t, category());
+
+ std::map<SourceId, SmallSourceIds<16>> updatedSourceIdsDictonary;
+
+ for (SourceId directoryId : m_projectStorage.typeAnnotationDirectorySourceIds())
+ updatedSourceIdsDictonary[directoryId] = {};
+
+ for (const auto &directoryPath : directoryPaths)
+ updateTypeAnnotations(directoryPath, package, notUpdatedSourceIds, updatedSourceIdsDictonary);
+
+ updateTypeAnnotationDirectories(package, notUpdatedSourceIds, updatedSourceIdsDictonary);
+}
+
void ProjectStorageUpdater::updateTypeAnnotations(
- const QString & /*propertyEditorResourcesPath*/,
- Storage::Synchronization::SynchronizationPackage & /*package*/,
- NotUpdatedSourceIds & /*notUpdatedSourceIds*/)
+ const QString &rootDirectoryPath,
+ Storage::Synchronization::SynchronizationPackage &package,
+ NotUpdatedSourceIds &notUpdatedSourceIds,
+ std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary)
+{
+ NanotraceHR::Tracer tracer("update type annotation directory"_t,
+ category(),
+ keyValue("path", rootDirectoryPath));
+
+ if (rootDirectoryPath.isEmpty())
+ return;
+
+ QDirIterator directoryIterator{rootDirectoryPath,
+ {"*.metainfo"},
+ QDir::NoDotAndDotDot | QDir::Files,
+ QDirIterator::Subdirectories};
+
+ while (directoryIterator.hasNext()) {
+ auto fileInfo = directoryIterator.nextFileInfo();
+ auto filePath = fileInfo.filePath();
+ SourceId sourceId = m_pathCache.sourceId(SourcePath{filePath});
+
+ auto directoryPath = fileInfo.canonicalPath();
+
+ SourceId directorySourceId = m_pathCache.sourceId(SourcePath{directoryPath + "/."});
+
+ auto state = fileState(sourceId, package, notUpdatedSourceIds);
+ if (state == FileState::Changed)
+ updateTypeAnnotation(directoryPath, fileInfo.filePath(), sourceId, directorySourceId, package);
+
+ if (state != FileState::NotChanged)
+ updatedSourceIdsDictonary[directorySourceId].push_back(sourceId);
+ }
+}
+
+void ProjectStorageUpdater::updateTypeAnnotationDirectories(
+ Storage::Synchronization::SynchronizationPackage &package,
+ NotUpdatedSourceIds &notUpdatedSourceIds,
+ std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary)
+{
+ for (auto &[directorySourceId, updatedSourceIds] : updatedSourceIdsDictonary) {
+ auto directoryState = fileState(directorySourceId, package, notUpdatedSourceIds);
+
+ if (directoryState != FileState::NotChanged) {
+ auto existingTypeAnnotationSourceIds = m_projectStorage.typeAnnotationSourceIds(
+ directorySourceId);
+
+ std::sort(updatedSourceIds.begin(), updatedSourceIds.end());
+
+ auto changedSourceIds = mergedSourceIds(existingTypeAnnotationSourceIds, updatedSourceIds);
+ package.updatedTypeAnnotationSourceIds.insert(package.updatedTypeAnnotationSourceIds.end(),
+ changedSourceIds.begin(),
+ changedSourceIds.end());
+ } else {
+ package.updatedTypeAnnotationSourceIds.insert(package.updatedTypeAnnotationSourceIds.end(),
+ updatedSourceIds.begin(),
+ updatedSourceIds.end());
+ }
+ }
+}
+
+namespace {
+QString contentFromFile(const QString &path)
{
- // const auto typeAnnotations = dir.entryInfoList({"*.metainfo"}, QDir::Files);
+ QFile file{path};
+ if (file.open(QIODevice::ReadOnly))
+ return QString::fromUtf8(file.readAll());
+
+ return {};
+}
+} // namespace
+
+void ProjectStorageUpdater::updateTypeAnnotation(const QString &directoryPath,
+ const QString &filePath,
+ SourceId sourceId,
+ SourceId directorySourceId,
+ Storage::Synchronization::SynchronizationPackage &package)
+{
+ NanotraceHR::Tracer tracer{"update type annotation path"_t,
+ category(),
+ keyValue("path", filePath),
+ keyValue("directory path", directoryPath)};
+
+ Storage::TypeAnnotationReader reader{m_projectStorage};
+
+ auto annotations = reader.parseTypeAnnotation(contentFromFile(filePath),
+ directoryPath,
+ sourceId,
+ directorySourceId);
+ auto &typeAnnotations = package.typeAnnotations;
+ package.typeAnnotations.insert(typeAnnotations.end(),
+ std::make_move_iterator(annotations.begin()),
+ std::make_move_iterator(annotations.end()));
}
void ProjectStorageUpdater::updatePropertyEditorPath(
@@ -752,6 +877,7 @@ void ProjectStorageUpdater::parseProjectDatas(const Storage::Synchronization::Pr
watchedSourceIds.qmlSourceIds.push_back(projectData.sourceId);
parseQmlComponent(projectData.sourceId, package, notUpdatedSourceIds);
+ break;
}
}
}
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
index c779403565..e21531deea 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
@@ -11,12 +11,15 @@
#include "projectstoragetypes.h"
#include "sourcepath.h"
+#include <modelfwd.h>
+
#include <tracing/qmldesignertracing.h>
#include <qmljs/parser/qmldirparser_p.h>
#include <QStringList>
+#include <map>
#include <vector>
namespace Sqlite {
@@ -40,7 +43,7 @@ public:
using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>;
ProjectStorageUpdater(FileSystemInterface &fileSystem,
- ProjectStorageInterface &projectStorage,
+ ProjectStorageType &projectStorage,
FileStatusCache &fileStatusCache,
PathCache &pathCache,
QmlDocumentParserInterface &qmlDocumentParser,
@@ -59,7 +62,8 @@ public:
void update(QStringList directories,
QStringList qmlTypesPaths,
- const QString &propertyEditorResourcesPath);
+ const QString &propertyEditorResourcesPath,
+ const QStringList &typeAnnotationPaths);
void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) override;
void pathsChanged(const SourceIds &filePathIds) override;
@@ -157,9 +161,21 @@ private:
void updatePropertyEditorPaths(const QString &propertyEditorResourcesPath,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds);
- void updateTypeAnnotations(const QString &propertyEditorResourcesPath,
+ void updateTypeAnnotations(const QString &directoryPath,
+ Storage::Synchronization::SynchronizationPackage &package,
+ NotUpdatedSourceIds &notUpdatedSourceIds,
+ std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary);
+ void updateTypeAnnotationDirectories(Storage::Synchronization::SynchronizationPackage &package,
+ NotUpdatedSourceIds &notUpdatedSourceIds,
+ std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary);
+ void updateTypeAnnotations(const QStringList &directoryPath,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds);
+ void updateTypeAnnotation(const QString &directoryPath,
+ const QString &filePath,
+ SourceId sourceId,
+ SourceId directorySourceId,
+ Storage::Synchronization::SynchronizationPackage &package);
void updatePropertyEditorPath(const QString &path,
Storage::Synchronization::SynchronizationPackage &package,
SourceId directorySourceId);
@@ -209,7 +225,7 @@ private:
private:
std::vector<IdPaths> m_changedIdPaths;
FileSystemInterface &m_fileSystem;
- ProjectStorageInterface &m_projectStorage;
+ ProjectStorageType &m_projectStorage;
FileStatusCache &m_fileStatusCache;
PathCache &m_pathCache;
QmlDocumentParserInterface &m_qmlDocumentParser;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp
index b829e9db36..67a63542bc 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp
+++ b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp
@@ -27,11 +27,11 @@ constexpr auto propertyElementName = "Property"_L1;
constexpr auto extraFileElementName = "ExtraFile"_L1;
} // namespace
-Synchronization::TypeAnnotations TypeAnnotationReader::parseTypeAnnotation(const QString &content,
- const QString &directoryPath,
- SourceId sourceId)
+Synchronization::TypeAnnotations TypeAnnotationReader::parseTypeAnnotation(
+ const QString &content, const QString &directoryPath, SourceId sourceId, SourceId directorySourceId)
{
m_sourceId = sourceId;
+ m_directorySourceId = directorySourceId;
m_directoryPath = directoryPath;
m_parserState = ParsingDocument;
if (!SimpleAbstractStreamReader::readFromSource(content)) {
@@ -178,7 +178,7 @@ TypeAnnotationReader::ParserSate TypeAnnotationReader::readDocument(const QStrin
TypeAnnotationReader::ParserSate TypeAnnotationReader::readMetaInfoRootElement(const QString &name)
{
if (name == typeElementName) {
- m_typeAnnotations.emplace_back(m_sourceId);
+ m_typeAnnotations.emplace_back(m_sourceId, m_directorySourceId);
m_itemLibraryEntries = json::array();
return ParsingType;
} else {
@@ -277,7 +277,7 @@ void TypeAnnotationReader::readItemLibraryEntryProperty(QStringView name, const
} else if (name == "category"_L1) {
m_itemLibraryEntries.back()["category"] = value;
} else if (name == "libraryIcon"_L1) {
- m_itemLibraryEntries.back()["iconPath"] = value;
+ m_itemLibraryEntries.back()["iconPath"] = absoluteFilePathForDocument(variant.toString());
} else if (name == "version"_L1) {
// setVersion(value.toString());
} else if (name == "requiredImport"_L1) {
@@ -427,8 +427,8 @@ void TypeAnnotationReader::setVersion(const QString &versionNumber)
int minor = 0;
if (!versionNumber.isEmpty()) {
- int val;
- bool ok;
+ int val = -1;
+ bool ok = false;
if (versionNumber.contains('.'_L1)) {
val = versionNumber.split('.'_L1).constFirst().toInt(&ok);
major = ok ? val : major;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h
index 9332d5bed9..a320493ee2 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h
@@ -49,7 +49,8 @@ public:
Synchronization::TypeAnnotations parseTypeAnnotation(const QString &content,
const QString &directoryPath,
- SourceId sourceId);
+ SourceId sourceId,
+ SourceId directorySourceId);
QStringList errors();
@@ -124,6 +125,7 @@ private:
json m_itemLibraryEntries;
Property m_currentProperty;
SourceId m_sourceId;
+ SourceId m_directorySourceId;
};
} // namespace QmlDesigner::Storage
diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp
index c415863e8a..2aadc45f24 100644
--- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp
+++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp
@@ -490,6 +490,11 @@ QString propertyEditorResourcesPath()
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
}
+QString qtCreatorItemLibraryPath()
+{
+ return Core::ICore::resourcePath("qmldesigner/itemLibrary").toString();
+}
+
} // namespace
void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project)
@@ -626,11 +631,13 @@ void QmlDesignerProjectManager::update()
if constexpr (isUsingQmlDesignerLite()) {
m_projectData->projectStorageData->updater.update(directoriesForLiteDesigner(),
qmlTypesForLiteDesigner(),
- propertyEditorResourcesPath());
+ propertyEditorResourcesPath(),
+ {qtCreatorItemLibraryPath()});
} else {
m_projectData->projectStorageData->updater.update(directories(m_projectData->activeTarget),
qmlTypes(m_projectData->activeTarget),
- propertyEditorResourcesPath());
+ propertyEditorResourcesPath(),
+ {qtCreatorItemLibraryPath()});
}
}
diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
index 3f3cdb7910..46cb42b60d 100644
--- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
+++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
@@ -374,7 +374,6 @@ MetaInfo {
name: "Keyframe"
category: "none"
version: "1.0"
- requiredImport: "none"
}
}
@@ -386,7 +385,6 @@ MetaInfo {
name: "KeyframeGroup"
category: "none"
version: "1.0"
- requiredImport: "none"
}
}