forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
ComponentVersion(int major, int minor);
|
||||
explicit ComponentVersion(const QString &versionString);
|
||||
~ComponentVersion();
|
||||
ComponentVersion()
|
||||
: _major(NoVersion)
|
||||
, _minor(NoVersion)
|
||||
{}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool isValid() const;
|
||||
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 { return _major >= 0 && _minor >= 0; }
|
||||
QString toString() const;
|
||||
void addToHash(QCryptographicHash &hash) const;
|
||||
};
|
||||
|
||||
@@ -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_));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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(
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectStorageUpdater::updateTypeAnnotations(
|
||||
const QString & /*propertyEditorResourcesPath*/,
|
||||
Storage::Synchronization::SynchronizationPackage & /*package*/,
|
||||
NotUpdatedSourceIds & /*notUpdatedSourceIds*/)
|
||||
namespace {
|
||||
|
||||
template<typename SourceIds1, typename SourceIds2>
|
||||
SmallSourceIds<16> mergedSourceIds(const SourceIds1 &sourceIds1, const SourceIds2 &sourceIds2)
|
||||
{
|
||||
// const auto typeAnnotations = dir.entryInfoList({"*.metainfo"}, QDir::Files);
|
||||
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 ¬UpdatedSourceIds)
|
||||
{
|
||||
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 &rootDirectoryPath,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
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 ¬UpdatedSourceIds,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ¬UpdatedSourceIds);
|
||||
void updateTypeAnnotations(const QString &propertyEditorResourcesPath,
|
||||
void updateTypeAnnotations(const QString &directoryPath,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary);
|
||||
void updateTypeAnnotationDirectories(Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary);
|
||||
void updateTypeAnnotations(const QStringList &directoryPath,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds);
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user