From 1b38d1d6ccc2dea94825d26607716dc417155552 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 2 Apr 2025 11:57:04 +0200 Subject: [PATCH 01/82] QmlDesigner: Cleanup storage cache The cache was not using locking. It is now activated. If that will be a performance problem we can add an extra path cache for the main thread. Change-Id: I74565b4a8679a2c015ff651c3480362e924809a3 Reviewed-by: Thomas Hartmann --- src/libs/utils/set_algorithm.h | 65 ++++++++++++++ .../libs/designercore/include/modelfwd.h | 6 +- .../projectstorage/projectstorage.h | 11 ++- .../sourcepathstorage/sourcepathcache.h | 29 ++++-- .../sourcepathstorage/storagecache.h | 88 +++++++------------ .../sourcepathstorage/storagecachefwd.h | 8 +- .../sourcepathstorage/storagecache-test.cpp | 11 ++- 7 files changed, 136 insertions(+), 82 deletions(-) diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index 4c595717050..629ca17a1dd 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -241,6 +241,71 @@ struct set_greedy_difference_functor inline constexpr set_greedy_difference_functor set_greedy_difference{}; +struct set_difference_functor +{ + template Sentinel1, + std::input_iterator Iterator2, + std::sentinel_for Sentinel2, + std::invocable &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable + constexpr void operator()(Iterator1 first1, + Sentinel1 last1, + Iterator2 first2, + Sentinel2 last2, + Callable &&callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + while (first1 != last1 && first2 != last2) { + if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) { + std::invoke(callable, *first1); + ++first1; + } else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) { + ++first2; + } else { + ++first1; + ++first2; + } + } + + while (first1 != last1) { + std::invoke(callable, *first1); + ++first1; + } + } + + template &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> + constexpr void operator()(Range1 &&range1, + Range2 &&range2, + Callable &&callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + (*this)(std::ranges::begin(range1), + std::ranges::end(range1), + std::ranges::begin(range2), + std::ranges::end(range2), + std::forward(callable), + std::move(comp), + std::move(proj1), + std::move(proj2)); + } +}; + +inline constexpr set_difference_functor set_difference{}; + struct set_has_common_element_functor { template #include +#include + namespace QmlDesigner { using PropertyName = QByteArray; using PropertyNameView = QByteArrayView; @@ -40,7 +42,7 @@ constexpr bool useProjectStorage() #endif } class SourcePathStorage; -using PathCache = SourcePathCache; +using PathCache = SourcePathCache; #ifdef QDS_MODEL_USE_PROJECTSTORAGEINTERFACE using ProjectStorageType = ProjectStorageInterface; @@ -48,7 +50,7 @@ class SourcePathCacheInterface; using PathCacheType = SourcePathCacheInterface; #else using ProjectStorageType = ProjectStorage; -using PathCacheType = SourcePathCache; +using PathCacheType = SourcePathCache; #endif struct ProjectStorageDependencies diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index 1e6d287abe2..41368208a69 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -284,10 +284,13 @@ private: friend ModuleStorageAdapter; - static bool moduleNameLess(ModuleView first, ModuleView second) noexcept + struct ModuleNameLess { - return first < second; - } + bool operator()(ModuleView first, ModuleView second) const noexcept + { + return first < second; + } + }; class ModuleCacheEntry : public StorageCacheEntry { @@ -314,7 +317,7 @@ private: using ModuleCacheEntries = std::vector; using ModuleCache - = StorageCache; + = StorageCache; ModuleId fetchModuleId(Utils::SmallStringView moduleName, Storage::ModuleKind moduleKind); diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h index cc7d0a89f98..c6808097350 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h @@ -142,27 +142,38 @@ private: Storage &storage; }; - static bool sourceLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept + struct SourceNameLess { - return std::lexicographical_compare(first.rbegin(), - first.rend(), - second.rbegin(), - second.rend()); - } + bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const noexcept + { + return first < second; + } + }; + + struct SourceContextLess + { + bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const noexcept + { + return std::ranges::lexicographical_compare(first.rbegin(), + first.rend(), + second.rbegin(), + second.rend()); + } + }; using SourceContextPathCache = StorageCache; - using SourceNameCache = StorageCache; private: diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h index 1a3e3ec3a05..07ac6ff52f9 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h @@ -33,7 +33,7 @@ template> class StorageCache { @@ -140,17 +140,11 @@ public: { m_entries = m_storage.fetchAll(); - std::sort(m_entries.begin(), m_entries.end(), [](ViewType first, ViewType second) { - return compare(first, second); - }); + std::ranges::sort(m_entries, Compare{}); std::size_t max_id = 0; - auto found = std::max_element(m_entries.begin(), - m_entries.end(), - [](const auto &first, const auto &second) { - return first.id < second.id; - }); + auto found = std::ranges::max_element(m_entries, {}, &CacheEntry::id); if (found != m_entries.end()) max_id = static_cast(found->id); @@ -162,31 +156,25 @@ public: void add(std::vector &&views) { - auto less = [](ViewType first, ViewType second) { return compare(first, second); }; + std::ranges::sort(views, Compare{}); - std::sort(views.begin(), views.end(), less); - - views.erase(std::unique(views.begin(), views.end()), views.end()); + auto removed = std::ranges::unique(views.begin(), views.end()); + views.erase(removed.begin(), removed.end()); CacheEntries newCacheEntries; newCacheEntries.reserve(views.size()); - std::set_difference(views.begin(), - views.end(), - m_entries.begin(), - m_entries.end(), - Utils::make_iterator([&](ViewType newView) { - IndexType index = m_storage.fetchId(newView); - newCacheEntries.emplace_back(newView, index); - }), - less); + Utils::set_difference( + views, + m_entries, + [&](ViewType newView) { + IndexType index = m_storage.fetchId(newView); + newCacheEntries.emplace_back(newView, index); + }, + Compare{}); if (newCacheEntries.size()) { - auto found = std::max_element(newCacheEntries.begin(), - newCacheEntries.end(), - [](const auto &first, const auto &second) { - return first.id < second.id; - }); + auto found = std::ranges::max_element(newCacheEntries, {}, &CacheEntry::id); auto max_id = static_cast(found->id); @@ -196,12 +184,12 @@ public: CacheEntries mergedCacheEntries; mergedCacheEntries.reserve(newCacheEntries.size() + m_entries.size()); - std::merge(std::make_move_iterator(m_entries.begin()), - std::make_move_iterator(m_entries.end()), - std::make_move_iterator(newCacheEntries.begin()), - std::make_move_iterator(newCacheEntries.end()), - std::back_inserter(mergedCacheEntries), - less); + std::ranges::merge(std::make_move_iterator(m_entries.begin()), + std::make_move_iterator(m_entries.end()), + std::make_move_iterator(newCacheEntries.begin()), + std::make_move_iterator(newCacheEntries.end()), + std::back_inserter(mergedCacheEntries), + Compare{}); m_entries = std::move(mergedCacheEntries); @@ -221,7 +209,7 @@ public: sharedLock.unlock(); std::lock_guard exclusiveLock(m_mutex); - if (!std::is_base_of::value) + if constexpr (!std::is_base_of_v) found = find(view); if (found == m_entries.end()) found = insertEntry(found, view, m_storage.fetchId(view)); @@ -235,7 +223,7 @@ public: std::vector ids; ids.reserve(values.size()); - std::transform(values.begin(), values.end(), std::back_inserter(ids), [&](const auto &values) { + std::ranges::transform(values, std::back_inserter(ids), [&](const auto &values) { return this->id(values); }); @@ -252,9 +240,9 @@ public: std::shared_lock sharedLock(m_mutex); if (IndexType::create(static_cast(m_indices.size()) + 1) > id) { - if (StorageCacheIndex indirectionIndex = m_indices.at(static_cast(id) - 1); + if (StorageCacheIndex indirectionIndex = m_indices[static_cast(id) - 1]; indirectionIndex.isValid()) { - return m_entries.at(static_cast(indirectionIndex)).value; + return m_entries[static_cast(indirectionIndex)].value; } } @@ -276,9 +264,7 @@ public: for (IndexType id : ids) { values.emplace_back( - m_entries - .at(static_cast(m_indices.at(static_cast(id) - 1))) - .value); + m_entries[static_cast(m_indices[static_cast(id) - 1])].value); } return values; } @@ -306,19 +292,10 @@ private: template static auto find(Entries &&entries, ViewType view) { - auto begin = entries.begin(); - auto end = entries.end(); - auto found = std::lower_bound(begin, end, view, compare); + auto found = std::ranges::lower_bound(entries, view, Compare{}); - if (found == entries.end()) { - return entries.end(); - } - - const auto &value = *found; - - if (value == view) { + if (found != entries.end() && *found == view) return found; - } return entries.end(); } @@ -329,9 +306,8 @@ private: auto found = find(view); - if (found != m_entries.end()) { + if (found != m_entries.end()) return found->id; - } return IndexType(); } @@ -341,9 +317,9 @@ private: std::shared_lock sharedLock(m_mutex); if (IndexType::create(static_cast(m_indices.size()) + 1) > id) { - if (StorageCacheIndex indirectionIndex = m_indices.at(static_cast(id) - 1); + if (StorageCacheIndex indirectionIndex = m_indices[static_cast(id) - 1]; indirectionIndex.isValid()) { - return m_entries.at(static_cast(indirectionIndex)).value; + return m_entries[static_cast(indirectionIndex)].value; } } @@ -377,7 +353,7 @@ private: auto indirectionIndex = static_cast(id) - 1; ensureSize(indirectionIndex); - m_indices.at(indirectionIndex) = newIndirectionIndex; + m_indices[indirectionIndex] = newIndirectionIndex; return inserted; } diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h index a74c782f634..4ee78b4fa93 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h @@ -9,12 +9,6 @@ namespace QmlDesigner { class NonLockingMutex; -template +template class StorageCache; } // namespace QmlDesigner diff --git a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp index 4b4850e26ae..61e2d4efde6 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp @@ -30,9 +30,12 @@ public: ProjectStorageMock &storage; }; -auto less(Utils::SmallStringView first, Utils::SmallStringView second) -> bool +struct Less { - return Utils::compare(first, second) < 0; + bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const + { + return Utils::compare(first, second) < 0; + } }; using CacheWithMockLocking = QmlDesigner::StorageCache, - less, + Less, QmlDesigner::Cache::SourceContext>; using CacheWithoutLocking = QmlDesigner::StorageCache, - less, + Less, QmlDesigner::Cache::SourceContext>; template From 5c3f3cc5922dff91c04d799ed39838d16f48da4b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 3 Apr 2025 15:35:20 +0200 Subject: [PATCH 02/82] QmlDesigner: Add interface to manually trigger project storage update It is triggering the path watcher to check if the directory was updated and then update the updater. Task-number: QDS-15136 Change-Id: I80d654c5e476a47f75c6ebda3fa86dfe69226cb4 Reviewed-by: Thomas Hartmann --- .../libs/designercore/CMakeLists.txt | 1 + .../libs/designercore/include/model.h | 1 + .../libs/designercore/include/modelfwd.h | 3 +- .../libs/designercore/model/model.cpp | 9 +- .../libs/designercore/model/model_p.h | 1 + .../projectstoragepathwatcher.h | 16 ++- .../projectstoragetriggerupdateinterface.h | 23 ++++ .../project/qmldesignerprojectmanager.cpp | 11 +- tests/unit/tests/mocks/CMakeLists.txt | 1 + .../mocks/projectstoragetriggerupdatemock.h | 19 +++ .../tests/testdesignercore/CMakeLists.txt | 1 + .../propertycomponentgenerator-test.cpp | 4 +- .../designercoreutils/modelutils-test.cpp | 5 +- .../designsystem/dsthemeqml-test.cpp | 4 +- .../listmodeleditor/listmodeleditor-test.cpp | 7 +- .../unittests/metainfo/nodemetainfo-test.cpp | 4 +- .../metainfo/propertymetainfo-test.cpp | 4 +- .../auxiliarypropertystorageview-test.cpp | 6 +- .../unit/tests/unittests/model/model-test.cpp | 123 +++++++++++------- .../tests/unittests/model/modelnode-test.cpp | 4 +- .../model/modelresourcemanagement-test.cpp | 4 +- .../unittests/model/nodelistproperty-test.cpp | 5 +- .../unittests/model/rewriterview-test.cpp | 4 +- .../projectstoragepathwatcher-test.cpp | 45 +++++++ 24 files changed, 239 insertions(+), 66 deletions(-) create mode 100644 src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h create mode 100644 tests/unit/tests/mocks/projectstoragetriggerupdatemock.h diff --git a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt index e3bb78e8dd1..5cfc58be14a 100644 --- a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt +++ b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt @@ -391,6 +391,7 @@ extend_qtc_library(QmlDesignerCore projectstorageinfotypes.h projectstorageobserver.h projectstoragepathwatcher.h + projectstoragetriggerupdateinterface.h projectstoragepathwatcherinterface.h projectstoragepathwatchernotifierinterface.h projectstoragepathwatcher.h diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 9ee93be5b09..ee80d1b5483 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -281,6 +281,7 @@ public: NotNullPointer projectStorage() const; const PathCacheType &pathCache() const; PathCacheType &pathCache(); + ProjectStorageTriggerUpdateInterface &projectStorageTriggerUpdate() const; void emitInstancePropertyChange(AbstractView *view, const QList> &propertyList); diff --git a/src/plugins/qmldesigner/libs/designercore/include/modelfwd.h b/src/plugins/qmldesigner/libs/designercore/include/modelfwd.h index 6557d8ebd5d..a886e2bb9dd 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/modelfwd.h +++ b/src/plugins/qmldesigner/libs/designercore/include/modelfwd.h @@ -42,6 +42,7 @@ constexpr bool useProjectStorage() #endif } class SourcePathStorage; +class ProjectStorageTriggerUpdateInterface; using PathCache = SourcePathCache; #ifdef QDS_MODEL_USE_PROJECTSTORAGEINTERFACE @@ -52,11 +53,11 @@ using PathCacheType = SourcePathCacheInterface; using ProjectStorageType = ProjectStorage; using PathCacheType = SourcePathCache; #endif - struct ProjectStorageDependencies { ProjectStorageType &storage; PathCacheType &cache; + ProjectStorageTriggerUpdateInterface &triggerUpdate; }; enum class PropertyType { diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index b0636a9f0ca..28b847fdfa4 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -85,6 +85,7 @@ ModelPrivate::ModelPrivate(Model *model, std::unique_ptr resourceManagement) : projectStorage{&projectStorageDependencies.storage} , pathCache{&projectStorageDependencies.cache} + , projectStorageTriggerUpdate{&projectStorageDependencies.triggerUpdate} , m_model{model} , m_resourceManagement{std::move(resourceManagement)} { @@ -110,6 +111,7 @@ ModelPrivate::ModelPrivate(Model *model, std::unique_ptr resourceManagement) : projectStorage{&projectStorageDependencies.storage} , pathCache{&projectStorageDependencies.cache} + , projectStorageTriggerUpdate{&projectStorageDependencies.triggerUpdate} , m_model{model} , m_resourceManagement{std::move(resourceManagement)} { @@ -1771,7 +1773,7 @@ Model::Model(const TypeName &typeName, ModelPointer Model::createModel(const TypeName &typeName, std::unique_ptr resourceManagement) { - return Model::create({*d->projectStorage, *d->pathCache}, + return Model::create({*d->projectStorage, *d->pathCache, *d->projectStorageTriggerUpdate}, typeName, imports(), fileUrl(), @@ -2018,6 +2020,11 @@ PathCacheType &Model::pathCache() return *d->pathCache; } +ProjectStorageTriggerUpdateInterface &Model::projectStorageTriggerUpdate() const +{ + return *d->projectStorageTriggerUpdate; +} + void Model::emitInstancePropertyChange(AbstractView *view, const QList> &propertyList) { diff --git a/src/plugins/qmldesigner/libs/designercore/model/model_p.h b/src/plugins/qmldesigner/libs/designercore/model/model_p.h index d9591ccbf9e..b2a8a31d692 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/libs/designercore/model/model_p.h @@ -347,6 +347,7 @@ private: public: NotNullPointer projectStorage = nullptr; NotNullPointer pathCache = nullptr; + NotNullPointer projectStorageTriggerUpdate = nullptr; ModelTracing::AsynchronousToken traceToken = ModelTracing::category().beginAsynchronous("Model"); private: diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index 8fe2ba60e0a..6b86a4b5cf0 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -8,6 +8,7 @@ #include "projectstoragepathwatcherinterface.h" #include "projectstoragepathwatchernotifierinterface.h" #include "projectstoragepathwatchertypes.h" +#include "projectstoragetriggerupdateinterface.h" #include @@ -34,7 +35,8 @@ void set_greedy_intersection_call( } template -class ProjectStoragePathWatcher : public ProjectStoragePathWatcherInterface +class ProjectStoragePathWatcher : public ProjectStoragePathWatcherInterface, + public ProjectStorageTriggerUpdateInterface { public: ProjectStoragePathWatcher(SourcePathCache &pathCache, @@ -83,6 +85,13 @@ public: removeUnusedEntries(entires, notContainsId); } + void checkForChangeInDirectory(SourceContextIds sourceContextIds) override + { + std::ranges::sort(sourceContextIds); + + addChangedPathForFilePath(sourceContextIds); + } + void removeIds(const ProjectPartIds &ids) override { auto removedEntries = removeIdsFromWatchedEntries(ids); @@ -279,10 +288,7 @@ public: return notWatchedPaths(uniquePaths(entries)); } - const WatcherEntries &watchedEntries() const - { - return m_watchedEntries; - } + const WatcherEntries &watchedEntries() const { return m_watchedEntries; } WatcherEntries removeIdsFromWatchedEntries(const ProjectPartIds &ids) { diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h new file mode 100644 index 00000000000..f03e0ee4b2f --- /dev/null +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h @@ -0,0 +1,23 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "projectstorageids.h" + +namespace QmlDesigner { + +class ProjectStorageTriggerUpdateInterface +{ +public: + ProjectStorageTriggerUpdateInterface() = default; + ProjectStorageTriggerUpdateInterface(const ProjectStorageTriggerUpdateInterface &) = delete; + ProjectStorageTriggerUpdateInterface &operator=(const ProjectStorageTriggerUpdateInterface &) = delete; + + virtual void checkForChangeInDirectory(SourceContextIds sourceContextIds) = 0; + +protected: + ~ProjectStorageTriggerUpdateInterface() = default; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp index 40d38afb62c..911a2508b65 100644 --- a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp @@ -366,14 +366,21 @@ namespace { return nullptr; } +[[maybe_unused]] ProjectStorageTriggerUpdateInterface *dummyTriggerUpdate() +{ + return nullptr; +} + } // namespace ProjectStorageDependencies QmlDesignerProjectManager::projectStorageDependencies() { if constexpr (useProjectStorage()) { - return {m_projectData->projectStorageData->storage, m_data->pathCache}; + return {m_projectData->projectStorageData->storage, + m_data->pathCache, + m_projectData->projectStorageData->pathWatcher}; } else { - return {*dummyProjectStorage(), *dummyPathCache()}; + return {*dummyProjectStorage(), *dummyPathCache(), *dummyTriggerUpdate()}; } } diff --git a/tests/unit/tests/mocks/CMakeLists.txt b/tests/unit/tests/mocks/CMakeLists.txt index 432a2ca2c54..a86e7a8f702 100644 --- a/tests/unit/tests/mocks/CMakeLists.txt +++ b/tests/unit/tests/mocks/CMakeLists.txt @@ -28,6 +28,7 @@ add_qtc_library(TestMocks OBJECT projectstorageobservermock.h projectstoragepathwatchermock.h projectstoragepathwatchernotifiermock.h + projectstoragetriggerupdatemock.h qmldocumentparsermock.h qmltypesparsermock.h sourcepathcachemock.h sourcepathcachemock.cpp diff --git a/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h b/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h new file mode 100644 index 00000000000..85f4afc2f50 --- /dev/null +++ b/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h @@ -0,0 +1,19 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../utils/googletest.h" + +#include + +class ProjectStorageTriggerUpdateMock : public QmlDesigner::ProjectStorageTriggerUpdateInterface +{ +public: + virtual ~ProjectStorageTriggerUpdateMock() = default; + + MOCK_METHOD(void, + checkForChangeInDirectory, + (QmlDesigner::SourceContextIds sourceContextIds), + (override)); +}; diff --git a/tests/unit/tests/testdesignercore/CMakeLists.txt b/tests/unit/tests/testdesignercore/CMakeLists.txt index 240c6b36390..dd9dad3bd30 100644 --- a/tests/unit/tests/testdesignercore/CMakeLists.txt +++ b/tests/unit/tests/testdesignercore/CMakeLists.txt @@ -342,6 +342,7 @@ extend_qtc_library(TestDesignerCore projectstorageinfotypes.h projectstorageobserver.h projectstoragepathwatcher.h + projectstoragetriggerupdateinterface.h projectstoragepathwatcherinterface.h projectstoragepathwatchernotifierinterface.h projectstoragepathwatcher.h diff --git a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp index 4b398420082..2a5f5cd87e3 100644 --- a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -173,10 +174,11 @@ protected: protected: inline static QSharedPointer simpleReaderNode; NiceMock viewMock; + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/foo.qml"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock resourceManagementMock; - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", -1, -1, diff --git a/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp b/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp index 24393accd04..c190585ab00 100644 --- a/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp +++ b/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp @@ -5,7 +5,9 @@ #include #include +#include #include + #include #include #include @@ -18,11 +20,12 @@ using QmlDesigner::Storage::ModuleKind; class ModelUtilsWithModel : public ::testing::Test { protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/model.qml"}; QmlDesigner::SourceId sourceId = pathCacheMock.createSourceId("/path/foo.qml"); NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; QmlDesigner::ModuleId moduleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", {QmlDesigner::Import::createLibraryImport("QML"), QmlDesigner::Import::createLibraryImport("QtQuick"), diff --git a/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp b/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp index 2fa8de50705..91205aeba18 100644 --- a/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp +++ b/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -103,9 +104,10 @@ protected: const QmlDesigner::GroupType groupType = GetParam(); const QmlDesigner::PropertyName groupName = GroupId(groupType); QmlDesigner::DSThemeGroup group; + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/model.qm"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "QtObject", {Import::createLibraryImport("QM"), Import::createLibraryImport("QtQuick")}, diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index 2e8de03cbd2..12013dfaeb9 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -183,12 +184,14 @@ public: } protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/foo.qml"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock> goIntoComponentMock; QmlDesigner::ModelPointer designerModel{ QmlDesigner::Model::create(QmlDesigner::ProjectStorageDependencies{projectStorageMock, - pathCacheMock}, + pathCacheMock, + projectStorageTriggerUpdateMock}, "Item", {QmlDesigner::Import::createLibraryImport("QtQml.Models"), QmlDesigner::Import::createLibraryImport("QtQuick")}, @@ -204,7 +207,7 @@ protected: ModelNode element2; ModelNode element3; QmlDesigner::ModelPointer componentModel{ - QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + QmlDesigner::Model::create({projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "ListModel", {QmlDesigner::Import::createLibraryImport("QtQml.Models"), QmlDesigner::Import::createLibraryImport("QtQuick")}, diff --git a/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp index 41ad91ee6e1..c315720c19e 100644 --- a/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp +++ b/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -105,9 +106,10 @@ protected: } protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCache{"/path/foo.qml"}; NiceMock projectStorageMock{pathCache.sourceId, "/path"}; - QmlDesigner::Model model{{projectStorageMock, pathCache}, + QmlDesigner::Model model{{projectStorageMock, pathCache, projectStorageTriggerUpdateMock}, "Item", {QmlDesigner::Import::createLibraryImport("QML"), QmlDesigner::Import::createLibraryImport("QtQuick"), diff --git a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp index b3e466de06c..820a580b1a7 100644 --- a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp +++ b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -41,9 +42,10 @@ protected: } protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCache{"/path/foo.qml"}; NiceMock projectStorageMock{pathCache.sourceId, "/path"}; - QmlDesigner::Model model{{projectStorageMock, pathCache}, + QmlDesigner::Model model{{projectStorageMock, pathCache, projectStorageTriggerUpdateMock}, "Item", {QmlDesigner::Import::createLibraryImport("QML"), QmlDesigner::Import::createLibraryImport("QtQuick"), diff --git a/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp b/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp index 2021ca4f5c7..d6719f5be92 100644 --- a/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp +++ b/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -40,17 +41,18 @@ protected: inline static std::unique_ptr staticData; Sqlite::Database &database = staticData->database; + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/foo.qml"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock resourceManagementMock; QmlDesigner::Imports imports = {QmlDesigner::Import::createLibraryImport("QtQuick")}; - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", imports, pathCacheMock.path.toQString(), std::make_unique( resourceManagementMock)}; - QmlDesigner::Model model2{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model2{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", imports, pathCacheMock.path.toQString(), diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 31ce1a30d8e..dff3a7904bd 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -119,13 +120,14 @@ protected: } protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/foo.qml"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock resourceManagementMock; QmlDesigner::Imports imports = {QmlDesigner::Import::createLibraryImport("QtQuick")}; NiceMock viewMock; QUrl fileUrl = QUrl::fromLocalFile(pathCacheMock.path.toQString()); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", imports, QUrl::fromLocalFile(pathCacheMock.path.toQString()), @@ -147,60 +149,60 @@ class Model_Creation : public Model TEST_F(Model_Creation, root_node_has_item_type_name) { - auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, - "Item", - imports, - fileUrl, - std::make_unique( - resourceManagementMock)); + auto model = QmlDesigner::Model::create( + {projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + imports, + fileUrl, + std::make_unique(resourceManagementMock)); ASSERT_THAT(model->rootModelNode().type(), Eq("Item")); } TEST_F(Model_Creation, root_node_has_item_meta_info) { - auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, - "Item", - imports, - fileUrl, - std::make_unique( - resourceManagementMock)); + auto model = QmlDesigner::Model::create( + {projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + imports, + fileUrl, + std::make_unique(resourceManagementMock)); ASSERT_THAT(model->rootModelNode().metaInfo(), model->qtQuickItemMetaInfo()); } TEST_F(Model_Creation, file_url) { - auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, - "Item", - imports, - fileUrl, - std::make_unique( - resourceManagementMock)); + auto model = QmlDesigner::Model::create( + {projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + imports, + fileUrl, + std::make_unique(resourceManagementMock)); ASSERT_THAT(model->fileUrl().toLocalFile(), Eq(pathCacheMock.path.toQString())); } TEST_F(Model_Creation, file_url_source_id) { - auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, - "Item", - imports, - fileUrl, - std::make_unique( - resourceManagementMock)); + auto model = QmlDesigner::Model::create( + {projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + imports, + fileUrl, + std::make_unique(resourceManagementMock)); ASSERT_THAT(model->fileUrlSourceId(), pathCacheMock.sourceId); } TEST_F(Model_Creation, imports) { - auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, - "Item", - imports, - fileUrl, - std::make_unique( - resourceManagementMock)); + auto model = QmlDesigner::Model::create( + {projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + imports, + fileUrl, + std::make_unique(resourceManagementMock)); ASSERT_THAT(model->imports(), UnorderedElementsAreArray(imports)); } @@ -645,7 +647,8 @@ TEST_F(Model_ResourceManagment, TEST_F(Model_ResourceManagment, by_default_remove_model_node_removes_node) { - QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "QtQuick.Item"}; NiceMock viewMock; newModel.attachView(&viewMock); auto node = createNodeWithParent(viewMock.rootModelNode()); @@ -657,7 +660,8 @@ TEST_F(Model_ResourceManagment, by_default_remove_model_node_removes_node) TEST_F(Model_ResourceManagment, by_default_remove_properties_removes_property) { - QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "QtQuick.Item"}; NiceMock viewMock; newModel.attachView(&viewMock); rootNode = viewMock.rootModelNode(); @@ -671,7 +675,9 @@ TEST_F(Model_ResourceManagment, by_default_remove_properties_removes_property) TEST_F(Model_ResourceManagment, by_default_remove_model_node_in_factory_method_calls_removes_node) { model.detachView(&viewMock); - auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + auto newModel = QmlDesigner::Model::create({projectStorageMock, + pathCacheMock, + projectStorageTriggerUpdateMock}, "Item", imports, pathCacheMock.path.toQString()); @@ -686,7 +692,9 @@ TEST_F(Model_ResourceManagment, by_default_remove_model_node_in_factory_method_c TEST_F(Model_ResourceManagment, by_default_remove_properties_in_factory_method_calls_remove_property) { model.detachView(&viewMock); - auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + auto newModel = QmlDesigner::Model::create({projectStorageMock, + pathCacheMock, + projectStorageTriggerUpdateMock}, "Item", imports, pathCacheMock.path.toQString()); @@ -780,7 +788,8 @@ TEST_F(Model_ResourceManagment, remove_model_nodes_bypasses_model_resource_manag TEST_F(Model_ResourceManagment, by_default_remove_model_nodes_in_factory_method_calls_removes_node) { - QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "QtQuick.Item"}; NiceMock viewMock; newModel.attachView(&viewMock); rootNode = viewMock.rootModelNode(); @@ -874,7 +883,8 @@ TEST_F(Model_ResourceManagment, remove_properties_bypasses_model_resource_manage TEST_F(Model_ResourceManagment, by_default_remove_properties_in_factory_method_calls_removes_properties) { model.detachView(&viewMock); - QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "QtQuick.Item"}; newModel.attachView(&viewMock); rootNode = viewMock.rootModelNode(); auto property = createProperty(rootNode, "yi"); @@ -1131,14 +1141,24 @@ TEST_F(Model_MetaInfo, add_project_storage_observer_to_project_storage) { EXPECT_CALL(projectStorageMock, addObserver(_)); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + -1, + -1, + nullptr, + {}}; } TEST_F(Model_MetaInfo, remove_project_storage_observer_from_project_storage) { EXPECT_CALL(projectStorageMock, removeObserver(_)).Times(2); // the fixture model is calling it too - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + -1, + -1, + nullptr, + {}}; } TEST_F(Model_MetaInfo, refresh_meta_infos_callback_is_calling_abstract_view) @@ -1148,7 +1168,12 @@ TEST_F(Model_MetaInfo, refresh_meta_infos_callback_is_calling_abstract_view) ProjectStorageObserverMock observerMock; QmlDesigner::ProjectStorageObserver *observer = nullptr; ON_CALL(projectStorageMock, addObserver(_)).WillByDefault([&](auto *o) { observer = o; }); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + -1, + -1, + nullptr, + {}}; model.attachView(&viewMock); EXPECT_CALL(viewMock, refreshMetaInfos(typeIds)); @@ -1163,7 +1188,12 @@ TEST_F(Model_MetaInfo, added_exported_type_names_are_changed_callback_is_calling ProjectStorageObserverMock observerMock; QmlDesigner::ProjectStorageObserver *observer = nullptr; ON_CALL(projectStorageMock, addObserver(_)).WillByDefault([&](auto *o) { observer = o; }); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + -1, + -1, + nullptr, + {}}; model.attachView(&viewMock); EXPECT_CALL(viewMock, exportedTypeNamesChanged(added, IsEmpty())); @@ -1178,7 +1208,12 @@ TEST_F(Model_MetaInfo, removed_exported_type_names_are_changed_callback_is_calli ProjectStorageObserverMock observerMock; QmlDesigner::ProjectStorageObserver *observer = nullptr; ON_CALL(projectStorageMock, addObserver(_)).WillByDefault([&](auto *o) { observer = o; }); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, + "Item", + -1, + -1, + nullptr, + {}}; model.attachView(&viewMock); EXPECT_CALL(viewMock, exportedTypeNamesChanged(IsEmpty(), removed)); @@ -1355,7 +1390,7 @@ TEST_F(Model_ViewManagement, dont_call_modelAttached_if_node_instance_view_is_al TEST_F(Model_ViewManagement, detach_node_instance_view_from_other_model_before_attach_to_new_model) { InSequence s; - QmlDesigner::Model otherModel{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model otherModel{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", imports, fileUrl, @@ -1401,7 +1436,7 @@ TEST_F(Model_ViewManagement, attach_view_is_not_calling_modelAttached_if_it_is_a TEST_F(Model_ViewManagement, view_is_detached_before_it_is_attached_ot_new_model) { InSequence s; - QmlDesigner::Model otherModel{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model otherModel{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", imports, fileUrl, diff --git a/tests/unit/tests/unittests/model/modelnode-test.cpp b/tests/unit/tests/unittests/model/modelnode-test.cpp index 61d81f6178f..9214f24d4da 100644 --- a/tests/unit/tests/unittests/model/modelnode-test.cpp +++ b/tests/unit/tests/unittests/model/modelnode-test.cpp @@ -4,6 +4,7 @@ #include "../utils/googletest.h" #include "../mocks/projectstoragemock.h" +#include "../mocks/projectstoragetriggerupdatemock.h" #include "../mocks/sourcepathcachemock.h" #include @@ -15,9 +16,10 @@ namespace { class ModelNode : public testing::Test { protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCache{"/path/foo.qml"}; NiceMock projectStorageMock{pathCache.sourceId, "/path"}; - QmlDesigner::Model model{{projectStorageMock, pathCache}, "Item"}; + QmlDesigner::Model model{{projectStorageMock, pathCache, projectStorageTriggerUpdateMock}, "Item"}; QmlDesigner::ModelNode rootNode = model.rootModelNode(); }; diff --git a/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp b/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp index b020c7cfd0d..dea3501843e 100644 --- a/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp +++ b/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp @@ -6,6 +6,7 @@ #include "../mocks/abstractviewmock.h" #include "../mocks/modelresourcemanagementmock.h" #include "../mocks/projectstoragemock.h" +#include "../mocks/projectstoragetriggerupdatemock.h" #include "../mocks/sourcepathcachemock.h" #include @@ -71,10 +72,11 @@ protected: protected: NiceMock viewMock; + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/foo.qml"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; QmlDesigner::ModelResourceManagement management; - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", {QmlDesigner::Import::createLibraryImport("QtQtuick")}, QUrl::fromLocalFile(pathCacheMock.path.toQString())}; diff --git a/tests/unit/tests/unittests/model/nodelistproperty-test.cpp b/tests/unit/tests/unittests/model/nodelistproperty-test.cpp index 023126f0f70..72df3f52365 100644 --- a/tests/unit/tests/unittests/model/nodelistproperty-test.cpp +++ b/tests/unit/tests/unittests/model/nodelistproperty-test.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -73,11 +74,13 @@ protected: } protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock pathCache{"/path/foo.qml"}; NiceMock projectStorageMock{pathCache.sourceId, "/path"}; QmlDesigner::ModelPointer model{ QmlDesigner::Model::create(QmlDesigner::ProjectStorageDependencies{projectStorageMock, - pathCache}, + pathCache, + projectStorageTriggerUpdateMock}, "Item", {QmlDesigner::Import::createLibraryImport("QtQuick")}, QUrl::fromLocalFile(pathCache.path.toQString()))}; diff --git a/tests/unit/tests/unittests/model/rewriterview-test.cpp b/tests/unit/tests/unittests/model/rewriterview-test.cpp index 8c62accd1d8..f2dbd028123 100644 --- a/tests/unit/tests/unittests/model/rewriterview-test.cpp +++ b/tests/unit/tests/unittests/model/rewriterview-test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -26,13 +27,14 @@ protected: ~RewriterView() { model.setRewriterView(nullptr); } protected: + NiceMock projectStorageTriggerUpdateMock; NiceMock externalDependenciesMock; NiceMock textModifierMock; NiceMock pathCacheMock{"/path/foo.qml"}; NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock resourceManagementMock; QmlDesigner::Imports imports = {QmlDesigner::Import::createLibraryImport("QtQuick")}; - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + QmlDesigner::Model model{{projectStorageMock, pathCacheMock, projectStorageTriggerUpdateMock}, "Item", imports, QUrl::fromLocalFile(pathCacheMock.path.toQString()), diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index ac591b8c909..25c3895f818 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -415,6 +415,51 @@ TEST_F(ProjectStoragePathWatcher, no_duplicate_path_changes) mockQFileSytemWatcher.directoryChanged(sourceContextPath); } +TEST_F(ProjectStoragePathWatcher, trigger_manual_two_notify_file_changes) +{ + watcher.updateIdPaths( + {{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, + {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3], sourceIds[4]}}, + {projectChunkId3, {sourceIds[4]}}}); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) + .WillByDefault(Return(FileStatus{sourceIds[0], 1, 2})); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[1]))) + .WillByDefault(Return(FileStatus{sourceIds[1], 1, 2})); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) + .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); + + EXPECT_CALL(notifier, + pathsWithIdsChanged( + ElementsAre(IdPaths{projectChunkId1, {sourceIds[0], sourceIds[1]}}, + IdPaths{projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}))); + + watcher.checkForChangeInDirectory({sourceIds[0].contextId(), sourceIds[1].contextId()}); +} + +TEST_F(ProjectStoragePathWatcher, trigger_manual_notify_for_path_changes) +{ + watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, + {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) + .WillByDefault(Return(FileStatus{sourceIds[0], 1, 2})); + + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) + .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); + + EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); + + watcher.checkForChangeInDirectory({sourceIds[0].contextId()}); +} + +TEST_F(ProjectStoragePathWatcher, trigger_manual_no_notify_for_unwatched_path_changes) +{ + watcher.updateIdPaths({{projectChunkId1, {sourceIds[3]}}, {projectChunkId2, {sourceIds[3]}}}); + + EXPECT_CALL(notifier, pathsChanged(IsEmpty())); + + watcher.checkForChangeInDirectory({sourceIds[0].contextId()}); +} + TEST_F(ProjectStoragePathWatcher, update_context_id_paths_adds_entry_in_new_directory) { watcher.updateIdPaths({ From 3a052a4d483eb9a03bfa6cb2d20977176621782a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 4 Apr 2025 13:13:55 +0200 Subject: [PATCH 03/82] QmlDesigner: Fix ProjectStoragePathWatcher::checkForChangeInDirectory The ids should be unique. Change-Id: Idee63b4631ca24602553af4caecb49bec7c97d69 Reviewed-by: Marco Bubke Reviewed-by: Thomas Hartmann --- .../designercore/projectstorage/projectstoragepathwatcher.h | 2 ++ .../unittests/projectstorage/projectstoragepathwatcher-test.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index 6b86a4b5cf0..e07571f665c 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -88,6 +88,8 @@ public: void checkForChangeInDirectory(SourceContextIds sourceContextIds) override { std::ranges::sort(sourceContextIds); + auto removed = std::ranges::unique(sourceContextIds); + sourceContextIds.erase(removed.begin(), removed.end()); addChangedPathForFilePath(sourceContextIds); } diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index 25c3895f818..69ff6ac423f 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -433,7 +433,7 @@ TEST_F(ProjectStoragePathWatcher, trigger_manual_two_notify_file_changes) ElementsAre(IdPaths{projectChunkId1, {sourceIds[0], sourceIds[1]}}, IdPaths{projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}))); - watcher.checkForChangeInDirectory({sourceIds[0].contextId(), sourceIds[1].contextId()}); + watcher.checkForChangeInDirectory({sourceIds[0].contextId(), sourceIds[2].contextId()}); } TEST_F(ProjectStoragePathWatcher, trigger_manual_notify_for_path_changes) From ccaa6b6ec77b57e9867d70b8e529b0cc3638aa81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Fri, 4 Apr 2025 14:02:53 +0200 Subject: [PATCH 04/82] QmlDesigner: fix kits not loaded warnings Change-Id: Iedf4120705c2e4f66d9acca104e1348848b73900 Reviewed-by: Knud Dollereder --- src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp | 2 ++ src/plugins/studiowelcome/studiowelcomeplugin.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp index 1569e4df949..822783144c4 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp @@ -853,6 +853,8 @@ int ToolBarBackend::currentStyle() const QStringList ToolBarBackend::kits() const { + if (!ProjectExplorer::KitManager::isLoaded()) + return {}; auto kits = Utils::filtered(ProjectExplorer::KitManager::kits(), [](ProjectExplorer::Kit *kit) { const auto qtVersion = QtSupport::QtKitAspect::qtVersion(kit); const auto dev = ProjectExplorer::RunDeviceKitAspect::device(kit); diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index e366afdc85c..93c0131d1ed 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -706,6 +706,8 @@ void StudioWelcomePlugin::extensionsInitialized() bool StudioWelcomePlugin::delayedInitialize() { QTimer::singleShot(2000, this, []() { + if (!ProjectExplorer::KitManager::isLoaded()) + return; auto modelManager = QmlJS::ModelManagerInterface::instance(); if (!modelManager) return; From 5ca2f1d61278693e3e22022a30e56d54715b57d9 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 4 Apr 2025 15:17:57 +0200 Subject: [PATCH 05/82] QmlDesigner: Add directory imports item library entries getter Move the code from itemLibraryEntries getter to directoryImportsItemLibraryEntries. Task-number: QDS-15144 Change-Id: Ibb078c2a0fc711f8843ac3a27b959726ad777baa Reviewed-by: Miikka Heikkinen --- .../libs/designercore/include/model.h | 1 + .../libs/designercore/model/model.cpp | 11 +++ .../projectstorage/projectstorage.cpp | 70 +++++++++++-------- .../projectstorage/projectstorage.h | 4 +- .../projectstorage/projectstorageinterface.h | 1 + tests/unit/tests/mocks/projectstoragemock.cpp | 7 ++ tests/unit/tests/mocks/projectstoragemock.h | 6 ++ .../unit/tests/unittests/model/model-test.cpp | 31 ++++++++ .../projectstorage/projectstorage-test.cpp | 4 +- 9 files changed, 102 insertions(+), 33 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index ee80d1b5483..ba73b3ab44c 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -209,6 +209,7 @@ public: #endif QList itemLibraryEntries() const; + QList directoryImportsItemLibraryEntries() const; void attachView(AbstractView *view); void detachView(AbstractView *view, ViewNotification emitDetachNotify = NotifyView); diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 28b847fdfa4..9f385c2a904 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2819,6 +2819,17 @@ QList Model::itemLibraryEntries() const #endif } +QList Model::directoryImportsItemLibraryEntries() const +{ +#ifdef QDS_USE_PROJECTSTORAGE + using namespace Storage::Info; + return toItemLibraryEntries(*d->pathCache, + d->projectStorage->directoryImportsItemLibraryEntries(d->m_sourceId)); +#else + return {}; +#endif +} + NodeMetaInfo Model::qtQuickTimelineKeyframeGroupMetaInfo() const { if constexpr (useProjectStorage()) { diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp index f7dfa4bcaac..d5395905d85 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp @@ -870,7 +870,7 @@ struct ProjectStorage::Statements " USING(moduleId) " " WHERE di.sourceId=?)", database}; - mutable Sqlite::ReadStatement<4, 2> selectLocalFileItemLibraryEntriesBySourceIdStatement{ + mutable Sqlite::ReadStatement<4, 2> selectDirectoryImportsItemLibraryEntriesBySourceIdStatement{ "SELECT typeId, etn.name, m.name, t.sourceId " "FROM documentImports AS di " " JOIN exportedTypeNames AS etn USING(moduleId) " @@ -1877,16 +1877,16 @@ Storage::Info::ItemLibraryEntries ProjectStorage::itemLibraryEntries(SourceId so using Storage::Info::ItemLibraryProperties; Storage::Info::ItemLibraryEntries entries; - auto typeAnnotationCallback = [&](TypeId typeId, - Utils::SmallStringView typeName, - 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 callback = [&](TypeId typeId, + Utils::SmallStringView typeName, + 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, typeName, name, iconPath, category, import, toolTip, templatePath); if (properties.size()) @@ -1895,23 +1895,7 @@ Storage::Info::ItemLibraryEntries ProjectStorage::itemLibraryEntries(SourceId so s->selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths); }; - s->selectItemLibraryEntriesBySourceIdStatement.readCallbackWithTransaction(typeAnnotationCallback, - sourceId); - - auto fileComponentCallback = [&](TypeId typeId, - Utils::SmallStringView typeName, - Utils::SmallStringView import, - SourceId componentSourceId) { - if (!isCapitalLetter(typeName.front())) - return; - - auto &last = entries.emplace_back(typeId, typeName, typeName, "My Components", import); - last.moduleKind = Storage::ModuleKind::PathLibrary; - last.componentSourceId = componentSourceId; - }; - - s->selectLocalFileItemLibraryEntriesBySourceIdStatement.readCallbackWithTransaction( - fileComponentCallback, sourceId, Storage::ModuleKind::PathLibrary); + s->selectItemLibraryEntriesBySourceIdStatement.readCallbackWithTransaction(callback, sourceId); tracer.end(keyValue("item library entries", entries)); @@ -1951,6 +1935,36 @@ Storage::Info::ItemLibraryEntries ProjectStorage::allItemLibraryEntries() const return entries; } +Storage::Info::ItemLibraryEntries ProjectStorage::directoryImportsItemLibraryEntries(SourceId sourceId) const +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"get directory import item library entries", + projectStorageCategory(), + keyValue("source id", sourceId)}; + + using Storage::Info::ItemLibraryProperties; + Storage::Info::ItemLibraryEntries entries; + + auto callback = [&](TypeId typeId, + Utils::SmallStringView typeName, + Utils::SmallStringView import, + SourceId componentSourceId) { + if (!isCapitalLetter(typeName.front())) + return; + + auto &last = entries.emplace_back(typeId, typeName, typeName, "My Components", import); + last.moduleKind = Storage::ModuleKind::PathLibrary; + last.componentSourceId = componentSourceId; + }; + + s->selectDirectoryImportsItemLibraryEntriesBySourceIdStatement + .readCallbackWithTransaction(callback, sourceId, Storage::ModuleKind::PathLibrary); + + tracer.end(keyValue("item library entries", entries)); + + return entries; +} + std::vector ProjectStorage::signalDeclarationNames(TypeId typeId) const { using NanotraceHR::keyValue; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index 41368208a69..7751338403e 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -110,12 +110,10 @@ public: SmallSourceContextIds<64> typeAnnotationDirectoryIds() const override; Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const override; - Storage::Info::ItemLibraryEntries itemLibraryEntries(ImportId importId) const; - Storage::Info::ItemLibraryEntries itemLibraryEntries(SourceId sourceId) const override; - Storage::Info::ItemLibraryEntries allItemLibraryEntries() const override; + Storage::Info::ItemLibraryEntries directoryImportsItemLibraryEntries(SourceId sourceId) const override; std::vector signalDeclarationNames(TypeId typeId) const override; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h index cc04ca19f18..f2aa26f44b9 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h @@ -65,6 +65,7 @@ public: virtual Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const = 0; virtual Storage::Info::ItemLibraryEntries itemLibraryEntries(SourceId sourceId) const = 0; virtual Storage::Info::ItemLibraryEntries allItemLibraryEntries() const = 0; + virtual Storage::Info::ItemLibraryEntries directoryImportsItemLibraryEntries(SourceId sourceId) const = 0; virtual std::vector<::Utils::SmallString> signalDeclarationNames(TypeId typeId) const = 0; virtual std::vector<::Utils::SmallString> functionDeclarationNames(TypeId typeId) const = 0; virtual std::optional<::Utils::SmallString> diff --git a/tests/unit/tests/mocks/projectstoragemock.cpp b/tests/unit/tests/mocks/projectstoragemock.cpp index 150930db1ab..9d5b89f7743 100644 --- a/tests/unit/tests/mocks/projectstoragemock.cpp +++ b/tests/unit/tests/mocks/projectstoragemock.cpp @@ -243,6 +243,13 @@ void ProjectStorageMock::setItemLibraryEntries( ON_CALL(*this, itemLibraryEntries(TypedEq(sourceId))).WillByDefault(Return(entries)); } +void ProjectStorageMock::setDirectoryImportsItemLibraryEntries( + QmlDesigner::SourceId sourceId, const QmlDesigner::Storage::Info::ItemLibraryEntries &entries) +{ + ON_CALL(*this, directoryImportsItemLibraryEntries(TypedEq(sourceId))) + .WillByDefault(Return(entries)); +} + namespace { void addBaseProperties(TypeId typeId, const QmlDesigner::SmallTypeIds<16> &baseTypeIds, diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index 1d64b0cc1e8..ac1bbfb2a4a 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -114,6 +114,8 @@ public: const QmlDesigner::Storage::Info::ItemLibraryEntries &entries); void setItemLibraryEntries(QmlDesigner::SourceId sourceId, const QmlDesigner::Storage::Info::ItemLibraryEntries &entries); + void setDirectoryImportsItemLibraryEntries( + QmlDesigner::SourceId sourceId, const QmlDesigner::Storage::Info::ItemLibraryEntries &entries); MOCK_METHOD(void, synchronize, @@ -228,6 +230,10 @@ public: allItemLibraryEntries, (), (const, override)); + MOCK_METHOD(QmlDesigner::Storage::Info::ItemLibraryEntries, + directoryImportsItemLibraryEntries, + (QmlDesigner::SourceId sourceId), + (const, override)); MOCK_METHOD(std::vector<::Utils::SmallString>, signalDeclarationNames, (QmlDesigner::TypeId typeId), diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index dff3a7904bd..8207ee4f245 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -1333,6 +1333,37 @@ TEST_F(Model_TypeAnnotation, item_library_entries) ElementsAre(u"/extra/file/path")))); } +TEST_F(Model_TypeAnnotation, directory_imports_item_library_entries) +{ + using namespace Qt::StringLiterals; + QmlDesigner::Storage::Info::ItemLibraryEntries storageEntries{{itemTypeId, + "Item", + "Item", + "/path/to/icon", + "basic category", + "QtQuick", + "It's a item", + "/path/to/template"}}; + storageEntries.front().properties.emplace_back("x", "double", Sqlite::ValueView::create(1)); + storageEntries.front().extraFilePaths.emplace_back("/extra/file/path"); + projectStorageMock.setDirectoryImportsItemLibraryEntries(pathCacheMock.sourceId, storageEntries); + + auto entries = model.directoryImportsItemLibraryEntries(); + + ASSERT_THAT(entries, + ElementsAre( + IsItemLibraryEntry(itemTypeId, + "Item", + u"Item", + u"/path/to/icon", + u"basic category", + u"QtQuick", + u"It's a item", + u"/path/to/template", + ElementsAre(IsItemLibraryProperty("x", "double"_L1, QVariant{1})), + ElementsAre(u"/extra/file/path")))); +} + class Model_ViewManagement : public Model { protected: diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index b948fb91ce1..79c75478bc4 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -8890,14 +8890,14 @@ TEST_F(ProjectStorage, get_item_library_entries_by_source_id) IsEmpty()))); } -TEST_F(ProjectStorage, get_local_file_item_library_entries_by_source_id) +TEST_F(ProjectStorage, get_directory_imports_item_library_entries_by_source_id) { auto package{createSimpleSynchronizationPackage()}; package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); package.types[1].exportedTypes.emplace_back(pathToModuleId, "Object"); storage.synchronize(package); - auto entries = storage.itemLibraryEntries(sourceId2); + auto entries = storage.directoryImportsItemLibraryEntries(sourceId2); ASSERT_THAT(entries, UnorderedElementsAre(IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), From 92e969361ae393d532f249f67f450009b2de7762 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 3 Mar 2025 14:59:13 +0200 Subject: [PATCH 06/82] QmlDesigner: Add Model::allItemLibraryEntries and use it in item lib Item library now allows searching for non-imported items also in project storage builds. Fixes: QDS-14849 Change-Id: I6eb5de7d55b8d07c2406242a3ec4c259b1e16302 Reviewed-by: Marco Bubke --- .../itemlibrary/itemlibrarymodel.cpp | 12 ++++---- .../libs/designercore/include/model.h | 1 + .../libs/designercore/model/model.cpp | 10 +++++++ .../unit/tests/unittests/model/model-test.cpp | 30 +++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 3baacb2571f..19a57659c8e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -358,15 +358,14 @@ void ItemLibraryModel::update(Model *model) itemLibImport->setImportExpanded(loadExpandedState(itemLibImport->importUrl())); } -#ifndef QDS_USE_PROJECTSTORAGE DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); const bool blockNewImports = document->inFileComponentModelActive(); -#endif TypeName currentFileType = QFileInfo(model->fileUrl().toLocalFile()).baseName().toUtf8(); - const QList itemLibEntries = model->itemLibraryEntries(); - for (const ItemLibraryEntry &entry : itemLibEntries) { + QList itemLibEntries = model->allItemLibraryEntries(); + itemLibEntries.append(model->directoryImportsItemLibraryEntries()); + for (const ItemLibraryEntry &entry : std::as_const(itemLibEntries)) { NodeMetaInfo metaInfo; #ifdef QDS_USE_PROJECTSTORAGE @@ -407,15 +406,14 @@ void ItemLibraryModel::update(Model *model) } } -#ifndef QDS_USE_PROJECTSTORAGE Import import = entryToImport(entry); bool hasImport = model->hasImport(import, true, true); +#ifndef QDS_USE_PROJECTSTORAGE bool isImportPossible = false; if (!hasImport) isImportPossible = !blockNewImports && model->isImportPossible(import, true, true); #else - bool hasImport = true; - bool isImportPossible = false; + bool isImportPossible = !blockNewImports; #endif bool isUsable = (valid && (isItem || forceVisibility)) && (entry.requiredImport().isEmpty() || hasImport); diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index ba73b3ab44c..6266a31b012 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -210,6 +210,7 @@ public: QList itemLibraryEntries() const; QList directoryImportsItemLibraryEntries() const; + QList allItemLibraryEntries() const; void attachView(AbstractView *view); void detachView(AbstractView *view, ViewNotification emitDetachNotify = NotifyView); diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 9f385c2a904..d6a80e05c36 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2830,6 +2830,16 @@ QList Model::directoryImportsItemLibraryEntries() const #endif } +QList Model::allItemLibraryEntries() const +{ +#ifdef QDS_USE_PROJECTSTORAGE + using namespace Storage::Info; + return toItemLibraryEntries(*d->pathCache, d->projectStorage->allItemLibraryEntries()); +#else + return d->metaInfo().itemLibraryInfo()->entries(); +#endif +} + NodeMetaInfo Model::qtQuickTimelineKeyframeGroupMetaInfo() const { if constexpr (useProjectStorage()) { diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 8207ee4f245..3d41c0ff3d5 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -1363,6 +1363,36 @@ TEST_F(Model_TypeAnnotation, directory_imports_item_library_entries) ElementsAre(IsItemLibraryProperty("x", "double"_L1, QVariant{1})), ElementsAre(u"/extra/file/path")))); } +TEST_F(Model_TypeAnnotation, all_item_library_entries) +{ + using namespace Qt::StringLiterals; + QmlDesigner::Storage::Info::ItemLibraryEntries storageEntries{{itemTypeId, + "Item", + "Item", + "/path/to/icon", + "basic category", + "QtQuick", + "It's a item", + "/path/to/template"}}; + storageEntries.front().properties.emplace_back("x", "double", Sqlite::ValueView::create(1)); + storageEntries.front().extraFilePaths.emplace_back("/extra/file/path"); + ON_CALL(projectStorageMock, allItemLibraryEntries()).WillByDefault(Return(storageEntries)); + + auto entries = model.allItemLibraryEntries(); + + ASSERT_THAT(entries, + ElementsAre( + IsItemLibraryEntry(itemTypeId, + "Item", + u"Item", + u"/path/to/icon", + u"basic category", + u"QtQuick", + u"It's a item", + u"/path/to/template", + ElementsAre(IsItemLibraryProperty("x", "double"_L1, QVariant{1})), + ElementsAre(u"/extra/file/path")))); +} class Model_ViewManagement : public Model { From 4465b3a18317c4430af89ef72339d0082cd12159 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 4 Apr 2025 13:41:15 +0300 Subject: [PATCH 07/82] QmlDesigner: Hide root window when rendering using qml-renderer puppet Window needs to have visible set to false as initial property or the window will briefly flash on the screen. Also suppress mac task bar icon. Fixes: QDS-15008 Change-Id: I2ee58b205bbf14ef8928a8adc6052fffa140e6b5 Reviewed-by: Thomas Hartmann --- .../qmlpuppet/qmlpuppet/renderer/qmlrenderer.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/tools/qmlpuppet/qmlpuppet/renderer/qmlrenderer.cpp b/src/tools/qmlpuppet/qmlpuppet/renderer/qmlrenderer.cpp index f445a2804b8..03cb6315725 100644 --- a/src/tools/qmlpuppet/qmlpuppet/renderer/qmlrenderer.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/renderer/qmlrenderer.cpp @@ -22,6 +22,9 @@ constexpr int DEFAULT_MAX_DIM = 1024; void QmlRenderer::initCoreApp() { +#ifdef Q_OS_MACOS + qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "true"); +#endif #if defined QT_WIDGETS_LIB createCoreApp(); #else @@ -144,9 +147,14 @@ bool QmlRenderer::setupRenderer() return false; } - QObject *renderObj = component.create(); + // Window components will flash the window briefly if we don't initialize visible to false + QVariantMap initialProps; + initialProps["visible"] = false; + QObject *renderObj = component.createWithInitialProperties(initialProps); if (renderObj) { + if (!qobject_cast(renderObj)) + renderObj->setProperty("visible", true); #ifdef QUICK3D_MODULE QQuickItem *contentItem3D = nullptr; renderObj->setParent(m_window->contentItem()); @@ -195,11 +203,6 @@ bool QmlRenderer::setupRenderer() // Hack to render Window items: reparent window content to m_window->contentItem() setRenderSize(renderWindow->size()); m_containerItem = m_window->contentItem(); - // Suppress the original window. - // Offscreen position ensures we don't get even brief flash of it. - renderWindow->setVisible(false); - renderWindow->resize(2, 2); - renderWindow->setPosition(-10000, -10000); const QList childItems = renderWindow->contentItem()->childItems(); for (QQuickItem *item : childItems) { item->setParent(m_window->contentItem()); From ff5ca5f5b4a36bac8bbc5455f7465a7cb9dea038 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 3 Apr 2025 14:25:49 +0200 Subject: [PATCH 08/82] QmlDesigner: Add warning for empty name cell Change-Id: I028362e9fc329247f5b068eee5f84ede28e65e9c Reviewed-by: Pranta Ghosh Dastider Reviewed-by: Thomas Hartmann --- share/qtcreator/qmldesigner/designsystem/Main.qml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/share/qtcreator/qmldesigner/designsystem/Main.qml b/share/qtcreator/qmldesigner/designsystem/Main.qml index 9578c6f8ef1..ae082adef4d 100644 --- a/share/qtcreator/qmldesigner/designsystem/Main.qml +++ b/share/qtcreator/qmldesigner/designsystem/Main.qml @@ -127,7 +127,7 @@ Rectangle { overlayInvalid.show() } - function showHeaderData(section: int, orientation: var) { + function showHeaderData(section: int, orientation: var, message: string) { if (orientation === Qt.Horizontal) { overlayInvalid.parent = horizontalHeaderView.contentItem overlayInvalid.cellItem = horizontalHeaderView.itemAtCell(Qt.point(overlay.section, 0)) @@ -136,7 +136,7 @@ Rectangle { overlayInvalid.cellItem = verticalHeaderView.itemAtCell(Qt.point(0, overlay.section)) } - notification.message = qsTr("This name is already in use, please use a different name.") + notification.message = message overlayInvalid.show() } @@ -1095,8 +1095,14 @@ Rectangle { // Revoke active focus from text field by forcing active focus on another item tableView.forceActiveFocus() - if (!result && overlayTextField.previousText !== overlayTextField.text) - overlayInvalid.showHeaderData(overlay.section, overlay.orientation) + if (overlayTextField.text === "") + overlayInvalid.showHeaderData(overlay.section, + overlay.orientation, + qsTr("No name found, please enter a valid name.")) + else if (!result && overlayTextField.previousText !== overlayTextField.text) + overlayInvalid.showHeaderData(overlay.section, + overlay.orientation, + qsTr("This name is already in use, please use a different name.")) } Text { From d41775ecd78c1ae896c3e2cfaaa30ce80d78163b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sun, 6 Apr 2025 01:10:35 +0200 Subject: [PATCH 09/82] Utils: Use span with initializer list Make span even more useful as it can takes initializer lists. void foo(Utils::span x); foo({1.2, 2.3}); Change-Id: Iaebbcad9dd875fbe0535b717941c6e0fc837303d Reviewed-by: Eike Ziller --- src/libs/utils/span.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/span.h b/src/libs/utils/span.h index f2c545940b7..3b716ae892e 100644 --- a/src/libs/utils/span.h +++ b/src/libs/utils/span.h @@ -6,9 +6,8 @@ #include // The (Apple) Clang implementation of span is incomplete until LLVM 15 / Xcode 14.3 / macOS 13 -#if __cplusplus >= 202002L \ - && !(defined(__apple_build_version__) && __apple_build_version__ < 14030022) -#include +#ifdef __cpp_lib_span_initializer_list +# include namespace Utils { using std::as_bytes; @@ -27,9 +26,9 @@ QT_WARNING_PUSH // disable automatic usage of std::span in span-lite // since we make that decision ourselves at the top of this header -#define span_CONFIG_SELECT_SPAN span_SPAN_NONSTD - -#include <3rdparty/span/span.hpp> +# define span_CONFIG_SELECT_SPAN span_SPAN_NONSTD +# define span_FEATURE_WITH_INITIALIZER_LIST_P2447 1 +# include <3rdparty/span/span.hpp> namespace Utils { using namespace nonstd; From 9c1336d49bfd8a5ab3d1847b2ef9b79115018f00 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 21 Mar 2025 13:28:43 +0100 Subject: [PATCH 10/82] UnitTests: Refactor ProjectStorageUpdater test part one Change-Id: I1c4416b301e47f58247426284da7173f386b69cc Reviewed-by: Thomas Hartmann --- .../projectstorageerrornotifierinterface.h | 2 + .../projectstorage/projectstorageupdater.cpp | 5 +- .../project/projectstorageerrornotifier.cpp | 18 + .../project/projectstorageerrornotifier.h | 1 + .../mocks/projectstorageerrornotifiermock.h | 1 + .../unit/tests/printers/gtest-qt-printing.cpp | 7 + tests/unit/tests/printers/gtest-qt-printing.h | 1 + .../projectstorageupdater-test.cpp | 444 ++++++++++-------- 8 files changed, 291 insertions(+), 188 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifierinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifierinterface.h index 34cb1638d66..df4efdc89b6 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifierinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifierinterface.h @@ -31,6 +31,8 @@ public: SourceId qmldirSourceId) = 0; + virtual void qmltypesFileMissing(QStringView qmltypesPath) = 0; + protected: ~ProjectStorageErrorNotifierInterface() = default; }; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index e9a26edd133..b0de72c73c1 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -1235,7 +1235,10 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Direct case FileState::Removed: case FileState::NotExists: case FileState::NotExistsUnchanged: - throw CannotParseQmlTypesFile{}; + tracer.tick("append updated source ids", keyValue("source id", directoryInfo.sourceId)); + package.updatedSourceIds.push_back(directoryInfo.sourceId); + + m_errorNotifier.qmltypesFileMissing(qmltypesPath); } tracer.end(keyValue("state", state)); diff --git a/src/plugins/qmldesigner/project/projectstorageerrornotifier.cpp b/src/plugins/qmldesigner/project/projectstorageerrornotifier.cpp index f6fefe2b297..25646c21a35 100644 --- a/src/plugins/qmldesigner/project/projectstorageerrornotifier.cpp +++ b/src/plugins/qmldesigner/project/projectstorageerrornotifier.cpp @@ -24,6 +24,17 @@ void logIssue(ProjectExplorer::Task::TaskType type, const QString &message, cons ProjectExplorer::TaskHub::addTask(task); ProjectExplorer::TaskHub::requestPopup(); } + +void logIssue(ProjectExplorer::Task::TaskType type, const QString &message, QStringView sourcePath) +{ + const Utils::Id category = ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM; + + Utils::FilePath filePath = Utils::FilePath::fromPathPart(sourcePath); + ProjectExplorer::Task task(type, message, filePath, -1, category); + ProjectExplorer::TaskHub::addTask(task); + ProjectExplorer::TaskHub::requestPopup(); +} + } // namespace void ProjectStorageErrorNotifier::typeNameCannotBeResolved(Utils::SmallStringView typeName, @@ -71,4 +82,11 @@ void ProjectStorageErrorNotifier::qmlDocumentDoesNotExistsForQmldirEntry(Utils:: m_pathCache.sourcePath(qmldirSourceId)); } +void ProjectStorageErrorNotifier::qmltypesFileMissing(QStringView qmltypesPath) +{ + logIssue(ProjectExplorer::Task::Warning, + Tr::tr("Not existing Qmltypes File %1.").arg(qmltypesPath), + qmltypesPath); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/project/projectstorageerrornotifier.h b/src/plugins/qmldesigner/project/projectstorageerrornotifier.h index ae720bac693..03606259d43 100644 --- a/src/plugins/qmldesigner/project/projectstorageerrornotifier.h +++ b/src/plugins/qmldesigner/project/projectstorageerrornotifier.h @@ -27,6 +27,7 @@ public: Storage::Version version, SourceId qmlDocumentSourceId, SourceId qmldirSourceId) override; + void qmltypesFileMissing(QStringView qmltypesPath) override; private: PathCacheType &m_pathCache; diff --git a/tests/unit/tests/mocks/projectstorageerrornotifiermock.h b/tests/unit/tests/mocks/projectstorageerrornotifiermock.h index 17281682974..e58b27d1a33 100644 --- a/tests/unit/tests/mocks/projectstorageerrornotifiermock.h +++ b/tests/unit/tests/mocks/projectstorageerrornotifiermock.h @@ -32,4 +32,5 @@ public: QmlDesigner::SourceId qmlDocumentSourceId, QmlDesigner::SourceId qmldirSourceId), (override)); + MOCK_METHOD(void, qmltypesFileMissing, (QStringView qmltypesPath), (override)); }; diff --git a/tests/unit/tests/printers/gtest-qt-printing.cpp b/tests/unit/tests/printers/gtest-qt-printing.cpp index ef4425e1eb7..9b0e166be5f 100644 --- a/tests/unit/tests/printers/gtest-qt-printing.cpp +++ b/tests/unit/tests/printers/gtest-qt-printing.cpp @@ -1,6 +1,8 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "gtest-qt-printing.h" + #include #include #include @@ -89,6 +91,11 @@ std::ostream &operator<<(std::ostream &out, const QIcon &icon) out << icon.cacheKey() << ")"; } +void PrintTo(QStringView text, std::ostream *os) +{ + *os << text; +} + void PrintTo(const QString &text, std::ostream *os) { *os << text; diff --git a/tests/unit/tests/printers/gtest-qt-printing.h b/tests/unit/tests/printers/gtest-qt-printing.h index a81994be167..2711f633198 100644 --- a/tests/unit/tests/printers/gtest-qt-printing.h +++ b/tests/unit/tests/printers/gtest-qt-printing.h @@ -45,6 +45,7 @@ std::ostream &operator<<(std::ostream &out, const QImage &image); std::ostream &operator<<(std::ostream &out, const QIcon &icon); void PrintTo(const QString &text, std::ostream *os); +void PrintTo(QStringView text, std::ostream *os); void PrintTo(const QVariant &variant, std::ostream *os); void PrintTo(const QByteArray &text, std::ostream *os); QT_END_NAMESPACE diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index ed063b5291e..ecc5081074b 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -21,6 +21,8 @@ namespace { +using namespace Qt::StringLiterals; + namespace Storage = QmlDesigner::Storage; using QmlDesigner::FileStatus; @@ -28,7 +30,6 @@ using QmlDesigner::ModuleId; using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; using QmlDesigner::SourceNameId; -namespace Storage = QmlDesigner::Storage; using QmlDesigner::IdPaths; using Storage::Import; using Storage::IsInsideProject; @@ -153,7 +154,7 @@ auto IsPropertyEditorQmlPath(const ModuleIdMatcher &moduleIdMatcher, directoryIdMatcher)); } -class ProjectStorageUpdater : public testing::Test +class BaseProjectStorageUpdater : public testing::Test { public: struct StaticData @@ -170,85 +171,16 @@ public: static void TearDownTestSuite() { staticData.reset(); } - ProjectStorageUpdater() + BaseProjectStorageUpdater() { - setFilesChanged({qmltypesPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1}); - setFilesAdded({qmltypes2PathSourceId, qmlDocumentSourceId2, qmlDocumentSourceId3}); - - setFilesDontChanged({directoryPathSourceId, - path1SourceId, - path2SourceId, - path3SourceId, - firstSourceId, - secondSourceId, - thirdSourceId, - qmltypes1SourceId, - qmltypes2SourceId, - itemLibraryPathSourceId}); - setFilesDontExistsUnchanged({createDirectorySourceId("/path/designer"), - createDirectorySourceId("/root/designer"), - createDirectorySourceId("/path/one/designer"), - createDirectorySourceId("/path/two/designer"), - createDirectorySourceId("/path/three/designer")}); - - setFilesAdded({qmldir1SourceId, qmldir2SourceId, qmldir3SourceId}); - - setContent(u"/path/qmldir", qmldirContent); - - setQmlFileNames(u"/path", {"First.qml", "First2.qml", "Second.qml"}); - ON_CALL(projectStorageMock, moduleId(_, _)).WillByDefault([&](const auto &name, const auto &kind) { return storage.moduleId(name, kind); }); - - firstType.prototype = ImportedType{"Object"}; - firstType.traits = TypeTraitsKind::Reference; - secondType.prototype = ImportedType{"Object2"}; - secondType.traits = TypeTraitsKind::Reference; - thirdType.prototype = ImportedType{"Object3"}; - thirdType.traits = TypeTraitsKind::Reference; - - setContent(u"/path/First.qml", qmlDocument1); - setContent(u"/path/First2.qml", qmlDocument2); - setContent(u"/path/Second.qml", qmlDocument3); - setContent(u"/path/example.qmltypes", qmltypes1); - setContent(u"/path/example2.qmltypes", qmltypes2); - setContent(u"/path/one/First.qml", qmlDocument1); - setContent(u"/path/one/Second.qml", qmlDocument2); - setContent(u"/path/two/Third.qml", qmlDocument3); - setContent(u"/path/one/example.qmltypes", qmltypes1); - setContent(u"/path/two/example2.qmltypes", qmltypes2); - - ON_CALL(qmlDocumentParserMock, parse(qmlDocument1, _, _, _, _)) - .WillByDefault([&](auto, auto &imports, auto, auto, auto) { - imports.push_back(import1); - return firstType; - }); - ON_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _, _, _)) - .WillByDefault([&](auto, auto &imports, auto, auto, auto) { - imports.push_back(import2); - return secondType; - }); - ON_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _, _, _)) - .WillByDefault([&](auto, auto &imports, auto, auto, auto) { - imports.push_back(import3); - return thirdType; - }); - ON_CALL(qmlTypesParserMock, parse(Eq(qmltypes1), _, _, _, _)) - .WillByDefault([&](auto, auto &imports, auto &types, auto, auto) { - types.push_back(objectType); - imports.push_back(import4); - }); - ON_CALL(qmlTypesParserMock, parse(Eq(qmltypes2), _, _, _, _)) - .WillByDefault([&](auto, auto &imports, auto &types, auto, auto) { - types.push_back(itemType); - imports.push_back(import5); - }); } - ~ProjectStorageUpdater() { storage.resetForTestsOnly(); } + ~BaseProjectStorageUpdater() { storage.resetForTestsOnly(); } - void setFilesDontChanged(const QmlDesigner::SourceIds &sourceIds) + void setFilesUnchanged(const QmlDesigner::SourceIds &sourceIds) { for (auto sourceId : sourceIds) { ON_CALL(fileSystemMock, fileStatus(Eq(sourceId))) @@ -288,7 +220,7 @@ public: } } - void setFilesDontExists(const QmlDesigner::SourceIds &sourceIds) + void setFilesNotExists(const QmlDesigner::SourceIds &sourceIds) { for (auto sourceId : sourceIds) { ON_CALL(fileSystemMock, fileStatus(Eq(sourceId))) @@ -298,7 +230,7 @@ public: } } - void setFilesDontExistsUnchanged(const QmlDesigner::SourceIds &sourceIds) + void setFilesNotExistsUnchanged(const QmlDesigner::SourceIds &sourceIds) { for (auto sourceId : sourceIds) { ON_CALL(fileSystemMock, fileStatus(Eq(sourceId))) @@ -395,6 +327,84 @@ protected: errorNotifierMock, projectPartId, qtPartId}; +}; + +class ProjectStorageUpdater : public BaseProjectStorageUpdater +{ +public: + ProjectStorageUpdater() + { + setFilesChanged({qmltypesPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1}); + setFilesAdded({qmltypes2PathSourceId, qmlDocumentSourceId2, qmlDocumentSourceId3}); + + setFilesUnchanged({directoryPathSourceId, + path1SourceId, + path2SourceId, + path3SourceId, + firstSourceId, + secondSourceId, + thirdSourceId, + qmltypes1SourceId, + qmltypes2SourceId, + itemLibraryPathSourceId}); + setFilesNotExistsUnchanged({createDirectorySourceId("/path/designer"), + createDirectorySourceId("/root/designer"), + createDirectorySourceId("/path/one/designer"), + createDirectorySourceId("/path/two/designer"), + createDirectorySourceId("/path/three/designer")}); + + setFilesAdded({qmldir1SourceId, qmldir2SourceId, qmldir3SourceId}); + + setContent(u"/path/qmldir", qmldirContent); + + setQmlFileNames(u"/path", {"First.qml", "First2.qml", "Second.qml"}); + + firstType.prototype = ImportedType{"Object"}; + firstType.traits = TypeTraitsKind::Reference; + secondType.prototype = ImportedType{"Object2"}; + secondType.traits = TypeTraitsKind::Reference; + thirdType.prototype = ImportedType{"Object3"}; + thirdType.traits = TypeTraitsKind::Reference; + + setContent(u"/path/First.qml", qmlDocument1); + setContent(u"/path/First2.qml", qmlDocument2); + setContent(u"/path/Second.qml", qmlDocument3); + setContent(u"/path/example.qmltypes", qmltypes1); + setContent(u"/path/example2.qmltypes", qmltypes2); + setContent(u"/path/one/First.qml", qmlDocument1); + setContent(u"/path/one/Second.qml", qmlDocument2); + setContent(u"/path/two/Third.qml", qmlDocument3); + setContent(u"/path/one/example.qmltypes", qmltypes1); + setContent(u"/path/two/example2.qmltypes", qmltypes2); + + ON_CALL(qmlDocumentParserMock, parse(qmlDocument1, _, _, _, _)) + .WillByDefault([&](auto, auto &imports, auto, auto, auto) { + imports.push_back(import1); + return firstType; + }); + ON_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _, _, _)) + .WillByDefault([&](auto, auto &imports, auto, auto, auto) { + imports.push_back(import2); + return secondType; + }); + ON_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _, _, _)) + .WillByDefault([&](auto, auto &imports, auto, auto, auto) { + imports.push_back(import3); + return thirdType; + }); + ON_CALL(qmlTypesParserMock, parse(Eq(qmltypes1), _, _, _, _)) + .WillByDefault([&](auto, auto &imports, auto &types, auto, auto) { + types.push_back(objectType); + imports.push_back(import4); + }); + ON_CALL(qmlTypesParserMock, parse(Eq(qmltypes2), _, _, _, _)) + .WillByDefault([&](auto, auto &imports, auto &types, auto, auto) { + types.push_back(itemType); + imports.push_back(import5); + }); + } + +protected: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); @@ -481,16 +491,25 @@ protected: SourceId qmltypes2SourceId = sourcePathCache.sourceId("/path/two/example2.qmltypes"); }; -TEST_F(ProjectStorageUpdater, get_content_for_qml_dir_paths_if_file_status_is_different) +class ProjectStorageUpdater_get_content_for_qml_dir_paths : public ProjectStorageUpdater { +public: + ProjectStorageUpdater_get_content_for_qml_dir_paths() + { + setFilesChanged({qmlDir1PathSourceId}); + setFilesAdded({qmlDir2PathSourceId}); + setFilesUnchanged({qmlDir3PathSourceId, path3SourceId}); + } + SourceId qmlDir1PathSourceId = sourcePathCache.sourceId("/path/one/qmldir"); SourceId qmlDir2PathSourceId = sourcePathCache.sourceId("/path/two/qmldir"); SourceId qmlDir3PathSourceId = sourcePathCache.sourceId("/path/three/qmldir"); SourceId path3SourceId = createDirectorySourceId("/path/three"); +}; + +TEST_F(ProjectStorageUpdater_get_content_for_qml_dir_paths, file_status_is_different) +{ QStringList directories = {"/path/one", "/path/two", "/path/three"}; - setFilesChanged({qmlDir1PathSourceId}); - setFilesAdded({qmlDir2PathSourceId}); - setFilesDontChanged({qmlDir3PathSourceId, path3SourceId}); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); @@ -498,18 +517,10 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_dir_paths_if_file_status_is_di updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, - get_content_for_qml_dir_paths_if_file_status_is_different_for_subdirectories) +TEST_F(ProjectStorageUpdater_get_content_for_qml_dir_paths, file_status_is_different_for_subdirectories) { - SourceId qmlDir1PathSourceId = sourcePathCache.sourceId("/path/one/qmldir"); - SourceId qmlDir2PathSourceId = sourcePathCache.sourceId("/path/two/qmldir"); - SourceId qmlDir3PathSourceId = sourcePathCache.sourceId("/path/three/qmldir"); - SourceId path3SourceId = createDirectorySourceId("/path/three"); QStringList directories = {"/path/one"}; setSubdirectoryPaths(u"/path/one", {"/path/two", "/path/three"}); - setFilesChanged({qmlDir1PathSourceId}); - setFilesAdded({qmlDir2PathSourceId}); - setFilesDontChanged({qmlDir3PathSourceId, path3SourceId}); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); @@ -540,31 +551,66 @@ TEST_F(ProjectStorageUpdater, request_file_status_from_file_system_for_subdirect updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, get_content_for_qml_types) +class ProjectStorageUpdater_get_content_for_qml_types : public BaseProjectStorageUpdater { +public: + ProjectStorageUpdater_get_content_for_qml_types() + { + setQmlFileNames(u"/path", {}); + setExpectedContent(u"/path/qmldir", qmldir); + setContent(u"/path/example.qmltypes", qmltypes); + setFilesUnchanged({directoryPathSourceId}); + setFilesChanged({qmlDirPathSourceId}); + } + +public: QString qmldir{R"(module Example typeinfo example.qmltypes)"}; - setQmlFileNames(u"/path", {}); - setExpectedContent(u"/path/qmldir", qmldir); + QString qmltypes{"Module {\ndependencies: [module1]}"}; + QStringList directories = {"/path"}; + SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); + SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); + SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); +}; + +TEST_F(ProjectStorageUpdater_get_content_for_qml_types, added_qml_types_file_provides_content) +{ + setFilesAdded({qmltypesPathSourceId}); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes")))); updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, get_content_for_qml_types_if_project_storage_file_status_is_invalid) +TEST_F(ProjectStorageUpdater_get_content_for_qml_types, changed_qml_types_file_provides_content) { - QString qmldir{R"(module Example - typeinfo example.qmltypes)"}; - setQmlFileNames(u"/path", {}); - setExpectedContent(u"/path/qmldir", qmldir); - setFilesAdded({qmltypesPathSourceId}); + setFilesChanged({qmltypesPathSourceId}); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes")))); updater.update({.qtDirectories = directories}); } +TEST_F(ProjectStorageUpdater_get_content_for_qml_types, removed_qml_types_file_does_not_provide_content) +{ + EXPECT_CALL(fileSystemMock, contentAsQString(_)).Times(AnyNumber()); + setFilesRemoved({qmltypesPathSourceId}); + + EXPECT_CALL(fileSystemMock, contentAsQString(Eq("/path/example.qmltypes"_L1))).Times(0); + + updater.update({.qtDirectories = directories}); +} + +TEST_F(ProjectStorageUpdater_get_content_for_qml_types, removed_qml_types_file_notifies_about_error) +{ + setFilesRemoved({qmltypesPathSourceId}); + + EXPECT_CALL(errorNotifierMock, qmltypesFileMissing(Eq("/path/example.qmltypes"_L1))); + + updater.update({.qtDirectories = directories}); +} + TEST_F(ProjectStorageUpdater, parse_qml_types) { QString qmldir{R"(module Example @@ -696,7 +742,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_types_in_subdirectories) TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) { - setFilesDontChanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); @@ -707,11 +753,11 @@ TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change_in_subdirectory { SourceId qmlDirRootPathSourceId = sourcePathCache.sourceId("/root/qmldir"); SourceId rootPathSourceId = createDirectorySourceId("/root"); - setFilesDontChanged({qmltypesPathSourceId, - qmltypes2PathSourceId, - qmlDirPathSourceId, - qmlDirRootPathSourceId, - rootPathSourceId}); + setFilesUnchanged({qmltypesPathSourceId, + qmltypes2PathSourceId, + qmlDirPathSourceId, + qmlDirRootPathSourceId, + rootPathSourceId}); QStringList directories = {"/root"}; setSubdirectoryPaths(u"/root", {"/path"}); @@ -726,7 +772,7 @@ TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_ignored_subdirectory) SourceId ignoreInQdsSourceId = sourcePathCache.sourceId("/path/ignore-in-qds"); SourceId rootPathSourceId = createDirectorySourceId("/root"); setFilesChanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); - setFilesDontChanged({rootPathSourceId, qmlDirRootPathSourceId, ignoreInQdsSourceId}); + setFilesUnchanged({rootPathSourceId, qmlDirRootPathSourceId, ignoreInQdsSourceId}); setSubdirectoryPaths(u"/root", {"/path"}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); @@ -741,7 +787,7 @@ TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_added_ignored_subdirector SourceId rootPathSourceId = createDirectorySourceId("/root"); setFilesChanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); setFilesAdded({ignoreInQdsSourceId}); - setFilesDontChanged({rootPathSourceId, qmlDirRootPathSourceId}); + setFilesUnchanged({rootPathSourceId, qmlDirRootPathSourceId}); setSubdirectoryPaths(u"/root", {"/path"}); EXPECT_CALL( @@ -841,7 +887,7 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_even_for_no_changes) setSubdirectoryPaths(u"/path/one", {"/path/three"}); auto rootDirectoryPathSourceId = createDirectorySourceId("/root"); setFilesChanged({path1SourceId, path2SourceId, path3SourceId}); - setFilesDontChanged({rootDirectoryPathSourceId}); + setFilesUnchanged({rootDirectoryPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", @@ -867,7 +913,7 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecti SourceId rootDirectoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, rootDirectoryPathId); setFilesChanged({rootDirectoryPathSourceId}); - setFilesDontExists({ + setFilesNotExists({ path1SourceId, path3SourceId, }); @@ -891,12 +937,34 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecti updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, synchronize_qml_types_throws_if_qmltpes_does_not_exists) +TEST_F(ProjectStorageUpdater, synchronize_qml_types_notfies_error_if_qmltypes_does_not_exists) { Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; - setFilesDontExists({qmltypesPathSourceId}); + setFilesNotExists({qmltypesPathSourceId}); - ASSERT_THROW(updater.update({.qtDirectories = directories}), QmlDesigner::CannotParseQmlTypesFile); + EXPECT_CALL(errorNotifierMock, qmltypesFileMissing(Eq("/path/example.qmltypes"_L1))); + + updater.update({.qtDirectories = directories}); +} + +TEST_F(ProjectStorageUpdater, + synchronize_qml_types_adds_updated_source_id_and_directory_info_for_missing_qmltypes_file) +{ + Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; + setFilesNotExists({qmltypesPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field("SynchronizationPackage::updatedSourceIds", + &SynchronizationPackage::updatedSourceIds, + Contains(qmltypesPathSourceId)), + Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + Contains(IsDirectoryInfo(directoryPathId, + qmltypesPathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes)))))); + + updater.update({.qtDirectories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_changed) @@ -905,7 +973,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_c setContent(u"/path/example.qmltypes", qmltypes); ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, _)) .WillByDefault([&](auto, auto &, auto &types, auto, auto) { types.push_back(objectType); }); - setFilesDontChanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); @@ -1252,7 +1320,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) FirstType 1.0 First.qml)"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); - setFilesDontChanged({qmlDirPathSourceId, qmlDocumentSourceId1}); + setFilesUnchanged({qmlDirPathSourceId, qmlDocumentSourceId1}); setFilesAdded({qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}}); @@ -1320,7 +1388,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) )"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesRemoved({qmlDocumentSourceId3}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, @@ -1390,7 +1458,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) )"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); @@ -1454,7 +1522,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) )"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); @@ -1517,7 +1585,7 @@ TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) FirstType 1.0 First.qml )"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesChanged({qmlDirPathSourceId}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, @@ -1581,7 +1649,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_dat FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({qmlDocumentSourceId3}); + setFilesUnchanged({qmlDocumentSourceId3}); EXPECT_CALL( projectStorageMock, @@ -1654,7 +1722,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed) {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmlDocumentSourceId1, exampleModuleId, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, exampleModuleId, FileType::QmlDocument}}); - setFilesDontChanged({qmlDirPathSourceId}); + setFilesUnchanged({qmlDirPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(AllOf( @@ -1710,7 +1778,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed_and_some {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmlDocumentSourceId1, exampleModuleId, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, exampleModuleId, FileType::QmlDocument}}); - setFilesDontChanged({qmlDirPathSourceId, qmltypes2PathSourceId, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDirPathSourceId, qmltypes2PathSourceId, qmlDocumentSourceId2}); EXPECT_CALL(projectStorageMock, synchronize(AllOf( @@ -1752,10 +1820,12 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_not_changed_and_some_rem {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmlDocumentSourceId1, exampleModuleId, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, exampleModuleId, FileType::QmlDocument}}); - setFilesDontChanged({qmlDirPathSourceId, qmltypes2PathSourceId, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDirPathSourceId, qmltypes2PathSourceId, qmlDocumentSourceId2}); setFilesRemoved({qmltypesPathSourceId, qmlDocumentSourceId1}); - ASSERT_THROW(updater.update({.qtDirectories = directories}), QmlDesigner::CannotParseQmlTypesFile); + EXPECT_CALL(errorNotifierMock, qmltypesFileMissing(Eq(u"/path/example.qmltypes"_s))); + + updater.update({.qtDirectories = directories}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_removed_files) @@ -1770,7 +1840,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_rem {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmlDocumentSourceId1, exampleModuleId, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, exampleModuleId, FileType::QmlDocument}}); - setFilesDontChanged({qmltypes2PathSourceId, qmlDocumentSourceId2}); + setFilesUnchanged({qmltypes2PathSourceId, qmlDocumentSourceId2}); setFilesRemoved({qmltypesPathSourceId, qmlDocumentSourceId1}); EXPECT_CALL( @@ -2259,7 +2329,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directories) TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_exists) { - setFilesDontExists({path2SourceId}); + setFilesNotExists({path2SourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2271,7 +2341,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_exists) TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_changed) { - setFilesDontChanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); + setFilesUnchanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2304,7 +2374,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldirs) TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_exists) { - setFilesDontExists({qmldir2SourceId}); + setFilesNotExists({qmldir2SourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2316,7 +2386,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_exists) TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_changed) { - setFilesDontChanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); + setFilesUnchanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2362,7 +2432,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_dont_changed) setQmlFileNames(u"/path/one", {"First.qml", "Second.qml"}); setQmlFileNames(u"/path/two", {"Third.qml"}); setContent(u"/path/one/qmldir", qmldir1); - setFilesDontChanged({firstSourceId, secondSourceId, thirdSourceId}); + setFilesUnchanged({firstSourceId, secondSourceId, thirdSourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2374,7 +2444,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_dont_changed) TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_changed) { - setFilesDontChanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); + setFilesUnchanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); setFilesChanged({firstSourceId, secondSourceId, thirdSourceId}); setDirectoryInfos(path1SourceContextId, {{path1SourceContextId, firstSourceId, exampleModuleId, FileType::QmlDocument}, @@ -2392,13 +2462,13 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_changed) TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files_and_directories_dont_changed) { - setFilesDontChanged({qmldir1SourceId, - qmldir2SourceId, - path1SourceId, - path2SourceId, - firstSourceId, - secondSourceId, - thirdSourceId}); + setFilesUnchanged({qmldir1SourceId, + qmldir2SourceId, + path1SourceId, + path2SourceId, + firstSourceId, + secondSourceId, + thirdSourceId}); setDirectoryInfos(path1SourceContextId, {{path1SourceContextId, firstSourceId, exampleModuleId, FileType::QmlDocument}, {path1SourceContextId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); @@ -2422,7 +2492,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_in_qmldir) setContent(u"/path/one/qmldir", qmldir1); setContent(u"/path/two/qmldir", qmldir2); - setFilesDontChanged({firstSourceId, secondSourceId, thirdSourceId}); + setFilesUnchanged({firstSourceId, secondSourceId, thirdSourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2440,7 +2510,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_in_qmldir_ typeinfo example2.qmltypes)"}; setContent(u"/path/one/qmldir", qmldir1); setContent(u"/path/two/qmldir", qmldir2); - setFilesDontChanged({qmltypes1SourceId, qmltypes2SourceId}); + setFilesUnchanged({qmltypes1SourceId, qmltypes2SourceId}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2452,7 +2522,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_in_qmldir_ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_changed) { - setFilesDontChanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); + setFilesUnchanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); setFilesChanged({qmltypes1SourceId, qmltypes2SourceId}); setDirectoryInfos(path1SourceContextId, {{path1SourceContextId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); @@ -2469,12 +2539,12 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_changed) TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories_dont_changed) { - setFilesDontChanged({qmldir1SourceId, - qmldir2SourceId, - path1SourceId, - path2SourceId, - qmltypes1SourceId, - qmltypes2SourceId}); + setFilesUnchanged({qmldir1SourceId, + qmldir2SourceId, + path1SourceId, + path2SourceId, + qmltypes1SourceId, + qmltypes2SourceId}); setDirectoryInfos(path1SourceContextId, {{path1SourceContextId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); setDirectoryInfos(path2SourceContextId, @@ -2490,7 +2560,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir) { - setFilesDontExists({qmlDirPathSourceId}); + setFilesNotExists({qmlDirPathSourceId}); setFilesChanged({directoryPathSourceId}); EXPECT_CALL( @@ -2559,7 +2629,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir) TEST_F(ProjectStorageUpdater, warn_about_non_existing_qml_document) { - setFilesDontExists({qmlDocumentSourceId1}); + setFilesNotExists({qmlDocumentSourceId1}); setFilesAdded({directoryPathSourceId}); QString qmldir{R"(module Example FirstType 1.0 First.qml @@ -2579,7 +2649,7 @@ TEST_F(ProjectStorageUpdater, warn_about_non_existing_qml_document) TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_parsed_type_if_qml_document_does_not_exists) { - setFilesDontExists({qmlDocumentSourceId1}); + setFilesNotExists({qmlDocumentSourceId1}); setFilesAdded({directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId2}); QString qmldir{R"(module Example FirstType 1.0 First.qml @@ -2694,10 +2764,10 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_if_direct TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_document) { - setFilesDontExistsUnchanged({qmlDirPathSourceId}); + setFilesNotExistsUnchanged({qmlDirPathSourceId}); setFilesChanged({directoryPathSourceId}); setFilesAdded({qmlDocumentSourceId3}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); @@ -2752,10 +2822,10 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_d TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_removes_qml_document) { - setFilesDontExists({qmlDirPathSourceId}); + setFilesNotExists({qmlDirPathSourceId}); setFilesChanged({directoryPathSourceId}); setFilesRemoved({qmlDocumentSourceId3}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, @@ -2802,7 +2872,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories) SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); - setFilesDontChanged({qmlDirPathSourceId}); + setFilesUnchanged({qmlDirPathSourceId}); EXPECT_CALL( projectStorageMock, @@ -2880,7 +2950,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_subdirectories) SourceId rootPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, rootPathId); SourceId rootQmldirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); setFilesChanged({directoryPathSourceId, rootPathSourceId}); - setFilesDontChanged({qmlDirPathSourceId, rootQmldirPathSourceId}); + setFilesUnchanged({qmlDirPathSourceId, rootQmldirPathSourceId}); setSubdirectoryPaths(u"/root", {"/path"}); setSubdirectorySourceIds(rootPathId, {directoryPathId}); @@ -2988,7 +3058,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_directory_change SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); - setFilesDontChanged({qmlDirPathSourceId}); + setFilesUnchanged({qmlDirPathSourceId}); auto directorySourceContextId = directoryPathSourceId.contextId(); EXPECT_CALL(patchWatcherMock, @@ -3138,7 +3208,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_add_only_qml_document_in_directory FirstType 1.0 First.qml)"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); - setFilesDontChanged({qmlDirPathSourceId, qmlDocumentSourceId1}); + setFilesUnchanged({qmlDirPathSourceId, qmlDocumentSourceId1}); setFilesAdded({qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}}); @@ -3206,7 +3276,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document) )"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesRemoved({qmlDocumentSourceId3}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, @@ -3276,7 +3346,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document_in_qmldir_onl )"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); @@ -3340,7 +3410,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_add_qml_document_to_qm )"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); @@ -3403,7 +3473,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_remove_qml_document_fr FirstType 1.0 First.qml )"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); + setFilesUnchanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesChanged({qmlDirPathSourceId}); setDirectoryInfos(directoryPathId, {{directoryPathId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, @@ -3467,7 +3537,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_dont_update_qml_docume FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({qmlDocumentSourceId3}); + setFilesUnchanged({qmlDocumentSourceId3}); EXPECT_CALL( projectStorageMock, @@ -3540,7 +3610,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldirs_dont_update_qml_documents_ FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({qmlDocumentSourceId3}); + setFilesUnchanged({qmlDocumentSourceId3}); EXPECT_CALL( projectStorageMock, @@ -3613,7 +3683,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directory_but_not_qmldir) {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmlDocumentSourceId1, exampleModuleId, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId2, exampleModuleId, FileType::QmlDocument}}); - setFilesDontChanged({qmlDirPathSourceId}); + setFilesUnchanged({qmlDirPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(AllOf( @@ -3704,7 +3774,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qml_documents) TEST_F(ProjectStorageUpdater, watcher_updates_removed_qml_documents) { - setFilesDontExistsUnchanged({annotationDirectorySourceId, qmlDirPathSourceId}); + setFilesNotExistsUnchanged({annotationDirectorySourceId, qmlDirPathSourceId}); setFilesRemoved({qmlDocumentSourceId2}); setFilesChanged({qmlDocumentSourceId1}); @@ -3761,7 +3831,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmltypes) setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged( + setFilesUnchanged( {directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2}); EXPECT_CALL(projectStorageMock, @@ -3790,12 +3860,12 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmltypes) {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); } -TEST_F(ProjectStorageUpdater, watcher_updates_removed_qmltypes_without_updated_qmldir) +TEST_F(ProjectStorageUpdater, DISABLED_watcher_updates_removed_qmltypes_without_updated_qmldir) { setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged( + setFilesUnchanged( {directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesRemoved({qmltypesPathSourceId}); @@ -3810,7 +3880,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removed_qmltypes_with_updated_qmld setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged( + setFilesUnchanged( {directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesRemoved({qmltypesPathSourceId}); updater.pathsWithIdsChanged( @@ -3858,7 +3928,7 @@ TEST_F(ProjectStorageUpdater, watcher_dont_watches_directories_after_qmltypes_ch setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged( + setFilesUnchanged( {directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2}); EXPECT_CALL(patchWatcherMock, updateContextIdPaths(_, _)).Times(0); @@ -3872,7 +3942,7 @@ TEST_F(ProjectStorageUpdater, watcher_dont_updates_qmltypes_for_other_projects) setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged( + setFilesUnchanged( {directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); @@ -3889,7 +3959,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_and_but_not_included_q SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); - setFilesDontChanged({qmlDirPathSourceId}); + setFilesUnchanged({qmlDirPathSourceId}); EXPECT_CALL( projectStorageMock, @@ -3965,7 +4035,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldir_and_but_not_included_qml_do FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({directoryPathSourceId}); + setFilesUnchanged({directoryPathSourceId}); setFilesChanged({qmlDirPathSourceId}); EXPECT_CALL( @@ -4052,7 +4122,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldir_and_but_not_included_qmltyp typeinfo example.qmltypes typeinfo example2.qmltypes)"}; setContent(u"/path/qmldir", qmldir); - setFilesDontChanged({directoryPathSourceId}); + setFilesUnchanged({directoryPathSourceId}); setFilesChanged({qmlDirPathSourceId, qmltypesPathSourceId, qmltypes2PathSourceId, @@ -4170,7 +4240,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens) setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); ON_CALL(projectStorageMock, synchronize(_)) .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); updater.pathsWithIdsChanged( @@ -4235,7 +4305,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); ON_CALL(projectStorageMock, synchronize(_)) .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); updater.pathsWithIdsChanged( @@ -4304,7 +4374,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument}, {directoryPathId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument}}); - setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); ON_CALL(projectStorageMock, synchronize(_)) .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); updater.pathsWithIdsChanged( @@ -4370,7 +4440,7 @@ TEST_F(ProjectStorageUpdater, input_is_cleared_after_successful_update) setDirectoryInfos(directoryPathId, {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); - setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); @@ -4548,7 +4618,7 @@ TEST_F(ProjectStorageUpdater, update_added_type_annotation) QmlDesigner::SourcePath{itemLibraryPath + "/quick.metainfo"}); auto qtQuickControlSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); - setFilesDontChanged({itemLibraryPathSourceId}); + setFilesUnchanged({itemLibraryPathSourceId}); setFilesAdded({qtQuickSourceId, qtQuickControlSourceId}); auto qtQuickModuleId = moduleId("QtQuick", ModuleKind::QmlLibrary); auto qtQuickControlsModuleId = moduleId("QtQuick.Controls.Basic", ModuleKind::QmlLibrary); @@ -4587,7 +4657,7 @@ TEST_F(ProjectStorageUpdater, update_changed_type_annotation) QmlDesigner::SourcePath{itemLibraryPath + "/quick.metainfo"}); auto qtQuickControlSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); - setFilesDontChanged({itemLibraryPathSourceId}); + setFilesUnchanged({itemLibraryPathSourceId}); setFilesChanged({qtQuickSourceId, qtQuickControlSourceId}); auto qtQuickModuleId = moduleId("QtQuick", ModuleKind::QmlLibrary); auto qtQuickControlsModuleId = moduleId("QtQuick.Controls.Basic", ModuleKind::QmlLibrary); @@ -4657,7 +4727,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_meta_info_file) .WillByDefault(Return(QmlDesigner::SmallSourceIds<4>{qtQuickSourceId, qtQuickControlSourceId})); setFilesChanged({itemLibraryPathSourceId}); setFilesRemoved({qtQuickSourceId}); - setFilesDontChanged({qtQuickControlSourceId}); + setFilesUnchanged({qtQuickControlSourceId}); EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field("SynchronizationPackage::typeAnnotations", @@ -4707,7 +4777,7 @@ TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_direct setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); - setFilesDontChanged({path1SourceId}); + setFilesUnchanged({path1SourceId}); setFilesAdded({designer1SourceId}); EXPECT_CALL(projectStorageMock, @@ -4741,7 +4811,7 @@ TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_dire setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); - setFilesDontChanged({path1SourceId}); + setFilesUnchanged({path1SourceId}); setFilesChanged({designer1SourceId}); EXPECT_CALL(projectStorageMock, @@ -4776,7 +4846,7 @@ TEST_F(ProjectStorageUpdater, dont_synchronize_empty_property_editor_qml_paths_d SourceContextId designer2DirectoryId = sourcePathCache.sourceContextId("/path/two/designer"); SourceId designer2SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer2DirectoryId); setFilesChanged({path2SourceId}); - setFilesDontExists({designer2SourceId}); + setFilesNotExists({designer2SourceId}); EXPECT_CALL(projectStorageMock, synchronize( @@ -4807,7 +4877,7 @@ TEST_F(ProjectStorageUpdater, remove_property_editor_qml_paths_if_designer_direc { SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); - setFilesDontChanged({path1SourceId, qmldir1SourceId}); + setFilesUnchanged({path1SourceId, qmldir1SourceId}); setFilesRemoved({designer1SourceId}); EXPECT_CALL(projectStorageMock, @@ -4849,7 +4919,7 @@ TEST_F(ProjectStorageUpdater, "/path/one/designer/CaoPane.qml"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); setFilesChanged({designer1SourceId}); - setFilesDontChanged({path1SourceId, qmldir1SourceId}); + setFilesUnchanged({path1SourceId, qmldir1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); setFileNames(u"/path/one/designer", {"FooSpecifics.qml", "HuoSpecificsDynamic.qml", "CaoPane.qml"}, @@ -4893,7 +4963,7 @@ TEST_F(ProjectStorageUpdater, "/path/one/designer/CaoPane.qml"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); setFilesChanged({path1SourceId}); - setFilesDontChanged({qmldir1SourceId, designer1SourceId}); + setFilesUnchanged({qmldir1SourceId, designer1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); setFileNames(u"/path/one/designer", {"FooSpecifics.qml", "HuoSpecificsDynamic.qml", "CaoPane.qml"}, @@ -4936,7 +5006,7 @@ TEST_F(ProjectStorageUpdater, synchronize_property_editor_qml_paths_directory_if "/path/one/designer/CaoPane.qml"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); setFilesChanged({qmldir1SourceId}); - setFilesDontChanged({path1SourceId, designer1SourceId}); + setFilesUnchanged({path1SourceId, designer1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); setFileNames(u"/path/one/designer", {"FooSpecifics.qml", "HuoSpecificsDynamic.qml", "CaoPane.qml"}, From 7f2518310c9ac8f1d5409ddd444d485a3063881f Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 21 Mar 2025 14:31:12 +0100 Subject: [PATCH 11/82] UnitTests: Remove useless tests Change-Id: I0495df35e000ac5eecafbe0429edd3d293633eb0 Reviewed-by: Thomas Hartmann --- .../projectstorageupdater-test.cpp | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index ecc5081074b..1b7938b3f58 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -528,29 +528,6 @@ TEST_F(ProjectStorageUpdater_get_content_for_qml_dir_paths, file_status_is_diffe updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, request_file_status_from_file_system) -{ - EXPECT_CALL(fileSystemMock, fileStatus(Ne(directoryPathSourceId))).Times(AnyNumber()); - - EXPECT_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))); - - updater.update({.qtDirectories = directories}); -} - -TEST_F(ProjectStorageUpdater, request_file_status_from_file_system_for_subdirectories) -{ - EXPECT_CALL(fileSystemMock, - fileStatus(AllOf(Ne(directoryPathSourceId), Ne(path1SourceId), Ne(path2SourceId)))) - .Times(AnyNumber()); - setSubdirectoryPaths(u"/path", {"/path/one", "/path/two"}); - - EXPECT_CALL(fileSystemMock, fileStatus(Eq(path1SourceId))); - EXPECT_CALL(fileSystemMock, fileStatus(Eq(path2SourceId))); - EXPECT_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))); - - updater.update({.qtDirectories = directories}); -} - class ProjectStorageUpdater_get_content_for_qml_types : public BaseProjectStorageUpdater { public: From b58ad8267a430ceb3837744352177c4238eef699 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 21 Mar 2025 18:05:26 +0100 Subject: [PATCH 12/82] UnitTests: Refactor parse qml types Change-Id: I668bf93e0e0c8cca099d4a19010d01be46422910 Reviewed-by: Thomas Hartmann --- .../projectstorageupdater-test.cpp | 98 ++++++++----------- 1 file changed, 41 insertions(+), 57 deletions(-) diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index 1b7938b3f58..34f74d797cc 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -588,16 +588,34 @@ TEST_F(ProjectStorageUpdater_get_content_for_qml_types, removed_qml_types_file_n updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, parse_qml_types) +class ProjectStorageUpdater_parse_qml_types : public BaseProjectStorageUpdater { - QString qmldir{R"(module Example +public: + ProjectStorageUpdater_parse_qml_types() + { + QString qmldir{R"(module Example typeinfo example.qmltypes typeinfo example2.qmltypes)"}; - setContent(u"/path/qmldir", qmldir); + setContent(u"/root/path/qmldir", qmldir); + setContent(u"/root/path/example.qmltypes", qmltypes); + setContent(u"/root/path/example2.qmltypes", qmltypes2); + } + +public: QString qmltypes{"Module {\ndependencies: []}"}; QString qmltypes2{"Module {\ndependencies: [foo]}"}; - setContent(u"/path/example.qmltypes", qmltypes); - setContent(u"/path/example2.qmltypes", qmltypes2); + ModuleId exampleCppNativeModuleId{storage.moduleId("Example", ModuleKind::CppLibrary)}; + SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/root/path/example.qmltypes"); + SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/root/path/example2.qmltypes"); + SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/root/path/qmldir"); + SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); +}; + +TEST_F(ProjectStorageUpdater_parse_qml_types, add_directory) +{ + setFilesAdded( + {directoryPathSourceId, qmlDirPathSourceId, qmltypesPathSourceId, qmltypes2PathSourceId}); EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, @@ -612,25 +630,17 @@ TEST_F(ProjectStorageUpdater, parse_qml_types) Field("DirectoryInfo::moduleId", &DirectoryInfo::moduleId, exampleCppNativeModuleId), IsInsideProject::No)); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root/path"}}); } -TEST_F(ProjectStorageUpdater, parse_added_qml_types) +TEST_F(ProjectStorageUpdater_parse_qml_types, add_qmltypes) { - QString qmldir{R"(module Example - typeinfo example.qmltypes - typeinfo example2.qmltypes)"}; - setContent(u"/path/qmldir", qmldir); - QString qmltypes{"Module {\ndependencies: []}"}; - QString qmltypes2{"Module {\ndependencies: [foo]}"}; - setContent(u"/path/example.qmltypes", qmltypes); - setContent(u"/path/example2.qmltypes", qmltypes2); - setFilesAdded({directoryPathSourceId, - qmlDirPathSourceId, - qmltypesPathSourceId, - qmltypes2PathSourceId, - qmlDocumentSourceId2, - qmlDocumentSourceId3}); + setDirectoryInfos( + directoryPathId, + {{directoryPathId, qmltypesPathSourceId, exampleCppNativeModuleId, FileType::QmlTypes}, + {directoryPathId, qmltypes2PathSourceId, exampleCppNativeModuleId, FileType::QmlTypes}}); + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); + setFilesAdded({qmltypesPathSourceId, qmltypes2PathSourceId}); EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, @@ -645,32 +655,13 @@ TEST_F(ProjectStorageUpdater, parse_added_qml_types) Field("DirectoryInfo::moduleId", &DirectoryInfo::moduleId, exampleCppNativeModuleId), IsInsideProject::No)); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root/path"}}); } -TEST_F(ProjectStorageUpdater, parse_qml_types_in_project) +TEST_F(ProjectStorageUpdater_parse_qml_types, add_directory_inide_project) { - QString qmldir{R"(module Example - typeinfo example.qmltypes)"}; - setContent(u"/path/qmldir", qmldir); - QString qmltypes{"Module {\ndependencies: []}"}; - setContent(u"/path/example.qmltypes", qmltypes); - - EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, IsInsideProject::Yes)); - - updater.update({.projectDirectory = "/path"}); -} - -TEST_F(ProjectStorageUpdater, parse_qml_types_inside_project) -{ - QString qmldir{R"(module Example - typeinfo example.qmltypes - typeinfo example2.qmltypes)"}; - setContent(u"/path/qmldir", qmldir); - QString qmltypes{"Module {\ndependencies: []}"}; - QString qmltypes2{"Module {\ndependencies: [foo]}"}; - setContent(u"/path/example.qmltypes", qmltypes); - setContent(u"/path/example2.qmltypes", qmltypes2); + setFilesAdded( + {directoryPathSourceId, qmlDirPathSourceId, qmltypesPathSourceId, qmltypes2PathSourceId}); EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, @@ -685,21 +676,14 @@ TEST_F(ProjectStorageUpdater, parse_qml_types_inside_project) Field("DirectoryInfo::moduleId", &DirectoryInfo::moduleId, exampleCppNativeModuleId), IsInsideProject::Yes)); - updater.update({.projectDirectory = "/path"}); + updater.update({.projectDirectory = "/root/path"}); } -TEST_F(ProjectStorageUpdater, parse_qml_types_in_subdirectories) +TEST_F(ProjectStorageUpdater_parse_qml_types, add_subdirectories) { - QString qmldir{R"(module Example - typeinfo example.qmltypes - typeinfo example2.qmltypes)"}; - setContent(u"/path/qmldir", qmldir); - QString qmltypes{"Module {\ndependencies: []}"}; - QString qmltypes2{"Module {\ndependencies: [foo]}"}; - setContent(u"/path/example.qmltypes", qmltypes); - setContent(u"/path/example2.qmltypes", qmltypes2); - QStringList directories = {"/root"}; - setSubdirectoryPaths(u"/root", {"/path"}); + setFilesAdded( + {directoryPathSourceId, qmlDirPathSourceId, qmltypesPathSourceId, qmltypes2PathSourceId}); + setSubdirectoryPaths(u"/root", {"/root/path"}); EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, @@ -714,7 +698,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_types_in_subdirectories) Field("DirectoryInfo::moduleId", &DirectoryInfo::moduleId, exampleCppNativeModuleId), IsInsideProject::No)); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root"}}); } TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) From 0a7cc8e06ee832d9ab79429b2c9b7bfdde429860 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 4 Apr 2025 16:00:17 +0300 Subject: [PATCH 13/82] QmlDesigner: Fix QmlListProperty append check There is no need to check for full list functionality support when we just want to add to the list. Fixes: QDS-14440 Change-Id: I4a5568b95879171f953db441ac610f476490880a Reviewed-by: Thomas Hartmann --- src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp index fb9f3cdd411..9dc8b7e6611 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp @@ -346,7 +346,7 @@ void ObjectNodeInstance::addToNewProperty(QObject *object, QObject *newParent, c if (isList(property)) { QQmlListReference list = qvariant_cast(property.read()); - if (!QmlPrivateGate::hasFullImplementedListInterface(list)) { + if (!list.isValid() || !list.canAppend()) { qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; return; } From 6a11b1bc58ed08029ce2563db4409cfc3c2c5183 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 22 Mar 2025 14:50:10 +0100 Subject: [PATCH 14/82] QmlDesigner: Modernize project storage watcher and file status cache Change-Id: Ia46d87803a74ebec7b7cc078115dd0bbbd02ec4d Reviewed-by: Thomas Hartmann --- .../projectstorage/directorypathcompressor.h | 4 +- .../designercore/projectstorage/filestatus.h | 19 +- .../projectstorage/filestatuscache.cpp | 76 ++++---- .../projectstoragepathwatcher.h | 166 +++++++----------- .../projectstoragepathwatchertypes.h | 22 +-- 5 files changed, 105 insertions(+), 182 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h index a13debc8326..0cdf52d1b4e 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h @@ -24,9 +24,7 @@ public: void addSourceContextId(SourceContextId sourceContextId) { - auto found = std::lower_bound(m_sourceContextIds.begin(), - m_sourceContextIds.end(), - sourceContextId); + auto found = std::ranges::lower_bound(m_sourceContextIds, sourceContextId); if (found == m_sourceContextIds.end() || *found != sourceContextId) m_sourceContextIds.insert(found, sourceContextId); diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h index 289f8fd0394..f02299fc8ac 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h @@ -25,24 +25,9 @@ public: && first.lastModified == second.lastModified; } - friend bool operator!=(const FileStatus &first, const FileStatus &second) + friend auto operator<=>(const FileStatus &first, const FileStatus &second) { - return !(first == second); - } - - friend bool operator<(const FileStatus &first, const FileStatus &second) - { - return first.sourceId < second.sourceId; - } - - friend bool operator<(SourceId first, const FileStatus &second) - { - return first < second.sourceId; - } - - friend bool operator<(const FileStatus &first, SourceId second) - { - return first.sourceId < second; + return first.sourceId <=> second.sourceId; } bool isExisting() const { return sourceId && size >= 0 && lastModified >= 0; } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.cpp index 211ba40dc72..2629bebf181 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.cpp @@ -24,12 +24,7 @@ long long FileStatusCache::fileSize(SourceId sourceId) const void FileStatusCache::update(SourceId sourceId) { - auto found = std::lower_bound(m_cacheEntries.begin(), - m_cacheEntries.end(), - sourceId, - [](const auto &first, const auto &second) { - return first < second; - }); + auto found = std::ranges::lower_bound(m_cacheEntries, sourceId, {}, &FileStatus::sourceId); if (found != m_cacheEntries.end() && found->sourceId == sourceId) *found = m_fileSystem.fileStatus(sourceId); @@ -37,13 +32,12 @@ void FileStatusCache::update(SourceId sourceId) void FileStatusCache::update(SourceIds sourceIds) { - std::set_intersection(m_cacheEntries.begin(), - m_cacheEntries.end(), - sourceIds.begin(), - sourceIds.end(), - Utils::make_iterator([&](auto &entry) { - entry = m_fileSystem.fileStatus(entry.sourceId); - })); + Utils::set_greedy_intersection( + m_cacheEntries, + sourceIds, + [&](auto &entry) { entry = m_fileSystem.fileStatus(entry.sourceId); }, + {}, + &FileStatus::sourceId); } SourceIds FileStatusCache::modified(SourceIds sourceIds) const @@ -51,44 +45,43 @@ SourceIds FileStatusCache::modified(SourceIds sourceIds) const SourceIds modifiedSourceIds; modifiedSourceIds.reserve(sourceIds.size()); - std::set_intersection(m_cacheEntries.begin(), - m_cacheEntries.end(), - sourceIds.begin(), - sourceIds.end(), - Utils::make_iterator([&](auto &entry) { - auto fileStatus = m_fileSystem.fileStatus(entry.sourceId); - if (fileStatus != entry) { - modifiedSourceIds.push_back(entry.sourceId); - entry = fileStatus; - } - })); + Utils::set_greedy_intersection( + m_cacheEntries, + sourceIds, + [&](auto &entry) { + auto fileStatus = m_fileSystem.fileStatus(entry.sourceId); + if (fileStatus != entry) { + modifiedSourceIds.push_back(entry.sourceId); + entry = fileStatus; + } + }, + {}, + &FileStatus::sourceId); FileStatuses newEntries; newEntries.reserve(sourceIds.size()); - std::set_difference(sourceIds.begin(), - sourceIds.end(), - m_cacheEntries.begin(), - m_cacheEntries.end(), - Utils::make_iterator([&](SourceId newSourceId) { - newEntries.push_back(m_fileSystem.fileStatus(newSourceId)); - modifiedSourceIds.push_back(newSourceId); - })); + Utils::set_greedy_difference( + sourceIds, + m_cacheEntries, + [&](SourceId newSourceId) { + newEntries.push_back(m_fileSystem.fileStatus(newSourceId)); + modifiedSourceIds.push_back(newSourceId); + }, + {}, + {}, + &FileStatus::sourceId); if (newEntries.size()) { FileStatuses mergedEntries; mergedEntries.reserve(m_cacheEntries.size() + newEntries.size()); - std::set_union(newEntries.begin(), - newEntries.end(), - m_cacheEntries.begin(), - m_cacheEntries.end(), - std::back_inserter(mergedEntries)); + std::ranges::set_union(newEntries, m_cacheEntries, std::back_inserter(mergedEntries)); m_cacheEntries = std::move(mergedEntries); } - std::sort(modifiedSourceIds.begin(), modifiedSourceIds.end()); + std::ranges::sort(modifiedSourceIds); return modifiedSourceIds; } @@ -100,12 +93,7 @@ FileStatusCache::size_type FileStatusCache::size() const const FileStatus &FileStatusCache::find(SourceId sourceId) const { - auto found = std::lower_bound(m_cacheEntries.begin(), - m_cacheEntries.end(), - sourceId, - [](const auto &first, const auto &second) { - return first < second; - }); + auto found = std::ranges::lower_bound(m_cacheEntries, sourceId, {}, &FileStatus::sourceId); if (found != m_cacheEntries.end() && found->sourceId == sourceId) return *found; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index e07571f665c..dfbb13b50b6 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -13,27 +13,12 @@ #include #include +#include #include namespace QmlDesigner { -template -void set_greedy_intersection_call( - InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable callable) -{ - while (first1 != last1 && first2 != last2) { - if (*first1 < *first2) { - ++first1; - } else { - if (*first2 < *first1) - ++first2; - else - callable(*first1++); - } - } -} - template class ProjectStoragePathWatcher : public ProjectStoragePathWatcherInterface, public ProjectStorageTriggerUpdateInterface @@ -63,7 +48,7 @@ public: addEntries(entires); auto notContainsdId = [&, &ids = ids](WatcherEntry entry) { - return !std::binary_search(ids.begin(), ids.end(), entry.id); + return !std::ranges::binary_search(ids, entry.id); }; removeUnusedEntries(entires, notContainsdId); } @@ -76,10 +61,8 @@ public: addEntries(entires); auto notContainsId = [&, &ids = ids](WatcherEntry entry) { - return !std::binary_search(ids.begin(), ids.end(), entry.id) - || !std::binary_search(sourceContextIds.begin(), - sourceContextIds.end(), - entry.sourceContextId); + return !std::ranges::binary_search(ids, entry.id) + || !std::ranges::binary_search(sourceContextIds, entry.sourceContextId); }; removeUnusedEntries(entires, notContainsId); @@ -126,28 +109,22 @@ public: ProjectChunkIds ids; ids.reserve(ids.size()); - auto outputIterator = std::back_inserter(entries); - for (const IdPaths &idPath : idPaths) { ProjectChunkId id = idPath.id; ids.push_back(id); - outputIterator = std::transform(idPath.sourceIds.begin(), - idPath.sourceIds.end(), - outputIterator, - [&](SourceId sourceId) { - return WatcherEntry{id, - sourceId.contextId(), - sourceId, - m_fileStatusCache.lastModifiedTime( - sourceId)}; - }); + std::ranges::transform(idPath.sourceIds, std::back_inserter(entries), [&](SourceId sourceId) { + return WatcherEntry{id, + sourceId.contextId(), + sourceId, + m_fileStatusCache.lastModifiedTime(sourceId)}; + }); } - std::sort(entries.begin(), entries.end()); - std::sort(ids.begin(), ids.end()); + std::ranges::sort(entries); + std::ranges::sort(ids); return {entries, ids}; } @@ -191,9 +168,9 @@ public: SourceContextIds sourceContextIds = Utils::transform( watcherEntries, &WatcherEntry::sourceContextId); - std::sort(sourceContextIds.begin(), sourceContextIds.end()); - sourceContextIds.erase(std::unique(sourceContextIds.begin(), sourceContextIds.end()), - sourceContextIds.end()); + std::ranges::sort(sourceContextIds); + auto removed = std::ranges::unique(sourceContextIds); + sourceContextIds.erase(removed.begin(), removed.end()); return convertWatcherEntriesToDirectoryPathList(sourceContextIds); } @@ -203,11 +180,7 @@ public: WatcherEntries notWatchedEntries; notWatchedEntries.reserve(entries.size()); - std::set_difference(entries.begin(), - entries.end(), - m_watchedEntries.cbegin(), - m_watchedEntries.cend(), - std::back_inserter(notWatchedEntries)); + std::ranges::set_difference(entries, m_watchedEntries, std::back_inserter(notWatchedEntries)); return notWatchedEntries; } @@ -217,11 +190,7 @@ public: SourceContextIds notWatchedDirectoryIds; notWatchedDirectoryIds.reserve(ids.size()); - std::set_difference(ids.begin(), - ids.end(), - m_watchedEntries.cbegin(), - m_watchedEntries.cend(), - std::back_inserter(notWatchedDirectoryIds)); + std::ranges::set_difference(ids, m_watchedEntries, std::back_inserter(notWatchedDirectoryIds)); return notWatchedDirectoryIds; } @@ -232,12 +201,10 @@ public: WatcherEntries notAnymoreWatchedEntries; notAnymoreWatchedEntries.reserve(m_watchedEntries.size()); - std::set_difference(m_watchedEntries.cbegin(), - m_watchedEntries.cend(), - newEntries.begin(), - newEntries.end(), - std::back_inserter(notAnymoreWatchedEntries), - compare); + std::ranges::set_difference(m_watchedEntries, + newEntries, + std::back_inserter(notAnymoreWatchedEntries), + compare); return notAnymoreWatchedEntries; } @@ -245,11 +212,9 @@ public: template WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries, Filter filter) const { - auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less()); + auto oldEntries = notAnymoreWatchedEntries(newEntries, std::ranges::less{}); - auto newEnd = std::remove_if(oldEntries.begin(), oldEntries.end(), filter); - - oldEntries.erase(newEnd, oldEntries.end()); + std::erase_if(oldEntries, filter); return oldEntries; } @@ -259,11 +224,7 @@ public: WatcherEntries newWatchedEntries; newWatchedEntries.reserve(m_watchedEntries.size() + newEntries.size()); - std::merge(m_watchedEntries.cbegin(), - m_watchedEntries.cend(), - newEntries.begin(), - newEntries.end(), - std::back_inserter(newWatchedEntries)); + std::ranges::merge(m_watchedEntries, newEntries, std::back_inserter(newWatchedEntries)); m_watchedEntries = std::move(newWatchedEntries); } @@ -273,14 +234,10 @@ public: SourceContextIds uniqueDirectoryIds; uniqueDirectoryIds.reserve(pathEntries.size()); - auto compare = [](WatcherEntry first, WatcherEntry second) { - return first.sourceContextId == second.sourceContextId; - }; - - std::unique_copy(pathEntries.begin(), - pathEntries.end(), - std::back_inserter(uniqueDirectoryIds), - compare); + std::ranges::unique_copy(pathEntries, + std::back_inserter(uniqueDirectoryIds), + {}, + &WatcherEntry::sourceContextId); return uniqueDirectoryIds; } @@ -294,15 +251,13 @@ public: WatcherEntries removeIdsFromWatchedEntries(const ProjectPartIds &ids) { - auto keep = [&](WatcherEntry entry) { - return !std::binary_search(ids.begin(), ids.end(), entry.id); - }; + auto keep = [&](WatcherEntry entry) { return !std::ranges::binary_search(ids, entry.id.id); }; - auto found = std::stable_partition(m_watchedEntries.begin(), m_watchedEntries.end(), keep); + auto removed = std::ranges::stable_partition(m_watchedEntries, keep); - WatcherEntries removedEntries(found, m_watchedEntries.end()); + WatcherEntries removedEntries(removed.begin(), removed.end()); - m_watchedEntries.erase(found, m_watchedEntries.end()); + m_watchedEntries.erase(removed.begin(), removed.end()); return removedEntries; } @@ -312,11 +267,9 @@ public: WatcherEntries newWatchedEntries; newWatchedEntries.reserve(m_watchedEntries.size() - oldEntries.size()); - std::set_difference(m_watchedEntries.cbegin(), - m_watchedEntries.cend(), - oldEntries.begin(), - oldEntries.end(), - std::back_inserter(newWatchedEntries)); + std::ranges::set_difference(m_watchedEntries, + oldEntries, + std::back_inserter(newWatchedEntries)); m_watchedEntries = std::move(newWatchedEntries); } @@ -332,19 +285,19 @@ public: WatcherEntries foundEntries; foundEntries.reserve(m_watchedEntries.size()); - set_greedy_intersection_call(m_watchedEntries.begin(), - m_watchedEntries.end(), - sourceContextIds.begin(), - sourceContextIds.end(), - [&](WatcherEntry &entry) { - m_fileStatusCache.update(entry.sourceId); - auto currentLastModified = m_fileStatusCache.lastModifiedTime( - entry.sourceId); - if (entry.lastModified < currentLastModified) { - foundEntries.push_back(entry); - entry.lastModified = currentLastModified; - } - }); + Utils::set_greedy_intersection( + m_watchedEntries, + sourceContextIds, + [&](WatcherEntry &entry) { + m_fileStatusCache.update(entry.sourceId); + auto currentLastModified = m_fileStatusCache.lastModifiedTime(entry.sourceId); + if (entry.lastModified < currentLastModified) { + foundEntries.push_back(entry); + entry.lastModified = currentLastModified; + } + }, + {}, + &WatcherEntry::sourceContextId); return foundEntries; } @@ -353,26 +306,31 @@ public: { auto sourceIds = Utils::transform(entries, &WatcherEntry::sourceId); - std::sort(sourceIds.begin(), sourceIds.end()); - - sourceIds.erase(std::unique(sourceIds.begin(), sourceIds.end()), sourceIds.end()); + std::ranges::sort(sourceIds); + auto removed = std::ranges::unique(sourceIds); + sourceIds.erase(removed.begin(), removed.end()); return sourceIds; } std::vector idPathsForWatcherEntries(WatcherEntries &&foundEntries) { - std::sort(foundEntries.begin(), foundEntries.end(), [](WatcherEntry first, WatcherEntry second) { - return std::tie(first.id, first.sourceId) < std::tie(second.id, second.sourceId); + std::ranges::sort(foundEntries, {}, [](const WatcherEntry &entry) { + return std::tie(entry.id, entry.sourceId); }); std::vector idPaths; idPaths.reserve(foundEntries.size()); - for (WatcherEntry entry : foundEntries) { - if (idPaths.empty() || idPaths.back().id != entry.id) - idPaths.emplace_back(entry.id, SourceIds{}); - idPaths.back().sourceIds.push_back(entry.sourceId); + if (foundEntries.size()) { + idPaths.emplace_back(foundEntries.front().id, SourceIds{}); + + for (WatcherEntry entry : foundEntries) { + if (idPaths.back().id != entry.id) + idPaths.emplace_back(entry.id, SourceIds{}); + + idPaths.back().sourceIds.push_back(entry.sourceId); + } } return idPaths; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h index eea6c4eef4e..be7763fd3e3 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h @@ -40,11 +40,15 @@ public: ProjectPartId id; SourceType sourceType; - auto operator<=>(const ProjectChunkId &) const = default; + auto operator==(const ProjectChunkId &other) const + { + return std::tie(id, sourceType) == std::tie(other.id, other.sourceType); + } - friend bool operator<(ProjectChunkId first, ProjectPartId second) { return first.id < second; } - - friend bool operator<(ProjectPartId first, ProjectChunkId second) { return first < second.id; } + auto operator<=>(const ProjectChunkId &other) const + { + return std::tie(id, sourceType) <=> std::tie(other.id, other.sourceType); + } template friend void convertToString(String &string, const ProjectChunkId &id) @@ -112,16 +116,6 @@ public: <=> std::tie(second.sourceContextId, second.sourceId, second.id); } - friend auto operator<=>(SourceContextId sourceContextId, WatcherEntry entry) - { - return sourceContextId <=> entry.sourceContextId; - } - - friend auto operator<=>(WatcherEntry entry, SourceContextId sourceContextId) - { - return entry.sourceContextId <=> sourceContextId; - } - operator SourceId() const { return sourceId; } operator SourceContextId() const { return sourceContextId; } From 88b8d5ea6c7c100e91649ac3a083460ae6a8ed41 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 4 Apr 2025 22:39:39 +0200 Subject: [PATCH 15/82] QmlDesigner: Use size for path watcher The modified time is only saved as milliseconds. That is quite coarse. So we check if the size changed too. Change-Id: Ib94382404002b3bcf2d1e45a73b814d8aba1935c Reviewed-by: Thomas Hartmann --- .../projectstoragepathwatcher.h | 11 ++++--- .../projectstoragepathwatchertypes.h | 1 + .../projectstoragepathwatcher-test.cpp | 32 +++++++++++++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index dfbb13b50b6..b00b6f6e21d 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -116,10 +116,12 @@ public: ids.push_back(id); std::ranges::transform(idPath.sourceIds, std::back_inserter(entries), [&](SourceId sourceId) { + auto fileStatus = m_fileStatusCache.find(sourceId); return WatcherEntry{id, sourceId.contextId(), sourceId, - m_fileStatusCache.lastModifiedTime(sourceId)}; + fileStatus.lastModified, + fileStatus.size}; }); } @@ -290,10 +292,11 @@ public: sourceContextIds, [&](WatcherEntry &entry) { m_fileStatusCache.update(entry.sourceId); - auto currentLastModified = m_fileStatusCache.lastModifiedTime(entry.sourceId); - if (entry.lastModified < currentLastModified) { + auto fileStatus = m_fileStatusCache.find(entry.sourceId); + if (entry.lastModified < fileStatus.lastModified || entry.size != fileStatus.size) { foundEntries.push_back(entry); - entry.lastModified = currentLastModified; + entry.lastModified = fileStatus.lastModified; + entry.size = fileStatus.size; } }, {}, diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h index be7763fd3e3..3490fdd391d 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h @@ -103,6 +103,7 @@ public: SourceContextId sourceContextId; SourceId sourceId; long long lastModified = -1; + long long size = -1; friend bool operator==(WatcherEntry first, WatcherEntry second) { diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index 69ff6ac423f..137acfef8d2 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -378,13 +378,12 @@ TEST_F(ProjectStoragePathWatcher, two_notify_file_changes) mockQFileSytemWatcher.directoryChanged(sourceContextPath2); } -TEST_F(ProjectStoragePathWatcher, notify_for_path_changes) +TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_modified_time_changes) { watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) .WillByDefault(Return(FileStatus{sourceIds[0], 1, 2})); - ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); @@ -393,6 +392,34 @@ TEST_F(ProjectStoragePathWatcher, notify_for_path_changes) mockQFileSytemWatcher.directoryChanged(sourceContextPath); } +TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_bigger) +{ + watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, + {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) + .WillByDefault(Return(FileStatus{sourceIds[0], 2, 1})); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) + .WillByDefault(Return(FileStatus{sourceIds[3], 2, 1})); + + EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); + + mockQFileSytemWatcher.directoryChanged(sourceContextPath); +} + +TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_smaller) +{ + watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, + {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) + .WillByDefault(Return(FileStatus{sourceIds[0], 0, 1})); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) + .WillByDefault(Return(FileStatus{sourceIds[3], 0, 1})); + + EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); + + mockQFileSytemWatcher.directoryChanged(sourceContextPath); +} + TEST_F(ProjectStoragePathWatcher, no_notify_for_unwatched_path_changes) { watcher.updateIdPaths({{projectChunkId1, {sourceIds[3]}}, {projectChunkId2, {sourceIds[3]}}}); @@ -442,7 +469,6 @@ TEST_F(ProjectStoragePathWatcher, trigger_manual_notify_for_path_changes) {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) .WillByDefault(Return(FileStatus{sourceIds[0], 1, 2})); - ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); From ee1a725da132144eaa49912f294fb75cd19dcc5b Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 24 Mar 2025 17:01:24 +0200 Subject: [PATCH 16/82] QmlDesigner: Allow adding a folder to content library Change-Id: If44fdc0f0a7c59011854fd358f0542ce35ac1079 Reviewed-by: Miikka Heikkinen Reviewed-by: Ali Kianian --- .../ContentLibraryUserView.qml | 346 ++++++++++-------- .../contentlibraryusermodel.cpp | 172 ++++++++- .../contentlibrary/contentlibraryusermodel.h | 24 +- .../contentlibrary/contentlibraryview.cpp | 30 +- .../contentlibrary/contentlibraryview.h | 2 +- .../contentlibrary/contentlibrarywidget.cpp | 15 + .../contentlibrary/contentlibrarywidget.h | 5 +- .../contentlibrary/usertexturecategory.cpp | 21 +- .../contentlibrary/usertexturecategory.h | 3 +- .../qmldesigner/qmldesignerconstants.h | 1 + 10 files changed, 430 insertions(+), 189 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml index 4ee3af47f83..91d131bb9aa 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import QtQuick +import QtQuick.Layouts import Qt.labs.qmlmodels import HelperWidgets as HelperWidgets import StudioControls as StudioControls @@ -79,171 +80,214 @@ Item { } } - HelperWidgets.ScrollView { - id: scrollView + ColumnLayout { + id: col + anchors.fill: parent + spacing: 0 - clip: true - interactive: !ctxMenuItem.opened && !ctxMenuTexture.opened - && !ContentLibraryBackend.rootView.isDragging && !HelperWidgets.Controller.contextMenuOpened - hideHorizontalScrollBar: true + Rectangle { + id: toolbar - Column { - Repeater { - id: categoryRepeater + width: parent.width + height: StudioTheme.Values.toolbarHeight + color: StudioTheme.Values.themeToolbarBackground - model: ContentLibraryBackend.userModel + HelperWidgets.AbstractButton { + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.add_medium + enabled: hasMaterial && hasModelSelection && hasQuick3DImport && hasMaterialLibrary + tooltip: qsTr("Add a custom bundle folder.") + onClicked: ContentLibraryBackend.rootView.browseBundleFolder() + x: 5 // left margin + } + } - delegate: HelperWidgets.Section { - id: section + HelperWidgets.ScrollView { + id: scrollView - width: root.width - leftPadding: StudioTheme.Values.sectionPadding - rightPadding: StudioTheme.Values.sectionPadding - topPadding: StudioTheme.Values.sectionPadding - bottomPadding: StudioTheme.Values.sectionPadding + Layout.fillWidth: true + Layout.fillHeight: true - caption: categoryTitle - dropEnabled: true - category: "ContentLib_User" + clip: true + interactive: !ctxMenuItem.opened && !ctxMenuTexture.opened + && !ContentLibraryBackend.rootView.isDragging && !HelperWidgets.Controller.contextMenuOpened + hideHorizontalScrollBar: true - function expandSection() { - section.expanded = true - } + Column { + Repeater { + id: categoryRepeater - property alias count: repeater.count + model: ContentLibraryBackend.userModel - onCountChanged: root.assignMaxCount() + delegate: HelperWidgets.Section { + id: section - onDropEnter: (drag) => { - let has3DNode = ContentLibraryBackend.rootView - .has3DNode(drag.getDataAsArrayBuffer(drag.formats[0])) - - let hasTexture = ContentLibraryBackend.rootView - .hasTexture(drag.formats[0], drag.urls) - - drag.accepted = (categoryTitle === "Textures" && hasTexture) - || (categoryTitle === "Materials" && drag.formats[0] === "application/vnd.qtdesignstudio.material") - || (categoryTitle === "3D" && has3DNode) - - section.highlight = drag.accepted - } - - onDropExit: { - section.highlight = false - } - - onDrop: (drag) => { - section.highlight = false - drag.accept() - section.expandSection() - - if (categoryTitle === "Textures") { - if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") - ContentLibraryBackend.rootView.acceptTexturesDrop(drag.urls) - else if (drag.formats[0] === "application/vnd.qtdesignstudio.texture") - ContentLibraryBackend.rootView.acceptTextureDrop(drag.getDataAsString(drag.formats[0])) - } else if (categoryTitle === "Materials") { - ContentLibraryBackend.rootView.acceptMaterialDrop(drag.getDataAsString(drag.formats[0])) - } else if (categoryTitle === "3D") { - ContentLibraryBackend.rootView.accept3DDrop(drag.getDataAsArrayBuffer(drag.formats[0])) - } - } - - Grid { - width: section.width - section.leftPadding - section.rightPadding - spacing: StudioTheme.Values.sectionGridSpacing - columns: root.numColumns - - Repeater { - id: repeater - model: categoryItems - - delegate: DelegateChooser { - role: "bundleId" - - DelegateChoice { - roleValue: "UserMaterials" - ContentLibraryItem { - width: root.cellWidth - height: root.cellHeight - visible: modelData.bundleItemVisible && !infoText.visible - - onShowContextMenu: ctxMenuItem.popupMenu(modelData) - onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) - } - } - DelegateChoice { - roleValue: "UserTextures" - delegate: ContentLibraryTexture { - width: root.cellWidth - height: root.cellWidth // for textures use a square size since there is no name row - - onShowContextMenu: ctxMenuTexture.popupMenu(modelData) - } - } - DelegateChoice { - roleValue: "User3D" - delegate: ContentLibraryItem { - width: root.cellWidth - height: root.cellHeight - visible: modelData.bundleItemVisible && !infoText.visible - - onShowContextMenu: ctxMenuItem.popupMenu(modelData) - onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) - } - } - } - - onCountChanged: root.assignMaxCount() - } - } - - Text { - text: qsTr("No match found."); - color: StudioTheme.Values.themeTextColor - font.pixelSize: StudioTheme.Values.baseFontSize - leftPadding: 10 - visible: infoText.text === "" && !searchBox.isEmpty() && categoryNoMatch - } - - Text { - id: infoText - - text: { - let categoryName = (categoryTitle === "3D") ? categoryTitle + " assets" - : categoryTitle.toLowerCase() - if (!ContentLibraryBackend.rootView.isQt6Project) { - qsTr("Content Library is not supported in Qt5 projects.") - } else if (!ContentLibraryBackend.rootView.hasQuick3DImport && categoryTitle !== "Textures") { - qsTr('To use %1, add the QtQuick3D module and the View3D - component in the Components view, or click - - here.') - .arg(categoryName) - .arg(StudioTheme.Values.themeInteraction) - } else if (!ContentLibraryBackend.rootView.hasMaterialLibrary && categoryTitle !== "Textures") { - qsTr("Content Library is disabled inside a non-visual component.") - } else if (categoryEmpty) { - qsTr("There are no "+ categoryName + " in the User Assets.") - } else { - "" - } - } - textFormat: Text.RichText - color: StudioTheme.Values.themeTextColor - font.pixelSize: StudioTheme.Values.mediumFontSize - padding: 10 - visible: infoText.text !== "" - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap width: root.width + leftPadding: StudioTheme.Values.sectionPadding + rightPadding: StudioTheme.Values.sectionPadding + topPadding: StudioTheme.Values.sectionPadding + bottomPadding: StudioTheme.Values.sectionPadding - onLinkActivated: ContentLibraryBackend.rootView.addQtQuick3D() + caption: categoryTitle + dropEnabled: true + category: "ContentLib_User" + showCloseButton: section.isCustomCat + closeButtonToolTip: qsTr("Remove folder") + closeButtonIcon: StudioTheme.Constants.deletepermanently_small - HoverHandler { - enabled: infoText.hoveredLink - cursorShape: Qt.PointingHandCursor + onCloseButtonClicked: { + ContentLibraryBackend.userModel.removeBundleDir(index) + } + + function expandSection() { + section.expanded = true + } + + property alias count: repeater.count + property bool isCustomCat: !["Textures", "Materials", "3D"].includes(section.caption); + + onCountChanged: root.assignMaxCount() + + onDropEnter: (drag) => { + let has3DNode = ContentLibraryBackend.rootView + .has3DNode(drag.getDataAsArrayBuffer(drag.formats[0])) + + let hasTexture = ContentLibraryBackend.rootView + .hasTexture(drag.formats[0], drag.urls) + + drag.accepted = (categoryTitle === "Textures" && hasTexture) + || (categoryTitle === "Materials" && drag.formats[0] === "application/vnd.qtdesignstudio.material") + || (categoryTitle === "3D" && has3DNode) + || (section.isCustomCat && hasTexture) + + section.highlight = drag.accepted + } + + onDropExit: { + section.highlight = false + } + + onDrop: (drag) => { + section.highlight = false + drag.accept() + section.expandSection() + + if (categoryTitle === "Textures") { + if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") + ContentLibraryBackend.rootView.acceptTexturesDrop(drag.urls) + else if (drag.formats[0] === "application/vnd.qtdesignstudio.texture") + ContentLibraryBackend.rootView.acceptTextureDrop(drag.getDataAsString(drag.formats[0])) + } else if (categoryTitle === "Materials") { + ContentLibraryBackend.rootView.acceptMaterialDrop(drag.getDataAsString(drag.formats[0])) + } else if (categoryTitle === "3D") { + ContentLibraryBackend.rootView.accept3DDrop(drag.getDataAsArrayBuffer(drag.formats[0])) + } else { // custom bundle folder + if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") + ContentLibraryBackend.rootView.acceptTexturesDrop(drag.urls, categoryBundlePath) + else if (drag.formats[0] === "application/vnd.qtdesignstudio.texture") + ContentLibraryBackend.rootView.acceptTextureDrop(drag.getDataAsString(drag.formats[0]), categoryBundlePath) + } + } + + Grid { + width: section.width - section.leftPadding - section.rightPadding + spacing: StudioTheme.Values.sectionGridSpacing + columns: root.numColumns + + Repeater { + id: repeater + + model: categoryItems + + delegate: DelegateChooser { + role: "bundleId" + + DelegateChoice { + roleValue: "UserMaterials" + ContentLibraryItem { + width: root.cellWidth + height: root.cellHeight + visible: modelData.bundleItemVisible && !infoText.visible + + onShowContextMenu: ctxMenuItem.popupMenu(modelData) + onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) + } + } + DelegateChoice { + roleValue: "UserTextures" + delegate: ContentLibraryTexture { + width: root.cellWidth + height: root.cellWidth // for textures use a square size since there is no name row + + onShowContextMenu: ctxMenuTexture.popupMenu(modelData) + } + } + DelegateChoice { + roleValue: "User3D" + delegate: ContentLibraryItem { + width: root.cellWidth + height: root.cellHeight + visible: modelData.bundleItemVisible && !infoText.visible + + onShowContextMenu: ctxMenuItem.popupMenu(modelData) + onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) + } + } + } + + onCountChanged: root.assignMaxCount() + } + } + + Text { + text: qsTr("No match found."); + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.baseFontSize + leftPadding: 10 + visible: infoText.text === "" && !searchBox.isEmpty() && categoryNoMatch + } + + Text { + id: infoText + + text: { + let categoryName = (categoryTitle === "3D") ? categoryTitle + " assets" + : categoryTitle.toLowerCase() + if (!ContentLibraryBackend.rootView.isQt6Project) { + qsTr("Content Library is not supported in Qt5 projects.") + } else if (!ContentLibraryBackend.rootView.hasQuick3DImport + && categoryTitle !== "Textures" && !section.isCustomCat) { + qsTr('To use %1, add the QtQuick3D module and the View3D + component in the Components view, or click + + here.') + .arg(categoryName) + .arg(StudioTheme.Values.themeInteraction) + } else if (!ContentLibraryBackend.rootView.hasMaterialLibrary + && categoryTitle !== "Textures" && !section.isCustomCat) { + qsTr("Content Library is disabled inside a non-visual component.") + } else if (categoryEmpty) { + qsTr("There are no items in this category.") + } else { + "" + } + } + textFormat: Text.RichText + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.mediumFontSize + padding: 10 + visible: infoText.text !== "" + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + width: root.width + + onLinkActivated: ContentLibraryBackend.rootView.addQtQuick3D() + + HoverHandler { + enabled: infoText.hoveredLink + cursorShape: Qt.PointingHandCursor + } } } } diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp index 47b06781123..042d25cf709 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp @@ -9,6 +9,7 @@ #include "contentlibrarytexture.h" #include "contentlibrarywidget.h" +#include #include #include #include @@ -16,6 +17,7 @@ #include #include +#include #include #include @@ -28,10 +30,18 @@ namespace QmlDesigner { ContentLibraryUserModel::ContentLibraryUserModel(ContentLibraryWidget *parent) : QAbstractListModel(parent) , m_widget(parent) + , m_fileWatcher(Utils::makeUniqueObjectPtr(parent)) { createCategories(); + + connect(m_fileWatcher.get(), &Utils::FileSystemWatcher::directoryChanged, this, + [this] (const QString &dirPath) { + reloadTextureCategory(Utils::FilePath::fromString(dirPath)); + }); } +ContentLibraryUserModel::~ContentLibraryUserModel() = default; + int ContentLibraryUserModel::rowCount(const QModelIndex &) const { return m_userCategories.size(); @@ -44,17 +54,22 @@ QVariant ContentLibraryUserModel::data(const QModelIndex &index, int role) const UserCategory *currCat = m_userCategories.at(index.row()); - if (role == TitleRole) + switch (role) { + case TitleRole: return currCat->title(); - if (role == ItemsRole) + case BundlePathRole: + return currCat->bundlePath().toVariant(); + + case ItemsRole: return QVariant::fromValue(currCat->items()); - if (role == NoMatchRole) + case NoMatchRole: return currCat->noMatch(); - if (role == EmptyRole) + case EmptyRole: return currCat->isEmpty(); + } return {}; } @@ -76,6 +91,71 @@ void ContentLibraryUserModel::createCategories() compUtils.user3DBundleId()}; m_userCategories << catMaterial << catTexture << cat3D; + + loadCustomCategories(userBundlePath); +} + +void ContentLibraryUserModel::loadCustomCategories(const Utils::FilePath &userBundlePath) +{ + auto jsonFilePath = userBundlePath.pathAppended(Constants::CUSTOM_BUNDLES_JSON_FILENAME); + if (!jsonFilePath.exists()) { + const QString jsonContent = QStringLiteral(R"({ "version": "%1", "items": {}})") + .arg(CUSTOM_BUNDLES_JSON_FILE_VERSION); + Utils::expected_str res = jsonFilePath.writeFileContents(jsonContent.toLatin1()); + QTC_ASSERT_EXPECTED(res, return); + } + + Utils::expected_str jsonContents = jsonFilePath.fileContents(); + QTC_ASSERT_EXPECTED(jsonContents, return); + + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonContents.value()); + QTC_ASSERT(!jsonDoc.isNull(), return); + + m_customCatsRootObj = jsonDoc.object(); + m_customCatsObj = m_customCatsRootObj.value("items").toObject(); + + for (auto it = m_customCatsObj.constBegin(); it != m_customCatsObj.constEnd(); ++it) { + auto dirPath = Utils::FilePath::fromString(it.key()); + if (!dirPath.exists()) + continue; + + addBundleDir(dirPath); + } +} + +bool ContentLibraryUserModel::bundleDirExists(const QString &dirPath) const +{ + return m_customCatsObj.contains(dirPath); +} + +void ContentLibraryUserModel::addBundleDir(const Utils::FilePath &dirPath) +{ + QTC_ASSERT(!dirPath.isEmpty(), return); + + // TODO: detect if a bundle exists in the dir, determine its type, and create a matching category. + // For now we consider a custom folder as a texture bundle + + auto newCat = new UserTextureCategory{dirPath.fileName(), dirPath}; + newCat->loadBundle(); + + beginInsertRows({}, m_userCategories.size(), m_userCategories.size()); + m_userCategories << newCat; + endInsertRows(); + + m_fileWatcher->addDirectory(dirPath, Utils::FileSystemWatcher::WatchAllChanges); + + // add the folder to custom bundles json file if it is missing + const QString dirPathStr = dirPath.toFSPathString(); + if (!m_customCatsObj.contains(dirPathStr)) { + m_customCatsObj.insert(dirPathStr, QJsonObject{}); + + m_customCatsRootObj["items"] = m_customCatsObj; + + auto userBundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User"); + auto jsonFilePath = userBundlePath.pathAppended(Constants::CUSTOM_BUNDLES_JSON_FILENAME); + auto result = jsonFilePath.writeFileContents(QJsonDocument(m_customCatsRootObj).toJson()); + QTC_ASSERT_EXPECTED(result,); + } } void ContentLibraryUserModel::addItem(const QString &bundleId, const QString &name, @@ -102,22 +182,36 @@ void ContentLibraryUserModel::refreshSection(const QString &bundleId) updateIsEmpty(); } -void ContentLibraryUserModel::addTextures(const Utils::FilePaths &paths) +void ContentLibraryUserModel::addTextures(const Utils::FilePaths &paths, const Utils::FilePath &bundlePath) { - auto texCat = qobject_cast(m_userCategories[TexturesSectionIdx]); + int catIdx = bundlePathToIndex(bundlePath); + UserTextureCategory *texCat = qobject_cast(m_userCategories.at(catIdx)); QTC_ASSERT(texCat, return); texCat->addItems(paths); - emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx), {ItemsRole, EmptyRole}); + emit dataChanged(index(catIdx), index(catIdx), {ItemsRole, EmptyRole}); updateIsEmpty(); } -void ContentLibraryUserModel::removeTextures(const QStringList &fileNames) +void ContentLibraryUserModel::reloadTextureCategory(const Utils::FilePath &dirPath) +{ + int catIdx = bundlePathToIndex(dirPath); + UserTextureCategory *texCat = qobject_cast(m_userCategories.at(catIdx)); + QTC_ASSERT(texCat, return); + + const Utils::FilePaths &paths = dirPath.dirEntries({Asset::supportedImageSuffixes(), QDir::Files}); + + texCat->clearItems(); + addTextures(paths, dirPath); +} + +void ContentLibraryUserModel::removeTextures(const QStringList &fileNames, const Utils::FilePath &bundlePath) { // note: this method doesn't refresh the model after textures removal - auto texCat = qobject_cast(m_userCategories[TexturesSectionIdx]); + int catIdx = bundlePathToIndex(bundlePath); + UserTextureCategory *texCat = qobject_cast(m_userCategories.at(catIdx)); QTC_ASSERT(texCat, return); const QObjectList items = texCat->items(); @@ -137,13 +231,28 @@ void ContentLibraryUserModel::removeTexture(ContentLibraryTexture *tex, bool ref Utils::FilePath::fromString(tex->iconPath()).removeFile(); // remove from model - m_userCategories[TexturesSectionIdx]->removeItem(tex); + UserTextureCategory *itemCat = qobject_cast(tex->parent()); + QTC_ASSERT(itemCat, return); + itemCat->removeItem(tex); // update model if (refresh) { - emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx)); + int catIdx = bundlePathToIndex(itemCat->bundlePath()); + emit dataChanged(index(catIdx), index(catIdx)); updateIsEmpty(); } + + const QString bundlePathStr = itemCat->bundlePath().toFSPathString(); + if (m_customCatsObj.contains(bundlePathStr)) { + m_customCatsObj.remove(bundlePathStr); + + m_customCatsRootObj["items"] = m_customCatsObj; + + auto userBundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User"); + auto jsonFilePath = userBundlePath.pathAppended(Constants::CUSTOM_BUNDLES_JSON_FILENAME); + auto result = jsonFilePath.writeFileContents(QJsonDocument(m_customCatsRootObj).toJson()); + QTC_ASSERT_EXPECTED(result,); + } } void ContentLibraryUserModel::removeFromContentLib(QObject *item) @@ -154,6 +263,30 @@ void ContentLibraryUserModel::removeFromContentLib(QObject *item) removeItem(castedItem); } +void ContentLibraryUserModel::removeBundleDir(int catIdx) +{ + auto texCat = qobject_cast(m_userCategories.at(catIdx)); + QTC_ASSERT(texCat, return); + + QString dirPath = texCat->bundlePath().toFSPathString(); + + // remove from json + QTC_ASSERT(m_customCatsObj.contains(dirPath), return); + m_customCatsObj.remove(dirPath); + m_customCatsRootObj["items"] = m_customCatsObj; + + auto userBundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User"); + auto jsonFilePath = userBundlePath.pathAppended(Constants::CUSTOM_BUNDLES_JSON_FILENAME); + auto result = jsonFilePath.writeFileContents(QJsonDocument(m_customCatsRootObj).toJson()); + QTC_ASSERT_EXPECTED(result, return); + + // remove from model + beginRemoveRows({}, catIdx, catIdx); + delete texCat; + m_userCategories.removeAt(catIdx); + endRemoveRows(); +} + void ContentLibraryUserModel::removeItemByName(const QString &qmlFileName, const QString &bundleId) { ContentLibraryItem *itemToRemove = nullptr; @@ -239,10 +372,27 @@ ContentLibraryUserModel::SectionIndex ContentLibraryUserModel::bundleIdToSection return {}; } +int ContentLibraryUserModel::bundlePathToIndex(const QString &bundlePath) const +{ + return bundlePathToIndex(Utils::FilePath::fromString(bundlePath)); +} + +int ContentLibraryUserModel::bundlePathToIndex(const Utils::FilePath &bundlePath) const +{ + for (int i = 0; i < m_userCategories.size(); ++i) { + if (m_userCategories.at(i)->bundlePath() == bundlePath) + return i; + } + + qWarning() << __FUNCTION__ << "Invalid bundlePath:" << bundlePath; + return -1; +} + QHash ContentLibraryUserModel::roleNames() const { static const QHash roles { {TitleRole, "categoryTitle"}, + {BundlePathRole, "categoryBundlePath"}, {EmptyRole, "categoryEmpty"}, {ItemsRole, "categoryItems"}, {NoMatchRole, "categoryNoMatch"} diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h index 172bad093a3..72b849aeba3 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h @@ -6,10 +6,15 @@ #include "usercategory.h" #include +#include #include #include +namespace Utils { +class FileSystemWatcher; +} + QT_FORWARD_DECLARE_CLASS(QUrl) namespace QmlDesigner { @@ -28,6 +33,7 @@ class ContentLibraryUserModel : public QAbstractListModel public: ContentLibraryUserModel(ContentLibraryWidget *parent = nullptr); + ~ContentLibraryUserModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; @@ -50,8 +56,9 @@ public: void addItem(const QString &bundleId, const QString &name, const QString &qml,const QUrl &icon, const QStringList &files); void refreshSection(const QString &bundleId); - void addTextures(const Utils::FilePaths &paths); - void removeTextures(const QStringList &fileNames); + void addTextures(const Utils::FilePaths &paths, const Utils::FilePath &bundlePath); + void reloadTextureCategory(const Utils::FilePath &dirPath); + void removeTextures(const QStringList &fileNames, const Utils::FilePath &bundlePath); void removeItemByName(const QString &qmlFileName, const QString &bundleId); @@ -59,12 +66,15 @@ public: QJsonObject &bundleObjectRef(const QString &bundleId); void loadBundles(bool force = false); + void addBundleDir(const Utils::FilePath &dirPath); + bool bundleDirExists(const QString &dirPath) const; Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryItem *mat, bool add = false); Q_INVOKABLE void addToProject(ContentLibraryItem *item); Q_INVOKABLE void removeFromProject(QObject *item); Q_INVOKABLE void removeTexture(QmlDesigner::ContentLibraryTexture *tex, bool refresh = true); Q_INVOKABLE void removeFromContentLib(QObject *item); + Q_INVOKABLE void removeBundleDir(int catIdx); signals: void hasRequiredQuick3DImportChanged(); @@ -79,14 +89,20 @@ private: EffectsSectionIdx }; void createCategories(); + void loadCustomCategories(const Utils::FilePath &userBundlePath); void loadMaterialBundle(); void load3DBundle(); void loadTextureBundle(); void removeItem(ContentLibraryItem *item); SectionIndex bundleIdToSectionIndex(const QString &bundleId) const; + int bundlePathToIndex(const QString &bundlePath) const; + int bundlePathToIndex(const Utils::FilePath &bundlePath) const; ContentLibraryWidget *m_widget = nullptr; + QJsonObject m_customCatsRootObj; + QJsonObject m_customCatsObj; QString m_searchText; + Utils::UniqueObjectPtr m_fileWatcher; QList m_userCategories; @@ -95,7 +111,9 @@ private: int m_quick3dMajorVersion = -1; int m_quick3dMinorVersion = -1; - enum Roles { TitleRole = Qt::UserRole + 1, ItemsRole, EmptyRole, NoMatchRole }; + enum Roles { TitleRole = Qt::UserRole + 1, BundlePathRole, ItemsRole, EmptyRole, NoMatchRole }; + + static constexpr char CUSTOM_BUNDLES_JSON_FILE_VERSION[] = "1.0"; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index d907e616524..2a181dfbc54 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -91,7 +91,7 @@ WidgetInfo ContentLibraryView::widgetInfo() }); connect(m_widget, &ContentLibraryWidget::acceptTextureDrop, this, - [this](const QString &internalId) { + [this](const QString &internalId, const QString &bundlePath) { ModelNode texNode = QmlDesignerPlugin::instance()->viewManager() .view()->modelNodeForInternalId(internalId.toInt()); auto [qmlString, depAssets] = m_bundleHelper->modelNodeToQmlString(texNode); @@ -104,11 +104,11 @@ WidgetInfo ContentLibraryView::widgetInfo() paths.append(path); } - addLibAssets(paths); + addLibAssets(paths, bundlePath); }); connect(m_widget, &ContentLibraryWidget::acceptTexturesDrop, this, - [this](const QList &urls) { + [this](const QList &urls, const QString &bundlePath) { QStringList paths; for (const QUrl &url : urls) { @@ -117,7 +117,7 @@ WidgetInfo ContentLibraryView::widgetInfo() if (Asset(path).isValidTextureSource()) paths.append(path); } - addLibAssets(paths); + addLibAssets(paths, bundlePath); }); connect(m_widget, &ContentLibraryWidget::acceptMaterialDrop, this, @@ -569,14 +569,16 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle } #endif -void ContentLibraryView::addLibAssets(const QStringList &paths) +void ContentLibraryView::addLibAssets(const QStringList &paths, const QString &bundlePath) { - auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/textures"); + auto fullBundlePath = Utils::FilePath::fromString(bundlePath.isEmpty() + ? Paths::bundlesPathSetting() + "/User/textures" + : bundlePath); Utils::FilePaths sourcePathsToAdd; Utils::FilePaths targetPathsToAdd; QStringList fileNamesToRemove; - const QStringList existingAssetsFileNames = Utils::transform(bundlePath.dirEntries(QDir::Files), + const QStringList existingAssetsFileNames = Utils::transform(fullBundlePath.dirEntries(QDir::Files), &Utils::FilePath::fileName); for (const QString &path : paths) { @@ -598,21 +600,13 @@ void ContentLibraryView::addLibAssets(const QStringList &paths) } // remove the to-be-overwritten resources from target bundle path - m_widget->userModel()->removeTextures(fileNamesToRemove); + m_widget->userModel()->removeTextures(fileNamesToRemove, fullBundlePath); // copy resources to target bundle path for (const Utils::FilePath &sourcePath : sourcePathsToAdd) { - Utils::FilePath targetPath = bundlePath.pathAppended(sourcePath.fileName()); + Utils::FilePath targetPath = fullBundlePath.pathAppended(sourcePath.fileName()); Asset asset{sourcePath.toFSPathString()}; - // save icon - QString iconSavePath = bundlePath.pathAppended("icons/" + sourcePath.baseName() + ".png") - .toFSPathString(); - QPixmap icon = asset.pixmap({120, 120}); - bool iconSaved = icon.save(iconSavePath); - if (!iconSaved) - qWarning() << __FUNCTION__ << "icon save failed"; - // save asset auto result = sourcePath.copyFile(targetPath); QTC_ASSERT_EXPECTED(result,); @@ -620,7 +614,7 @@ void ContentLibraryView::addLibAssets(const QStringList &paths) targetPathsToAdd.append(targetPath); } - m_widget->userModel()->addTextures(targetPathsToAdd); + m_widget->userModel()->addTextures(targetPathsToAdd, fullBundlePath); } // TODO: combine this method with BundleHelper::exportComponent() diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index e8cc641c32c..0872d51a1bd 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -63,7 +63,7 @@ private: bool isItemBundle(const QString &bundleId) const; void active3DSceneChanged(qint32 sceneId); void updateBundlesQuick3DVersion(); - void addLibAssets(const QStringList &paths); + void addLibAssets(const QStringList &paths, const QString &bundlePath = {}); void addLib3DComponent(const ModelNode &node); void addLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); void importBundleToContentLib(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index 588d1851707..9b3860cebf1 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -190,6 +190,21 @@ ContentLibraryWidget::~ContentLibraryWidget() { } +void ContentLibraryWidget::browseBundleFolder() +{ + DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); + QTC_ASSERT(document, return); + const QString currentDir = document->fileName().parentDir().toUrlishString(); + + QString dir = QFileDialog::getExistingDirectory(Core::ICore::dialogParent(), + tr("Choose Directory"), + currentDir, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + if (!dir.isEmpty() && !m_userModel->bundleDirExists(dir)) + m_userModel->addBundleDir(Utils::FilePath::fromString(dir)); +} + void ContentLibraryWidget::createImporter() { m_importer = new BundleImporter(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h index 76a4c24b8b8..ee7cb3509d2 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h @@ -104,6 +104,7 @@ public: Q_INVOKABLE bool has3DNode(const QByteArray &data) const; Q_INVOKABLE bool hasTexture(const QString &format, const QVariant &data) const; Q_INVOKABLE void addQtQuick3D(); + Q_INVOKABLE void browseBundleFolder(); QSize sizeHint() const override; @@ -127,8 +128,8 @@ signals: void hasModelSelectionChanged(); void importBundle(); void requestTab(int tabIndex); - void acceptTexturesDrop(const QList &urls); - void acceptTextureDrop(const QString &internalId); + void acceptTexturesDrop(const QList &urls, const QString &bundlePath = {}); + void acceptTextureDrop(const QString &internalId, const QString &bundlePath = {}); void acceptMaterialDrop(const QString &internalId); void accept3DDrop(const QByteArray &internalIds); void importQtQuick3D(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp index 22b9cf20aa3..ec603068505 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp @@ -5,7 +5,7 @@ #include "contentlibrarytexture.h" -#include +#include #include namespace QmlDesigner { @@ -27,7 +27,7 @@ void UserTextureCategory::loadBundle(bool force) m_bundlePath.ensureWritableDir(); m_bundlePath.pathAppended("icons").ensureWritableDir(); - addItems(m_bundlePath.dirEntries(QDir::Files)); + addItems(m_bundlePath.dirEntries({Asset::supportedImageSuffixes(), QDir::Files})); m_bundleLoaded = true; } @@ -55,6 +55,14 @@ void UserTextureCategory::addItems(const Utils::FilePaths &paths) QSize imgDims = info.first; qint64 imgFileSize = info.second; + if (!iconFileInfo.exists()) { // generate an icon if one doesn't exist + Asset asset{filePath.toFSPathString()}; + QPixmap icon = asset.pixmap({120, 120}); + bool iconSaved = icon.save(iconFileInfo.filePath()); + if (!iconSaved) + qWarning() << __FUNCTION__ << "icon save failed"; + } + auto tex = new ContentLibraryTexture(this, iconFileInfo, dirPath, suffix, imgDims, imgFileSize); m_items.append(tex); } @@ -63,4 +71,13 @@ void UserTextureCategory::addItems(const Utils::FilePaths &paths) emit itemsChanged(); } +void UserTextureCategory::clearItems() +{ + qDeleteAll(m_items); + m_items.clear(); + + setIsEmpty(true); + emit itemsChanged(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h index 511e2ea3f83..8687f322fd3 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h +++ b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h @@ -16,10 +16,11 @@ class UserTextureCategory : public UserCategory public: UserTextureCategory(const QString &title, const Utils::FilePath &bundlePath); - void loadBundle(bool force) override; + void loadBundle(bool force = false) override; void filter(const QString &searchText) override; void addItems(const Utils::FilePaths &paths); + void clearItems(); }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 58fc32e9932..7bde8178caa 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -59,6 +59,7 @@ inline constexpr char EDIT3D_SNAP_CONFIG[] = "QmlDesigner.Editor3D.SnapConfig"; inline constexpr char EDIT3D_CAMERA_SPEED_CONFIG[] = "QmlDesigner.Editor3D.CameraSpeedConfig"; inline constexpr char BUNDLE_JSON_FILENAME[] = "bundle.json"; +inline constexpr char CUSTOM_BUNDLES_JSON_FILENAME[] = "custom_bundles.json"; inline constexpr char BUNDLE_SUFFIX[] = "qdsbundle"; inline constexpr char COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE[] = "Effects"; inline constexpr char COMPONENT_BUNDLES_ASSET_REF_FILE[] = "_asset_ref.json"; From 8f6e603eb781386ec50f89e6722d6003a1db8f6b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 31 Mar 2025 15:48:55 +0200 Subject: [PATCH 17/82] QmlDesigner: Add missing tooltips Task-number: QDS-15077 Change-Id: I9ef9d8fbb13cdab5010913bc83c64762cf11645d Reviewed-by: Pranta Ghosh Dastider Reviewed-by: Thomas Hartmann --- .../timelineeditor/timelinetoolbar.cpp | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp index e204c0ad4a0..b680572b740 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "timelinetoolbar.h" +#include #include "timelineconstants.h" #include "timelinegraphicsscene.h" @@ -132,7 +133,7 @@ QString TimelineToolBar::currentTimelineId() const void TimelineToolBar::setCurrentState(const QString &name) { if (name.isEmpty()) - m_stateLabel->setText(tr("Base State")); + m_stateLabel->setText(Tr::tr("Base State")); else m_stateLabel->setText(name); } @@ -191,9 +192,9 @@ void TimelineToolBar::setIsMcu(bool isMcu) { m_curvePicker->setDisabled(isMcu); if (isMcu) - m_curvePicker->setText(tr("Not Supported for MCUs")); + m_curvePicker->setText(Tr::tr("Not Supported for MCUs")); else - m_curvePicker->setText(tr(m_curveEditorName)); + m_curvePicker->setText(Tr::tr(m_curveEditorName)); } void TimelineToolBar::setActionEnabled(const QString &name, bool enabled) @@ -232,7 +233,7 @@ void TimelineToolBar::createLeftControls() auto *settingsAction = createAction(TimelineConstants::C_SETTINGS, Theme::iconFromName(Theme::Icon::settings_medium), - tr("Timeline Settings"), + Tr::tr("Timeline Settings"), QKeySequence(Qt::Key_S)); connect(settingsAction, &QAction::triggered, this, &TimelineToolBar::settingDialogClicked); @@ -267,7 +268,7 @@ void TimelineToolBar::createCenterControls() auto *toStart = createAction(TimelineConstants::C_TO_START, Theme::iconFromName(Theme::Icon::toStartFrame_medium), - tr("To Start"), + Tr::tr("Start Frame"), QKeySequence(Qt::Key_Home)); connect(toStart, &QAction::triggered, this, &TimelineToolBar::toFirstFrameTriggered); @@ -277,7 +278,7 @@ void TimelineToolBar::createCenterControls() auto *previous = createAction(TimelineConstants::C_PREVIOUS, Theme::iconFromName(Theme::Icon::toPrevFrame_medium), - tr("Previous"), + Tr::tr("Previous Frame"), QKeySequence(Qt::Key_Comma)); connect(previous, &QAction::triggered, this, &TimelineToolBar::previousFrameTriggered); @@ -292,7 +293,7 @@ void TimelineToolBar::createCenterControls() m_playing = createAction(TimelineConstants::C_PLAY, playbackIcon, - tr("Play"), + Tr::tr("Play"), QKeySequence(Qt::Key_Space)); m_playing->setCheckable(true); connect(m_playing, &QAction::triggered, this, &TimelineToolBar::playTriggered); @@ -302,7 +303,7 @@ void TimelineToolBar::createCenterControls() auto *next = createAction(TimelineConstants::C_NEXT, Theme::iconFromName(Theme::Icon::toNextFrame_medium), - tr("Next"), + Tr::tr("Next Frame"), QKeySequence(Qt::Key_Period)); connect(next, &QAction::triggered, this, &TimelineToolBar::nextFrameTriggered); @@ -312,7 +313,7 @@ void TimelineToolBar::createCenterControls() auto *toEnd = createAction(TimelineConstants::C_TO_END, Theme::iconFromName(Theme::Icon::toEndFrame_medium), - tr("To End"), + Tr::tr("End Frame"), QKeySequence(Qt::Key_End)); connect(toEnd, &QAction::triggered, this, &TimelineToolBar::toLastFrameTriggered); @@ -327,7 +328,7 @@ void TimelineToolBar::createCenterControls() // TODO: Toggles looping. Select shortcut for this QDS-4941 auto *loopAnimation = createAction(TimelineConstants::C_LOOP_PLAYBACK, Theme::iconFromName(Theme::Icon::loopPlayback_medium), - tr("Loop Playback"), + Tr::tr("Loop Playback"), Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Space); loopAnimation->setCheckable(true); @@ -340,7 +341,7 @@ void TimelineToolBar::createCenterControls() m_animationPlaybackSpeed = createToolBarLineEdit(this); LineEditDoubleValidator *validator = new LineEditDoubleValidator(0.1, 100.0, 1, m_animationPlaybackSpeed); m_animationPlaybackSpeed->setValidator(validator); - m_animationPlaybackSpeed->setToolTip(tr("Playback Speed")); + m_animationPlaybackSpeed->setToolTip(Tr::tr("Playback Speed")); addWidget(m_animationPlaybackSpeed); auto emitPlaybackSpeedChanged = [this, validator]() { @@ -356,6 +357,7 @@ void TimelineToolBar::createCenterControls() addSeparator(); m_currentFrame = createToolBarLineEdit(this); + m_currentFrame->setToolTip(Tr::tr("Timeline Current Frame")); addWidget(m_currentFrame); auto emitCurrentChanged = [this] { emit currentFrameChanged(m_currentFrame->text().toInt()); }; @@ -372,7 +374,7 @@ void TimelineToolBar::createCenterControls() m_recording = createAction(TimelineConstants::C_AUTO_KEYFRAME, autoKeyIcon, - tr("Auto Key"), + Tr::tr("Auto Key"), QKeySequence(Qt::Key_K)); m_recording->setCheckable(true); @@ -387,9 +389,9 @@ void TimelineToolBar::createCenterControls() addSpacing(10); m_curvePicker = createAction(TimelineConstants::C_CURVE_PICKER, - Theme::iconFromName(Theme::Icon::curveDesigner_medium), - tr(m_curveEditorName), - QKeySequence(Qt::Key_C)); + Theme::iconFromName(Theme::Icon::curveDesigner_medium), + Tr::tr(m_curveEditorName), + QKeySequence(Qt::Key_C)); m_curvePicker->setObjectName("Easing Curve Editor"); connect(m_curvePicker, &QAction::triggered, this, &TimelineToolBar::openEasingCurveEditor); @@ -416,6 +418,7 @@ void TimelineToolBar::createRightControls() addSeparator(); m_firstFrame = createToolBarLineEdit(this); + m_firstFrame->setToolTip(Tr::tr("Timeline First Frame")); addWidget(m_firstFrame); auto emitStartChanged = [this] { emit startFrameChanged(m_firstFrame->text().toInt()); }; @@ -427,7 +430,7 @@ void TimelineToolBar::createRightControls() auto *zoomOut = createAction(TimelineConstants::C_ZOOM_OUT, Theme::iconFromName(Theme::Icon::zoomOut_medium), - tr("Zoom Out"), + Tr::tr("Zoom Out"), QKeySequence(QKeySequence::ZoomOut)); connect(zoomOut, &QAction::triggered, [this] { @@ -454,7 +457,7 @@ void TimelineToolBar::createRightControls() auto *zoomIn = createAction(TimelineConstants::C_ZOOM_IN, Theme::iconFromName(Theme::Icon::zoomIn_medium), - tr("Zoom In"), + Tr::tr("Zoom In"), QKeySequence(QKeySequence::ZoomIn)); connect(zoomIn, &QAction::triggered, [this] { @@ -467,6 +470,7 @@ void TimelineToolBar::createRightControls() addSeparator(); m_lastFrame = createToolBarLineEdit(this); + m_lastFrame->setToolTip(Tr::tr("Timeline Last Frame")); addWidget(m_lastFrame); auto emitEndChanged = [this] { emit endFrameChanged(m_lastFrame->text().toInt()); }; From 398b783f1a8b279082f1098408bdb836095f616b Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Mon, 7 Apr 2025 11:24:29 +0300 Subject: [PATCH 18/82] QMLRewriter: Fix the very first child position case in member search If we want to insert an object to the top (pos = -1), we should find the current first object, and return the last non-object item found before the first object. If there's no object, it will be automatically return the last non-object. Change-Id: Icf78b219af4c0735b7a05e0a8692202dada877fc Reviewed-by: Thomas Hartmann --- .../libs/designercore/filemanager/qmlrewriter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp index 77021f02324..aa2f794e4da 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp @@ -275,9 +275,6 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder, int pos) { - if (pos < 0) - return searchMemberToInsertAfter(members, propertyOrder); - // An empty property name should be available in the propertyOrder List, which is the right place // to define the objects there. const int objectDefinitionInsertionPoint = propertyOrder.indexOf(PropertyName()); @@ -291,6 +288,8 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( int idx = -1; if (QmlJS::AST::cast(member)) { + if (pos < 0) + break; lastObjectDef = iter; if (objectPos++ == pos) break; From 440915c88c24d6561fa7b17ebdeeed522dedf282 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 25 Mar 2025 18:13:31 +0100 Subject: [PATCH 19/82] UnitTests: Empty project updates Change-Id: I1ee29e057ed45fbd0a1212a2063ebdc1021f2fbd Reviewed-by: Thomas Hartmann --- .../projectstorageupdater-test.cpp | 82 +++++++++++++------ 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index 34f74d797cc..9d9de800271 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -701,55 +701,91 @@ TEST_F(ProjectStorageUpdater_parse_qml_types, add_subdirectories) updater.update({.qtDirectories = {"/root"}}); } -TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) +class ProjectStorageUpdater_synchronize_empty : public BaseProjectStorageUpdater { - setFilesUnchanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); +public: + ProjectStorageUpdater_synchronize_empty() + { + QString qmldir{R"(module Example + typeinfo example.qmltypes + typeinfo example2.qmltypes)"}; + setContent(u"/root/path/qmldir", qmldir); + setContent(u"/root/path/example.qmltypes", qmltypes); + setContent(u"/root/path/example2.qmltypes", qmltypes2); + setSubdirectoryPaths(u"/root", {"/root/path"}); + } + +public: + QString qmltypes{"Module {\ndependencies: []}"}; + QString qmltypes2{"Module {\ndependencies: [foo]}"}; + SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/root/path/example.qmltypes"); + SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/root/path/example2.qmltypes"); + SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/root/path/qmldir"); + SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + SourceId annotationDirectoryId = createDirectorySourceId("/root/path/designer"); + SourceId rootQmlDirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); + SourceId rootDirectoryPathSourceId = createDirectorySourceId("/root"); + SourceId rootAnnotationDirectoryId = createDirectorySourceId("/root/designer"); + SourceId ignoreInQdsSourceId = sourcePathCache.sourceId("/root/path/ignore-in-qds"); +}; + +TEST_F(ProjectStorageUpdater_synchronize_empty, for_no_change_for_qt) +{ + setFilesUnchanged( + {qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId, directoryPathSourceId}); + setFilesNotExistsUnchanged({annotationDirectoryId}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root/path"}}); } -TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change_in_subdirectory) +TEST_F(ProjectStorageUpdater_synchronize_empty, for_no_change_for_project) +{ + setFilesUnchanged( + {qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId, directoryPathSourceId}); + setFilesNotExistsUnchanged({annotationDirectoryId}); + + EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); + + updater.update({.projectDirectory = "/root/path"}); +} + +TEST_F(ProjectStorageUpdater_synchronize_empty, for_no_change_in_subdirectory) { - SourceId qmlDirRootPathSourceId = sourcePathCache.sourceId("/root/qmldir"); - SourceId rootPathSourceId = createDirectorySourceId("/root"); setFilesUnchanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId, - qmlDirRootPathSourceId, - rootPathSourceId}); - QStringList directories = {"/root"}; - setSubdirectoryPaths(u"/root", {"/path"}); + rootDirectoryPathSourceId, + directoryPathSourceId}); + setFilesNotExistsUnchanged( + {annotationDirectoryId, rootQmlDirPathSourceId, rootAnnotationDirectoryId, ignoreInQdsSourceId}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root"}}); } -TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_ignored_subdirectory) +TEST_F(ProjectStorageUpdater_synchronize_empty, for_ignored_subdirectory) { - SourceId qmlDirRootPathSourceId = sourcePathCache.sourceId("/root/qmldir"); - SourceId ignoreInQdsSourceId = sourcePathCache.sourceId("/path/ignore-in-qds"); - SourceId rootPathSourceId = createDirectorySourceId("/root"); setFilesChanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); - setFilesUnchanged({rootPathSourceId, qmlDirRootPathSourceId, ignoreInQdsSourceId}); - setSubdirectoryPaths(u"/root", {"/path"}); + setFilesUnchanged({rootDirectoryPathSourceId, directoryPathSourceId, ignoreInQdsSourceId}); + setFilesNotExistsUnchanged( + {rootAnnotationDirectoryId, annotationDirectoryId, rootQmlDirPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); updater.update({.projectDirectory = "/root"}); } -TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_added_ignored_subdirectory) +TEST_F(ProjectStorageUpdater_synchronize_empty, not_for_added_ignored_subdirectory) { - SourceId qmlDirRootPathSourceId = sourcePathCache.sourceId("/root/qmldir"); - SourceId ignoreInQdsSourceId = sourcePathCache.sourceId("/path/ignore-in-qds"); - SourceId rootPathSourceId = createDirectorySourceId("/root"); setFilesChanged({qmltypesPathSourceId, qmltypes2PathSourceId, qmlDirPathSourceId}); + setFilesUnchanged({rootDirectoryPathSourceId, directoryPathSourceId}); setFilesAdded({ignoreInQdsSourceId}); - setFilesUnchanged({rootPathSourceId, qmlDirRootPathSourceId}); - setSubdirectoryPaths(u"/root", {"/path"}); + setFilesNotExistsUnchanged( + {rootAnnotationDirectoryId, annotationDirectoryId, rootQmlDirPathSourceId}); EXPECT_CALL( projectStorageMock, From ca40cebf92ca6f2c81c7d4d2f718e65acd4a58d8 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 27 Mar 2025 18:46:55 +0100 Subject: [PATCH 20/82] QmlDesigner: Refactor subdirectory tests Change-Id: I24f54c1e4b5a72db3bfc0c82aa470033c7bff095 Reviewed-by: Thomas Hartmann --- .../projectstorage/projectstorageupdater.cpp | 2 +- .../projectstorageupdater-test.cpp | 200 ++++++++++++++---- 2 files changed, 160 insertions(+), 42 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index b0de72c73c1..b9778f07636 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -595,7 +595,7 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct {}, &Directory::sourceContextId); - if (isChanged(directoryState)) { + if (isChangedOrAdded(directoryState)) { for (const auto &[subdirectoryPath, subdirectoryId] : existingSubdirecories) { package.directoryInfos.emplace_back(directoryId, SourceId::create(SourceNameId{}, subdirectoryId), diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index 9d9de800271..4ef25c57438 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -273,12 +273,12 @@ public: EXPECT_CALL(fileSystemMock, contentAsQString(Eq(path))).WillRepeatedly(Return(content)); } - void setSubdirectoryPaths(QStringView directoryPath, const QStringList &subdirectoryPaths) + void setFileSystemSubdirectories(QStringView directoryPath, const QStringList &subdirectoryPaths) { ON_CALL(fileSystemMock, subdirectories(Eq(directoryPath))).WillByDefault(Return(subdirectoryPaths)); } - void setSubdirectorySourceIds(SourceContextId directoryId, + void setStorageSubdirectories(SourceContextId directoryId, const QmlDesigner::SmallSourceContextIds<32> &subdirectoryIds) { ON_CALL(projectStorageMock, fetchSubdirectoryIds(Eq(directoryId))) @@ -520,7 +520,7 @@ TEST_F(ProjectStorageUpdater_get_content_for_qml_dir_paths, file_status_is_diffe TEST_F(ProjectStorageUpdater_get_content_for_qml_dir_paths, file_status_is_different_for_subdirectories) { QStringList directories = {"/path/one"}; - setSubdirectoryPaths(u"/path/one", {"/path/two", "/path/three"}); + setFileSystemSubdirectories(u"/path/one", {"/path/two", "/path/three"}); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); @@ -683,7 +683,7 @@ TEST_F(ProjectStorageUpdater_parse_qml_types, add_subdirectories) { setFilesAdded( {directoryPathSourceId, qmlDirPathSourceId, qmltypesPathSourceId, qmltypes2PathSourceId}); - setSubdirectoryPaths(u"/root", {"/root/path"}); + setFileSystemSubdirectories(u"/root", {"/root/path"}); EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, @@ -712,7 +712,7 @@ public: setContent(u"/root/path/qmldir", qmldir); setContent(u"/root/path/example.qmltypes", qmltypes); setContent(u"/root/path/example2.qmltypes", qmltypes2); - setSubdirectoryPaths(u"/root", {"/root/path"}); + setFileSystemSubdirectories(u"/root", {"/root/path"}); } public: @@ -848,14 +848,51 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types) updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, synchronize_subdircectories) +class ProjectStorageUpdater_synchronize_subdirectories : public BaseProjectStorageUpdater +{ +public: + ProjectStorageUpdater_synchronize_subdirectories() + { + setFileSystemSubdirectories(u"/root", {"/root/one", "/root/two"}); + setFileSystemSubdirectories(u"/root/one", {"/root/one/three"}); + } + +public: + SourceId rootDirectoryPathSourceId = createDirectorySourceId("/root"); + SourceContextId rootDirectoryPathId = rootDirectoryPathSourceId.contextId(); + SourceId path1SourceId = createDirectorySourceId("/root/one"); + SourceContextId path1SourceContextId = path1SourceId.contextId(); + SourceId path2SourceId = createDirectorySourceId("/root/two"); + SourceContextId path2SourceContextId = path2SourceId.contextId(); + SourceId path3SourceId = createDirectorySourceId("/root/one/three"); + SourceContextId path3SourceContextId = path3SourceId.contextId(); +}; + +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, added_qt_subdircectories) +{ + setFilesAdded({rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId}); + + EXPECT_CALL( + projectStorageMock, + synchronize(AllOf( + Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + UnorderedElementsAre( + IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + UnorderedElementsAre(rootDirectoryPathId, + path1SourceContextId, + path2SourceContextId, + path3SourceContextId))))); + + updater.update({.qtDirectories = {"/root"}}); +} + +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, changed_qt_subdircectories) { - QStringList directories = {"/root"}; - setSubdirectoryPaths(u"/root", {"/path/one", "/path/two"}); - setSubdirectoryPaths(u"/path/one", {"/path/three"}); - SourceContextId rootDirectoryPathId = sourcePathCache.sourceContextId("/root"); - SourceId rootDirectoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, - rootDirectoryPathId); setFilesChanged({rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId}); EXPECT_CALL( @@ -874,15 +911,57 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories) path2SourceContextId, path3SourceContextId))))); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root"}}); } -TEST_F(ProjectStorageUpdater, synchronize_subdircectories_even_for_no_changes) +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, added_project_subdircectories) +{ + setFilesAdded({rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId}); + + EXPECT_CALL( + projectStorageMock, + synchronize(AllOf( + Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + UnorderedElementsAre( + IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + UnorderedElementsAre(rootDirectoryPathId, + path1SourceContextId, + path2SourceContextId, + path3SourceContextId))))); + + updater.update({.projectDirectory = "/root"}); +} + +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, changed_project_subdircectories) +{ + setFilesChanged({rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId}); + + EXPECT_CALL( + projectStorageMock, + synchronize(AllOf( + Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + UnorderedElementsAre( + IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + UnorderedElementsAre(rootDirectoryPathId, + path1SourceContextId, + path2SourceContextId, + path3SourceContextId))))); + + updater.update({.projectDirectory = "/root"}); +} + +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, qt_subdirectories_if_root_is_not_changed) { - QStringList directories = {"/root"}; - setSubdirectoryPaths(u"/root", {"/path/one", "/path/two"}); - setSubdirectoryPaths(u"/path/one", {"/path/three"}); - auto rootDirectoryPathSourceId = createDirectorySourceId("/root"); setFilesChanged({path1SourceId, path2SourceId, path3SourceId}); setFilesUnchanged({rootDirectoryPathSourceId}); @@ -899,23 +978,38 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_even_for_no_changes) path2SourceContextId, path3SourceContextId))))); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root"}}); } -TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecties) +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, project_subdirectories_if_root_is_not_changed) +{ + setFilesChanged({path1SourceId, path2SourceId, path3SourceId}); + setFilesUnchanged({rootDirectoryPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(path1SourceContextId, + path3SourceId, + ModuleId{}, + FileType::Directory))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + UnorderedElementsAre(path1SourceContextId, + path2SourceContextId, + path3SourceContextId))))); + + updater.update({.projectDirectory = "/root"}); +} + +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_qt_subdirecties) { - QStringList directories = {"/root"}; - setSubdirectoryPaths(u"/root", {"/path/two"}); - SourceContextId rootDirectoryPathId = sourcePathCache.sourceContextId("/root"); - SourceId rootDirectoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, - rootDirectoryPathId); setFilesChanged({rootDirectoryPathSourceId}); - setFilesNotExists({ - path1SourceId, - path3SourceId, - }); - setSubdirectorySourceIds(rootDirectoryPathId, {path1SourceContextId, path2SourceContextId}); - setSubdirectorySourceIds(path1SourceContextId, {path3SourceContextId}); + setFilesRemoved({path1SourceId, path3SourceId}); + setFilesUnchanged({path2SourceId}); + setStorageSubdirectories(rootDirectoryPathId, {path1SourceContextId, path2SourceContextId}); + setStorageSubdirectories(path1SourceContextId, {path3SourceContextId}); + setFileSystemSubdirectories(u"/root", {"/root/two"}); EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", @@ -928,10 +1022,34 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecti &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, path1SourceContextId, - path2SourceContextId, path3SourceContextId))))); - updater.update({.qtDirectories = directories}); + updater.update({.qtDirectories = {"/root"}}); +} + +TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_project_subdirecties) +{ + setFilesChanged({rootDirectoryPathSourceId}); + setFilesRemoved({path1SourceId, path3SourceId}); + setFilesUnchanged({path2SourceId}); + setStorageSubdirectories(rootDirectoryPathId, {path1SourceContextId, path2SourceContextId}); + setStorageSubdirectories(path1SourceContextId, {path3SourceContextId}); + setFileSystemSubdirectories(u"/root", {"/root/two"}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(rootDirectoryPathId, + path2SourceId, + ModuleId{}, + FileType::Directory))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + UnorderedElementsAre(rootDirectoryPathId, + path1SourceContextId, + path3SourceContextId))))); + + updater.update({.projectDirectory = {"/root"}}); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_notfies_error_if_qmltypes_does_not_exists) @@ -2948,8 +3066,8 @@ TEST_F(ProjectStorageUpdater, watcher_updates_subdirectories) SourceId rootQmldirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); setFilesChanged({directoryPathSourceId, rootPathSourceId}); setFilesUnchanged({qmlDirPathSourceId, rootQmldirPathSourceId}); - setSubdirectoryPaths(u"/root", {"/path"}); - setSubdirectorySourceIds(rootPathId, {directoryPathId}); + setFileSystemSubdirectories(u"/root", {"/path"}); + setStorageSubdirectories(rootPathId, {directoryPathId}); EXPECT_CALL( projectStorageMock, @@ -4771,7 +4889,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_directory) TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_directory) { - setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); + setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); setFilesUnchanged({path1SourceId}); @@ -4805,7 +4923,7 @@ TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_direct TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_directory) { - setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); + setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); setFilesUnchanged({path1SourceId}); @@ -4839,7 +4957,7 @@ TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_dire TEST_F(ProjectStorageUpdater, dont_synchronize_empty_property_editor_qml_paths_directory) { - setSubdirectoryPaths(u"/path/two", {}); + setFileSystemSubdirectories(u"/path/two", {}); SourceContextId designer2DirectoryId = sourcePathCache.sourceContextId("/path/two/designer"); SourceId designer2SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer2DirectoryId); setFilesChanged({path2SourceId}); @@ -4904,7 +5022,7 @@ TEST_F(ProjectStorageUpdater, remove_property_editor_qml_paths_if_designer_direc TEST_F(ProjectStorageUpdater, synchronize_property_editor_qml_paths_directory_if_designer_directory_is_changed) { - setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); + setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); QString qmldir{R"(module Bar)"}; setContent(u"/path/one/qmldir", qmldir); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); @@ -4948,7 +5066,7 @@ TEST_F(ProjectStorageUpdater, TEST_F(ProjectStorageUpdater, synchronize_property_editor_qml_paths_directory_if_qml_directory_is_changed) { - setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); + setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); QString qmldir{R"(module Bar)"}; setContent(u"/path/one/qmldir", qmldir); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); @@ -4991,7 +5109,7 @@ TEST_F(ProjectStorageUpdater, TEST_F(ProjectStorageUpdater, synchronize_property_editor_qml_paths_directory_if_qmldir_is_changed) { - setSubdirectoryPaths(u"/path/one", {"/path/one/designer"}); + setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); QString qmldir{R"(module Bar)"}; setContent(u"/path/one/qmldir", qmldir); SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); From bb7da1720e053b7fcf6683c4662bed326ae61cc5 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 28 Mar 2025 17:28:46 +0100 Subject: [PATCH 21/82] UnitTests: Refactor qml types test Using paraemterized test to make the test smaller but at the same time check more parameter. Change-Id: I6294dfb2483943de52a31e5939cff993f97d40ae Reviewed-by: Thomas Hartmann --- .../projectstorage/projectstorageupdater.cpp | 19 +- .../unit/tests/printers/gtest-qt-printing.cpp | 8 + tests/unit/tests/printers/gtest-qt-printing.h | 1 + .../projectstorageupdater-test.cpp | 411 +++++++++++++----- .../tests/utils/google-using-declarations.h | 1 + 5 files changed, 321 insertions(+), 119 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index b9778f07636..a6fc2320ee3 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -484,7 +484,7 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct qmldirState, qmldirSourceId, isInsideProject); - tracer.tick("append updated project source id", keyValue("module id", moduleId)); + tracer.tick("append updated directory source id", keyValue("module id", moduleId)); package.updatedDirectoryInfoDirectoryIds.push_back(directoryId); if (isInsideProject == IsInsideProject::Yes) { @@ -1168,13 +1168,21 @@ void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos, tracer.tick("append module dependenct source source id", keyValue("source id", sourceId)); package.updatedModuleDependencySourceIds.push_back(sourceId); - const auto &directoryInfo = package.directoryInfos.emplace_back( - directoryId, sourceId, moduleId, Storage::Synchronization::FileType::QmlTypes); - tracer.tick("append project data", keyValue("source id", sourceId)); + const Storage::Synchronization::DirectoryInfo directoryInfo{ + directoryId, sourceId, moduleId, Storage::Synchronization::FileType::QmlTypes}; const QString qmltypesPath = directoryPath + "/" + typeInfo; - parseTypeInfo(directoryInfo, qmltypesPath, package, notUpdatedSourceIds, isInsideProject); + auto state = parseTypeInfo(directoryInfo, + qmltypesPath, + package, + notUpdatedSourceIds, + isInsideProject); + + if (isExisting(state)) { + package.directoryInfos.push_back(directoryInfo); + tracer.tick("append directory info", keyValue("source id", directoryInfo.sourceId)); + } } } @@ -1225,6 +1233,7 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Direct const auto content = m_fileSystem.contentAsQString(qmltypesPath); m_qmlTypesParser.parse(content, package.imports, package.types, directoryInfo, isInsideProject); + break; } case FileState::Unchanged: { diff --git a/tests/unit/tests/printers/gtest-qt-printing.cpp b/tests/unit/tests/printers/gtest-qt-printing.cpp index 9b0e166be5f..d9c3d4d4ad3 100644 --- a/tests/unit/tests/printers/gtest-qt-printing.cpp +++ b/tests/unit/tests/printers/gtest-qt-printing.cpp @@ -91,6 +91,14 @@ std::ostream &operator<<(std::ostream &out, const QIcon &icon) out << icon.cacheKey() << ")"; } +std::ostream &operator<<(std::ostream &out, const QStringList &list) +{ + if (list.isEmpty()) + return out << "[]"; + + return out << "[" << list.join("\", \"") << "]"; +} + void PrintTo(QStringView text, std::ostream *os) { *os << text; diff --git a/tests/unit/tests/printers/gtest-qt-printing.h b/tests/unit/tests/printers/gtest-qt-printing.h index 2711f633198..27b2e8fa6a4 100644 --- a/tests/unit/tests/printers/gtest-qt-printing.h +++ b/tests/unit/tests/printers/gtest-qt-printing.h @@ -43,6 +43,7 @@ std::ostream &operator<<(std::ostream &out, QByteArrayView byteArray); std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format); std::ostream &operator<<(std::ostream &out, const QImage &image); std::ostream &operator<<(std::ostream &out, const QIcon &icon); +std::ostream &operator<<(std::ostream &out, const QStringList &list); void PrintTo(const QString &text, std::ostream *os); void PrintTo(QStringView text, std::ostream *os); diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index 4ef25c57438..100991573cc 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -19,6 +19,43 @@ #include #include +namespace QmlDesigner { + +static std::string toString(ProjectStorageUpdater::FileState state) +{ + using FileState = ProjectStorageUpdater::FileState; + switch (state) { + case FileState::Added: + return "added"; + case FileState::Changed: + return "changed"; + case FileState::Removed: + return "removed"; + case FileState::NotExists: + return "not_exists"; + case FileState::NotExistsUnchanged: + return "not_exists_unchanged"; + case FileState::Unchanged: + return "unchanged"; + } + + return ""; +} + +[[maybe_unused]] static std::ostream &operator<<(std::ostream &out, + ProjectStorageUpdater::FileState state) +{ + return out << toString(state); +} + +[[maybe_unused]] static std::ostream &operator<<(std::ostream &out, + ProjectStorageUpdater::Update update) +{ + return out << "(" << update.projectDirectory << "," << update.qtDirectories << "," + << update.propertyEditorResourcesPath << "," << update.typeAnnotationPaths << ")"; +} +} // namespace QmlDesigner + namespace { using namespace Qt::StringLiterals; @@ -50,6 +87,8 @@ using Storage::Synchronization::Type; using Storage::TypeTraits; using Storage::TypeTraitsKind; using Storage::Version; +using FileState = QmlDesigner::ProjectStorageUpdater::FileState; +using Update = QmlDesigner::ProjectStorageUpdater::Update; MATCHER_P5(IsStorageType, typeName, @@ -240,6 +279,29 @@ public: } } + void setFiles(FileState state, const QmlDesigner::SourceIds &sourceIds) + { + switch (state) { + case FileState::Unchanged: + setFilesUnchanged(sourceIds); + break; + case FileState::Changed: + setFilesChanged(sourceIds); + break; + case FileState::Added: + setFilesAdded(sourceIds); + break; + case FileState::Removed: + setFilesRemoved(sourceIds); + break; + case FileState::NotExists: + setFilesNotExists(sourceIds); + break; + case FileState::NotExistsUnchanged: + setFilesNotExistsUnchanged(sourceIds); + } + } + void setFileNames(QStringView directoryPath, const QStringList &fileNames, const QStringList &nameFilters) @@ -805,49 +867,6 @@ TEST_F(ProjectStorageUpdater_synchronize_empty, not_for_added_ignored_subdirecto updater.update({.projectDirectory = "/root"}); } -TEST_F(ProjectStorageUpdater, synchronize_qml_types) -{ - Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; - QString qmltypes{"Module {\ndependencies: []}"}; - setQmlFileNames(u"/path", {}); - setContent(u"/path/example.qmltypes", qmltypes); - ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, _)) - .WillByDefault([&](auto, auto &imports, auto &types, auto, auto) { - types.push_back(objectType); - imports.push_back(import); - }); - - EXPECT_CALL(projectStorageMock, moduleId(Eq("Example"), ModuleKind::QmlLibrary)); - EXPECT_CALL(projectStorageMock, moduleId(Eq("Example"), ModuleKind::CppLibrary)); - EXPECT_CALL(projectStorageMock, moduleId(Eq("/path"), ModuleKind::PathLibrary)); - EXPECT_CALL(projectStorageMock, - synchronize( - AllOf(Field("SynchronizationPackage::imports", - &SynchronizationPackage::imports, - ElementsAre(import)), - Field("SynchronizationPackage::types", - &SynchronizationPackage::types, - ElementsAre(Eq(objectType))), - Field("SynchronizationPackage::updatedSourceIds", - &SynchronizationPackage::updatedSourceIds, - UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId)), - Field("SynchronizationPackage::fileStatuses", - &SynchronizationPackage::fileStatuses, - UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21), - IsFileStatus(qmltypesPathSourceId, 1, 21))), - Field("SynchronizationPackage::directoryInfos", - &SynchronizationPackage::directoryInfos, - UnorderedElementsAre(IsDirectoryInfo(directoryPathId, - qmltypesPathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes))), - Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", - &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(directoryPathId))))); - - updater.update({.qtDirectories = directories}); -} - class ProjectStorageUpdater_synchronize_subdirectories : public BaseProjectStorageUpdater { public: @@ -1052,34 +1071,254 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_project_sub updater.update({.projectDirectory = {"/root"}}); } -TEST_F(ProjectStorageUpdater, synchronize_qml_types_notfies_error_if_qmltypes_does_not_exists) +class synchronize_qml_types : public BaseProjectStorageUpdater { +public: + synchronize_qml_types() + + { + setQmlFileNames(u"/path", {}); + + QString qmltypes{"Module {\ndependencies: []}"}; + setContent(u"/path/example.qmltypes", qmltypes); + setContent(u"/path/qmldir", "module Example\ntypeinfo example.qmltypes\n"); + ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, _)) + .WillByDefault([&](auto, auto &imports, auto &types, auto, auto) { + types.push_back(objectType); + imports.push_back(import); + }); + setFilesNotExistsUnchanged({annotationDirectorySourceId}); + } + +public: + SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); + SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); + SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + SourceId annotationDirectorySourceId = createDirectorySourceId("/path/designer"); + ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; + ModuleId exampleModuleId{storage.moduleId("Example", ModuleKind::QmlLibrary)}; + ModuleId exampleCppNativeModuleId{storage.moduleId("Example", ModuleKind::CppLibrary)}; Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; - setFilesNotExists({qmltypesPathSourceId}); + Type objectType{"QObject", + ImportedType{}, + ImportedType{}, + Storage::TypeTraitsKind::Reference, + qmltypesPathSourceId, + {ExportedType{exampleModuleId, "Object"}, ExportedType{exampleModuleId, "Obj"}}}; +}; + +using ChangeQmlTypesParameters = std::tuple; + +class synchronize_changed_qml_types : public synchronize_qml_types, + public testing::WithParamInterface +{ +public: + synchronize_changed_qml_types() + : state{std::get<1>(GetParam())} + , directoryState{std::get<2>(GetParam())} + , qmldirState{std::get<3>(GetParam())} + , update{std::get<0>(GetParam())} + + { + if (qmldirState == FileState::Unchanged) { + setDirectoryInfos( + directoryPathId, + {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}}); + } + + if (state == FileState::Added) + directoryState = FileState::Changed; + } + +public: + FileState state; + FileState directoryState; + FileState qmldirState; + const Update &update; +}; + +auto updateStatesName = [](const testing::TestParamInfo &info) { + std::string name = toString(std::get<1>(info.param)); + + name += "_qmltypes_file_in_"; + + if (std::get<0>(info.param).projectDirectory.isEmpty()) + name += "qt_"; + else + name += "project_"; + + name += toString(std::get<2>(info.param)); + + name += "_directory_"; + + name += toString(std::get<3>(info.param)); + + name += "_qmldir"; + + return name; +}; + +INSTANTIATE_TEST_SUITE_P(ProjectStorageUpdater, + synchronize_changed_qml_types, + testing::Combine(testing::Values(Update{.qtDirectories = {"/path"}}, + Update{.projectDirectory = "/path"}), + testing::Values(FileState::Added, FileState::Changed), + testing::Values(FileState::Changed, FileState::Unchanged), + testing::Values(FileState::Changed, FileState::Unchanged)), + updateStatesName); + +TEST_P(synchronize_changed_qml_types, from_qt_directory_update_types) +{ + setFiles(directoryState, {directoryPathSourceId}); + setFiles(qmldirState, {qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field("SynchronizationPackage::imports", + &SynchronizationPackage::imports, + ElementsAre(import)), + Field("SynchronizationPackage::types", + &SynchronizationPackage::types, + ElementsAre(Eq(objectType))), + Field("SynchronizationPackage::updatedSourceIds", + &SynchronizationPackage::updatedSourceIds, + Contains(qmltypesPathSourceId))))); + + updater.update(update); +} + +TEST_P(synchronize_changed_qml_types, from_qt_directory_update_file_status) +{ + setFiles(directoryState, {directoryPathSourceId}); + setFiles(qmldirState, {qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field("SynchronizationPackage::fileStatuses", + &SynchronizationPackage::fileStatuses, + Contains(IsFileStatus(qmltypesPathSourceId, 1, 21))), + Field("SynchronizationPackage::updatedFileStatusSourceIds", + &SynchronizationPackage::updatedFileStatusSourceIds, + Contains(qmltypesPathSourceId))))); + + updater.update(update); +} + +TEST_P(synchronize_changed_qml_types, from_qt_directory_update_directory_infos) +{ + bool directoryUnchanged = directoryState == FileState::Unchanged + && qmldirState == FileState::Unchanged; + setFiles(directoryState, {directoryPathSourceId}); + setFiles(qmldirState, {qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize( + AllOf(Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + Conditional(directoryUnchanged, + IsEmpty(), + Contains(IsDirectoryInfo(directoryPathId, + qmltypesPathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes)))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + Conditional(directoryUnchanged, IsEmpty(), Contains(directoryPathId)))))); + + updater.update(update); +} + +using NonExistingQmlTypesParameters = std::tuple; + +class synchronize_non_existing_qml_types + : public synchronize_qml_types, + public testing::WithParamInterface +{ +public: + synchronize_non_existing_qml_types() + : state{std::get<1>(GetParam())} + , update{std::get<0>(GetParam())} + + { + setDirectoryInfos(directoryPathId, + {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}}); + } + +public: + FileState state; + const Update &update; +}; + +auto updateStateName = [](const testing::TestParamInfo &info) { + std::string name = toString(std::get<1>(info.param)); + + if (std::get<0>(info.param).projectDirectory.isEmpty()) + name += "_qt"; + else + name += "_project"; + + return name; +}; + +INSTANTIATE_TEST_SUITE_P(ProjectStorageUpdater, + synchronize_non_existing_qml_types, + testing::Combine(testing::Values(Update{.qtDirectories = {"/path"}}, + Update{.projectDirectory = "/path"}), + testing::Values(FileState::Removed, FileState::NotExists)), + updateStateName); + +TEST_P(synchronize_non_existing_qml_types, notfies_error) +{ + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); EXPECT_CALL(errorNotifierMock, qmltypesFileMissing(Eq("/path/example.qmltypes"_L1))); - updater.update({.qtDirectories = directories}); + updater.update(update); } -TEST_F(ProjectStorageUpdater, - synchronize_qml_types_adds_updated_source_id_and_directory_info_for_missing_qmltypes_file) +TEST_P(synchronize_non_existing_qml_types, notfies_error_if_direcory_and_qmldir_file_is_changed) { - Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; - setFilesNotExists({qmltypesPathSourceId}); + setFilesChanged({directoryPathSourceId, qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); + + EXPECT_CALL(errorNotifierMock, qmltypesFileMissing(Eq("/path/example.qmltypes"_L1))); + + updater.update(update); +} + +TEST_P(synchronize_non_existing_qml_types, updates_source_ids) +{ + setFilesUnchanged({directoryPathSourceId, qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field("SynchronizationPackage::updatedSourceIds", &SynchronizationPackage::updatedSourceIds, - Contains(qmltypesPathSourceId)), - Field("SynchronizationPackage::directoryInfos", - &SynchronizationPackage::directoryInfos, - Contains(IsDirectoryInfo(directoryPathId, - qmltypesPathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes)))))); + Contains(qmltypesPathSourceId))))); - updater.update({.qtDirectories = directories}); + updater.update(update); +} + +TEST_P(synchronize_non_existing_qml_types, updates_directory_info) +{ + setFilesChanged({directoryPathSourceId, qmlDirPathSourceId}); + setFiles(state, {qmltypesPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", + &SynchronizationPackage::directoryInfos, + Not(Contains(IsDirectoryInfo(directoryPathId, + qmltypesPathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes)))), + Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", + &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, + Contains(directoryPathId))))); + + updater.update(update); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_changed) @@ -1830,62 +2069,6 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_dat updater.update({.qtDirectories = directories}); } -TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed) -{ - setDirectoryInfos(directoryPathId, - {{directoryPathId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, - {directoryPathId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, - {directoryPathId, qmlDocumentSourceId1, exampleModuleId, FileType::QmlDocument}, - {directoryPathId, qmlDocumentSourceId2, exampleModuleId, FileType::QmlDocument}}); - setFilesUnchanged({qmlDirPathSourceId}); - - EXPECT_CALL(projectStorageMock, - synchronize(AllOf( - Field("SynchronizationPackage::imports", - &SynchronizationPackage::imports, - UnorderedElementsAre(import1, import2, import4, import5)), - Field("SynchronizationPackage::types", - &SynchronizationPackage::types, - UnorderedElementsAre( - Eq(objectType), - Eq(itemType), - AllOf(IsStorageType("First.qml", - ImportedType{"Object"}, - TypeTraitsKind::Reference, - qmlDocumentSourceId1, - ChangeLevel::ExcludeExportedTypes), - Field("Type::exportedTypes", &Type::exportedTypes, IsEmpty())), - AllOf(IsStorageType("First2.qml", - ImportedType{"Object2"}, - TypeTraitsKind::Reference, - qmlDocumentSourceId2, - ChangeLevel::ExcludeExportedTypes), - Field("Type::exportedTypes", &Type::exportedTypes, IsEmpty())))), - Field("SynchronizationPackage::updatedSourceIds", - &SynchronizationPackage::updatedSourceIds, - UnorderedElementsAre(qmltypesPathSourceId, - qmltypes2PathSourceId, - qmlDocumentSourceId1, - qmlDocumentSourceId2)), - Field("SynchronizationPackage::fileStatuses", - &SynchronizationPackage::fileStatuses, - UnorderedElementsAre(IsFileStatus(qmltypesPathSourceId, 1, 21), - IsFileStatus(qmltypes2PathSourceId, 1, 21), - IsFileStatus(qmlDocumentSourceId1, 1, 21), - IsFileStatus(qmlDocumentSourceId2, 1, 21))), - Field("SynchronizationPackage::updatedFileStatusSourceIds", - &SynchronizationPackage::updatedFileStatusSourceIds, - UnorderedElementsAre(qmltypesPathSourceId, - qmltypes2PathSourceId, - qmlDocumentSourceId1, - qmlDocumentSourceId2)), - Field("SynchronizationPackage::directoryInfos", - &SynchronizationPackage::directoryInfos, - IsEmpty())))); - - updater.update({.qtDirectories = directories}); -} - TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed_and_some_updated_files) { setDirectoryInfos(directoryPathId, diff --git a/tests/unit/tests/utils/google-using-declarations.h b/tests/unit/tests/utils/google-using-declarations.h index 213608916fb..8dd8e790b5c 100644 --- a/tests/unit/tests/utils/google-using-declarations.h +++ b/tests/unit/tests/utils/google-using-declarations.h @@ -17,6 +17,7 @@ using testing::AtMost; using testing::Between; using testing::ByMove; using testing::ByRef; +using testing::Conditional; using testing::ContainerEq; using testing::Contains; using testing::Each; From 260d602d77958c804733caf60369cf5e52888084 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 3 Apr 2025 22:42:52 +0200 Subject: [PATCH 22/82] QmlDesigner: Fix <=> Change-Id: Iafbb85f80cc3cd023487359bb56c9f3738d3358c Reviewed-by: Thomas Hartmann --- .../qmldesigner/libs/designercore/include/import.h | 2 +- .../qmldesigner/libs/designercore/include/modelnode.h | 2 +- .../libs/designercore/projectstorage/filestatus.h | 2 +- .../libs/designercore/projectstorage/projectstorage.h | 9 +++++---- .../projectstorage/projectstoragepathwatchertypes.h | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/import.h b/src/plugins/qmldesigner/libs/designercore/include/import.h index ca9bd010192..ae415e51923 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/import.h +++ b/src/plugins/qmldesigner/libs/designercore/include/import.h @@ -59,7 +59,7 @@ public: || second.m_version.isEmpty()); } - friend auto operator<=>(const Import &first, const Import &second) + friend std::weak_ordering operator<=>(const Import &first, const Import &second) { return std::tie(first.m_url, first.m_type) <=> std::tie(second.m_url, second.m_type); } diff --git a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h index 91f05a4d5ca..e9e060117ea 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h @@ -263,7 +263,7 @@ public: return firstNode.m_internalNode == secondNode.m_internalNode; } - friend auto operator<=>(const ModelNode &firstNode, const ModelNode &secondNode) + friend std::weak_ordering operator<=>(const ModelNode &firstNode, const ModelNode &secondNode) { return firstNode.m_internalNode <=> secondNode.m_internalNode; } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h index f02299fc8ac..1a29f957f6a 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h @@ -25,7 +25,7 @@ public: && first.lastModified == second.lastModified; } - friend auto operator<=>(const FileStatus &first, const FileStatus &second) + friend std::weak_ordering operator<=>(const FileStatus &first, const FileStatus &second) { return first.sourceId <=> second.sourceId; } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index 7751338403e..a6206e111c2 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -364,8 +364,8 @@ private: , sourceId{sourceId} {} - friend auto operator<=>(const AliasPropertyDeclaration &first, - const AliasPropertyDeclaration &second) + friend std::weak_ordering operator<=>(const AliasPropertyDeclaration &first, + const AliasPropertyDeclaration &second) { return std::tie(first.typeId, first.propertyDeclarationId) <=> std::tie(second.typeId, second.propertyDeclarationId); @@ -434,7 +434,8 @@ private: == std::tie(second.typeId, second.propertyDeclarationId); } - friend auto operator<=>(const PropertyDeclaration &first, const PropertyDeclaration &second) + friend std::weak_ordering operator<=>(const PropertyDeclaration &first, + const PropertyDeclaration &second) { return std::tie(first.typeId, first.propertyDeclarationId) <=> std::tie(second.typeId, second.propertyDeclarationId); @@ -470,7 +471,7 @@ private: , prototypeNameId{std::move(prototypeNameId)} {} - friend auto operator<=>(Prototype first, Prototype second) + friend std::weak_ordering operator<=>(Prototype first, Prototype second) { return first.typeId <=> second.typeId; } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h index 3490fdd391d..e7870e6bfda 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h @@ -111,7 +111,7 @@ public: && first.sourceId == second.sourceId; } - friend auto operator<=>(const WatcherEntry &first, const WatcherEntry &second) + friend std::weak_ordering operator<=>(const WatcherEntry &first, const WatcherEntry &second) { return std::tie(first.sourceContextId, first.sourceId, first.id) <=> std::tie(second.sourceContextId, second.sourceId, second.id); From 91aea4c74eafd2ea670bc436a1de0de985c254fc Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 8 Apr 2025 11:26:39 +0200 Subject: [PATCH 23/82] QmlDesigner: Rename SourceName and SourceContext into FileName and DirectoryPath Change-Id: I7851b7f065498e4d21f2ea3c68fe46c135949291 Reviewed-by: Thomas Hartmann --- .../designercore/include/projectstorageids.h | 4 +- .../libs/designercore/include/sourcepathids.h | 18 +- .../projectstorage/directorypathcompressor.h | 18 +- .../projectstorage/filesystem.cpp | 2 +- .../projectstorage/projectstorage.cpp | 24 +- .../projectstorage/projectstorage.h | 22 +- .../projectstorage/projectstorageinterface.h | 10 +- .../projectstoragepathwatcher.h | 62 ++--- .../projectstoragepathwatcherinterface.h | 2 +- .../projectstoragepathwatchertypes.h | 10 +- .../projectstoragetriggerupdateinterface.h | 2 +- .../projectstorage/projectstoragetypes.h | 20 +- .../projectstorage/projectstorageupdater.cpp | 110 ++++---- .../projectstorage/projectstorageupdater.h | 36 +-- .../projectstorage/typeannotationreader.cpp | 2 +- .../projectstorage/typeannotationreader.h | 4 +- .../sourcepathstorage/sourcepathcache.h | 118 ++++---- .../sourcepathcacheinterface.h | 12 +- .../sourcepathstorage/sourcepathcachetypes.h | 18 +- .../sourcepathexceptions.cpp | 24 +- .../sourcepathstorage/sourcepathexceptions.h | 16 +- .../sourcepathstorage/sourcepathstorage.cpp | 188 ++++++------- .../sourcepathstorage/sourcepathstorage.h | 24 +- .../project/qmldesignerprojectmanager.cpp | 4 +- .../tests/matchers/projectstorage-matcher.h | 2 +- tests/unit/tests/mocks/projectstoragemock.h | 42 +-- .../mocks/projectstoragepathwatchermock.h | 2 +- .../mocks/projectstoragetriggerupdatemock.h | 2 +- tests/unit/tests/mocks/sourcepathcachemock.h | 20 +- .../tests/mocks/sqlitereadstatementmock.h | 28 +- .../tests/printers/gtest-creator-printing.cpp | 6 +- .../tests/printers/gtest-creator-printing.h | 8 +- .../directorypathcompressor-test.cpp | 40 +-- .../projectstorage/projectstorage-test.cpp | 176 ++++++------ .../projectstoragepathwatcher-test.cpp | 86 +++--- .../projectstorageupdater-test.cpp | 254 +++++++++--------- .../projectstorage/qmldocumentparser-test.cpp | 6 +- .../projectstorage/qmltypesparser-test.cpp | 4 +- .../typeannotationreader-test.cpp | 2 +- .../sourcepathcache-test.cpp | 251 ++++++++--------- .../sourcepathstorage-test.cpp | 120 ++++----- .../sourcepathstorage/storagecache-test.cpp | 108 ++++---- 42 files changed, 953 insertions(+), 954 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h index a5f8ad35a9d..1b875cefbbb 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h +++ b/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h @@ -11,8 +11,8 @@ enum class ProjectStorageIdType { Type, PropertyType, PropertyDeclaration, - SourceName, - SourceContext, + FileName, + DirectoryPath, StorageCacheIndex, FunctionDeclaration, SignalDeclaration, diff --git a/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h b/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h index 7bac16dcd50..3857ef01410 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h +++ b/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h @@ -12,22 +12,22 @@ namespace QmlDesigner { enum class SourcePathIdType { - SourceName, - SourceContext, + FileName, + DirectoryPath, }; -using SourceContextId = Sqlite::BasicId; -using SourceContextIds = std::vector; +using DirectoryPathId = Sqlite::BasicId; +using DirectoryPathIds = std::vector; template -using SmallSourceContextIds = QVarLengthArray; +using SmallDirectoryPathIds = QVarLengthArray; -using SourceNameId = Sqlite::BasicId; -using SourceNameIds = std::vector; +using FileNameId = Sqlite::BasicId; +using FileNameIds = std::vector; template -using SmallSourceNameIds = QVarLengthArray; +using SmallFileNameIds = QVarLengthArray; -using SourceId = Sqlite::CompoundBasicId; +using SourceId = Sqlite::CompoundBasicId; using SourceIds = std::vector; template using SmallSourceIds = QVarLengthArray; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h index 0cdf52d1b4e..f4b581caa76 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h @@ -22,26 +22,26 @@ public: ~DirectoryPathCompressor() = default; - void addSourceContextId(SourceContextId sourceContextId) + void addDirectoryPathId(DirectoryPathId directoryPathId) { - auto found = std::ranges::lower_bound(m_sourceContextIds, sourceContextId); + auto found = std::ranges::lower_bound(m_directoryPathIds, directoryPathId); - if (found == m_sourceContextIds.end() || *found != sourceContextId) - m_sourceContextIds.insert(found, sourceContextId); + if (found == m_directoryPathIds.end() || *found != directoryPathId) + m_directoryPathIds.insert(found, directoryPathId); restartTimer(); } - const SourceContextIds &sourceContextIds() { return m_sourceContextIds; } + const DirectoryPathIds &directoryPathIds() { return m_directoryPathIds; } - virtual void setCallback(std::function &&callback) + virtual void setCallback(std::function &&callback) { if (connection) QObject::disconnect(connection); connection = QObject::connect(&m_timer, &Timer::timeout, [this, callback = std::move(callback)] { try { - callback(m_sourceContextIds); - m_sourceContextIds.clear(); + callback(m_directoryPathIds); + m_directoryPathIds.clear(); } catch (const std::exception &) { } }); @@ -70,7 +70,7 @@ private: }; private: - SourceContextIds m_sourceContextIds; + DirectoryPathIds m_directoryPathIds; QMetaObject::Connection connection; ConnectionGuard connectionGuard{connection}; Timer m_timer; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp index a06c2d527ff..67124c4387a 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp @@ -51,7 +51,7 @@ long long FileSystem::lastModified(SourceId sourceId) const FileStatus FileSystem::fileStatus(SourceId sourceId) const { auto path = sourceId.mainId() ? m_sourcePathCache.sourcePath(sourceId) - : m_sourcePathCache.sourceContextPath(sourceId.contextId()); + : m_sourcePathCache.directoryPath(sourceId.contextId()); QFileInfo fileInfo(QString{path}); fileInfo.refresh(); diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp index d5395905d85..79f0a103016 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp @@ -1762,7 +1762,7 @@ Storage::Info::TypeHints ProjectStorage::typeHints(TypeId typeId) const return typeHints; } -SmallSourceIds<4> ProjectStorage::typeAnnotationSourceIds(SourceContextId directoryId) const +SmallSourceIds<4> ProjectStorage::typeAnnotationSourceIds(DirectoryPathId directoryId) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get type annotaion source ids", @@ -1777,13 +1777,13 @@ SmallSourceIds<4> ProjectStorage::typeAnnotationSourceIds(SourceContextId direct return sourceIds; } -SmallSourceContextIds<64> ProjectStorage::typeAnnotationDirectoryIds() const +SmallDirectoryPathIds<64> ProjectStorage::typeAnnotationDirectoryIds() const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get type annotaion source ids", projectStorageCategory()}; auto sourceIds = s->selectTypeAnnotationDirectoryIdsStatement - .valuesWithTransaction>(); + .valuesWithTransaction>(); tracer.end(keyValue("source ids", sourceIds)); @@ -2226,7 +2226,7 @@ std::optional ProjectStorage::fetchDire return directoryInfo; } -Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(SourceContextId directoryId) const +Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(DirectoryPathId directoryId) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch directory infos by directory id", @@ -2243,7 +2243,7 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(Sou } Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos( - SourceContextId directoryId, Storage::Synchronization::FileType fileType) const + DirectoryPathId directoryId, Storage::Synchronization::FileType fileType) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch directory infos by source id and file type", @@ -2261,7 +2261,7 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos( } Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos( - const SourceContextIds &directoryIds) const + const DirectoryPathIds &directoryIds) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch directory infos by source ids", @@ -2277,7 +2277,7 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos( return directoryInfos; } -SmallSourceContextIds<32> ProjectStorage::fetchSubdirectoryIds(SourceContextId directoryId) const +SmallDirectoryPathIds<32> ProjectStorage::fetchSubdirectoryIds(DirectoryPathId directoryId) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch subdirectory source ids", @@ -2288,7 +2288,7 @@ SmallSourceContextIds<32> ProjectStorage::fetchSubdirectoryIds(SourceContextId d .rangeWithTransaction(directoryId, Storage::Synchronization::FileType::Directory); - SmallSourceContextIds<32> directoryIds; + SmallDirectoryPathIds<32> directoryIds; for (SourceId sourceId : sourceIds) directoryIds.push_back(sourceId.contextId()); @@ -2609,7 +2609,7 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types, } void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::DirectoryInfos &directoryInfos, - const SourceContextIds &updatedDirectoryInfoDirectoryIds) + const DirectoryPathIds &updatedDirectoryInfoDirectoryIds) { NanotraceHR::Tracer tracer{"synchronize directory infos", projectStorageCategory()}; @@ -4057,13 +4057,13 @@ void ProjectStorage::addTypeIdToPropertyEditorQmlPaths( void ProjectStorage::synchronizePropertyEditorPaths( Storage::Synchronization::PropertyEditorQmlPaths &paths, - SourceContextIds updatedPropertyEditorQmlPathsSourceContextIds) + DirectoryPathIds updatedPropertyEditorQmlPathsDirectoryPathIds) { using Storage::Synchronization::PropertyEditorQmlPath; std::ranges::sort(paths, {}, &PropertyEditorQmlPath::typeId); auto range = s->selectPropertyEditorPathsForForSourceIdsStatement.range( - toIntegers(updatedPropertyEditorQmlPathsSourceContextIds)); + toIntegers(updatedPropertyEditorQmlPathsDirectoryPathIds)); auto compareKey = [](const PropertyEditorQmlPathView &view, const PropertyEditorQmlPath &value) { return view.typeId <=> value.typeId; @@ -4110,7 +4110,7 @@ void ProjectStorage::synchronizePropertyEditorPaths( void ProjectStorage::synchronizePropertyEditorQmlPaths( Storage::Synchronization::PropertyEditorQmlPaths &paths, - SourceContextIds updatedPropertyEditorQmlPathsSourceIds) + DirectoryPathIds updatedPropertyEditorQmlPathsSourceIds) { NanotraceHR::Tracer tracer{"synchronize property editor qml paths", projectStorageCategory()}; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index a6206e111c2..441dc72c705 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -105,9 +105,9 @@ public: Storage::Info::TypeHints typeHints(TypeId typeId) const override; - SmallSourceIds<4> typeAnnotationSourceIds(SourceContextId directoryId) const override; + SmallSourceIds<4> typeAnnotationSourceIds(DirectoryPathId directoryId) const override; - SmallSourceContextIds<64> typeAnnotationDirectoryIds() const override; + SmallDirectoryPathIds<64> typeAnnotationDirectoryIds() const override; Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const override; Storage::Info::ItemLibraryEntries itemLibraryEntries(ImportId importId) const; @@ -220,11 +220,11 @@ public: std::optional fetchDirectoryInfo(SourceId sourceId) const override; - Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(SourceContextId directoryId) const override; + Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(DirectoryPathId directoryId) const override; Storage::Synchronization::DirectoryInfos fetchDirectoryInfos( - SourceContextId directoryId, Storage::Synchronization::FileType fileType) const override; - Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(const SourceContextIds &directoryIds) const; - SmallSourceContextIds<32> fetchSubdirectoryIds(SourceContextId directoryId) const override; + DirectoryPathId directoryId, Storage::Synchronization::FileType fileType) const override; + Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(const DirectoryPathIds &directoryIds) const; + SmallDirectoryPathIds<32> fetchSubdirectoryIds(DirectoryPathId directoryId) const override; void setPropertyEditorPathId(TypeId typeId, SourceId pathId); @@ -574,7 +574,7 @@ private: const SourceIds &updatedSourceIds); void synchronizeDirectoryInfos(Storage::Synchronization::DirectoryInfos &directoryInfos, - const SourceContextIds &updatedDirectoryInfoDirectoryIds); + const DirectoryPathIds &updatedDirectoryInfoDirectoryIds); void synchronizeFileStatuses(FileStatuses &fileStatuses, const SourceIds &updatedSourceIds); @@ -789,7 +789,7 @@ private: class PropertyEditorQmlPathView { public: - PropertyEditorQmlPathView(TypeId typeId, SourceId pathId, SourceContextId directoryId) + PropertyEditorQmlPathView(TypeId typeId, SourceId pathId, DirectoryPathId directoryId) : typeId{typeId} , pathId{pathId} , directoryId{directoryId} @@ -811,14 +811,14 @@ private: public: TypeId typeId; SourceId pathId; - SourceContextId directoryId; + DirectoryPathId directoryId; }; void synchronizePropertyEditorPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths, - SourceContextIds updatedPropertyEditorQmlPathsSourceContextIds); + DirectoryPathIds updatedPropertyEditorQmlPathsDirectoryPathIds); void synchronizePropertyEditorQmlPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths, - SourceContextIds updatedPropertyEditorQmlPathsSourceIds); + DirectoryPathIds updatedPropertyEditorQmlPathsSourceIds); void synchronizeFunctionDeclarations( TypeId typeId, Storage::Synchronization::FunctionDeclarations &functionsDeclarations); diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h index f2aa26f44b9..4591530e0c8 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h @@ -58,8 +58,8 @@ public: = 0; virtual PropertyDeclarationId defaultPropertyDeclarationId(TypeId typeId) const = 0; virtual std::optional type(TypeId typeId) const = 0; - virtual SmallSourceIds<4> typeAnnotationSourceIds(SourceContextId directoryId) const = 0; - virtual SmallSourceContextIds<64> typeAnnotationDirectoryIds() const = 0; + virtual SmallSourceIds<4> typeAnnotationSourceIds(DirectoryPathId directoryId) const = 0; + virtual SmallDirectoryPathIds<64> typeAnnotationDirectoryIds() 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; @@ -82,13 +82,13 @@ public: virtual bool isBasedOn(TypeId, TypeId, TypeId, TypeId, TypeId, TypeId, TypeId, TypeId) const = 0; virtual FileStatus fetchFileStatus(SourceId sourceId) const = 0; - virtual Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(SourceContextId directoryId) const = 0; + virtual Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(DirectoryPathId directoryId) const = 0; virtual Storage::Synchronization::DirectoryInfos fetchDirectoryInfos( - SourceContextId directoryId, Storage::Synchronization::FileType) const + DirectoryPathId directoryId, Storage::Synchronization::FileType) const = 0; virtual std::optional fetchDirectoryInfo(SourceId sourceId) const = 0; - virtual SmallSourceContextIds<32> fetchSubdirectoryIds(SourceContextId directoryId) const = 0; + virtual SmallDirectoryPathIds<32> fetchSubdirectoryIds(DirectoryPathId directoryId) const = 0; virtual SourceId propertyEditorPathId(TypeId typeId) const = 0; virtual const Storage::Info::CommonTypeCache &commonTypeCache() const = 0; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index b00b6f6e21d..674ff189f39 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -36,8 +36,8 @@ public: [&](const QString &path) { compressChangedDirectoryPath(path); }); m_directoryPathCompressor.setCallback( - [&](const QmlDesigner::SourceContextIds &sourceContextIds) { - addChangedPathForFilePath(sourceContextIds); + [&](const QmlDesigner::DirectoryPathIds &directoryPathIds) { + addChangedPathForFilePath(directoryPathIds); }); } @@ -54,7 +54,7 @@ public: } void updateContextIdPaths(const std::vector &idPaths, - const SourceContextIds &sourceContextIds) override + const DirectoryPathIds &directoryPathIds) override { const auto &[entires, ids] = convertIdPathsToWatcherEntriesAndIds(idPaths); @@ -62,19 +62,19 @@ public: auto notContainsId = [&, &ids = ids](WatcherEntry entry) { return !std::ranges::binary_search(ids, entry.id) - || !std::ranges::binary_search(sourceContextIds, entry.sourceContextId); + || !std::ranges::binary_search(directoryPathIds, entry.directoryPathId); }; removeUnusedEntries(entires, notContainsId); } - void checkForChangeInDirectory(SourceContextIds sourceContextIds) override + void checkForChangeInDirectory(DirectoryPathIds directoryPathIds) override { - std::ranges::sort(sourceContextIds); - auto removed = std::ranges::unique(sourceContextIds); - sourceContextIds.erase(removed.begin(), removed.end()); + std::ranges::sort(directoryPathIds); + auto removed = std::ranges::unique(directoryPathIds); + directoryPathIds.erase(removed.begin(), removed.end()); - addChangedPathForFilePath(sourceContextIds); + addChangedPathForFilePath(directoryPathIds); } void removeIds(const ProjectPartIds &ids) override @@ -158,23 +158,23 @@ public: FileSystemWatcher &fileSystemWatcher() { return m_fileSystemWatcher; } - QStringList convertWatcherEntriesToDirectoryPathList(const SourceContextIds &sourceContextIds) const + QStringList convertWatcherEntriesToDirectoryPathList(const DirectoryPathIds &directoryPathIds) const { - return Utils::transform(sourceContextIds, [&](SourceContextId id) { - return QString(m_pathCache.sourceContextPath(id)); + return Utils::transform(directoryPathIds, [&](DirectoryPathId id) { + return QString(m_pathCache.directoryPath(id)); }); } QStringList convertWatcherEntriesToDirectoryPathList(const WatcherEntries &watcherEntries) const { - SourceContextIds sourceContextIds = Utils::transform( - watcherEntries, &WatcherEntry::sourceContextId); + DirectoryPathIds directoryPathIds = Utils::transform( + watcherEntries, &WatcherEntry::directoryPathId); - std::ranges::sort(sourceContextIds); - auto removed = std::ranges::unique(sourceContextIds); - sourceContextIds.erase(removed.begin(), removed.end()); + std::ranges::sort(directoryPathIds); + auto removed = std::ranges::unique(directoryPathIds); + directoryPathIds.erase(removed.begin(), removed.end()); - return convertWatcherEntriesToDirectoryPathList(sourceContextIds); + return convertWatcherEntriesToDirectoryPathList(directoryPathIds); } WatcherEntries notWatchedEntries(const WatcherEntries &entries) const @@ -187,9 +187,9 @@ public: return notWatchedEntries; } - SourceContextIds notWatchedPaths(const SourceContextIds &ids) const + DirectoryPathIds notWatchedPaths(const DirectoryPathIds &ids) const { - SourceContextIds notWatchedDirectoryIds; + DirectoryPathIds notWatchedDirectoryIds; notWatchedDirectoryIds.reserve(ids.size()); std::ranges::set_difference(ids, m_watchedEntries, std::back_inserter(notWatchedDirectoryIds)); @@ -231,20 +231,20 @@ public: m_watchedEntries = std::move(newWatchedEntries); } - static SourceContextIds uniquePaths(const WatcherEntries &pathEntries) + static DirectoryPathIds uniquePaths(const WatcherEntries &pathEntries) { - SourceContextIds uniqueDirectoryIds; + DirectoryPathIds uniqueDirectoryIds; uniqueDirectoryIds.reserve(pathEntries.size()); std::ranges::unique_copy(pathEntries, std::back_inserter(uniqueDirectoryIds), {}, - &WatcherEntry::sourceContextId); + &WatcherEntry::directoryPathId); return uniqueDirectoryIds; } - SourceContextIds filterNotWatchedPaths(const WatcherEntries &entries) const + DirectoryPathIds filterNotWatchedPaths(const WatcherEntries &entries) const { return notWatchedPaths(uniquePaths(entries)); } @@ -278,18 +278,18 @@ public: void compressChangedDirectoryPath(const QString &path) { - m_directoryPathCompressor.addSourceContextId( - m_pathCache.sourceContextId(Utils::PathString{path})); + m_directoryPathCompressor.addDirectoryPathId( + m_pathCache.directoryPathId(Utils::PathString{path})); } - WatcherEntries watchedEntriesForPaths(const QmlDesigner::SourceContextIds &sourceContextIds) + WatcherEntries watchedEntriesForPaths(const QmlDesigner::DirectoryPathIds &directoryPathIds) { WatcherEntries foundEntries; foundEntries.reserve(m_watchedEntries.size()); Utils::set_greedy_intersection( m_watchedEntries, - sourceContextIds, + directoryPathIds, [&](WatcherEntry &entry) { m_fileStatusCache.update(entry.sourceId); auto fileStatus = m_fileStatusCache.find(entry.sourceId); @@ -300,7 +300,7 @@ public: } }, {}, - &WatcherEntry::sourceContextId); + &WatcherEntry::directoryPathId); return foundEntries; } @@ -339,10 +339,10 @@ public: return idPaths; } - void addChangedPathForFilePath(const SourceContextIds &sourceContextIds) + void addChangedPathForFilePath(const DirectoryPathIds &directoryPathIds) { if (m_notifier) { - WatcherEntries foundEntries = watchedEntriesForPaths(sourceContextIds); + WatcherEntries foundEntries = watchedEntriesForPaths(directoryPathIds); SourceIds watchedSourceIds = watchedPaths(foundEntries); diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcherinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcherinterface.h index 8e67b80b9a7..28b96bb6a40 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcherinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcherinterface.h @@ -20,7 +20,7 @@ public: virtual void updateIdPaths(const std::vector &idPaths) = 0; virtual void updateContextIdPaths(const std::vector &idPaths, - const SourceContextIds &sourceContextIds) + const DirectoryPathIds &directoryPathIds) = 0; virtual void removeIds(const ProjectPartIds &ids) = 0; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h index e7870e6bfda..addfe704d8c 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h @@ -100,26 +100,26 @@ class WatcherEntry { public: ProjectChunkId id; - SourceContextId sourceContextId; + DirectoryPathId directoryPathId; SourceId sourceId; long long lastModified = -1; long long size = -1; friend bool operator==(WatcherEntry first, WatcherEntry second) { - return first.id == second.id && first.sourceContextId == second.sourceContextId + return first.id == second.id && first.directoryPathId == second.directoryPathId && first.sourceId == second.sourceId; } friend std::weak_ordering operator<=>(const WatcherEntry &first, const WatcherEntry &second) { - return std::tie(first.sourceContextId, first.sourceId, first.id) - <=> std::tie(second.sourceContextId, second.sourceId, second.id); + return std::tie(first.directoryPathId, first.sourceId, first.id) + <=> std::tie(second.directoryPathId, second.sourceId, second.id); } operator SourceId() const { return sourceId; } - operator SourceContextId() const { return sourceContextId; } + operator DirectoryPathId() const { return directoryPathId; } }; using WatcherEntries = std::vector; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h index f03e0ee4b2f..f8e80714e24 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetriggerupdateinterface.h @@ -14,7 +14,7 @@ public: ProjectStorageTriggerUpdateInterface(const ProjectStorageTriggerUpdateInterface &) = delete; ProjectStorageTriggerUpdateInterface &operator=(const ProjectStorageTriggerUpdateInterface &) = delete; - virtual void checkForChangeInDirectory(SourceContextIds sourceContextIds) = 0; + virtual void checkForChangeInDirectory(DirectoryPathIds directoryPathIds) = 0; protected: ~ProjectStorageTriggerUpdateInterface() = default; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetypes.h index 0331418568a..cc7c2a33577 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetypes.h @@ -1154,7 +1154,7 @@ public: PropertyEditorQmlPath(ModuleId moduleId, TypeNameString typeName, SourceId pathId, - SourceContextId directoryId) + DirectoryPathId directoryId) : typeName{typeName} , pathId{pathId} , directoryId{directoryId} @@ -1179,7 +1179,7 @@ public: TypeNameString typeName; TypeId typeId; SourceId pathId; - SourceContextId directoryId; + DirectoryPathId directoryId; ModuleId moduleId; }; @@ -1188,7 +1188,7 @@ using PropertyEditorQmlPaths = std::vector; class DirectoryInfo { public: - DirectoryInfo(SourceContextId directoryId, SourceId sourceId, ModuleId moduleId, FileType fileType) + DirectoryInfo(DirectoryPathId directoryId, SourceId sourceId, ModuleId moduleId, FileType fileType) : directoryId{directoryId} , sourceId{sourceId} , moduleId{moduleId} @@ -1216,7 +1216,7 @@ public: } public: - SourceContextId directoryId; + DirectoryPathId directoryId; SourceId sourceId; ModuleId moduleId; FileType fileType; @@ -1227,13 +1227,13 @@ using DirectoryInfos = std::vector; class TypeAnnotation { public: - TypeAnnotation(SourceId sourceId, SourceContextId directoryId) + TypeAnnotation(SourceId sourceId, DirectoryPathId directoryId) : sourceId{sourceId} , directoryId{directoryId} {} TypeAnnotation(SourceId sourceId, - SourceContextId directoryId, + DirectoryPathId directoryId, Utils::SmallStringView typeName, ModuleId moduleId, Utils::SmallStringView iconPath, @@ -1274,7 +1274,7 @@ public: SourceId sourceId; ModuleId moduleId; TypeTraits traits; - SourceContextId directoryId; + DirectoryPathId directoryId; }; using TypeAnnotations = std::vector; @@ -1314,7 +1314,7 @@ public: , fileStatuses(std::move(fileStatuses)) {} - SynchronizationPackage(SourceContextIds updatedDirectoryInfoDirectoryIds, + SynchronizationPackage(DirectoryPathIds updatedDirectoryInfoDirectoryIds, DirectoryInfos directoryInfos) : directoryInfos(std::move(directoryInfos)) , updatedDirectoryInfoDirectoryIds(std::move(updatedDirectoryInfoDirectoryIds)) @@ -1327,13 +1327,13 @@ public: SourceIds updatedFileStatusSourceIds; FileStatuses fileStatuses; DirectoryInfos directoryInfos; - SourceContextIds updatedDirectoryInfoDirectoryIds; + DirectoryPathIds updatedDirectoryInfoDirectoryIds; Imports moduleDependencies; SourceIds updatedModuleDependencySourceIds; ModuleExportedImports moduleExportedImports; ModuleIds updatedModuleIds; PropertyEditorQmlPaths propertyEditorQmlPaths; - SourceContextIds updatedPropertyEditorQmlPathDirectoryIds; + DirectoryPathIds updatedPropertyEditorQmlPathDirectoryIds; TypeAnnotations typeAnnotations; SourceIds updatedTypeAnnotationSourceIds; }; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index a6fc2320ee3..1c63bbfba45 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -417,8 +417,8 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct FileState annotationDirectoryState, SourcePath qmldirSourcePath, SourceId qmldirSourceId, - SourceContextId directoryId, - SourceContextId annotationDirectoryId, + DirectoryPathId directoryId, + DirectoryPathId annotationDirectoryId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -513,9 +513,9 @@ void ProjectStorageUpdater::updateDirectories(const QStringList &directories, } void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &directoryPath, - SourceContextId directoryId, + DirectoryPathId directoryId, FileState directoryState, - const SourceContextIds &subdirectoriesToIgnore, + const DirectoryPathIds &subdirectoriesToIgnore, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -523,35 +523,35 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct { struct Directory { - Directory(Utils::SmallStringView path, SourceContextId sourceContextId) + Directory(Utils::SmallStringView path, DirectoryPathId directoryPathId) : path{path} - , sourceContextId{sourceContextId} + , directoryPathId{directoryPathId} {} Utils::PathString path; - SourceContextId sourceContextId; + DirectoryPathId directoryPathId; }; using Directories = QVarLengthArray; auto subdirectoryIds = m_projectStorage.fetchSubdirectoryIds(directoryId); auto subdirectories = Utils::transform( - subdirectoryIds, [&](SourceContextId sourceContextId) -> Directory { - auto subdirectoryPath = m_pathCache.sourceContextPath(sourceContextId); - return {subdirectoryPath, sourceContextId}; + subdirectoryIds, [&](DirectoryPathId directoryPathId) -> Directory { + auto subdirectoryPath = m_pathCache.directoryPath(directoryPathId); + return {subdirectoryPath, directoryPathId}; }); auto exisitingSubdirectoryPaths = m_fileSystem.subdirectories(directoryPath.toQString()); Directories existingSubdirecories; - auto skipDirectory = [&](std::string_view subdirectoryPath, SourceContextId sourceContextId) { + auto skipDirectory = [&](std::string_view subdirectoryPath, DirectoryPathId directoryPathId) { if (subdirectoryPath.ends_with("designer")) return true; if (isInsideProject == IsInsideProject::Yes) { - static SourceNameId ignoreInQdsSourceNameId = m_pathCache.sourceNameId("ignore-in-qds"); + static FileNameId ignoreInQdsFileNameId = m_pathCache.fileNameId("ignore-in-qds"); - SourceId ignoreInQdsSourceId = SourceId::create(ignoreInQdsSourceNameId, sourceContextId); + SourceId ignoreInQdsSourceId = SourceId::create(ignoreInQdsFileNameId, directoryPathId); auto ignoreInQdsState = fileState(ignoreInQdsSourceId, package, notUpdatedSourceIds); @@ -567,17 +567,17 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct }; for (Utils::PathString subdirectoryPath : exisitingSubdirectoryPaths) { - SourceContextId sourceContextId = m_pathCache.sourceContextId(subdirectoryPath); + DirectoryPathId directoryPathId = m_pathCache.directoryPathId(subdirectoryPath); - if (skipDirectory(subdirectoryPath, sourceContextId)) + if (skipDirectory(subdirectoryPath, directoryPathId)) continue; - subdirectories.emplace_back(subdirectoryPath, sourceContextId); - existingSubdirecories.emplace_back(subdirectoryPath, sourceContextId); + subdirectories.emplace_back(subdirectoryPath, directoryPathId); + existingSubdirecories.emplace_back(subdirectoryPath, directoryPathId); } - std::ranges::sort(subdirectories, {}, &Directory::sourceContextId); - auto removed = std::ranges::unique(subdirectories, {}, &Directory::sourceContextId); + std::ranges::sort(subdirectories, {}, &Directory::directoryPathId); + auto removed = std::ranges::unique(subdirectories, {}, &Directory::directoryPathId); subdirectories.erase(removed.begin(), removed.end()); auto updateDirectory = [&](const Directory &subdirectory) { @@ -593,12 +593,12 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct subdirectoriesToIgnore, updateDirectory, {}, - &Directory::sourceContextId); + &Directory::directoryPathId); if (isChangedOrAdded(directoryState)) { for (const auto &[subdirectoryPath, subdirectoryId] : existingSubdirecories) { package.directoryInfos.emplace_back(directoryId, - SourceId::create(SourceNameId{}, subdirectoryId), + SourceId::create(FileNameId{}, subdirectoryId), ModuleId{}, Storage::Synchronization::FileType::Directory); } @@ -607,8 +607,8 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct void ProjectStorageUpdater::annotationDirectoryChanged( Utils::SmallStringView directoryPath, - SourceContextId directoryId, - SourceContextId annotationDirectoryId, + DirectoryPathId directoryId, + DirectoryPathId annotationDirectoryId, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package) { @@ -624,7 +624,7 @@ void ProjectStorageUpdater::annotationDirectoryChanged( void ProjectStorageUpdater::updatePropertyEditorFiles( Utils::SmallStringView directoryPath, - SourceContextId directoryId, + DirectoryPathId directoryId, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package) { @@ -643,7 +643,7 @@ void ProjectStorageUpdater::updatePropertyEditorFiles( void ProjectStorageUpdater::updatePropertyEditorFile( const QString &fileName, - SourceContextId directoryId, + DirectoryPathId directoryId, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package) { @@ -659,7 +659,7 @@ void ProjectStorageUpdater::updatePropertyEditorFile( } void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPath, - const SourceContextIds &subdirectoriesToIgnore, + const DirectoryPathIds &subdirectoriesToIgnore, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -669,18 +669,18 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa SourcePath qmldirPath{directoryPath + "/qmldir"}; SourceId qmldirSourceId = m_pathCache.sourceId(qmldirPath); - SourceContextId directoryId = qmldirSourceId.contextId(); + DirectoryPathId directoryId = qmldirSourceId.contextId(); auto directoryState = fileState(directoryId, package, notUpdatedSourceIds); if (isExisting(directoryState)) - WatchedSourceIds.directoryIds.push_back(SourceId::create(SourceNameId{}, directoryId)); + WatchedSourceIds.directoryIds.push_back(SourceId::create(FileNameId{}, directoryId)); auto qmldirState = fileState(qmldirSourceId, package, notUpdatedSourceIds); if (isExisting(qmldirState)) WatchedSourceIds.qmldirSourceIds.push_back(qmldirSourceId); SourcePath annotationDirectoryPath{directoryPath + "/designer"}; - auto annotationDirectoryId = m_pathCache.sourceContextId(annotationDirectoryPath); + auto annotationDirectoryId = m_pathCache.directoryPathId(annotationDirectoryPath); auto annotationDirectoryState = fileState(annotationDirectoryId, package, notUpdatedSourceIds); switch (combineState(directoryState, qmldirState, annotationDirectoryState)) { @@ -765,7 +765,7 @@ void ProjectStorageUpdater::updatePropertyEditorPaths( while (dirIterator.hasNext()) { auto pathInfo = dirIterator.nextFileInfo(); - SourceContextId directoryId = m_pathCache.sourceContextId( + DirectoryPathId directoryId = m_pathCache.directoryPathId( Utils::PathString{pathInfo.filePath()}); auto state = fileState(directoryId, package, notUpdatedSourceIds); @@ -798,9 +798,9 @@ void ProjectStorageUpdater::updateTypeAnnotations(const QStringList &directoryPa { NanotraceHR::Tracer tracer("update type annotations", category()); - std::map> updatedSourceIdsDictonary; + std::map> updatedSourceIdsDictonary; - for (SourceContextId directoryId : m_projectStorage.typeAnnotationDirectoryIds()) + for (DirectoryPathId directoryId : m_projectStorage.typeAnnotationDirectoryIds()) updatedSourceIdsDictonary[directoryId] = {}; for (const auto &directoryPath : directoryPaths) @@ -813,7 +813,7 @@ void ProjectStorageUpdater::updateTypeAnnotations( const QString &rootDirectoryPath, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, - std::map> &updatedSourceIdsDictonary) + std::map> &updatedSourceIdsDictonary) { NanotraceHR::Tracer tracer("update type annotation directory", category(), @@ -834,7 +834,7 @@ void ProjectStorageUpdater::updateTypeAnnotations( auto directoryPath = fileInfo.canonicalPath(); - SourceContextId directoryId = m_pathCache.sourceContextId(Utils::PathString{directoryPath}); + DirectoryPathId directoryId = m_pathCache.directoryPathId(Utils::PathString{directoryPath}); auto state = fileState(sourceId, package, notUpdatedSourceIds); if (isChangedOrAdded(state)) @@ -848,7 +848,7 @@ void ProjectStorageUpdater::updateTypeAnnotations( void ProjectStorageUpdater::updateTypeAnnotationDirectories( Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, - std::map> &updatedSourceIdsDictonary) + std::map> &updatedSourceIdsDictonary) { for (auto &[directoryId, updatedSourceIds] : updatedSourceIdsDictonary) { auto directoryState = fileState(directoryId, package, notUpdatedSourceIds); @@ -886,7 +886,7 @@ QString contentFromFile(const QString &path) void ProjectStorageUpdater::updateTypeAnnotation(const QString &directoryPath, const QString &filePath, SourceId sourceId, - SourceContextId directoryId, + DirectoryPathId directoryId, Storage::Synchronization::SynchronizationPackage &package) { NanotraceHR::Tracer tracer{"update type annotation path", @@ -909,7 +909,7 @@ void ProjectStorageUpdater::updateTypeAnnotation(const QString &directoryPath, void ProjectStorageUpdater::updatePropertyEditorPath( const QString &directoryPath, Storage::Synchronization::SynchronizationPackage &package, - SourceContextId directoryId, + DirectoryPathId directoryId, long long pathOffset) { NanotraceHR::Tracer tracer{"update property editor path", @@ -929,7 +929,7 @@ void ProjectStorageUpdater::updatePropertyEditorPath( void ProjectStorageUpdater::updatePropertyEditorFilePath( const QString &path, Storage::Synchronization::SynchronizationPackage &package, - SourceContextId directoryId, + DirectoryPathId directoryId, long long pathOffset) { NanotraceHR::Tracer tracer{"update property editor file path", @@ -960,15 +960,15 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath( } namespace { -SourceContextIds filterUniqueSourceContextIds(const SourceIds &sourceIds) +DirectoryPathIds filterUniqueDirectoryPathIds(const SourceIds &sourceIds) { - auto sourceContextIds = Utils::transform(sourceIds, &SourceId::contextId); + auto directoryPathIds = Utils::transform(sourceIds, &SourceId::contextId); - std::sort(sourceContextIds.begin(), sourceContextIds.end()); - auto newEnd = std::unique(sourceContextIds.begin(), sourceContextIds.end()); - sourceContextIds.erase(newEnd, sourceContextIds.end()); + std::sort(directoryPathIds.begin(), directoryPathIds.end()); + auto newEnd = std::unique(directoryPathIds.begin(), directoryPathIds.end()); + directoryPathIds.erase(newEnd, directoryPathIds.end()); - return sourceContextIds; + return directoryPathIds; } SourceIds filterUniqueSourceIds(SourceIds sourceIds) @@ -1049,9 +1049,9 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan auto updateDirectory = [&](const SourceIds &directorySourceIds, WatchedSourceIds &watchedSourceIds) { - auto directoryIds = filterUniqueSourceContextIds(directorySourceIds); + auto directoryIds = filterUniqueDirectoryPathIds(directorySourceIds); for (auto directoryId : directoryIds) { - Utils::PathString directory = m_pathCache.sourceContextPath(directoryId); + Utils::PathString directory = m_pathCache.directoryPath(directoryId); this->updateDirectory(directory, directoryIds, package, @@ -1067,7 +1067,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan auto projectDirectoryIds = updateDirectory(project.directory, watchedProjectSourceIds); auto parseQmlComponent = [&](SourceIds qmlDocumentSourceIds, - const SourceContextIds &directoryIds, + const DirectoryPathIds &directoryIds, IsInsideProject isInsideProject) { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmlDocumentSourceIds))) { if (!contains(directoryIds, sourceId.contextId())) @@ -1079,7 +1079,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan parseQmlComponent(std::move(project.qmlDocument), projectDirectoryIds, IsInsideProject::Yes); auto parseTypeInfo = [&](SourceIds qmltypesSourceIds, - const SourceContextIds &directoryIds, + const DirectoryPathIds &directoryIds, IsInsideProject isInsideProject) { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) { if (!contains(directoryIds, sourceId.contextId())) { @@ -1116,7 +1116,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan auto directoryIdsSize = projectDirectoryIds.size() + qtDirectoryIds.size(); if (directoryIdsSize > 0) { - SourceContextIds directoryIds; + DirectoryPathIds directoryIds; std::vector newIdPaths; idPaths.reserve(8); appendIdPaths(std::move(watchedQtSourceIds), m_qtPartId, newIdPaths); @@ -1135,7 +1135,7 @@ void ProjectStorageUpdater::pathsChanged(const SourceIds &) {} void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos, const std::vector &qmldirDependencies, const std::vector &qmldirImports, - SourceContextId directoryId, + DirectoryPathId directoryId, const QString &directoryPath, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package, @@ -1258,7 +1258,7 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Direct void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFilePath, Utils::SmallStringView directoryPath, Storage::Synchronization::ExportedTypes exportedTypes, - SourceContextId directoryId, + DirectoryPathId directoryId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &watchedSourceIds, @@ -1426,7 +1426,7 @@ Storage::Synchronization::ExportedTypes createExportedTypes(ProjectStorageUpdate } // namespace void ProjectStorageUpdater::parseQmlComponents(Components components, - SourceContextId directoryId, + DirectoryPathId directoryId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -1442,7 +1442,7 @@ void ProjectStorageUpdater::parseQmlComponents(Components components, std::ranges::sort(components, [](auto &&first, auto &&second) { return first.fileName < second.fileName; }); - auto directoryPath = m_pathCache.sourceContextPath(directoryId); + auto directoryPath = m_pathCache.directoryPath(directoryId); auto callback = [&](ComponentRange componentsWithSameFileName) { const auto &firstComponent = *componentsWithSameFileName.begin(); @@ -1511,11 +1511,11 @@ ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState( } ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState( - SourceContextId sourceContextId, + DirectoryPathId directoryPathId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds) const { - auto sourceId = SourceId::create(SourceNameId{}, sourceContextId); + auto sourceId = SourceId::create(FileNameId{}, directoryPathId); return fileState(sourceId, package, notUpdatedSourceIds); } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h index 8d22bddd035..7dd38706d38 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h @@ -142,15 +142,15 @@ private: NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds); void updateDirectory(const Utils::PathString &directory, - const SourceContextIds &subdirecoriesToIgnore, + const DirectoryPathIds &subdirecoriesToIgnore, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, IsInsideProject isInsideProject); void updateSubdirectories(const Utils::PathString &directory, - SourceContextId directoryId, + DirectoryPathId directoryId, FileState directoryFileState, - const SourceContextIds &subdirecoriesToIgnore, + const DirectoryPathIds &subdirecoriesToIgnore, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -161,24 +161,24 @@ private: FileState annotationDirectoryState, SourcePath qmldirSourcePath, SourceId qmldirSourceId, - SourceContextId directoryId, - SourceContextId annotationDirectoryId, + DirectoryPathId directoryId, + DirectoryPathId annotationDirectoryId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, IsInsideProject isInsideProject, ProjectStorageTracing::Category::TracerType &tracer); void annotationDirectoryChanged(Utils::SmallStringView directoryPath, - SourceContextId directoryId, - SourceContextId annotationDirectoryId, + DirectoryPathId directoryId, + DirectoryPathId annotationDirectoryId, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package); void updatePropertyEditorFiles(Utils::SmallStringView directyPath, - SourceContextId directoryId, + DirectoryPathId directoryId, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package); void updatePropertyEditorFile(const QString &fileName, - SourceContextId directoryId, + DirectoryPathId directoryId, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package); void updatePropertyEditorPaths(const QString &propertyEditorResourcesPath, @@ -187,31 +187,31 @@ private: void updateTypeAnnotations(const QString &directoryPath, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, - std::map> &updatedSourceIdsDictonary); + std::map> &updatedSourceIdsDictonary); void updateTypeAnnotationDirectories( Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, - std::map> &updatedSourceIdsDictonary); + std::map> &updatedSourceIdsDictonary); void updateTypeAnnotations(const QStringList &directoryPath, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds); void updateTypeAnnotation(const QString &directoryPath, const QString &filePath, SourceId sourceId, - SourceContextId directoryId, + DirectoryPathId directoryId, Storage::Synchronization::SynchronizationPackage &package); void updatePropertyEditorPath(const QString &path, Storage::Synchronization::SynchronizationPackage &package, - SourceContextId directoryId, + DirectoryPathId directoryId, long long pathOffset); void updatePropertyEditorFilePath(const QString &filePath, Storage::Synchronization::SynchronizationPackage &package, - SourceContextId directoryId, + DirectoryPathId directoryId, long long pathOffset); void parseTypeInfos(const QStringList &typeInfos, const std::vector &qmldirDependencies, const std::vector &qmldirImports, - SourceContextId directoryId, + DirectoryPathId directoryId, const QString &directoryPath, ModuleId moduleId, Storage::Synchronization::SynchronizationPackage &package, @@ -229,7 +229,7 @@ private: NotUpdatedSourceIds ¬UpdatedSourceIds, IsInsideProject isInsideProject); void parseQmlComponents(Components components, - SourceContextId directoryId, + DirectoryPathId directoryId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -239,7 +239,7 @@ private: void parseQmlComponent(Utils::SmallStringView fileName, Utils::SmallStringView directory, Storage::Synchronization::ExportedTypes exportedTypes, - SourceContextId directoryId, + DirectoryPathId directoryId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds, WatchedSourceIds &WatchedSourceIds, @@ -254,7 +254,7 @@ private: FileState fileState(SourceId sourceId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds) const; - FileState fileState(SourceContextId sourceContextId, + FileState fileState(DirectoryPathId directoryPathId, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds) const; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.cpp index d646b8b90db..5f86875173b 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.cpp @@ -28,7 +28,7 @@ constexpr auto extraFileElementName = "ExtraFile"_L1; } // namespace Synchronization::TypeAnnotations TypeAnnotationReader::parseTypeAnnotation( - const QString &content, const QString &directoryPath, SourceId sourceId, SourceContextId directoryId) + const QString &content, const QString &directoryPath, SourceId sourceId, DirectoryPathId directoryId) { m_sourceId = sourceId; m_directoryId = directoryId; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.h index 1c704618ae8..af40d985988 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.h @@ -50,7 +50,7 @@ public: Synchronization::TypeAnnotations parseTypeAnnotation(const QString &content, const QString &directoryPath, SourceId sourceId, - SourceContextId directoryId); + DirectoryPathId directoryId); QStringList errors(); @@ -125,7 +125,7 @@ private: json m_itemLibraryEntries; Property m_currentProperty; SourceId m_sourceId; - SourceContextId m_directoryId; + DirectoryPathId m_directoryId; }; } // namespace QmlDesigner::Storage diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h index c6808097350..e35e4a04857 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h @@ -31,8 +31,8 @@ class SourcePathCache final : public SourcePathCacheInterface public: SourcePathCache(Storage &storage) - : m_sourceContextStorageAdapter{storage} - , m_sourceNameStorageAdapter{storage} + : m_directoryPathStorageAdapter{storage} + , m_fileNameStorageAdapter{storage} { populateIfEmpty(); @@ -43,44 +43,44 @@ public: void populateIfEmpty() override { - if (m_sourceNameCache.isEmpty()) { - m_sourceContextPathCache.populate(); - m_sourceNameCache.populate(); + if (m_fileNameCache.isEmpty()) { + m_directoryPathCache.populate(); + m_fileNameCache.populate(); } } SourceId sourceId(SourcePathView sourcePath) const override { - Utils::SmallStringView sourceContextPath = sourcePath.directory(); + Utils::SmallStringView directoryPath = sourcePath.directory(); - auto sourceContextId = m_sourceContextPathCache.id(sourceContextPath); + auto directoryPathId = m_directoryPathCache.id(directoryPath); - Utils::SmallStringView sourceName = sourcePath.name(); + Utils::SmallStringView fileName = sourcePath.name(); - auto sourceNameId = m_sourceNameCache.id(sourceName); + auto fileNameId = m_fileNameCache.id(fileName); - return SourceId::create(sourceNameId, sourceContextId); + return SourceId::create(fileNameId, directoryPathId); } - SourceNameId sourceNameId(Utils::SmallStringView sourceName) const override + FileNameId fileNameId(Utils::SmallStringView fileName) const override { - return m_sourceNameCache.id(sourceName); + return m_fileNameCache.id(fileName); } - SourceId sourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName) const override + SourceId sourceId(DirectoryPathId directoryPathId, Utils::SmallStringView fileName) const override { - SourceNameId sourceNameId = m_sourceNameCache.id(sourceName); + FileNameId fileNameId = m_fileNameCache.id(fileName); - return SourceId::create(sourceNameId, sourceContextId); + return SourceId::create(fileNameId, directoryPathId); } - SourceContextId sourceContextId(Utils::SmallStringView sourceContextPath) const override + DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const override { - Utils::SmallStringView path = sourceContextPath.back() == '/' - ? sourceContextPath.substr(0, sourceContextPath.size() - 1) - : sourceContextPath; + Utils::SmallStringView path = directoryPath.back() == '/' + ? directoryPath.substr(0, directoryPath.size() - 1) + : directoryPath; - return m_sourceContextPathCache.id(path); + return m_directoryPathCache.id(path); } SourcePath sourcePath(SourceId sourceId) const override @@ -88,61 +88,61 @@ public: if (!sourceId) [[unlikely]] throw NoSourcePathForInvalidSourceId(); - auto sourceName = m_sourceNameCache.value(sourceId.mainId()); + auto fileName = m_fileNameCache.value(sourceId.mainId()); - Utils::PathString sourceContextPath = m_sourceContextPathCache.value(sourceId.contextId()); + Utils::PathString directoryPath = m_directoryPathCache.value(sourceId.contextId()); - return SourcePath{sourceContextPath, sourceName}; + return SourcePath{directoryPath, fileName}; } - Utils::PathString sourceContextPath(SourceContextId sourceContextId) const override + Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override { - if (!sourceContextId) [[unlikely]] - throw NoSourceContextPathForInvalidSourceContextId(); + if (!directoryPathId) [[unlikely]] + throw NoDirectoryPathForInvalidDirectoryPathId(); - return m_sourceContextPathCache.value(sourceContextId); + return m_directoryPathCache.value(directoryPathId); } - Utils::SmallString sourceName(SourceNameId sourceNameId) const override + Utils::SmallString fileName(FileNameId fileNameId) const override { - if (!sourceNameId) [[unlikely]] - throw NoSourceNameForInvalidSourceNameId(); + if (!fileNameId) [[unlikely]] + throw NoFileNameForInvalidFileNameId(); - return m_sourceNameCache.value(sourceNameId); + return m_fileNameCache.value(fileNameId); } private: - class SourceContextStorageAdapter + class DirectoryPathStorageAdapter { public: - auto fetchId(Utils::SmallStringView sourceContextPath) + auto fetchId(Utils::SmallStringView directoryPath) { - return storage.fetchSourceContextId(sourceContextPath); + return storage.fetchDirectoryPathId(directoryPath); } - auto fetchValue(SourceContextId id) { return storage.fetchSourceContextPath(id); } + auto fetchValue(DirectoryPathId id) { return storage.fetchDirectoryPath(id); } - auto fetchAll() { return storage.fetchAllSourceContexts(); } + auto fetchAll() { return storage.fetchAllDirectoryPaths(); } Storage &storage; }; - class SourceNameStorageAdapter + class FileNameStorageAdapter { public: - auto fetchId(Utils::SmallStringView sourceNameView) + auto fetchId(Utils::SmallStringView fileNameView) { - return storage.fetchSourceNameId(sourceNameView); + return storage.fetchFileNameId(fileNameView); } - auto fetchValue(SourceNameId id) { return storage.fetchSourceName(id); } + auto fetchValue(FileNameId id) { return storage.fetchFileName(id); } - auto fetchAll() { return storage.fetchAllSourceNames(); } + auto fetchAll() { return storage.fetchAllFileNames(); } Storage &storage; }; - struct SourceNameLess + struct FileNameLess { bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const noexcept { @@ -150,7 +150,7 @@ private: } }; - struct SourceContextLess + struct DirectoryPathLess { bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const noexcept { @@ -161,26 +161,26 @@ private: } }; - using SourceContextPathCache = StorageCache; - using SourceNameCache = StorageCache; + using FileNameCache = StorageCache; + FileNameLess, + Cache::FileName>; private: - SourceContextStorageAdapter m_sourceContextStorageAdapter; - SourceNameStorageAdapter m_sourceNameStorageAdapter; - mutable SourceContextPathCache m_sourceContextPathCache{m_sourceContextStorageAdapter}; - mutable SourceNameCache m_sourceNameCache{m_sourceNameStorageAdapter}; + DirectoryPathStorageAdapter m_directoryPathStorageAdapter; + FileNameStorageAdapter m_fileNameStorageAdapter; + mutable DirectoryPathCache m_directoryPathCache{m_directoryPathStorageAdapter}; + mutable FileNameCache m_fileNameCache{m_fileNameStorageAdapter}; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcacheinterface.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcacheinterface.h index 6f2378643f7..8cb9d27b986 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcacheinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcacheinterface.h @@ -24,19 +24,19 @@ public: virtual SourceId sourceId(SourcePathView sourcePath) const = 0; - virtual SourceId sourceId(SourceContextId sourceContextId, - Utils::SmallStringView sourceName) const + virtual SourceId sourceId(DirectoryPathId directoryPathId, + Utils::SmallStringView fileName) const = 0; - virtual SourceNameId sourceNameId(Utils::SmallStringView sourceName) const = 0; + virtual FileNameId fileNameId(Utils::SmallStringView fileName) const = 0; - virtual SourceContextId sourceContextId(Utils::SmallStringView sourceContextPath) const = 0; + virtual DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const = 0; virtual SourcePath sourcePath(SourceId sourceId) const = 0; - virtual Utils::PathString sourceContextPath(SourceContextId sourceContextId) const = 0; + virtual Utils::PathString directoryPath(DirectoryPathId directoryPathId) const = 0; - virtual Utils::SmallString sourceName(SourceNameId sourceNameId) const = 0; + virtual Utils::SmallString fileName(FileNameId fileNameId) const = 0; protected: ~SourcePathCacheInterface() = default; diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcachetypes.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcachetypes.h index 0f6a40c626c..645340456a0 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcachetypes.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcachetypes.h @@ -13,35 +13,35 @@ namespace QmlDesigner::Cache { -class SourceContext - : public StorageCacheEntry +class DirectoryPath + : public StorageCacheEntry { - using Base = StorageCacheEntry; + using Base = StorageCacheEntry; public: using Base::Base; - friend bool operator==(const SourceContext &first, const SourceContext &second) + friend bool operator==(const DirectoryPath &first, const DirectoryPath &second) { return first.id == second.id && first.value == second.value; } }; -using SourceContexts = std::vector; +using DirectoryPaths = std::vector; -class SourceName : public StorageCacheEntry +class FileName : public StorageCacheEntry { - using Base = StorageCacheEntry; + using Base = StorageCacheEntry; public: using Base::Base; - friend bool operator==(const SourceName &first, const SourceName &second) + friend bool operator==(const FileName &first, const FileName &second) { return first.id == second.id && first.value == second.value; } }; -using SourceNames = std::vector; +using FileNames = std::vector; } // namespace QmlDesigner::Cache diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.cpp b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.cpp index 04365236e71..4e55c977be1 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.cpp +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.cpp @@ -26,42 +26,42 @@ const char *NoSourcePathForInvalidSourceId::what() const noexcept return "You cannot get a file path for an invalid file path id!"; } -NoSourceContextPathForInvalidSourceContextId::NoSourceContextPathForInvalidSourceContextId() +NoDirectoryPathForInvalidDirectoryPathId::NoDirectoryPathForInvalidDirectoryPathId() { - category().threadEvent("NoSourceContextPathForInvalidSourceContextId"); + category().threadEvent("NoDirectoryPathForInvalidDirectoryPathId"); } -const char *NoSourceContextPathForInvalidSourceContextId::what() const noexcept +const char *NoDirectoryPathForInvalidDirectoryPathId::what() const noexcept { return "You cannot get a directory path for an invalid directory path id!"; } -SourceContextIdDoesNotExists::SourceContextIdDoesNotExists() +DirectoryPathIdDoesNotExists::DirectoryPathIdDoesNotExists() { - category().threadEvent("SourceContextIdDoesNotExists"); + category().threadEvent("DirectoryPathIdDoesNotExists"); } -const char *SourceContextIdDoesNotExists::what() const noexcept +const char *DirectoryPathIdDoesNotExists::what() const noexcept { return "The source context id does not exist in the database!"; } -SourceNameIdDoesNotExists::SourceNameIdDoesNotExists() +FileNameIdDoesNotExists::FileNameIdDoesNotExists() { - category().threadEvent("SourceNameIdDoesNotExists"); + category().threadEvent("FileNameIdDoesNotExists"); } -const char *SourceNameIdDoesNotExists::what() const noexcept +const char *FileNameIdDoesNotExists::what() const noexcept { return "The source id does not exist in the database!"; } -NoSourceNameForInvalidSourceNameId::NoSourceNameForInvalidSourceNameId() +NoFileNameForInvalidFileNameId::NoFileNameForInvalidFileNameId() { - category().threadEvent("NoSourceNameForInvalidSourceNameId"); + category().threadEvent("NoFileNameForInvalidFileNameId"); } -const char *NoSourceNameForInvalidSourceNameId::what() const noexcept +const char *NoFileNameForInvalidFileNameId::what() const noexcept { return "You cannot get a source name for an invalid source name id!"; } diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.h index 958f99fab93..23691db61c2 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.h @@ -27,31 +27,31 @@ public: const char *what() const noexcept override; }; -class QMLDESIGNERCORE_EXPORT NoSourceNameForInvalidSourceNameId : public SourcePathError +class QMLDESIGNERCORE_EXPORT NoFileNameForInvalidFileNameId : public SourcePathError { public: - NoSourceNameForInvalidSourceNameId(); + NoFileNameForInvalidFileNameId(); const char *what() const noexcept override; }; -class QMLDESIGNERCORE_EXPORT NoSourceContextPathForInvalidSourceContextId : public SourcePathError +class QMLDESIGNERCORE_EXPORT NoDirectoryPathForInvalidDirectoryPathId : public SourcePathError { public: - NoSourceContextPathForInvalidSourceContextId(); + NoDirectoryPathForInvalidDirectoryPathId(); const char *what() const noexcept override; }; -class QMLDESIGNERCORE_EXPORT SourceContextIdDoesNotExists : public SourcePathError +class QMLDESIGNERCORE_EXPORT DirectoryPathIdDoesNotExists : public SourcePathError { public: - SourceContextIdDoesNotExists(); + DirectoryPathIdDoesNotExists(); const char *what() const noexcept override; }; -class QMLDESIGNERCORE_EXPORT SourceNameIdDoesNotExists : public SourcePathError +class QMLDESIGNERCORE_EXPORT FileNameIdDoesNotExists : public SourcePathError { public: - SourceNameIdDoesNotExists(); + FileNameIdDoesNotExists(); const char *what() const noexcept override; }; diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.cpp b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.cpp index e1f8beaab51..f10384467f1 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.cpp +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.cpp @@ -18,24 +18,24 @@ struct SourcePathStorage::Statements {} Sqlite::Database &database; - mutable Sqlite::ReadStatement<1, 1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{ - "SELECT sourceContextId FROM sourceContexts WHERE sourceContextPath = ?", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceContextPathFromSourceContextsBySourceContextIdStatement{ - "SELECT sourceContextPath FROM sourceContexts WHERE sourceContextId = ?", database}; - mutable Sqlite::ReadStatement<2> selectAllSourceContextsStatement{ - "SELECT sourceContextPath, sourceContextId FROM sourceContexts", database}; - Sqlite::WriteStatement<1> insertIntoSourceContextsStatement{ - "INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceNameIdFromSourceNamesBySourceNameStatement{ - "SELECT sourceNameId FROM sourceNames WHERE sourceName = ?", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceNameFromSourceNamesBySourceNameIdStatement{ - "SELECT sourceName FROM sourceNames WHERE sourceNameId = ?", database}; + mutable Sqlite::ReadStatement<1, 1> selectDirectoryPathIdFromDirectoryPathsByDirectoryPathStatement{ + "SELECT directoryPathId FROM directoryPaths WHERE directoryPath = ?", database}; + mutable Sqlite::ReadStatement<1, 1> selectDirectoryPathFromDirectoryPathsByDirectoryPathIdStatement{ + "SELECT directoryPath FROM directoryPaths WHERE directoryPathId = ?", database}; + mutable Sqlite::ReadStatement<2> selectAllDirectoryPathsStatement{ + "SELECT directoryPath, directoryPathId FROM directoryPaths", database}; + Sqlite::WriteStatement<1> insertIntoDirectoryPathsStatement{ + "INSERT INTO directoryPaths(directoryPath) VALUES (?)", database}; + mutable Sqlite::ReadStatement<1, 1> selectFileNameIdFromFileNamesByFileNameStatement{ + "SELECT fileNameId FROM fileNames WHERE fileName = ?", database}; + mutable Sqlite::ReadStatement<1, 1> selectFileNameFromFileNamesByFileNameIdStatement{ + "SELECT fileName FROM fileNames WHERE fileNameId = ?", database}; Sqlite::WriteStatement<1> insertIntoSourcesStatement{ - "INSERT INTO sourceNames(sourceName) VALUES (?)", database}; + "INSERT INTO fileNames(fileName) VALUES (?)", database}; mutable Sqlite::ReadStatement<2> selectAllSourcesStatement{ - "SELECT sourceName, sourceNameId FROM sourceNames", database}; - Sqlite::WriteStatement<0> deleteAllSourceNamesStatement{"DELETE FROM sourceNames", database}; - Sqlite::WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; + "SELECT fileName, fileNameId FROM fileNames", database}; + Sqlite::WriteStatement<0> deleteAllFileNamesStatement{"DELETE FROM fileNames", database}; + Sqlite::WriteStatement<0> deleteAllDirectoryPathsStatement{"DELETE FROM directoryPaths", database}; }; class SourcePathStorage::Initializer @@ -44,32 +44,32 @@ public: Initializer(Database &database, bool isInitialized) { if (!isInitialized) { - createSourceContextsTable(database); - createSourceNamesTable(database); + createDirectoryPathsTable(database); + createFileNamesTable(database); } } - void createSourceContextsTable(Database &database) + void createDirectoryPathsTable(Database &database) { Sqlite::Table table; table.setUseIfNotExists(true); - table.setName("sourceContexts"); - table.addColumn("sourceContextId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}}); - const Sqlite::Column &sourceContextPathColumn = table.addColumn("sourceContextPath"); + table.setName("directoryPaths"); + table.addColumn("directoryPathId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}}); + const Sqlite::Column &directoryPathColumn = table.addColumn("directoryPath"); - table.addUniqueIndex({sourceContextPathColumn}); + table.addUniqueIndex({directoryPathColumn}); table.initialize(database); } - void createSourceNamesTable(Database &database) + void createFileNamesTable(Database &database) { Sqlite::StrictTable table; table.setUseIfNotExists(true); - table.setName("sourceNames"); - table.addColumn("sourceNameId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); - const auto &sourceNameColumn = table.addColumn("sourceName", Sqlite::StrictColumnType::Text); - table.addUniqueIndex({sourceNameColumn}); + table.setName("fileNames"); + table.addColumn("fileNameId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); + const auto &fileNameColumn = table.addColumn("fileName", Sqlite::StrictColumnType::Text); + table.addUniqueIndex({fileNameColumn}); table.initialize(database); } @@ -88,52 +88,52 @@ SourcePathStorage::SourcePathStorage(Database &database, bool isInitialized) SourcePathStorage::~SourcePathStorage() = default; -SourceContextId SourcePathStorage::fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath) +DirectoryPathId SourcePathStorage::fetchDirectoryPathIdUnguarded(Utils::SmallStringView directoryPath) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source context id unguarded", category()}; - auto sourceContextId = readSourceContextId(sourceContextPath); + auto directoryPathId = readDirectoryPathId(directoryPath); - return sourceContextId ? sourceContextId : writeSourceContextId(sourceContextPath); + return directoryPathId ? directoryPathId : writeDirectoryPathId(directoryPath); } -SourceContextId SourcePathStorage::fetchSourceContextId(Utils::SmallStringView sourceContextPath) +DirectoryPathId SourcePathStorage::fetchDirectoryPathId(Utils::SmallStringView directoryPath) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source context id", category(), - keyValue("source context path", sourceContextPath)}; + keyValue("source context path", directoryPath)}; - SourceContextId sourceContextId; + DirectoryPathId directoryPathId; try { - sourceContextId = Sqlite::withDeferredTransaction(database, [&] { - return fetchSourceContextIdUnguarded(sourceContextPath); + directoryPathId = Sqlite::withDeferredTransaction(database, [&] { + return fetchDirectoryPathIdUnguarded(directoryPath); }); } catch (const Sqlite::ConstraintPreventsModification &) { - sourceContextId = fetchSourceContextId(sourceContextPath); + directoryPathId = fetchDirectoryPathId(directoryPath); } - tracer.end(keyValue("source context id", sourceContextId)); + tracer.end(keyValue("source context id", directoryPathId)); - return sourceContextId; + return directoryPathId; } -Utils::PathString SourcePathStorage::fetchSourceContextPath(SourceContextId sourceContextId) const +Utils::PathString SourcePathStorage::fetchDirectoryPath(DirectoryPathId directoryPathId) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source context path", category(), - keyValue("source context id", sourceContextId)}; + keyValue("source context id", directoryPathId)}; auto path = Sqlite::withDeferredTransaction(database, [&] { - auto optionalSourceContextPath = s->selectSourceContextPathFromSourceContextsBySourceContextIdStatement - .optionalValue(sourceContextId); + auto optionalDirectoryPath = s->selectDirectoryPathFromDirectoryPathsByDirectoryPathIdStatement + .optionalValue(directoryPathId); - if (!optionalSourceContextPath) - throw SourceContextIdDoesNotExists(); + if (!optionalDirectoryPath) + throw DirectoryPathIdDoesNotExists(); - return std::move(*optionalSourceContextPath); + return std::move(*optionalDirectoryPath); }); tracer.end(keyValue("source context path", path)); @@ -141,133 +141,133 @@ Utils::PathString SourcePathStorage::fetchSourceContextPath(SourceContextId sour return path; } -Cache::SourceContexts SourcePathStorage::fetchAllSourceContexts() const +Cache::DirectoryPaths SourcePathStorage::fetchAllDirectoryPaths() const { NanotraceHR::Tracer tracer{"fetch all source contexts", category()}; - return s->selectAllSourceContextsStatement.valuesWithTransaction(); + return s->selectAllDirectoryPathsStatement.valuesWithTransaction(); } -SourceNameId SourcePathStorage::fetchSourceNameId(Utils::SmallStringView sourceName) +FileNameId SourcePathStorage::fetchFileNameId(Utils::SmallStringView fileName) { using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source id", category(), keyValue("source name", sourceName)}; + NanotraceHR::Tracer tracer{"fetch source id", category(), keyValue("source name", fileName)}; - auto sourceNameId = Sqlite::withDeferredTransaction(database, [&] { - return fetchSourceNameIdUnguarded(sourceName); + auto fileNameId = Sqlite::withDeferredTransaction(database, [&] { + return fetchFileNameIdUnguarded(fileName); }); - tracer.end(keyValue("source name id", sourceNameId)); + tracer.end(keyValue("source name id", fileNameId)); - return sourceNameId; + return fileNameId; } -Utils::SmallString SourcePathStorage::fetchSourceName(SourceNameId sourceNameId) const +Utils::SmallString SourcePathStorage::fetchFileName(FileNameId fileNameId) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source name and source context id", category(), - keyValue("source name id", sourceNameId)}; + keyValue("source name id", fileNameId)}; - auto sourceName = s->selectSourceNameFromSourceNamesBySourceNameIdStatement - .valueWithTransaction(sourceNameId); + auto fileName = s->selectFileNameFromFileNamesByFileNameIdStatement + .valueWithTransaction(fileNameId); - if (sourceName.empty()) - throw SourceNameIdDoesNotExists(); + if (fileName.empty()) + throw FileNameIdDoesNotExists(); - tracer.end(keyValue("source name", sourceName)); + tracer.end(keyValue("source name", fileName)); - return sourceName; + return fileName; } void SourcePathStorage::clearSources() { Sqlite::withImmediateTransaction(database, [&] { - s->deleteAllSourceContextsStatement.execute(); - s->deleteAllSourceNamesStatement.execute(); + s->deleteAllDirectoryPathsStatement.execute(); + s->deleteAllFileNamesStatement.execute(); }); } -Cache::SourceNames SourcePathStorage::fetchAllSourceNames() const +Cache::FileNames SourcePathStorage::fetchAllFileNames() const { NanotraceHR::Tracer tracer{"fetch all sources", category()}; - return s->selectAllSourcesStatement.valuesWithTransaction(); + return s->selectAllSourcesStatement.valuesWithTransaction(); } -SourceNameId SourcePathStorage::fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName) +FileNameId SourcePathStorage::fetchFileNameIdUnguarded(Utils::SmallStringView fileName) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source id unguarded", category(), - keyValue("source name", sourceName)}; + keyValue("source name", fileName)}; - auto sourceId = readSourceNameId(sourceName); + auto sourceId = readFileNameId(fileName); if (!sourceId) - sourceId = writeSourceNameId(sourceName); + sourceId = writeFileNameId(fileName); tracer.end(keyValue("source id", sourceId)); return sourceId; } -SourceContextId SourcePathStorage::readSourceContextId(Utils::SmallStringView sourceContextPath) +DirectoryPathId SourcePathStorage::readDirectoryPathId(Utils::SmallStringView directoryPath) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"read source context id", category(), - keyValue("source context path", sourceContextPath)}; + keyValue("source context path", directoryPath)}; - auto sourceContextId = s->selectSourceContextIdFromSourceContextsBySourceContextPathStatement - .value(sourceContextPath); + auto directoryPathId = s->selectDirectoryPathIdFromDirectoryPathsByDirectoryPathStatement + .value(directoryPath); - tracer.end(keyValue("source context id", sourceContextId)); + tracer.end(keyValue("source context id", directoryPathId)); - return sourceContextId; + return directoryPathId; } -SourceContextId SourcePathStorage::writeSourceContextId(Utils::SmallStringView sourceContextPath) +DirectoryPathId SourcePathStorage::writeDirectoryPathId(Utils::SmallStringView directoryPath) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"write source context id", category(), - keyValue("source context path", sourceContextPath)}; + keyValue("source context path", directoryPath)}; - s->insertIntoSourceContextsStatement.write(sourceContextPath); + s->insertIntoDirectoryPathsStatement.write(directoryPath); - auto sourceContextId = SourceContextId::create(static_cast(database.lastInsertedRowId())); + auto directoryPathId = DirectoryPathId::create(static_cast(database.lastInsertedRowId())); - tracer.end(keyValue("source context id", sourceContextId)); + tracer.end(keyValue("source context id", directoryPathId)); - return sourceContextId; + return directoryPathId; } -SourceNameId SourcePathStorage::writeSourceNameId(Utils::SmallStringView sourceName) +FileNameId SourcePathStorage::writeFileNameId(Utils::SmallStringView fileName) { using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"write source id", category(), keyValue("source name", sourceName)}; + NanotraceHR::Tracer tracer{"write source id", category(), keyValue("source name", fileName)}; - s->insertIntoSourcesStatement.write(sourceName); + s->insertIntoSourcesStatement.write(fileName); - auto sourceNameId = SourceNameId::create(static_cast(database.lastInsertedRowId())); + auto fileNameId = FileNameId::create(static_cast(database.lastInsertedRowId())); - tracer.end(keyValue("source name id", sourceNameId)); + tracer.end(keyValue("source name id", fileNameId)); - return sourceNameId; + return fileNameId; } -SourceNameId SourcePathStorage::readSourceNameId(Utils::SmallStringView sourceName) +FileNameId SourcePathStorage::readFileNameId(Utils::SmallStringView fileName) { using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"read source id", category(), keyValue("source name", sourceName)}; + NanotraceHR::Tracer tracer{"read source id", category(), keyValue("source name", fileName)}; - auto sourceNameId = s->selectSourceNameIdFromSourceNamesBySourceNameStatement.value( - sourceName); + auto fileNameId = s->selectFileNameIdFromFileNamesByFileNameStatement.value( + fileName); - tracer.end(keyValue("source id", sourceNameId)); + tracer.end(keyValue("source id", fileNameId)); - return sourceNameId; + return fileNameId; } void SourcePathStorage::resetForTestsOnly() diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.h index 2fc5896a320..b3e306ee18e 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.h @@ -21,34 +21,34 @@ public: SourcePathStorage(Database &database, bool isInitialized); ~SourcePathStorage(); - SourceContextId fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath); + DirectoryPathId fetchDirectoryPathIdUnguarded(Utils::SmallStringView directoryPath); - SourceContextId fetchSourceContextId(Utils::SmallStringView sourceContextPath); + DirectoryPathId fetchDirectoryPathId(Utils::SmallStringView directoryPath); - Utils::PathString fetchSourceContextPath(SourceContextId sourceContextId) const; + Utils::PathString fetchDirectoryPath(DirectoryPathId directoryPathId) const; - Cache::SourceContexts fetchAllSourceContexts() const; + Cache::DirectoryPaths fetchAllDirectoryPaths() const; - SourceNameId fetchSourceNameId(Utils::SmallStringView sourceName); + FileNameId fetchFileNameId(Utils::SmallStringView fileName); - Utils::SmallString fetchSourceName(SourceNameId sourceId) const; + Utils::SmallString fetchFileName(FileNameId sourceId) const; void clearSources(); - Cache::SourceNames fetchAllSourceNames() const; + Cache::FileNames fetchAllFileNames() const; - SourceNameId fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName); + FileNameId fetchFileNameIdUnguarded(Utils::SmallStringView fileName); void resetForTestsOnly(); private: - SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath); + DirectoryPathId readDirectoryPathId(Utils::SmallStringView directoryPath); - SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath); + DirectoryPathId writeDirectoryPathId(Utils::SmallStringView directoryPath); - SourceNameId writeSourceNameId(Utils::SmallStringView sourceName); + FileNameId writeFileNameId(Utils::SmallStringView fileName); - SourceNameId readSourceNameId(Utils::SmallStringView sourceName); + FileNameId readFileNameId(Utils::SmallStringView fileName); class Initializer; diff --git a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp index 911a2508b65..84d515e8cb8 100644 --- a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp @@ -214,10 +214,10 @@ public: , qmlDocumentParser{storage, pathCache} , pathWatcher{pathCache, fileStatusCache, &updater} , projectPartId{ProjectPartId::create( - pathCache.sourceContextId(Utils::PathString{project->projectDirectory().path()}) + pathCache.directoryPathId(Utils::PathString{project->projectDirectory().path()}) .internalId())} , qtPartId{ProjectPartId::create( - pathCache.sourceContextId(Utils::PathString{qmlPath(project)}).internalId())} + pathCache.directoryPathId(Utils::PathString{qmlPath(project)}).internalId())} , updater{fileSystem, storage, fileStatusCache, diff --git a/tests/unit/tests/matchers/projectstorage-matcher.h b/tests/unit/tests/matchers/projectstorage-matcher.h index 197aa36af24..877f1d2cae5 100644 --- a/tests/unit/tests/matchers/projectstorage-matcher.h +++ b/tests/unit/tests/matchers/projectstorage-matcher.h @@ -78,7 +78,7 @@ MATCHER_P3(IsItemLibraryProperty, template auto IsTypeAnnotation(QmlDesigner::SourceId sourceId, - QmlDesigner::SourceContextId directoryId, + QmlDesigner::DirectoryPathId directoryId, Utils::SmallStringView typeName, QmlDesigner::ModuleId moduleId, IconPathMatcher iconPath, diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index ac1bbfb2a4a..404e00f0e72 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -207,9 +207,9 @@ public: (const, override)); MOCK_METHOD(QmlDesigner::SmallSourceIds<4>, typeAnnotationSourceIds, - (QmlDesigner::SourceContextId directoryId), + (QmlDesigner::DirectoryPathId directoryId), (const, override)); - MOCK_METHOD(QmlDesigner::SmallSourceContextIds<64>, + MOCK_METHOD(QmlDesigner::SmallDirectoryPathIds<64>, typeAnnotationDirectoryIds, (), (const, override)); @@ -315,18 +315,18 @@ public: MOCK_METHOD(QmlDesigner::Storage::Synchronization::DirectoryInfos, fetchDirectoryInfos, - (QmlDesigner::SourceContextId directoryId), + (QmlDesigner::DirectoryPathId directoryId), (const, override)); MOCK_METHOD(QmlDesigner::Storage::Synchronization::DirectoryInfos, fetchDirectoryInfos, - (QmlDesigner::SourceContextId directoryId, + (QmlDesigner::DirectoryPathId directoryId, QmlDesigner::Storage::Synchronization::FileType), (const, override)); - MOCK_METHOD(QmlDesigner::SmallSourceContextIds<32>, + MOCK_METHOD(QmlDesigner::SmallDirectoryPathIds<32>, fetchSubdirectoryIds, - (QmlDesigner::SourceContextId directoryId), + (QmlDesigner::DirectoryPathId directoryId), (const, override)); MOCK_METHOD(std::optional, @@ -334,25 +334,25 @@ public: (QmlDesigner::SourceId sourceId), (const, override)); - MOCK_METHOD(QmlDesigner::SourceContextId, - fetchSourceContextId, - (::Utils::SmallStringView SourceContextPath), + MOCK_METHOD(QmlDesigner::DirectoryPathId, + fetchDirectoryPathId, + (::Utils::SmallStringView DirectoryPath), ()); - MOCK_METHOD(QmlDesigner::SourceNameId, fetchSourceNameId, (::Utils::SmallStringView sourceName), ()); - MOCK_METHOD(QmlDesigner::SourceContextId, - fetchSourceContextIdUnguarded, - (::Utils::SmallStringView sourceContextPath), + MOCK_METHOD(QmlDesigner::FileNameId, fetchFileNameId, (::Utils::SmallStringView fileName), ()); + MOCK_METHOD(QmlDesigner::DirectoryPathId, + fetchDirectoryPathIdUnguarded, + (::Utils::SmallStringView directoryPath), ()); - MOCK_METHOD(QmlDesigner::SourceNameId, - fetchSourceNameIdUnguarded, - (::Utils::SmallStringView sourceName), + MOCK_METHOD(QmlDesigner::FileNameId, + fetchFileNameIdUnguarded, + (::Utils::SmallStringView fileName), ()); MOCK_METHOD(::Utils::PathString, - fetchSourceContextPath, - (QmlDesigner::SourceContextId sourceContextId)); - MOCK_METHOD(Utils::SmallString, fetchSourceName, (QmlDesigner::SourceNameId sourceId)); - MOCK_METHOD(std::vector, fetchAllSourceContexts, (), ()); - MOCK_METHOD(std::vector, fetchAllSourceNames, (), ()); + fetchDirectoryPath, + (QmlDesigner::DirectoryPathId directoryPathId)); + MOCK_METHOD(Utils::SmallString, fetchFileName, (QmlDesigner::FileNameId sourceId)); + MOCK_METHOD(std::vector, fetchAllDirectoryPaths, (), ()); + MOCK_METHOD(std::vector, fetchAllFileNames, (), ()); MOCK_METHOD(QmlDesigner::SourceId, propertyEditorPathId, diff --git a/tests/unit/tests/mocks/projectstoragepathwatchermock.h b/tests/unit/tests/mocks/projectstoragepathwatchermock.h index dd4e015d0b0..85918bde040 100644 --- a/tests/unit/tests/mocks/projectstoragepathwatchermock.h +++ b/tests/unit/tests/mocks/projectstoragepathwatchermock.h @@ -14,7 +14,7 @@ public: MOCK_METHOD(void, updateContextIdPaths, (const std::vector &idPaths, - const QmlDesigner::SourceContextIds &sourceContextIds), + const QmlDesigner::DirectoryPathIds &directoryPathIds), (override)); MOCK_METHOD(void, removeIds, (const QmlDesigner::ProjectPartIds &ids), (override)); MOCK_METHOD(void, diff --git a/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h b/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h index 85f4afc2f50..f77a125990d 100644 --- a/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h +++ b/tests/unit/tests/mocks/projectstoragetriggerupdatemock.h @@ -14,6 +14,6 @@ public: MOCK_METHOD(void, checkForChangeInDirectory, - (QmlDesigner::SourceContextIds sourceContextIds), + (QmlDesigner::DirectoryPathIds directoryPathIds), (override)); }; diff --git a/tests/unit/tests/mocks/sourcepathcachemock.h b/tests/unit/tests/mocks/sourcepathcachemock.h index 5b4f16fe175..715dae589cd 100644 --- a/tests/unit/tests/mocks/sourcepathcachemock.h +++ b/tests/unit/tests/mocks/sourcepathcachemock.h @@ -22,27 +22,27 @@ public: (const, override)); MOCK_METHOD(QmlDesigner::SourceId, sourceId, - (QmlDesigner::SourceContextId sourceContextId, Utils::SmallStringView sourceName), + (QmlDesigner::DirectoryPathId directoryPathId, Utils::SmallStringView fileName), (const, override)); - MOCK_METHOD(QmlDesigner::SourceNameId, - sourceNameId, - (Utils::SmallStringView sourceName), + MOCK_METHOD(QmlDesigner::FileNameId, + fileNameId, + (Utils::SmallStringView fileName), (const, override)); MOCK_METHOD(QmlDesigner::SourcePath, sourcePath, (QmlDesigner::SourceId sourceId), (const, override)); - MOCK_METHOD(QmlDesigner::SourceContextId, - sourceContextId, + MOCK_METHOD(QmlDesigner::DirectoryPathId, + directoryPathId, (Utils::SmallStringView directoryPath), (const, override)); MOCK_METHOD(Utils::PathString, - sourceContextPath, - (QmlDesigner::SourceContextId directoryPathId), + directoryPath, + (QmlDesigner::DirectoryPathId directoryPathId), (const, override)); MOCK_METHOD(Utils::SmallString, - sourceName, - (QmlDesigner::SourceNameId sourceName), + fileName, + (QmlDesigner::FileNameId fileName), (const, override)); MOCK_METHOD(void, populateIfEmpty, (), (override)); }; diff --git a/tests/unit/tests/mocks/sqlitereadstatementmock.h b/tests/unit/tests/mocks/sqlitereadstatementmock.h index aaeb9df94b4..d00e44a60c2 100644 --- a/tests/unit/tests/mocks/sqlitereadstatementmock.h +++ b/tests/unit/tests/mocks/sqlitereadstatementmock.h @@ -64,21 +64,21 @@ public: (long long, Utils::SmallStringView), ()); - MOCK_METHOD(std::vector, - valuesReturnCacheSourceContexts, + MOCK_METHOD(std::vector, + valuesReturnCacheDirectoryPaths, (std::size_t), ()); - MOCK_METHOD(std::vector, - valuesReturnCacheSourceNames, + MOCK_METHOD(std::vector, + valuesReturnCacheFileNames, (std::size_t), ()); MOCK_METHOD(Sqlite::TimeStamp, valueWithTransactionReturnsTimeStamp, (Utils::SmallStringView), ()); MOCK_METHOD(int, valueWithTransactionReturnsInt, (Utils::SmallStringView), ()); - MOCK_METHOD(QmlDesigner::SourceContextId, valueReturnsSourceContextId, (Utils::SmallStringView), ()); - MOCK_METHOD(QmlDesigner::SourceContextId, valueWithTransactionReturnsSourceContextId, (int), ()); + MOCK_METHOD(QmlDesigner::DirectoryPathId, valueReturnsDirectoryPathId, (Utils::SmallStringView), ()); + MOCK_METHOD(QmlDesigner::DirectoryPathId, valueWithTransactionReturnsDirectoryPathId, (int), ()); MOCK_METHOD(QmlDesigner::SourceId, valueReturnsSourceId, (int, Utils::SmallStringView), ()); @@ -161,8 +161,8 @@ public: else if constexpr (std::is_same_v>) return valueReturnsPropertyDeclaration(queryValues...); - else if constexpr (std::is_same_v) - return valueReturnsSourceContextId(queryValues...); + else if constexpr (std::is_same_v) + return valueReturnsDirectoryPathId(queryValues...); else if constexpr (std::is_same_v) return valueReturnsSourceId(queryValues...); else if constexpr (std::is_same_v) @@ -181,8 +181,8 @@ public: else if constexpr (std::is_same_v>) return valueReturnsPropertyDeclaration(queryValues...); - else if constexpr (std::is_same_v) - return valueWithTransactionReturnsSourceContextId(queryValues...); + else if constexpr (std::is_same_v) + return valueWithTransactionReturnsDirectoryPathId(queryValues...); else if constexpr (std::is_same_v) return valueWithTransactionReturnsTimeStamp(queryValues...); else if constexpr (std::is_same_v) @@ -207,10 +207,10 @@ public: return valuesReturnStringVector(reserveSize); else if constexpr (std::is_same_v) return valuesReturnRowIds(reserveSize); - else if constexpr (std::is_same_v) - return valuesReturnCacheSourceContexts(reserveSize); - else if constexpr (std::is_same_v) - return valuesReturnCacheSourceNames(reserveSize); + else if constexpr (std::is_same_v) + return valuesReturnCacheDirectoryPaths(reserveSize); + else if constexpr (std::is_same_v) + return valuesReturnCacheFileNames(reserveSize); else if constexpr (std::is_same_v) return valuesReturnsStorageTypes(reserveSize, queryValues...); else if constexpr (std::is_same_v) diff --git a/tests/unit/tests/printers/gtest-creator-printing.cpp b/tests/unit/tests/printers/gtest-creator-printing.cpp index 6d82128ab18..231348b7f8b 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.cpp +++ b/tests/unit/tests/printers/gtest-creator-printing.cpp @@ -489,7 +489,7 @@ std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths) std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry) { - return out << "(" << entry.sourceId << ", " << entry.sourceContextId << ", " << entry.id << ", " + return out << "(" << entry.sourceId << ", " << entry.directoryPathId << ", " << entry.id << ", " << entry.lastModified << ")"; } @@ -600,9 +600,9 @@ std::ostream &operator<<(std::ostream &out, AuxiliaryDataType type) namespace Cache { -std::ostream &operator<<(std::ostream &out, const SourceContext &sourceContext) +std::ostream &operator<<(std::ostream &out, const DirectoryPath &directoryPath) { - return out << "(" << sourceContext.id << ", " << sourceContext.value << ")"; + return out << "(" << directoryPath.id << ", " << directoryPath.value << ")"; } } // namespace Cache diff --git a/tests/unit/tests/printers/gtest-creator-printing.h b/tests/unit/tests/printers/gtest-creator-printing.h index cb5731c53e6..b0ef8395a6a 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.h +++ b/tests/unit/tests/printers/gtest-creator-printing.h @@ -164,9 +164,9 @@ std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey> mockCompressorCallback; + NiceMock> mockCompressorCallback; QmlDesigner::DirectoryPathCompressor> compressor; NiceMock &mockTimer = compressor.timer(); - SourceContextId sourceContextId1{SourceContextId::create(1)}; - SourceContextId sourceContextId2{SourceContextId::create(2)}; + DirectoryPathId directoryPathId1{DirectoryPathId::create(1)}; + DirectoryPathId directoryPathId2{DirectoryPathId::create(2)}; }; TEST_F(DirectoryPathCompressor, add_file_path) { - compressor.addSourceContextId(sourceContextId1); + compressor.addDirectoryPathId(directoryPathId1); - ASSERT_THAT(compressor.sourceContextIds(), ElementsAre(sourceContextId1)); + ASSERT_THAT(compressor.directoryPathIds(), ElementsAre(directoryPathId1)); } TEST_F(DirectoryPathCompressor, clear__after_calling_callback) { - compressor.addSourceContextId(sourceContextId1); + compressor.addDirectoryPathId(directoryPathId1); compressor.timer().emitTimoutIfStarted(); - ASSERT_THAT(compressor.sourceContextIds(), IsEmpty()); + ASSERT_THAT(compressor.directoryPathIds(), IsEmpty()); } TEST_F(DirectoryPathCompressor, dont_clear_for_thrown_exception) { - compressor.addSourceContextId(sourceContextId1); - compressor.setCallback([](const SourceContextIds &) { throw std::exception{}; }); + compressor.addDirectoryPathId(directoryPathId1); + compressor.setCallback([](const DirectoryPathIds &) { throw std::exception{}; }); compressor.timer().emitTimoutIfStarted(); - ASSERT_THAT(compressor.sourceContextIds(), ElementsAre(sourceContextId1)); + ASSERT_THAT(compressor.directoryPathIds(), ElementsAre(directoryPathId1)); } TEST_F(DirectoryPathCompressor, call_restart_timer_after_adding_path) { EXPECT_CALL(mockTimer, start(20)); - compressor.addSourceContextId(sourceContextId1); + compressor.addDirectoryPathId(directoryPathId1); } TEST_F(DirectoryPathCompressor, call_time_out_after_adding_path) { - EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(sourceContextId1, sourceContextId2))); + EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(directoryPathId1, directoryPathId2))); - compressor.addSourceContextId(sourceContextId1); - compressor.addSourceContextId(sourceContextId2); + compressor.addDirectoryPathId(directoryPathId1); + compressor.addDirectoryPathId(directoryPathId2); } TEST_F(DirectoryPathCompressor, remove_duplicates) { - EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(sourceContextId1, sourceContextId2))); + EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(directoryPathId1, directoryPathId2))); - compressor.addSourceContextId(sourceContextId1); - compressor.addSourceContextId(sourceContextId2); - compressor.addSourceContextId(sourceContextId1); + compressor.addDirectoryPathId(directoryPathId1); + compressor.addDirectoryPathId(directoryPathId2); + compressor.addDirectoryPathId(directoryPathId1); } } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 79c75478bc4..45b2a3e56a4 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -24,11 +24,11 @@ using QmlDesigner::FileStatuses; using QmlDesigner::FlagIs; using QmlDesigner::ModuleId; using QmlDesigner::PropertyDeclarationId; -using QmlDesigner::SourceContextId; -using QmlDesigner::SourceContextIds; +using QmlDesigner::DirectoryPathId; +using QmlDesigner::DirectoryPathIds; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; -using QmlDesigner::SourceNameId; +using QmlDesigner::FileNameId; using QmlDesigner::Storage::ModuleKind; using QmlDesigner::Storage::Synchronization::SynchronizationPackage; using QmlDesigner::Storage::Synchronization::TypeAnnotations; @@ -1070,16 +1070,16 @@ protected: package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "QtObject", sourceId1, - sourceContextIdPath6); + directoryPathIdPath6); package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item", sourceId2, - sourceContextIdPath6); + directoryPathIdPath6); package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item3D", sourceId3, - sourceContextIdPath6); - package.updatedPropertyEditorQmlPathDirectoryIds.emplace_back(sourceContextIdPath6); + directoryPathIdPath6); + package.updatedPropertyEditorQmlPathDirectoryIds.emplace_back(directoryPathIdPath6); return package; } @@ -1093,7 +1093,7 @@ protected: traits.visibleInLibrary = FlagIs::True; annotations.emplace_back(sourceId4, - sourceContextIdPath6, + directoryPathIdPath6, "Object", qmlModuleId, "/path/to/icon.png", @@ -1115,7 +1115,7 @@ protected: "properties":[["color", "color", "#blue"]]}])xy"); annotations.emplace_back(sourceId5, - sourceContextIdPath6, + directoryPathIdPath6, "Item", qtQuickModuleId, "/path/to/quick.png", @@ -1140,7 +1140,7 @@ protected: traits.visibleInLibrary = FlagIs::True; annotations.emplace_back(sourceId5, - sourceContextIdPath1, + directoryPathIdPath1, "Item", qtQuickModuleId, "/path/to/quick.png", @@ -1253,13 +1253,13 @@ protected: SourceId sourceId5{sourcePathCache.sourceId(path5)}; SourceId sourceId6{sourcePathCache.sourceId(path6)}; SourceId sourceIdPath1{sourcePathCache.sourceId(pathPath1)}; - SourceContextId sourceContextIdPath1{sourceIdPath1.contextId()}; + DirectoryPathId directoryPathIdPath1{sourceIdPath1.contextId()}; SourceId sourceIdPath6{sourcePathCache.sourceId(pathPath6)}; - SourceContextId sourceContextIdPath6{sourceIdPath6.contextId()}; + DirectoryPathId directoryPathIdPath6{sourceIdPath6.contextId()}; SourceId qmlProjectSourceId{sourcePathCache.sourceId("/path1/qmldir")}; - SourceContextId qmlProjectSourceContextId = qmlProjectSourceId.contextId(); + DirectoryPathId qmlProjectDirectoryPathId = qmlProjectSourceId.contextId(); SourceId qtQuickProjectSourceId{sourcePathCache.sourceId("/path2/qmldir")}; - SourceContextId qtQuickProjectSourceContextId = qtQuickProjectSourceId.contextId(); + DirectoryPathId qtQuickProjectDirectoryPathId = qtQuickProjectSourceId.contextId(); ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; ModuleId qmlNativeModuleId{storage.moduleId("Qml", ModuleKind::CppLibrary)}; ModuleId qtQuickModuleId{storage.moduleId("QtQuick", ModuleKind::QmlLibrary)}; @@ -5829,261 +5829,261 @@ TEST_F(ProjectStorage, populate_module_cache) TEST_F(ProjectStorage, add_directory_infoes) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); - ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceContextId, qtQuickProjectSourceContextId}), + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}), UnorderedElementsAre(directoryInfo1, directoryInfo2, directoryInfo3)); } TEST_F(ProjectStorage, remove_directory_info) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1}}); - ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceContextId, qtQuickProjectSourceContextId}), + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}), UnorderedElementsAre(directoryInfo1)); } TEST_F(ProjectStorage, update_directory_info_file_type) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2b{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2b{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlTypes}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1, directoryInfo2b}}); + SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1, directoryInfo2b}}); - ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceContextId, qtQuickProjectSourceContextId}), + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}), UnorderedElementsAre(directoryInfo1, directoryInfo2b, directoryInfo3)); } TEST_F(ProjectStorage, update_directory_info_module_id) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId3, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2b{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2b{qmlProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId2, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1, directoryInfo2b}}); + SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1, directoryInfo2b}}); - ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceContextId, qtQuickProjectSourceContextId}), + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}), UnorderedElementsAre(directoryInfo1, directoryInfo2b, directoryInfo3)); } TEST_F(ProjectStorage, throw_for_invalid_source_id_in_directory_info) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, SourceId{}, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; ASSERT_THROW(storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1}}), + SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1}}), QmlDesigner::DirectoryInfoHasInvalidSourceId); } TEST_F(ProjectStorage, insert_directory_info_with_invalid_module_id) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, ModuleId{}, Storage::Synchronization::FileType::QmlDocument}; - storage.synchronize(SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1}}); + storage.synchronize(SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1}}); - ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceContextId, qtQuickProjectSourceContextId}), + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}), UnorderedElementsAre(directoryInfo1)); } TEST_F(ProjectStorage, update_directory_info_with_invalid_module_id) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - storage.synchronize(SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1}}); + storage.synchronize(SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1}}); directoryInfo1.moduleId = ModuleId{}; - storage.synchronize(SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1}}); + storage.synchronize(SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1}}); - ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceContextId, qtQuickProjectSourceContextId}), + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}), UnorderedElementsAre(directoryInfo1)); } -TEST_F(ProjectStorage, throw_for_updating_with_invalid_project_source_context_id_in_directory_info) +TEST_F(ProjectStorage, throw_for_updating_with_invalid_project_directory_path_id_in_directory_info) { Storage::Synchronization::DirectoryInfo directoryInfo1{ - SourceContextId{}, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; + DirectoryPathId{}, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; ASSERT_THROW(storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId}, {directoryInfo1}}), + SynchronizationPackage{{qmlProjectDirectoryPathId}, {directoryInfo1}}), QmlDesigner::DirectoryInfoHasInvalidProjectSourceId); } -TEST_F(ProjectStorage, fetch_directory_infos_by_directory_source_context_ids) +TEST_F(ProjectStorage, fetch_directory_infos_by_directory_directory_path_ids) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); auto directoryInfos = storage.fetchDirectoryInfos( - {qmlProjectSourceContextId, qtQuickProjectSourceContextId}); + {qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}); ASSERT_THAT(directoryInfos, UnorderedElementsAre(directoryInfo1, directoryInfo2, directoryInfo3)); } -TEST_F(ProjectStorage, fetch_directory_infos_by_directory_source_context_id) +TEST_F(ProjectStorage, fetch_directory_infos_by_directory_directory_path_id) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); - auto directoryInfo = storage.fetchDirectoryInfos(qmlProjectSourceContextId); + auto directoryInfo = storage.fetchDirectoryInfos(qmlProjectDirectoryPathId); ASSERT_THAT(directoryInfo, UnorderedElementsAre(directoryInfo1, directoryInfo2)); } -TEST_F(ProjectStorage, fetch_directory_infos_by_directory_source_context_id_and_file_type) +TEST_F(ProjectStorage, fetch_directory_infos_by_directory_directory_path_id_and_file_type) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, ModuleId{}, Storage::Synchronization::FileType::Directory}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; - Storage::Synchronization::DirectoryInfo directoryInfo4{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo4{qmlProjectDirectoryPathId, sourceId4, ModuleId{}, Storage::Synchronization::FileType::Directory}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3, directoryInfo4}}); - auto directoryInfo = storage.fetchDirectoryInfos(qmlProjectSourceContextId, + auto directoryInfo = storage.fetchDirectoryInfos(qmlProjectDirectoryPathId, Storage::Synchronization::FileType::Directory); ASSERT_THAT(directoryInfo, UnorderedElementsAre(directoryInfo2, directoryInfo4)); } -TEST_F(ProjectStorage, fetch_subdirectory_source_context_ids) +TEST_F(ProjectStorage, fetch_subdirectory_directory_path_ids) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - auto directory1Id = SourceId::create(SourceNameId{}, sourceId2.contextId()); - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + auto directory1Id = SourceId::create(FileNameId{}, sourceId2.contextId()); + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, directory1Id, ModuleId{}, Storage::Synchronization::FileType::Directory}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; - auto directory2Id = SourceId::create(SourceNameId{}, sourceId4.contextId()); - Storage::Synchronization::DirectoryInfo directoryInfo4{qmlProjectSourceContextId, + auto directory2Id = SourceId::create(FileNameId{}, sourceId4.contextId()); + Storage::Synchronization::DirectoryInfo directoryInfo4{qmlProjectDirectoryPathId, directory2Id, ModuleId{}, Storage::Synchronization::FileType::Directory}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3, directoryInfo4}}); - auto directoryInfo = storage.fetchSubdirectoryIds(qmlProjectSourceContextId); + auto directoryInfo = storage.fetchSubdirectoryIds(qmlProjectDirectoryPathId); ASSERT_THAT(directoryInfo, UnorderedElementsAre(directory1Id.contextId(), directory2Id.contextId())); @@ -6091,20 +6091,20 @@ TEST_F(ProjectStorage, fetch_subdirectory_source_context_ids) TEST_F(ProjectStorage, fetch_directory_info_by_source_id) { - Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceContextId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectDirectoryPathId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize( - SynchronizationPackage{{qmlProjectSourceContextId, qtQuickProjectSourceContextId}, + SynchronizationPackage{{qmlProjectDirectoryPathId, qtQuickProjectDirectoryPathId}, {directoryInfo1, directoryInfo2, directoryInfo3}}); auto directoryInfo = storage.fetchDirectoryInfo(sourceId2); @@ -8295,7 +8295,7 @@ TEST_F(ProjectStorage, synchronize_property_editor_adds_path) package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item3D", sourceId3, - sourceContextIdPath6); + directoryPathIdPath6); storage.synchronize(package); @@ -8310,7 +8310,7 @@ TEST_F(ProjectStorage, synchronize_property_editor_with_non_existing_type_name) package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item4D", sourceId4, - sourceContextIdPath6); + directoryPathIdPath6); storage.synchronize(package); @@ -8675,7 +8675,7 @@ TEST_F(ProjectStorage, synchronize_type_annotation_directory_source_id) storage.synchronize(package); - ASSERT_THAT(storage.typeAnnotationSourceIds(sourceContextIdPath6), + ASSERT_THAT(storage.typeAnnotationSourceIds(directoryPathIdPath6), UnorderedElementsAre(sourceId4, sourceId5)); } @@ -8687,7 +8687,7 @@ TEST_F(ProjectStorage, get_type_annotation_source_ids) package.typeAnnotations); storage.synchronize(package); - auto sourceIds = storage.typeAnnotationSourceIds(sourceContextIdPath6); + auto sourceIds = storage.typeAnnotationSourceIds(directoryPathIdPath6); ASSERT_THAT(sourceIds, UnorderedElementsAre(sourceId4, sourceId5)); } @@ -8702,7 +8702,7 @@ TEST_F(ProjectStorage, get_type_annotation_directory_source_ids) auto sourceIds = storage.typeAnnotationDirectoryIds(); - ASSERT_THAT(sourceIds, ElementsAre(sourceContextIdPath1, sourceContextIdPath6)); + ASSERT_THAT(sourceIds, ElementsAre(directoryPathIdPath1, directoryPathIdPath6)); } TEST_F(ProjectStorage, get_all_item_library_entries) diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index 137acfef8d2..ee6d99c27f4 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -27,8 +27,8 @@ using QmlDesigner::ProjectChunkId; using QmlDesigner::ProjectChunkIds; using QmlDesigner::ProjectPartId; using QmlDesigner::ProjectPartIds; -using QmlDesigner::SourceContextId; -using QmlDesigner::SourceContextIds; +using QmlDesigner::DirectoryPathId; +using QmlDesigner::DirectoryPathIds; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; using QmlDesigner::SourcePath; @@ -62,11 +62,11 @@ protected: return FileStatus{sourceId, 1, 1}; }); - ON_CALL(mockFileSystem, directoryEntries(Eq(sourceContextPath))) + ON_CALL(mockFileSystem, directoryEntries(Eq(directoryPath))) .WillByDefault(Return(SourceIds{sourceIds[0], sourceIds[1]})); - ON_CALL(mockFileSystem, directoryEntries(Eq(sourceContextPath2))) + ON_CALL(mockFileSystem, directoryEntries(Eq(directoryPath2))) .WillByDefault(Return(SourceIds{sourceIds[2], sourceIds[3]})); - ON_CALL(mockFileSystem, directoryEntries(Eq(sourceContextPath3))) + ON_CALL(mockFileSystem, directoryEntries(Eq(directoryPath3))) .WillByDefault(Return(SourceIds{sourceIds[4]})); } @@ -98,40 +98,40 @@ protected: SourcePathView path5{"/path3/path"}; QString path1QString = QString(path1.toStringView()); QString path2QString = QString(path2.toStringView()); - QString sourceContextPath = "/path"; - QString sourceContextPath2 = "/path2"; - QString sourceContextPath3 = "/path3"; - Utils::PathString sourceContextPathString = sourceContextPath; - Utils::PathString sourceContextPathString2 = sourceContextPath2; + QString directoryPath = "/path"; + QString directoryPath2 = "/path2"; + QString directoryPath3 = "/path3"; + Utils::PathString directoryPathString = directoryPath; + Utils::PathString directoryPathString2 = directoryPath2; SourceIds sourceIds = {pathCache.sourceId(path1), pathCache.sourceId(path2), pathCache.sourceId(path3), pathCache.sourceId(path4), pathCache.sourceId(path5)}; - SourceContextIds sourceContextIds = {sourceIds[0].contextId(), + DirectoryPathIds directoryPathIds = {sourceIds[0].contextId(), sourceIds[2].contextId(), sourceIds[4].contextId()}; ProjectChunkIds ids{projectChunkId1, projectChunkId2, projectChunkId3}; - WatcherEntry watcherEntry1{projectChunkId1, sourceContextIds[0], sourceIds[0]}; - WatcherEntry watcherEntry2{projectChunkId2, sourceContextIds[0], sourceIds[0]}; - WatcherEntry watcherEntry3{projectChunkId1, sourceContextIds[0], sourceIds[1]}; - WatcherEntry watcherEntry4{projectChunkId2, sourceContextIds[0], sourceIds[1]}; - WatcherEntry watcherEntry5{projectChunkId3, sourceContextIds[0], sourceIds[1]}; - WatcherEntry watcherEntry6{projectChunkId1, sourceContextIds[1], sourceIds[2]}; - WatcherEntry watcherEntry7{projectChunkId2, sourceContextIds[1], sourceIds[3]}; - WatcherEntry watcherEntry8{projectChunkId3, sourceContextIds[1], sourceIds[3]}; - WatcherEntry watcherEntry9{projectChunkId4, sourceContextIds[0], sourceIds[0]}; - WatcherEntry watcherEntry10{projectChunkId4, sourceContextIds[0], sourceIds[1]}; - WatcherEntry watcherEntry11{projectChunkId4, sourceContextIds[1], sourceIds[2]}; - WatcherEntry watcherEntry12{projectChunkId4, sourceContextIds[1], sourceIds[3]}; - WatcherEntry watcherEntry13{projectChunkId4, sourceContextIds[2], sourceIds[4]}; + WatcherEntry watcherEntry1{projectChunkId1, directoryPathIds[0], sourceIds[0]}; + WatcherEntry watcherEntry2{projectChunkId2, directoryPathIds[0], sourceIds[0]}; + WatcherEntry watcherEntry3{projectChunkId1, directoryPathIds[0], sourceIds[1]}; + WatcherEntry watcherEntry4{projectChunkId2, directoryPathIds[0], sourceIds[1]}; + WatcherEntry watcherEntry5{projectChunkId3, directoryPathIds[0], sourceIds[1]}; + WatcherEntry watcherEntry6{projectChunkId1, directoryPathIds[1], sourceIds[2]}; + WatcherEntry watcherEntry7{projectChunkId2, directoryPathIds[1], sourceIds[3]}; + WatcherEntry watcherEntry8{projectChunkId3, directoryPathIds[1], sourceIds[3]}; + WatcherEntry watcherEntry9{projectChunkId4, directoryPathIds[0], sourceIds[0]}; + WatcherEntry watcherEntry10{projectChunkId4, directoryPathIds[0], sourceIds[1]}; + WatcherEntry watcherEntry11{projectChunkId4, directoryPathIds[1], sourceIds[2]}; + WatcherEntry watcherEntry12{projectChunkId4, directoryPathIds[1], sourceIds[3]}; + WatcherEntry watcherEntry13{projectChunkId4, directoryPathIds[2], sourceIds[4]}; }; TEST_F(ProjectStoragePathWatcher, add_id_paths) { EXPECT_CALL(mockQFileSytemWatcher, addPaths( - UnorderedElementsAre(QString(sourceContextPath), QString(sourceContextPath2)))); + UnorderedElementsAre(QString(directoryPath), QString(directoryPath2)))); watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); @@ -142,7 +142,7 @@ TEST_F(ProjectStoragePathWatcher, update_id_paths_calls_add_path_in_file_watcher watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1]}}, {projectChunkId2, {sourceIds[0], sourceIds[1]}}}); - EXPECT_CALL(mockQFileSytemWatcher, addPaths(UnorderedElementsAre(QString(sourceContextPath2)))); + EXPECT_CALL(mockQFileSytemWatcher, addPaths(UnorderedElementsAre(QString(directoryPath2)))); watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); @@ -153,7 +153,7 @@ TEST_F(ProjectStoragePathWatcher, update_id_paths_and_remove_unused_paths_calls_ watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); - EXPECT_CALL(mockQFileSytemWatcher, removePaths(UnorderedElementsAre(QString(sourceContextPath2)))); + EXPECT_CALL(mockQFileSytemWatcher, removePaths(UnorderedElementsAre(QString(directoryPath2)))); watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1]}}, {projectChunkId2, {sourceIds[0], sourceIds[1]}}}); @@ -226,7 +226,7 @@ TEST_F(ProjectStoragePathWatcher, add_empty_entries) TEST_F(ProjectStoragePathWatcher, add_entries_with_same_id_and_different_paths) { EXPECT_CALL(mockQFileSytemWatcher, - addPaths(ElementsAre(sourceContextPath, sourceContextPath2, sourceContextPath3))); + addPaths(ElementsAre(directoryPath, directoryPath2, directoryPath3))); watcher.updateIdPaths( {{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[4]}}}); @@ -234,7 +234,7 @@ TEST_F(ProjectStoragePathWatcher, add_entries_with_same_id_and_different_paths) TEST_F(ProjectStoragePathWatcher, add_entries_with_different_id_and_same_paths) { - EXPECT_CALL(mockQFileSytemWatcher, addPaths(ElementsAre(sourceContextPath))); + EXPECT_CALL(mockQFileSytemWatcher, addPaths(ElementsAre(directoryPath))); watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1]}}}); } @@ -294,7 +294,7 @@ TEST_F(ProjectStoragePathWatcher, remove_path_for_one_id) watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1]}}, {projectChunkId3, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); - EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(sourceContextPath2))); + EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath2))); watcher.removeIds({projectChunkId3.id}); } @@ -316,7 +316,7 @@ TEST_F(ProjectStoragePathWatcher, remove_all_paths_for_three_id) {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); EXPECT_CALL(mockQFileSytemWatcher, - removePaths(ElementsAre(sourceContextPath, sourceContextPath2))); + removePaths(ElementsAre(directoryPath, directoryPath2))); watcher.removeIds({projectChunkId1.id, projectChunkId2.id, projectChunkId3.id}); } @@ -327,7 +327,7 @@ TEST_F(ProjectStoragePathWatcher, remove_one_path_for_two_id) {projectChunkId2, {sourceIds[0], sourceIds[1]}}, {projectChunkId3, {sourceIds[3]}}}); - EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(sourceContextPath))); + EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath))); watcher.removeIds({projectChunkId1.id, projectChunkId2.id}); } @@ -374,8 +374,8 @@ TEST_F(ProjectStoragePathWatcher, two_notify_file_changes) ElementsAre(IdPaths{projectChunkId1, {sourceIds[0], sourceIds[1]}}, IdPaths{projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}))); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); - mockQFileSytemWatcher.directoryChanged(sourceContextPath2); + mockQFileSytemWatcher.directoryChanged(directoryPath); + mockQFileSytemWatcher.directoryChanged(directoryPath2); } TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_modified_time_changes) @@ -389,7 +389,7 @@ TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_modified_time_chang EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); + mockQFileSytemWatcher.directoryChanged(directoryPath); } TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_bigger) @@ -403,7 +403,7 @@ TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_bigger) EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); + mockQFileSytemWatcher.directoryChanged(directoryPath); } TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_smaller) @@ -417,7 +417,7 @@ TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_smaller) EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); + mockQFileSytemWatcher.directoryChanged(directoryPath); } TEST_F(ProjectStoragePathWatcher, no_notify_for_unwatched_path_changes) @@ -426,7 +426,7 @@ TEST_F(ProjectStoragePathWatcher, no_notify_for_unwatched_path_changes) EXPECT_CALL(notifier, pathsChanged(IsEmpty())); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); + mockQFileSytemWatcher.directoryChanged(directoryPath); } TEST_F(ProjectStoragePathWatcher, no_duplicate_path_changes) @@ -438,8 +438,8 @@ TEST_F(ProjectStoragePathWatcher, no_duplicate_path_changes) EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); - mockQFileSytemWatcher.directoryChanged(sourceContextPath); + mockQFileSytemWatcher.directoryChanged(directoryPath); + mockQFileSytemWatcher.directoryChanged(directoryPath); } TEST_F(ProjectStoragePathWatcher, trigger_manual_two_notify_file_changes) @@ -493,7 +493,7 @@ TEST_F(ProjectStoragePathWatcher, update_context_id_paths_adds_entry_in_new_dire {projectChunkId4, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3]}}, }); - watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[4]}}}, {sourceContextIds[2]}); + watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[4]}}}, {directoryPathIds[2]}); ASSERT_THAT(watcher.watchedEntries(), UnorderedElementsAre(watcherEntry1, @@ -515,7 +515,7 @@ TEST_F(ProjectStoragePathWatcher, update_context_id_paths_adds_entry_to_director watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3]}}}, - {sourceContextIds[1]}); + {directoryPathIds[1]}); ASSERT_THAT(watcher.watchedEntries(), UnorderedElementsAre(watcherEntry1, @@ -534,7 +534,7 @@ TEST_F(ProjectStoragePathWatcher, update_context_id_paths_removes_entry) {projectChunkId4, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3]}}, }); - watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[3]}}}, {sourceContextIds[1]}); + watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[3]}}}, {directoryPathIds[1]}); ASSERT_THAT(watcher.watchedEntries(), UnorderedElementsAre(watcherEntry1, diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index 100991573cc..f10635cc2a1 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -62,12 +62,12 @@ using namespace Qt::StringLiterals; namespace Storage = QmlDesigner::Storage; +using QmlDesigner::DirectoryPathId; +using QmlDesigner::FileNameId; using QmlDesigner::FileStatus; -using QmlDesigner::ModuleId; -using QmlDesigner::SourceContextId; -using QmlDesigner::SourceId; -using QmlDesigner::SourceNameId; using QmlDesigner::IdPaths; +using QmlDesigner::ModuleId; +using QmlDesigner::SourceId; using Storage::Import; using Storage::IsInsideProject; using Storage::ModuleKind; @@ -178,11 +178,11 @@ MATCHER(PackageIsEmpty, std::string(negation ? "isn't empty" : "is empty")) && package.typeAnnotations.empty() && package.updatedTypeAnnotationSourceIds.empty(); } -template +template auto IsPropertyEditorQmlPath(const ModuleIdMatcher &moduleIdMatcher, const TypeNameMatcher &typeNameMatcher, const SourceIdMatcher &pathIdMatcher, - const SourceContextIdMatcher &directoryIdMatcher) + const DirectoryPathIdMatcher &directoryIdMatcher) { return AllOf( Field("PropertyEditorQmlPath::moduleId", &PropertyEditorQmlPath::moduleId, moduleIdMatcher), @@ -315,7 +315,7 @@ public: setFileNames(directoryPath, qmlFileNames, {"*.qml"}); } - void setDirectoryInfos(SourceContextId directorySourceId, const DirectoryInfos &directoryInfos) + void setDirectoryInfos(DirectoryPathId directorySourceId, const DirectoryInfos &directoryInfos) { ON_CALL(projectStorageMock, fetchDirectoryInfos(Eq(directorySourceId))) .WillByDefault(Return(directoryInfos)); @@ -340,8 +340,8 @@ public: ON_CALL(fileSystemMock, subdirectories(Eq(directoryPath))).WillByDefault(Return(subdirectoryPaths)); } - void setStorageSubdirectories(SourceContextId directoryId, - const QmlDesigner::SmallSourceContextIds<32> &subdirectoryIds) + void setStorageSubdirectories(DirectoryPathId directoryId, + const QmlDesigner::SmallDirectoryPathIds<32> &subdirectoryIds) { ON_CALL(projectStorageMock, fetchSubdirectoryIds(Eq(directoryId))) .WillByDefault(Return(subdirectoryIds)); @@ -354,8 +354,8 @@ public: SourceId createDirectorySourceId(Utils::SmallStringView path) const { - auto directoryId = sourcePathCache.sourceContextId(path); - return SourceId::create(SourceNameId{}, directoryId); + auto directoryId = sourcePathCache.directoryPathId(path); + return SourceId::create(FileNameId{}, directoryId); } SourceId createDirectorySourceIdFromQString(const QString &path) const @@ -470,22 +470,21 @@ protected: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); - SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); SourceId annotationDirectorySourceId = createDirectorySourceId("/path/designer"); SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml"); SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First2.qml"); SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml"); const QString itemLibraryPath = QDir::cleanPath( UNITTEST_DIR "/../../../../share/qtcreator/qmldesigner/itemLibrary/"); - SourceContextId itemLibraryPathSourceContextId = sourcePathCache.sourceContextId( + DirectoryPathId itemLibraryPathDirectoryPathId = sourcePathCache.directoryPathId( Utils::PathString{itemLibraryPath}); - SourceId itemLibraryPathSourceId = SourceId::create(SourceNameId{}, - itemLibraryPathSourceContextId); + SourceId itemLibraryPathSourceId = SourceId::create(FileNameId{}, itemLibraryPathDirectoryPathId); const QString qmlImportsPath = QDir::cleanPath(UNITTEST_DIR "/projectstorage/data/qml"); - SourceContextId qmlImportsPathSourceContextId = sourcePathCache.sourceContextId( + DirectoryPathId qmlImportsPathDirectoryPathId = sourcePathCache.directoryPathId( Utils::PathString{itemLibraryPath}); - SourceId qmlImportsPathSourceId = SourceId::create(SourceNameId{}, qmlImportsPathSourceContextId); + SourceId qmlImportsPathSourceId = SourceId::create(FileNameId{}, qmlImportsPathDirectoryPathId); ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; ModuleId qmlCppNativeModuleId{storage.moduleId("Qml", ModuleKind::CppLibrary)}; ModuleId exampleModuleId{storage.moduleId("Example", ModuleKind::QmlLibrary)}; @@ -537,12 +536,12 @@ protected: QmlDesigner::SourceType::Qml}; QmlDesigner::ProjectChunkId otherQmltypesProjectChunkId{otherProjectPartId, QmlDesigner::SourceType::QmlTypes}; - SourceContextId path1SourceContextId = sourcePathCache.sourceContextId("/path/one"); - SourceId path1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, path1SourceContextId); - SourceContextId path2SourceContextId = sourcePathCache.sourceContextId("/path/two"); - SourceId path2SourceId = SourceId::create(QmlDesigner::SourceNameId{}, path2SourceContextId); - SourceContextId path3SourceContextId = sourcePathCache.sourceContextId("/path/three"); - SourceId path3SourceId = SourceId::create(QmlDesigner::SourceNameId{}, path3SourceContextId); + DirectoryPathId path1DirectoryPathId = sourcePathCache.directoryPathId("/path/one"); + SourceId path1SourceId = SourceId::create(QmlDesigner::FileNameId{}, path1DirectoryPathId); + DirectoryPathId path2DirectoryPathId = sourcePathCache.directoryPathId("/path/two"); + SourceId path2SourceId = SourceId::create(QmlDesigner::FileNameId{}, path2DirectoryPathId); + DirectoryPathId path3DirectoryPathId = sourcePathCache.directoryPathId("/path/three"); + SourceId path3SourceId = SourceId::create(QmlDesigner::FileNameId{}, path3DirectoryPathId); SourceId qmldir1SourceId = sourcePathCache.sourceId("/path/one/qmldir"); SourceId qmldir2SourceId = sourcePathCache.sourceId("/path/two/qmldir"); SourceId qmldir3SourceId = sourcePathCache.sourceId("/path/three/qmldir"); @@ -609,8 +608,8 @@ public: QStringList directories = {"/path"}; SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); - SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); }; TEST_F(ProjectStorageUpdater_get_content_for_qml_types, added_qml_types_file_provides_content) @@ -670,8 +669,8 @@ public: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/root/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/root/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/root/path/qmldir"); - SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); }; TEST_F(ProjectStorageUpdater_parse_qml_types, add_directory) @@ -783,8 +782,8 @@ public: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/root/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/root/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/root/path/qmldir"); - SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); SourceId annotationDirectoryId = createDirectorySourceId("/root/path/designer"); SourceId rootQmlDirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); SourceId rootDirectoryPathSourceId = createDirectorySourceId("/root"); @@ -878,13 +877,13 @@ public: public: SourceId rootDirectoryPathSourceId = createDirectorySourceId("/root"); - SourceContextId rootDirectoryPathId = rootDirectoryPathSourceId.contextId(); + DirectoryPathId rootDirectoryPathId = rootDirectoryPathSourceId.contextId(); SourceId path1SourceId = createDirectorySourceId("/root/one"); - SourceContextId path1SourceContextId = path1SourceId.contextId(); + DirectoryPathId path1DirectoryPathId = path1SourceId.contextId(); SourceId path2SourceId = createDirectorySourceId("/root/two"); - SourceContextId path2SourceContextId = path2SourceId.contextId(); + DirectoryPathId path2DirectoryPathId = path2SourceId.contextId(); SourceId path3SourceId = createDirectorySourceId("/root/one/three"); - SourceContextId path3SourceContextId = path3SourceId.contextId(); + DirectoryPathId path3DirectoryPathId = path3SourceId.contextId(); }; TEST_F(ProjectStorageUpdater_synchronize_subdirectories, added_qt_subdircectories) @@ -899,13 +898,13 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, added_qt_subdircectorie UnorderedElementsAre( IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), - IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + IsDirectoryInfo(path1DirectoryPathId, path3SourceId, ModuleId{}, FileType::Directory))), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, - path1SourceContextId, - path2SourceContextId, - path3SourceContextId))))); + path1DirectoryPathId, + path2DirectoryPathId, + path3DirectoryPathId))))); updater.update({.qtDirectories = {"/root"}}); } @@ -922,13 +921,13 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, changed_qt_subdircector UnorderedElementsAre( IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), - IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + IsDirectoryInfo(path1DirectoryPathId, path3SourceId, ModuleId{}, FileType::Directory))), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, - path1SourceContextId, - path2SourceContextId, - path3SourceContextId))))); + path1DirectoryPathId, + path2DirectoryPathId, + path3DirectoryPathId))))); updater.update({.qtDirectories = {"/root"}}); } @@ -945,13 +944,13 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, added_project_subdircec UnorderedElementsAre( IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), - IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + IsDirectoryInfo(path1DirectoryPathId, path3SourceId, ModuleId{}, FileType::Directory))), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, - path1SourceContextId, - path2SourceContextId, - path3SourceContextId))))); + path1DirectoryPathId, + path2DirectoryPathId, + path3DirectoryPathId))))); updater.update({.projectDirectory = "/root"}); } @@ -968,13 +967,13 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, changed_project_subdirc UnorderedElementsAre( IsDirectoryInfo(rootDirectoryPathId, path1SourceId, ModuleId{}, FileType::Directory), IsDirectoryInfo(rootDirectoryPathId, path2SourceId, ModuleId{}, FileType::Directory), - IsDirectoryInfo(path1SourceContextId, path3SourceId, ModuleId{}, FileType::Directory))), + IsDirectoryInfo(path1DirectoryPathId, path3SourceId, ModuleId{}, FileType::Directory))), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, - path1SourceContextId, - path2SourceContextId, - path3SourceContextId))))); + path1DirectoryPathId, + path2DirectoryPathId, + path3DirectoryPathId))))); updater.update({.projectDirectory = "/root"}); } @@ -987,15 +986,15 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, qt_subdirectories_if_ro EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", &SynchronizationPackage::directoryInfos, - UnorderedElementsAre(IsDirectoryInfo(path1SourceContextId, + UnorderedElementsAre(IsDirectoryInfo(path1DirectoryPathId, path3SourceId, ModuleId{}, FileType::Directory))), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(path1SourceContextId, - path2SourceContextId, - path3SourceContextId))))); + UnorderedElementsAre(path1DirectoryPathId, + path2DirectoryPathId, + path3DirectoryPathId))))); updater.update({.qtDirectories = {"/root"}}); } @@ -1008,15 +1007,15 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, project_subdirectories_ EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field("SynchronizationPackage::directoryInfos", &SynchronizationPackage::directoryInfos, - UnorderedElementsAre(IsDirectoryInfo(path1SourceContextId, + UnorderedElementsAre(IsDirectoryInfo(path1DirectoryPathId, path3SourceId, ModuleId{}, FileType::Directory))), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(path1SourceContextId, - path2SourceContextId, - path3SourceContextId))))); + UnorderedElementsAre(path1DirectoryPathId, + path2DirectoryPathId, + path3DirectoryPathId))))); updater.update({.projectDirectory = "/root"}); } @@ -1026,8 +1025,8 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_qt_subdirec setFilesChanged({rootDirectoryPathSourceId}); setFilesRemoved({path1SourceId, path3SourceId}); setFilesUnchanged({path2SourceId}); - setStorageSubdirectories(rootDirectoryPathId, {path1SourceContextId, path2SourceContextId}); - setStorageSubdirectories(path1SourceContextId, {path3SourceContextId}); + setStorageSubdirectories(rootDirectoryPathId, {path1DirectoryPathId, path2DirectoryPathId}); + setStorageSubdirectories(path1DirectoryPathId, {path3DirectoryPathId}); setFileSystemSubdirectories(u"/root", {"/root/two"}); EXPECT_CALL(projectStorageMock, @@ -1040,8 +1039,8 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_qt_subdirec Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, - path1SourceContextId, - path3SourceContextId))))); + path1DirectoryPathId, + path3DirectoryPathId))))); updater.update({.qtDirectories = {"/root"}}); } @@ -1051,8 +1050,8 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_project_sub setFilesChanged({rootDirectoryPathSourceId}); setFilesRemoved({path1SourceId, path3SourceId}); setFilesUnchanged({path2SourceId}); - setStorageSubdirectories(rootDirectoryPathId, {path1SourceContextId, path2SourceContextId}); - setStorageSubdirectories(path1SourceContextId, {path3SourceContextId}); + setStorageSubdirectories(rootDirectoryPathId, {path1DirectoryPathId, path2DirectoryPathId}); + setStorageSubdirectories(path1DirectoryPathId, {path3DirectoryPathId}); setFileSystemSubdirectories(u"/root", {"/root/two"}); EXPECT_CALL(projectStorageMock, @@ -1065,8 +1064,8 @@ TEST_F(ProjectStorageUpdater_synchronize_subdirectories, for_deleted_project_sub Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, UnorderedElementsAre(rootDirectoryPathId, - path1SourceContextId, - path3SourceContextId))))); + path1DirectoryPathId, + path3DirectoryPathId))))); updater.update({.projectDirectory = {"/root"}}); } @@ -1093,8 +1092,8 @@ public: public: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); - SourceContextId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); + SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); SourceId annotationDirectorySourceId = createDirectorySourceId("/path/designer"); ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; ModuleId exampleModuleId{storage.moduleId("Example", ModuleKind::QmlLibrary)}; @@ -2744,11 +2743,11 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_changed) { setFilesUnchanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); setFilesChanged({firstSourceId, secondSourceId, thirdSourceId}); - setDirectoryInfos(path1SourceContextId, - {{path1SourceContextId, firstSourceId, exampleModuleId, FileType::QmlDocument}, - {path1SourceContextId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); - setDirectoryInfos(path2SourceContextId, - {{path2SourceContextId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(path1DirectoryPathId, + {{path1DirectoryPathId, firstSourceId, exampleModuleId, FileType::QmlDocument}, + {path1DirectoryPathId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); + setDirectoryInfos(path2DirectoryPathId, + {{path2DirectoryPathId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2767,11 +2766,11 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files_and_directories_dont firstSourceId, secondSourceId, thirdSourceId}); - setDirectoryInfos(path1SourceContextId, - {{path1SourceContextId, firstSourceId, exampleModuleId, FileType::QmlDocument}, - {path1SourceContextId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); - setDirectoryInfos(path2SourceContextId, - {{path2SourceContextId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(path1DirectoryPathId, + {{path1DirectoryPathId, firstSourceId, exampleModuleId, FileType::QmlDocument}, + {path1DirectoryPathId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); + setDirectoryInfos(path2DirectoryPathId, + {{path2DirectoryPathId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2822,10 +2821,10 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_changed) { setFilesUnchanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); setFilesChanged({qmltypes1SourceId, qmltypes2SourceId}); - setDirectoryInfos(path1SourceContextId, - {{path1SourceContextId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); - setDirectoryInfos(path2SourceContextId, - {{path2SourceContextId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path1DirectoryPathId, + {{path1DirectoryPathId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path2DirectoryPathId, + {{path2DirectoryPathId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -2843,10 +2842,10 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories path2SourceId, qmltypes1SourceId, qmltypes2SourceId}); - setDirectoryInfos(path1SourceContextId, - {{path1SourceContextId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); - setDirectoryInfos(path2SourceContextId, - {{path2SourceContextId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path1DirectoryPathId, + {{path1DirectoryPathId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path2DirectoryPathId, + {{path2DirectoryPathId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{qtPartId, @@ -3244,8 +3243,8 @@ TEST_F(ProjectStorageUpdater, watcher_updates_subdirectories) FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - SourceContextId rootPathId = sourcePathCache.sourceContextId("/root"); - SourceId rootPathSourceId = SourceId::create(QmlDesigner::SourceNameId{}, rootPathId); + DirectoryPathId rootPathId = sourcePathCache.directoryPathId("/root"); + SourceId rootPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, rootPathId); SourceId rootQmldirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); setFilesChanged({directoryPathSourceId, rootPathSourceId}); setFilesUnchanged({qmlDirPathSourceId, rootQmldirPathSourceId}); @@ -3357,7 +3356,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_directory_change setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); setFilesUnchanged({qmlDirPathSourceId}); - auto directorySourceContextId = directoryPathSourceId.contextId(); + auto directoryDirectoryPathId = directoryPathSourceId.contextId(); EXPECT_CALL(patchWatcherMock, updateContextIdPaths( @@ -3367,7 +3366,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_directory_change IdPaths{qtPartId, QmlDesigner::SourceType::Qml, {qmlDocumentSourceId1, qmlDocumentSourceId2, qmlDocumentSourceId3}}), - UnorderedElementsAre(directorySourceContextId))); + UnorderedElementsAre(directoryDirectoryPathId))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } @@ -3472,7 +3471,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_qmldir_changes) FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - auto directorySourceContextId = qmlDirPathSourceId.contextId(); + auto directoryDirectoryPathId = qmlDirPathSourceId.contextId(); EXPECT_CALL(patchWatcherMock, updateContextIdPaths( @@ -3482,7 +3481,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_qmldir_changes) IdPaths{qtPartId, QmlDesigner::SourceType::Qml, {qmlDocumentSourceId1, qmlDocumentSourceId2, qmlDocumentSourceId3}}), - UnorderedElementsAre(directorySourceContextId))); + UnorderedElementsAre(directoryDirectoryPathId))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}}); } @@ -4793,9 +4792,9 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes) }); auto sourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QML/QtObjectPane.qml"}); - auto directoryId = sourcePathCache.sourceContextId( + auto directoryId = sourcePathCache.directoryPathId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QML"}); - auto directorySourceId = SourceId::create(QmlDesigner::SourceNameId{}, directoryId); + auto directorySourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryId); setFilesChanged({directorySourceId}); auto qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); @@ -4828,15 +4827,14 @@ TEST_F(ProjectStorageUpdater, update_property_editor_specifics) }); auto textSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/TextSpecifics.qml"}); - auto qtQuickDirectoryId = sourcePathCache.sourceContextId( + auto qtQuickDirectoryId = sourcePathCache.directoryPathId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick"}); - auto qtQuickDirectorySourceId = SourceId::create(QmlDesigner::SourceNameId{}, qtQuickDirectoryId); + auto qtQuickDirectorySourceId = SourceId::create(QmlDesigner::FileNameId{}, qtQuickDirectoryId); auto buttonSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/Controls/ButtonSpecifics.qml"}); - auto controlsDirectoryId = sourcePathCache.sourceContextId( + auto controlsDirectoryId = sourcePathCache.directoryPathId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/Controls"}); - auto controlsDirectorySourceId = SourceId::create(QmlDesigner::SourceNameId{}, - controlsDirectoryId); + auto controlsDirectorySourceId = SourceId::create(QmlDesigner::FileNameId{}, controlsDirectoryId); setFilesChanged({qtQuickDirectorySourceId, controlsDirectorySourceId}); auto qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto controlsModuleId = storage.moduleId("QtQuick.Controls", ModuleKind::QmlLibrary); @@ -4888,7 +4886,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations) synchronize(AllOf(Field("SynchronizationPackage::typeAnnotations", &SynchronizationPackage::typeAnnotations, IsSupersetOf({IsTypeAnnotation(qtQuickSourceId, - itemLibraryPathSourceContextId, + itemLibraryPathDirectoryPathId, "Item", qtQuickModuleId, StartsWith(itemLibraryPath), @@ -4896,7 +4894,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations) _, _), IsTypeAnnotation(qtQuickControlSourceId, - itemLibraryPathSourceContextId, + itemLibraryPathDirectoryPathId, "Button", qtQuickControlsModuleId, StartsWith(itemLibraryPath), @@ -4927,7 +4925,7 @@ TEST_F(ProjectStorageUpdater, update_added_type_annotation) synchronize(AllOf(Field("SynchronizationPackage::typeAnnotations", &SynchronizationPackage::typeAnnotations, IsSupersetOf({IsTypeAnnotation(qtQuickSourceId, - itemLibraryPathSourceContextId, + itemLibraryPathDirectoryPathId, "Item", qtQuickModuleId, StartsWith(itemLibraryPath), @@ -4935,7 +4933,7 @@ TEST_F(ProjectStorageUpdater, update_added_type_annotation) _, _), IsTypeAnnotation(qtQuickControlSourceId, - itemLibraryPathSourceContextId, + itemLibraryPathDirectoryPathId, "Button", qtQuickControlsModuleId, StartsWith(itemLibraryPath), @@ -4966,7 +4964,7 @@ TEST_F(ProjectStorageUpdater, update_changed_type_annotation) synchronize(AllOf(Field("SynchronizationPackage::typeAnnotations", &SynchronizationPackage::typeAnnotations, IsSupersetOf({IsTypeAnnotation(qtQuickSourceId, - itemLibraryPathSourceContextId, + itemLibraryPathDirectoryPathId, "Item", qtQuickModuleId, StartsWith(itemLibraryPath), @@ -4974,7 +4972,7 @@ TEST_F(ProjectStorageUpdater, update_changed_type_annotation) _, _), IsTypeAnnotation(qtQuickControlSourceId, - itemLibraryPathSourceContextId, + itemLibraryPathDirectoryPathId, "Button", qtQuickControlsModuleId, StartsWith(itemLibraryPath), @@ -5020,8 +5018,8 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_meta_info_file) auto qtQuickControlSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); ON_CALL(projectStorageMock, typeAnnotationDirectoryIds()) - .WillByDefault(Return(QmlDesigner::SmallSourceContextIds<64>{itemLibraryPathSourceContextId})); - ON_CALL(projectStorageMock, typeAnnotationSourceIds(itemLibraryPathSourceContextId)) + .WillByDefault(Return(QmlDesigner::SmallDirectoryPathIds<64>{itemLibraryPathDirectoryPathId})); + ON_CALL(projectStorageMock, typeAnnotationSourceIds(itemLibraryPathDirectoryPathId)) .WillByDefault(Return(QmlDesigner::SmallSourceIds<4>{qtQuickSourceId, qtQuickControlSourceId})); setFilesChanged({itemLibraryPathSourceId}); setFilesRemoved({qtQuickSourceId}); @@ -5052,10 +5050,10 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_directory) auto qtQuickControlSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); ON_CALL(projectStorageMock, typeAnnotationDirectoryIds()) - .WillByDefault(Return(QmlDesigner::SmallSourceContextIds<64>{ - itemLibraryPathSourceContextId, + .WillByDefault(Return(QmlDesigner::SmallDirectoryPathIds<64>{ + itemLibraryPathDirectoryPathId, })); - ON_CALL(projectStorageMock, typeAnnotationSourceIds(itemLibraryPathSourceContextId)) + ON_CALL(projectStorageMock, typeAnnotationSourceIds(itemLibraryPathDirectoryPathId)) .WillByDefault(Return(QmlDesigner::SmallSourceIds<4>{qtQuickSourceId, qtQuickControlSourceId})); setFilesRemoved({itemLibraryPathSourceId, qtQuickSourceId, qtQuickControlSourceId}); @@ -5073,8 +5071,8 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_directory) TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_directory) { setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); - SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); + DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); + SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); setFilesUnchanged({path1SourceId}); setFilesAdded({designer1SourceId}); @@ -5099,7 +5097,7 @@ TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_direct IsEmpty()), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(path1SourceContextId))))); + UnorderedElementsAre(path1DirectoryPathId))))); updater.update({.projectDirectory = "/path/one"}); } @@ -5107,8 +5105,8 @@ TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_direct TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_directory) { setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); - SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); + DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); + SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); setFilesUnchanged({path1SourceId}); setFilesChanged({designer1SourceId}); @@ -5133,7 +5131,7 @@ TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_dire IsEmpty()), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(path1SourceContextId))))); + UnorderedElementsAre(path1DirectoryPathId))))); updater.update({.projectDirectory = "/path/one"}); } @@ -5141,8 +5139,8 @@ TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_dire TEST_F(ProjectStorageUpdater, dont_synchronize_empty_property_editor_qml_paths_directory) { setFileSystemSubdirectories(u"/path/two", {}); - SourceContextId designer2DirectoryId = sourcePathCache.sourceContextId("/path/two/designer"); - SourceId designer2SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer2DirectoryId); + DirectoryPathId designer2DirectoryId = sourcePathCache.directoryPathId("/path/two/designer"); + SourceId designer2SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer2DirectoryId); setFilesChanged({path2SourceId}); setFilesNotExists({designer2SourceId}); @@ -5166,15 +5164,15 @@ TEST_F(ProjectStorageUpdater, dont_synchronize_empty_property_editor_qml_paths_d IsEmpty()), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(path2SourceContextId))))); + UnorderedElementsAre(path2DirectoryPathId))))); updater.update({.projectDirectory = "/path/two"}); } TEST_F(ProjectStorageUpdater, remove_property_editor_qml_paths_if_designer_directory_is_removed) { - SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); + DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); + SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); setFilesUnchanged({path1SourceId, qmldir1SourceId}); setFilesRemoved({designer1SourceId}); @@ -5197,7 +5195,7 @@ TEST_F(ProjectStorageUpdater, remove_property_editor_qml_paths_if_designer_direc IsEmpty()), Field("SynchronizationPackage::updatedDirectoryInfoDirectoryIds", &SynchronizationPackage::updatedDirectoryInfoDirectoryIds, - UnorderedElementsAre(path1SourceContextId))))); + UnorderedElementsAre(path1DirectoryPathId))))); updater.update({.projectDirectory = "/path/one"}); } @@ -5208,14 +5206,14 @@ TEST_F(ProjectStorageUpdater, setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); QString qmldir{R"(module Bar)"}; setContent(u"/path/one/qmldir", qmldir); - SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); + DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); SourceId propertyEditorSpecificSourceId = sourcePathCache.sourceId( "/path/one/designer/FooSpecifics.qml"); SourceId propertyEditorSpecificDynamicSourceId = sourcePathCache.sourceId( "/path/one/designer/HuoSpecificsDynamic.qml"); SourceId propertyEditorPaneSourceId = sourcePathCache.sourceId( "/path/one/designer/CaoPane.qml"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); setFilesChanged({designer1SourceId}); setFilesUnchanged({path1SourceId, qmldir1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); @@ -5252,14 +5250,14 @@ TEST_F(ProjectStorageUpdater, setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); QString qmldir{R"(module Bar)"}; setContent(u"/path/one/qmldir", qmldir); - SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); + DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); SourceId propertyEditorSpecificSourceId = sourcePathCache.sourceId( "/path/one/designer/FooSpecifics.qml"); SourceId propertyEditorSpecificDynamicSourceId = sourcePathCache.sourceId( "/path/one/designer/HuoSpecificsDynamic.qml"); SourceId propertyEditorPaneSourceId = sourcePathCache.sourceId( "/path/one/designer/CaoPane.qml"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); setFilesChanged({path1SourceId}); setFilesUnchanged({qmldir1SourceId, designer1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); @@ -5295,14 +5293,14 @@ TEST_F(ProjectStorageUpdater, synchronize_property_editor_qml_paths_directory_if setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); QString qmldir{R"(module Bar)"}; setContent(u"/path/one/qmldir", qmldir); - SourceContextId designer1DirectoryId = sourcePathCache.sourceContextId("/path/one/designer"); + DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); SourceId propertyEditorSpecificSourceId = sourcePathCache.sourceId( "/path/one/designer/FooSpecifics.qml"); SourceId propertyEditorSpecificDynamicSourceId = sourcePathCache.sourceId( "/path/one/designer/HuoSpecificsDynamic.qml"); SourceId propertyEditorPaneSourceId = sourcePathCache.sourceId( "/path/one/designer/CaoPane.qml"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::SourceNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); setFilesChanged({qmldir1SourceId}); setFilesUnchanged({path1SourceId, designer1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); diff --git a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp index 848d76082bb..a4fbde175d9 100644 --- a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp @@ -18,7 +18,7 @@ namespace { namespace Storage = QmlDesigner::Storage; namespace Synchronization = Storage::Synchronization; using QmlDesigner::ModuleId; -using QmlDesigner::SourceContextId; +using QmlDesigner::DirectoryPathId; using QmlDesigner::SourceId; using QmlDesigner::Storage::ModuleKind; using Storage::TypeTraits; @@ -158,8 +158,8 @@ protected: QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; Storage::Imports imports; SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")}; - SourceContextId qmlFileSourceContextId{qmlFileSourceId.contextId()}; - Utils::PathString directoryPath{sourcePathCache.sourceContextPath(qmlFileSourceContextId)}; + DirectoryPathId qmlFileDirectoryPathId{qmlFileSourceId.contextId()}; + Utils::PathString directoryPath{sourcePathCache.directoryPath(qmlFileDirectoryPathId)}; ModuleId directoryModuleId{storage.moduleId(directoryPath, ModuleKind::PathLibrary)}; }; diff --git a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp index d25dc12a83a..74800191cf8 100644 --- a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp @@ -17,7 +17,7 @@ namespace { namespace Storage = QmlDesigner::Storage; namespace Synchronization = QmlDesigner::Storage::Synchronization; using QmlDesigner::ModuleId; -using QmlDesigner::SourceContextId; +using QmlDesigner::DirectoryPathId; using QmlDesigner::SourceId; using QmlDesigner::Storage::ModuleKind; @@ -200,7 +200,7 @@ protected: qmltypesFileSourceId, qtQmlNativeModuleId, Synchronization::FileType::QmlTypes}; - SourceContextId qmltypesFileSourceContextId{qmltypesFileSourceId.contextId()}; + DirectoryPathId qmltypesFileDirectoryPathId{qmltypesFileSourceId.contextId()}; }; TEST_F(QmlTypesParser, imports) diff --git a/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp b/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp index d802289dabb..f6ea2472f51 100644 --- a/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp @@ -53,7 +53,7 @@ protected: QmlDesigner::ProjectStorage &storage = staticData->storage; QmlDesigner::Storage::TypeAnnotationReader reader{storage}; QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(33); - QmlDesigner::SourceContextId directoryId = QmlDesigner::SourceContextId::create(77); + QmlDesigner::DirectoryPathId directoryId = QmlDesigner::DirectoryPathId::create(77); QmlDesigner::Storage::TypeTraits traits; }; diff --git a/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp index ea10cde418e..d7def11d0a6 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp @@ -10,13 +10,13 @@ namespace { -using QmlDesigner::SourceContextId; +using QmlDesigner::DirectoryPathId; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; -using QmlDesigner::SourceNameId; +using QmlDesigner::FileNameId; using Cache = QmlDesigner::SourcePathCache>; using NFP = QmlDesigner::SourcePath; -using QmlDesigner::Cache::SourceName; +using QmlDesigner::Cache::FileName; using QmlDesigner::SourcePathView; using QmlDesigner::SourcePathViews; @@ -25,48 +25,48 @@ class SourcePathCache : public testing::Test protected: SourcePathCache() { - ON_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).WillByDefault(Return(sourceContextId5)); - ON_CALL(storageMock, fetchSourceContextId(Eq("/path2/to"))).WillByDefault(Return(sourceContextId6)); - ON_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).WillByDefault(Return(sourceNameId42)); - ON_CALL(storageMock, fetchSourceNameId(Eq("file2.cpp"))).WillByDefault(Return(sourceNameId63)); - ON_CALL(storageMock, fetchSourceContextPath(sourceContextId5)) + ON_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))).WillByDefault(Return(directoryPathId5)); + ON_CALL(storageMock, fetchDirectoryPathId(Eq("/path2/to"))).WillByDefault(Return(directoryPathId6)); + ON_CALL(storageMock, fetchFileNameId(Eq("file.cpp"))).WillByDefault(Return(fileNameId42)); + ON_CALL(storageMock, fetchFileNameId(Eq("file2.cpp"))).WillByDefault(Return(fileNameId63)); + ON_CALL(storageMock, fetchDirectoryPath(directoryPathId5)) .WillByDefault(Return(Utils::PathString("/path/to"))); - ON_CALL(storageMock, fetchSourceName(sourceNameId42)).WillByDefault(Return("file.cpp")); - ON_CALL(storageMockFilled, fetchAllSourceNames()) - .WillByDefault(Return(std::vector( - {{"file.cpp", sourceNameId42}, {"file2.cpp", sourceNameId63}}))); - ON_CALL(storageMockFilled, fetchAllSourceContexts()) - .WillByDefault(Return(std::vector( - {{"/path2/to", sourceContextId6}, {"/path/to", sourceContextId5}}))); - ON_CALL(storageMockFilled, fetchSourceContextId(Eq("/path/to"))) - .WillByDefault(Return(sourceContextId5)); - ON_CALL(storageMockFilled, fetchSourceNameId(Eq("file.cpp"))).WillByDefault(Return(sourceNameId42)); + ON_CALL(storageMock, fetchFileName(fileNameId42)).WillByDefault(Return("file.cpp")); + ON_CALL(storageMockFilled, fetchAllFileNames()) + .WillByDefault(Return(std::vector( + {{"file.cpp", fileNameId42}, {"file2.cpp", fileNameId63}}))); + ON_CALL(storageMockFilled, fetchAllDirectoryPaths()) + .WillByDefault(Return(std::vector( + {{"/path2/to", directoryPathId6}, {"/path/to", directoryPathId5}}))); + ON_CALL(storageMockFilled, fetchDirectoryPathId(Eq("/path/to"))) + .WillByDefault(Return(directoryPathId5)); + ON_CALL(storageMockFilled, fetchFileNameId(Eq("file.cpp"))).WillByDefault(Return(fileNameId42)); } protected: - SourceNameId sourceNameId42 = SourceNameId::create(42); - SourceNameId sourceNameId63 = SourceNameId::create(63); - SourceContextId sourceContextId5 = SourceContextId::create(5); - SourceContextId sourceContextId6 = SourceContextId::create(6); - SourceId sourceId542 = SourceId::create(sourceNameId42, sourceContextId5); - SourceId sourceId563 = SourceId::create(sourceNameId63, sourceContextId5); - SourceId sourceId642 = SourceId::create(sourceNameId42, sourceContextId6); + FileNameId fileNameId42 = FileNameId::create(42); + FileNameId fileNameId63 = FileNameId::create(63); + DirectoryPathId directoryPathId5 = DirectoryPathId::create(5); + DirectoryPathId directoryPathId6 = DirectoryPathId::create(6); + SourceId sourceId542 = SourceId::create(fileNameId42, directoryPathId5); + SourceId sourceId563 = SourceId::create(fileNameId63, directoryPathId5); + SourceId sourceId642 = SourceId::create(fileNameId42, directoryPathId6); NiceMock storageMock; Cache cache{storageMock}; NiceMock storageMockFilled; Cache cacheNotFilled{storageMockFilled}; }; -TEST_F(SourcePathCache, source_id_with_out_any_entry_call_source_context_id) +TEST_F(SourcePathCache, source_id_with_out_any_entry_call_directory_path_id) { - EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))); + EXPECT_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))); cache.sourceId(SourcePathView("/path/to/file.cpp")); } TEST_F(SourcePathCache, source_id_with_out_any_entry_calls) { - EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchFileNameId(Eq("file.cpp"))); cache.sourceId(SourcePathView("/path/to/file.cpp")); } @@ -78,11 +78,11 @@ TEST_F(SourcePathCache, source_id_of_source_id_with_out_any_entry) ASSERT_THAT(sourceId, sourceId542); } -TEST_F(SourcePathCache, source_id_with_source_context_id_and_source_name) +TEST_F(SourcePathCache, source_id_with_directory_path_id_and_file_name) { - auto sourceContextId = cache.sourceContextId("/path/to"_sv); + auto directoryPathId = cache.directoryPathId("/path/to"_sv); - auto sourceId = cache.sourceId(sourceContextId, "file.cpp"_sv); + auto sourceId = cache.sourceId(directoryPathId, "file.cpp"_sv); ASSERT_THAT(sourceId, sourceId542); } @@ -91,18 +91,19 @@ TEST_F(SourcePathCache, if_entry_exists_dont_call_in_strorage) { cache.sourceId(SourcePathView("/path/to/file.cpp")); - EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); - EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).Times(0); + EXPECT_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))).Times(0); + EXPECT_CALL(storageMock, fetchFileNameId(Eq("file.cpp"))).Times(0); cache.sourceId(SourcePathView("/path/to/file.cpp")); } -TEST_F(SourcePathCache, if_directory_entry_exists_dont_call_fetch_source_context_id_but_still_call_fetch_source_id) +TEST_F(SourcePathCache, + if_directory_entry_exists_dont_call_fetch_directory_path_id_but_still_call_fetch_source_id) { cache.sourceId(SourcePathView("/path/to/file2.cpp")); - EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); - EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))).Times(0); + EXPECT_CALL(storageMock, fetchFileNameId(Eq("file.cpp"))); cache.sourceId(SourcePathView("/path/to/file.cpp")); } @@ -116,7 +117,7 @@ TEST_F(SourcePathCache, get_source_id_with_cached_value) ASSERT_THAT(sourceId, sourceId542); } -TEST_F(SourcePathCache, get_source_id_with_source_context_id_cached) +TEST_F(SourcePathCache, get_source_id_with_directory_path_id_cached) { cache.sourceId(SourcePathView("/path/to/file.cpp")); @@ -166,135 +167,135 @@ TEST_F(SourcePathCache, duplicate_file_paths_are_equal) ASSERT_THAT(sourcePath2Id, Eq(sourcePath1Id)); } -TEST_F(SourcePathCache, source_context_id_calls_fetch_source_context_id) +TEST_F(SourcePathCache, directory_path_id_calls_fetch_directory_path_id) { - EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))); + EXPECT_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))); - cache.sourceContextId(Utils::SmallString("/path/to")); + cache.directoryPathId(Utils::SmallString("/path/to")); } -TEST_F(SourcePathCache, second_source_context_id_calls_not_fetch_source_context_id) +TEST_F(SourcePathCache, second_directory_path_id_calls_not_fetch_directory_path_id) { - cache.sourceContextId(Utils::SmallString("/path/to")); + cache.directoryPathId(Utils::SmallString("/path/to")); - EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); + EXPECT_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))).Times(0); - cache.sourceContextId(Utils::SmallString("/path/to")); + cache.directoryPathId(Utils::SmallString("/path/to")); } -TEST_F(SourcePathCache, source_context_id_with_trailing_slash) +TEST_F(SourcePathCache, directory_path_id_with_trailing_slash) { - EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))); + EXPECT_CALL(storageMock, fetchDirectoryPathId(Eq("/path/to"))); - cache.sourceContextId(Utils::SmallString("/path/to/")); + cache.directoryPathId(Utils::SmallString("/path/to/")); } -TEST_F(SourcePathCache, source_context_id) +TEST_F(SourcePathCache, directory_path_id) { - auto id = cache.sourceContextId(Utils::SmallString("/path/to")); + auto id = cache.directoryPathId(Utils::SmallString("/path/to")); - ASSERT_THAT(id, Eq(sourceContextId5)); + ASSERT_THAT(id, Eq(directoryPathId5)); } -TEST_F(SourcePathCache, source_context_id_is_already_in_cache) +TEST_F(SourcePathCache, directory_path_id_is_already_in_cache) { - auto firstId = cache.sourceContextId(Utils::SmallString("/path/to")); + auto firstId = cache.directoryPathId(Utils::SmallString("/path/to")); - auto secondId = cache.sourceContextId(Utils::SmallString("/path/to")); + auto secondId = cache.directoryPathId(Utils::SmallString("/path/to")); ASSERT_THAT(secondId, firstId); } -TEST_F(SourcePathCache, source_context_id_is_already_in_cache_with_trailing_slash) +TEST_F(SourcePathCache, directory_path_id_is_already_in_cache_with_trailing_slash) { - auto firstId = cache.sourceContextId(Utils::SmallString("/path/to/")); + auto firstId = cache.directoryPathId(Utils::SmallString("/path/to/")); - auto secondId = cache.sourceContextId(Utils::SmallString("/path/to/")); + auto secondId = cache.directoryPathId(Utils::SmallString("/path/to/")); ASSERT_THAT(secondId, firstId); } -TEST_F(SourcePathCache, source_context_id_is_already_in_cache_with_and_without_trailing_slash) +TEST_F(SourcePathCache, directory_path_id_is_already_in_cache_with_and_without_trailing_slash) { - auto firstId = cache.sourceContextId(Utils::SmallString("/path/to/")); + auto firstId = cache.directoryPathId(Utils::SmallString("/path/to/")); - auto secondId = cache.sourceContextId(Utils::SmallString("/path/to")); + auto secondId = cache.directoryPathId(Utils::SmallString("/path/to")); ASSERT_THAT(secondId, firstId); } -TEST_F(SourcePathCache, source_context_id_is_already_in_cache_without_and_with_trailing_slash) +TEST_F(SourcePathCache, directory_path_id_is_already_in_cache_without_and_with_trailing_slash) { - auto firstId = cache.sourceContextId(Utils::SmallString("/path/to")); + auto firstId = cache.directoryPathId(Utils::SmallString("/path/to")); - auto secondId = cache.sourceContextId(Utils::SmallString("/path/to/")); + auto secondId = cache.directoryPathId(Utils::SmallString("/path/to/")); ASSERT_THAT(secondId, firstId); } TEST_F(SourcePathCache, throw_for_getting_a_directory_path_with_an_invalid_id) { - SourceContextId sourceContextId; + DirectoryPathId directoryPathId; - ASSERT_THROW(cache.sourceContextPath(sourceContextId), - QmlDesigner::NoSourceContextPathForInvalidSourceContextId); + ASSERT_THROW(cache.directoryPath(directoryPathId), + QmlDesigner::NoDirectoryPathForInvalidDirectoryPathId); } TEST_F(SourcePathCache, get_a_directory_path) { - SourceContextId sourceContextId{sourceContextId5}; + DirectoryPathId directoryPathId{directoryPathId5}; - auto sourceContextPath = cache.sourceContextPath(sourceContextId); + auto directoryPath = cache.directoryPath(directoryPathId); - ASSERT_THAT(sourceContextPath, Eq(Utils::SmallStringView{"/path/to"})); + ASSERT_THAT(directoryPath, Eq(Utils::SmallStringView{"/path/to"})); } -TEST_F(SourcePathCache, get_a_directory_path_with_cached_source_context_id) +TEST_F(SourcePathCache, get_a_directory_path_with_cached_directory_path_id) { - SourceContextId sourceContextId{sourceContextId5}; - cache.sourceContextPath(sourceContextId); + DirectoryPathId directoryPathId{directoryPathId5}; + cache.directoryPath(directoryPathId); - auto sourceContextPath = cache.sourceContextPath(sourceContextId); + auto directoryPath = cache.directoryPath(directoryPathId); - ASSERT_THAT(sourceContextPath, Eq(Utils::SmallStringView{"/path/to"})); + ASSERT_THAT(directoryPath, Eq(Utils::SmallStringView{"/path/to"})); } TEST_F(SourcePathCache, directory_path_calls_fetch_directory_path) { - EXPECT_CALL(storageMock, fetchSourceContextPath(Eq(sourceContextId5))); + EXPECT_CALL(storageMock, fetchDirectoryPath(Eq(directoryPathId5))); - cache.sourceContextPath(sourceContextId5); + cache.directoryPath(directoryPathId5); } TEST_F(SourcePathCache, second_directory_path_calls_not_fetch_directory_path) { - cache.sourceContextPath(sourceContextId5); + cache.directoryPath(directoryPathId5); - EXPECT_CALL(storageMock, fetchSourceContextPath(_)).Times(0); + EXPECT_CALL(storageMock, fetchDirectoryPath(_)).Times(0); - cache.sourceContextPath(sourceContextId5); + cache.directoryPath(directoryPathId5); } -TEST_F(SourcePathCache, fetch_source_context_from_source_id) +TEST_F(SourcePathCache, fetch_directory_path_from_source_id) { - auto sourceContextId = sourceId542.contextId(); + auto directoryPathId = sourceId542.contextId(); - ASSERT_THAT(sourceContextId, Eq(sourceContextId5)); + ASSERT_THAT(directoryPathId, Eq(directoryPathId5)); } -TEST_F(SourcePathCache, fetch_source_context_id_after_fetching_file_path_by_source_id) +TEST_F(SourcePathCache, fetch_directory_path_id_after_fetching_file_path_by_source_id) { cache.sourcePath(sourceId542); - auto sourceContextId = sourceId542.contextId(); + auto directoryPathId = sourceId542.contextId(); - ASSERT_THAT(sourceContextId, Eq(sourceContextId5)); + ASSERT_THAT(directoryPathId, Eq(directoryPathId5)); } -TEST_F(SourcePathCache, fetch_all_source_contexts_and_sources_at_creation) +TEST_F(SourcePathCache, fetch_all_directory_paths_and_sources_at_creation) { - EXPECT_CALL(storageMock, fetchAllSourceContexts()); - EXPECT_CALL(storageMock, fetchAllSourceNames()); + EXPECT_CALL(storageMock, fetchAllDirectoryPaths()); + EXPECT_CALL(storageMock, fetchAllFileNames()); Cache cache{storageMock}; } @@ -308,20 +309,20 @@ TEST_F(SourcePathCache, get_file_id_in_filled_cache) ASSERT_THAT(id, Eq(sourceId642)); } -TEST_F(SourcePathCache, get_source_context_id_in_filled_cache) +TEST_F(SourcePathCache, get_directory_path_id_in_filled_cache) { Cache cacheFilled{storageMockFilled}; auto id = sourceId542.contextId(); - ASSERT_THAT(id, Eq(sourceContextId5)); + ASSERT_THAT(id, Eq(directoryPathId5)); } TEST_F(SourcePathCache, get_directory_path_in_filled_cache) { Cache cacheFilled{storageMockFilled}; - auto path = cacheFilled.sourceContextPath(sourceContextId5); + auto path = cacheFilled.directoryPath(directoryPathId5); ASSERT_THAT(path, Eq("/path/to")); } @@ -348,8 +349,8 @@ TEST_F(SourcePathCache, dont_populate_if_not_empty) { cacheNotFilled.sourceId("/path/to/file.cpp"); - EXPECT_CALL(storageMockFilled, fetchAllSourceContexts()).Times(0); - EXPECT_CALL(storageMockFilled, fetchAllSourceNames()).Times(0); + EXPECT_CALL(storageMockFilled, fetchAllDirectoryPaths()).Times(0); + EXPECT_CALL(storageMockFilled, fetchAllFileNames()).Times(0); cacheNotFilled.populateIfEmpty(); } @@ -358,7 +359,7 @@ TEST_F(SourcePathCache, get_directory_path_after_populate_if_empty) { cacheNotFilled.populateIfEmpty(); - auto path = cacheNotFilled.sourceContextPath(sourceContextId5); + auto path = cacheNotFilled.directoryPath(directoryPathId5); ASSERT_THAT(path, Eq("/path/to")); } @@ -372,78 +373,78 @@ TEST_F(SourcePathCache, get_file_path_after_populate_if_empty) ASSERT_THAT(path, Eq("/path/to/file.cpp")); } -TEST_F(SourcePathCache, source_name_id_calls_fetch_source_name_id) +TEST_F(SourcePathCache, file_name_id_calls_fetch_file_name_id) { - EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchFileNameId(Eq("file.cpp"))); - cache.sourceNameId(Utils::SmallString("file.cpp")); + cache.fileNameId(Utils::SmallString("file.cpp")); } -TEST_F(SourcePathCache, second_source_name_id_calls_not_fetch_source_name_id) +TEST_F(SourcePathCache, second_file_name_id_calls_not_fetch_file_name_id) { - cache.sourceNameId(Utils::SmallString("file.cpp")); + cache.fileNameId(Utils::SmallString("file.cpp")); - EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).Times(0); + EXPECT_CALL(storageMock, fetchFileNameId(Eq("file.cpp"))).Times(0); - cache.sourceNameId(Utils::SmallString("file.cpp")); + cache.fileNameId(Utils::SmallString("file.cpp")); } -TEST_F(SourcePathCache, source_name_id) +TEST_F(SourcePathCache, file_name_id) { - auto id = cache.sourceNameId(Utils::SmallString("file.cpp")); + auto id = cache.fileNameId(Utils::SmallString("file.cpp")); - ASSERT_THAT(id, Eq(sourceNameId42)); + ASSERT_THAT(id, Eq(fileNameId42)); } -TEST_F(SourcePathCache, source_name_id_is_already_in_cache) +TEST_F(SourcePathCache, file_name_id_is_already_in_cache) { - auto firstId = cache.sourceNameId(Utils::SmallString("file.cpp")); + auto firstId = cache.fileNameId(Utils::SmallString("file.cpp")); - auto secondId = cache.sourceNameId(Utils::SmallString("file.cpp")); + auto secondId = cache.fileNameId(Utils::SmallString("file.cpp")); ASSERT_THAT(secondId, firstId); } -TEST_F(SourcePathCache, throw_for_getting_source_name_with_an_invalid_id) +TEST_F(SourcePathCache, throw_for_getting_file_name_with_an_invalid_id) { - SourceNameId sourceNameId; + FileNameId fileNameId; - ASSERT_THROW(cache.sourceName(sourceNameId), QmlDesigner::NoSourceNameForInvalidSourceNameId); + ASSERT_THROW(cache.fileName(fileNameId), QmlDesigner::NoFileNameForInvalidFileNameId); } -TEST_F(SourcePathCache, get_a_source_name) +TEST_F(SourcePathCache, get_a_file_name) { - SourceNameId sourceNameId{sourceNameId42}; + FileNameId fileNameId{fileNameId42}; - auto sourceName = cache.sourceName(sourceNameId); + auto fileName = cache.fileName(fileNameId); - ASSERT_THAT(sourceName, Eq(Utils::SmallStringView{"file.cpp"})); + ASSERT_THAT(fileName, Eq(Utils::SmallStringView{"file.cpp"})); } -TEST_F(SourcePathCache, get_a_source_name_with_cached_source_name_id) +TEST_F(SourcePathCache, get_a_file_name_with_cached_file_name_id) { - SourceNameId sourceNameId{sourceNameId42}; - cache.sourceName(sourceNameId); + FileNameId fileNameId{fileNameId42}; + cache.fileName(fileNameId); - auto sourceName = cache.sourceName(sourceNameId); + auto fileName = cache.fileName(fileNameId); - ASSERT_THAT(sourceName, Eq(Utils::SmallStringView{"file.cpp"})); + ASSERT_THAT(fileName, Eq(Utils::SmallStringView{"file.cpp"})); } -TEST_F(SourcePathCache, source_name_calls_fetch_source_name) +TEST_F(SourcePathCache, file_name_calls_fetch_file_name) { - EXPECT_CALL(storageMock, fetchSourceName(Eq(sourceNameId42))); + EXPECT_CALL(storageMock, fetchFileName(Eq(fileNameId42))); - cache.sourceName(sourceNameId42); + cache.fileName(fileNameId42); } -TEST_F(SourcePathCache, second_source_name_calls_not_fetch_source_name) +TEST_F(SourcePathCache, second_file_name_calls_not_fetch_file_name) { - cache.sourceName(sourceNameId42); + cache.fileName(fileNameId42); - EXPECT_CALL(storageMock, fetchSourceName(_)).Times(0); + EXPECT_CALL(storageMock, fetchFileName(_)).Times(0); - cache.sourceName(sourceNameId42); + cache.fileName(fileNameId42); } } // namespace diff --git a/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp index abc08bf21b1..34a07cc7b42 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp @@ -7,21 +7,21 @@ namespace { -using QmlDesigner::Cache::SourceContext; -using QmlDesigner::Cache::SourceName; -using QmlDesigner::SourceContextId; +using QmlDesigner::Cache::DirectoryPath; +using QmlDesigner::Cache::FileName; +using QmlDesigner::DirectoryPathId; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; -using QmlDesigner::SourceNameId; +using QmlDesigner::FileNameId; -MATCHER_P2(IsSourceContext, +MATCHER_P2(IsDirectoryPath, id, value, - std::string(negation ? "isn't " : "is ") + PrintToString(SourceContext{value, id})) + std::string(negation ? "isn't " : "is ") + PrintToString(DirectoryPath{value, id})) { - const SourceContext &sourceContext = arg; + const DirectoryPath &directoryPath = arg; - return sourceContext.id == id && sourceContext.value == value; + return directoryPath.id == id && directoryPath.value == value; } class SourcePathStorage : public testing::Test @@ -43,14 +43,14 @@ protected: void addSomeDummyData() { - storage.fetchSourceContextId("/path/dummy"); - storage.fetchSourceContextId("/path/dummy2"); - storage.fetchSourceContextId("/path/"); + storage.fetchDirectoryPathId("/path/dummy"); + storage.fetchDirectoryPathId("/path/dummy2"); + storage.fetchDirectoryPathId("/path/"); - storage.fetchSourceNameId("foo"); - storage.fetchSourceNameId("dummy"); - storage.fetchSourceNameId("bar"); - storage.fetchSourceNameId("bar"); + storage.fetchFileNameId("foo"); + storage.fetchFileNameId("dummy"); + storage.fetchFileNameId("bar"); + storage.fetchFileNameId("bar"); } template @@ -67,112 +67,112 @@ protected: Sqlite::Database &database = staticData->database; }; -TEST_F(SourcePathStorage, fetch_source_context_id_returns_always_the_same_id_for_the_same_path) +TEST_F(SourcePathStorage, fetch_directory_path_id_returns_always_the_same_id_for_the_same_path) { - auto sourceContextId = storage.fetchSourceContextId("/path/to"); + auto directoryPathId = storage.fetchDirectoryPathId("/path/to"); - auto newSourceContextId = storage.fetchSourceContextId("/path/to"); + auto newDirectoryPathId = storage.fetchDirectoryPathId("/path/to"); - ASSERT_THAT(newSourceContextId, Eq(sourceContextId)); + ASSERT_THAT(newDirectoryPathId, Eq(directoryPathId)); } -TEST_F(SourcePathStorage, fetch_source_context_id_returns_not_the_same_id_for_different_path) +TEST_F(SourcePathStorage, fetch_directory_path_id_returns_not_the_same_id_for_different_path) { - auto sourceContextId = storage.fetchSourceContextId("/path/to"); + auto directoryPathId = storage.fetchDirectoryPathId("/path/to"); - auto newSourceContextId = storage.fetchSourceContextId("/path/to2"); + auto newDirectoryPathId = storage.fetchDirectoryPathId("/path/to2"); - ASSERT_THAT(newSourceContextId, Ne(sourceContextId)); + ASSERT_THAT(newDirectoryPathId, Ne(directoryPathId)); } -TEST_F(SourcePathStorage, fetch_source_context_path) +TEST_F(SourcePathStorage, fetch_directory_path_path) { - auto sourceContextId = storage.fetchSourceContextId("/path/to"); + auto directoryPathId = storage.fetchDirectoryPathId("/path/to"); - auto path = storage.fetchSourceContextPath(sourceContextId); + auto path = storage.fetchDirectoryPath(directoryPathId); ASSERT_THAT(path, Eq("/path/to")); } -TEST_F(SourcePathStorage, fetch_unknown_source_context_path_throws) +TEST_F(SourcePathStorage, fetch_unknown_directory_path_path_throws) { - ASSERT_THROW(storage.fetchSourceContextPath(SourceContextId::create(323)), - QmlDesigner::SourceContextIdDoesNotExists); + ASSERT_THROW(storage.fetchDirectoryPath(DirectoryPathId::create(323)), + QmlDesigner::DirectoryPathIdDoesNotExists); } -TEST_F(SourcePathStorage, fetch_all_source_contexts_are_empty_if_no_source_contexts_exists) +TEST_F(SourcePathStorage, fetch_all_directory_paths_are_empty_if_no_directory_paths_exists) { storage.clearSources(); - auto sourceContexts = storage.fetchAllSourceContexts(); + auto directoryPaths = storage.fetchAllDirectoryPaths(); - ASSERT_THAT(toValues(sourceContexts), IsEmpty()); + ASSERT_THAT(toValues(directoryPaths), IsEmpty()); } -TEST_F(SourcePathStorage, fetch_all_source_contexts) +TEST_F(SourcePathStorage, fetch_all_directory_paths) { storage.clearSources(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceContextId2 = storage.fetchSourceContextId("/path/to2"); + auto directoryPathId = storage.fetchDirectoryPathId("/path/to"); + auto directoryPathId2 = storage.fetchDirectoryPathId("/path/to2"); - auto sourceContexts = storage.fetchAllSourceContexts(); + auto directoryPaths = storage.fetchAllDirectoryPaths(); - ASSERT_THAT(toValues(sourceContexts), - UnorderedElementsAre(IsSourceContext(sourceContextId, "/path/to"), - IsSourceContext(sourceContextId2, "/path/to2"))); + ASSERT_THAT(toValues(directoryPaths), + UnorderedElementsAre(IsDirectoryPath(directoryPathId, "/path/to"), + IsDirectoryPath(directoryPathId2, "/path/to2"))); } TEST_F(SourcePathStorage, fetch_source_id_first_time) { addSomeDummyData(); - auto sourceNameId = storage.fetchSourceNameId("foo"); + auto fileNameId = storage.fetchFileNameId("foo"); - ASSERT_TRUE(sourceNameId.isValid()); + ASSERT_TRUE(fileNameId.isValid()); } TEST_F(SourcePathStorage, fetch_existing_source_id) { addSomeDummyData(); - auto createdSourceNameId = storage.fetchSourceNameId("foo"); + auto createdFileNameId = storage.fetchFileNameId("foo"); - auto sourceNameId = storage.fetchSourceNameId("foo"); + auto fileNameId = storage.fetchFileNameId("foo"); - ASSERT_THAT(sourceNameId, createdSourceNameId); + ASSERT_THAT(fileNameId, createdFileNameId); } TEST_F(SourcePathStorage, fetch_source_id_with_different_name_are_not_equal) { addSomeDummyData(); - auto sourceNameId2 = storage.fetchSourceNameId("foo"); + auto fileNameId2 = storage.fetchFileNameId("foo"); - auto sourceNameId = storage.fetchSourceNameId("foo2"); + auto fileNameId = storage.fetchFileNameId("foo2"); - ASSERT_THAT(sourceNameId, Ne(sourceNameId2)); + ASSERT_THAT(fileNameId, Ne(fileNameId2)); } -TEST_F(SourcePathStorage, fetch_source_name_and_source_context_id_for_non_existing_source_id) +TEST_F(SourcePathStorage, fetch_file_name_and_directory_path_id_for_non_existing_source_id) { - ASSERT_THROW(storage.fetchSourceName(SourceNameId::create(212)), - QmlDesigner::SourceNameIdDoesNotExists); + ASSERT_THROW(storage.fetchFileName(FileNameId::create(212)), + QmlDesigner::FileNameIdDoesNotExists); } -TEST_F(SourcePathStorage, fetch_source_name_for_non_existing_entry) +TEST_F(SourcePathStorage, fetch_file_name_for_non_existing_entry) { addSomeDummyData(); - auto sourceNameId = storage.fetchSourceNameId("foo"); + auto fileNameId = storage.fetchFileNameId("foo"); - auto sourceName = storage.fetchSourceName(sourceNameId); + auto fileName = storage.fetchFileName(fileNameId); - ASSERT_THAT(sourceName, Eq("foo")); + ASSERT_THAT(fileName, Eq("foo")); } TEST_F(SourcePathStorage, fetch_all_sources) { storage.clearSources(); - auto sources = storage.fetchAllSourceNames(); + auto sources = storage.fetchAllFileNames(); ASSERT_THAT(toValues(sources), IsEmpty()); } @@ -182,7 +182,7 @@ TEST_F(SourcePathStorage, fetch_source_id_unguarded_first_time) addSomeDummyData(); std::lock_guard lock{database}; - auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); + auto sourceId = storage.fetchFileNameIdUnguarded("foo"); ASSERT_TRUE(sourceId.isValid()); } @@ -191,9 +191,9 @@ TEST_F(SourcePathStorage, fetch_existing_source_id_unguarded) { addSomeDummyData(); std::lock_guard lock{database}; - auto createdSourceId = storage.fetchSourceNameIdUnguarded("foo"); + auto createdSourceId = storage.fetchFileNameIdUnguarded("foo"); - auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); + auto sourceId = storage.fetchFileNameIdUnguarded("foo"); ASSERT_THAT(sourceId, createdSourceId); } @@ -202,9 +202,9 @@ TEST_F(SourcePathStorage, fetch_source_id_unguarded_with_different_name_are_not_ { addSomeDummyData(); std::lock_guard lock{database}; - auto sourceId2 = storage.fetchSourceNameIdUnguarded("foo"); + auto sourceId2 = storage.fetchFileNameIdUnguarded("foo"); - auto sourceId = storage.fetchSourceNameIdUnguarded("foo2"); + auto sourceId = storage.fetchFileNameIdUnguarded("foo2"); ASSERT_THAT(sourceId, Ne(sourceId2)); } diff --git a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp index 61e2d4efde6..161aac89f29 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp @@ -14,18 +14,18 @@ namespace { -using QmlDesigner::SourceContextId; +using QmlDesigner::DirectoryPathId; using QmlDesigner::StorageCacheException; using Utils::compare; class StorageAdapter { public: - auto fetchId(Utils::SmallStringView view) const { return storage.fetchSourceContextId(view); } + auto fetchId(Utils::SmallStringView view) const { return storage.fetchDirectoryPathId(view); } - auto fetchValue(SourceContextId id) const { return storage.fetchSourceContextPath(id); } + auto fetchValue(DirectoryPathId id) const { return storage.fetchDirectoryPath(id); } - auto fetchAll() const { return storage.fetchAllSourceContexts(); } + auto fetchAll() const { return storage.fetchAllDirectoryPaths(); } ProjectStorageMock &storage; }; @@ -40,19 +40,19 @@ struct Less using CacheWithMockLocking = QmlDesigner::StorageCache, Less, - QmlDesigner::Cache::SourceContext>; + QmlDesigner::Cache::DirectoryPath>; using CacheWithoutLocking = QmlDesigner::StorageCache, Less, - QmlDesigner::Cache::SourceContext>; + QmlDesigner::Cache::DirectoryPath>; template class StorageCache : public testing::Test @@ -67,17 +67,17 @@ protected: return std::lexicographical_compare(f.rbegin(), f.rend(), l.rbegin(), l.rend()); }); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))).WillByDefault(Return(id42)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq("bar"))).WillByDefault(Return(id43)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq("poo"))).WillByDefault(Return(id44)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq("taa"))).WillByDefault(Return(id45)); - ON_CALL(this->mockStorage, fetchSourceContextPath(this->id41)) + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))).WillByDefault(Return(id42)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq("bar"))).WillByDefault(Return(id43)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq("poo"))).WillByDefault(Return(id44)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq("taa"))).WillByDefault(Return(id45)); + ON_CALL(this->mockStorage, fetchDirectoryPath(this->id41)) .WillByDefault(Return(Utils::PathString("bar"))); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq(filePath1))).WillByDefault(Return(id1)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq(filePath2))).WillByDefault(Return(id2)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq(filePath3))).WillByDefault(Return(id3)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq(filePath4))).WillByDefault(Return(id4)); - ON_CALL(this->mockStorage, fetchSourceContextId(Eq(filePath5))).WillByDefault(Return(id5)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq(filePath1))).WillByDefault(Return(id1)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq(filePath2))).WillByDefault(Return(id2)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq(filePath3))).WillByDefault(Return(id3)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq(filePath4))).WillByDefault(Return(id4)); + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq(filePath5))).WillByDefault(Return(id5)); } protected: @@ -92,16 +92,16 @@ protected: Utils::PathString filePath5{"/file/pathFife"}; Utils::PathStringVector filePaths{filePath1, filePath2, filePath3, filePath4, filePath5}; Utils::PathStringVector reverseFilePaths{filePath1, filePath2, filePath3, filePath4, filePath5}; - SourceContextId id1{SourceContextId::create(1)}; - SourceContextId id2{SourceContextId::create(2)}; - SourceContextId id3{SourceContextId::create(3)}; - SourceContextId id4{SourceContextId::create(4)}; - SourceContextId id5{SourceContextId::create(5)}; - SourceContextId id41{SourceContextId::create(41)}; - SourceContextId id42{SourceContextId::create(42)}; - SourceContextId id43{SourceContextId::create(43)}; - SourceContextId id44{SourceContextId::create(44)}; - SourceContextId id45{SourceContextId::create(45)}; + DirectoryPathId id1{DirectoryPathId::create(1)}; + DirectoryPathId id2{DirectoryPathId::create(2)}; + DirectoryPathId id3{DirectoryPathId::create(3)}; + DirectoryPathId id4{DirectoryPathId::create(4)}; + DirectoryPathId id5{DirectoryPathId::create(5)}; + DirectoryPathId id41{DirectoryPathId::create(41)}; + DirectoryPathId id42{DirectoryPathId::create(42)}; + DirectoryPathId id43{DirectoryPathId::create(43)}; + DirectoryPathId id44{DirectoryPathId::create(44)}; + DirectoryPathId id45{DirectoryPathId::create(45)}; }; using CacheTypes = ::testing::Types; @@ -220,8 +220,8 @@ TYPED_TEST(StorageCache, is_not_empty_after_populate_with_some_entries) typename TypeParam::CacheEntries entries{{this->filePath1, this->id1}, {this->filePath2, this->id4}, {this->filePath3, this->id3}, - {this->filePath4, SourceContextId::create(5)}}; - ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); + {this->filePath4, DirectoryPathId::create(5)}}; + ON_CALL(this->mockStorage, fetchAllDirectoryPaths()).WillByDefault(Return(entries)); this->cache.uncheckedPopulate(); @@ -232,12 +232,12 @@ TYPED_TEST(StorageCache, get_entry_after_populate_with_some_entries) { typename TypeParam::CacheEntries entries{{this->filePath1, this->id1}, {this->filePath2, this->id2}, - {this->filePath3, SourceContextId::create(7)}, + {this->filePath3, DirectoryPathId::create(7)}, {this->filePath4, this->id4}}; - ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); + ON_CALL(this->mockStorage, fetchAllDirectoryPaths()).WillByDefault(Return(entries)); this->cache.uncheckedPopulate(); - auto value = this->cache.value(SourceContextId::create(7)); + auto value = this->cache.value(DirectoryPathId::create(7)); ASSERT_THAT(value, this->filePath3); } @@ -248,7 +248,7 @@ TYPED_TEST(StorageCache, entries_have_unique_ids) {this->filePath2, this->id2}, {this->filePath3, this->id3}, {this->filePath4, this->id3}}; - ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); + ON_CALL(this->mockStorage, fetchAllDirectoryPaths()).WillByDefault(Return(entries)); ASSERT_THROW(this->cache.populate(), StorageCacheException); } @@ -259,7 +259,7 @@ TYPED_TEST(StorageCache, multiple_entries) {this->filePath1, this->id2}, {this->filePath3, this->id3}, {this->filePath4, this->id4}}; - ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); + ON_CALL(this->mockStorage, fetchAllDirectoryPaths()).WillByDefault(Return(entries)); ASSERT_THROW(this->cache.populate(), StorageCacheException); } @@ -283,7 +283,7 @@ TYPED_TEST(StorageCache, id_with_storage_function_is_read_and_write_locked_for_u EXPECT_CALL(this->mockMutex, lock_shared()); EXPECT_CALL(this->mockMutex, unlock_shared()); EXPECT_CALL(this->mockMutex, lock()); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))); EXPECT_CALL(this->mockMutex, unlock()); this->cache.id("foo"); @@ -297,7 +297,7 @@ TYPED_TEST(StorageCache, id_with_storage_function_is_read_locked_for_known_entry EXPECT_CALL(this->mockMutex, lock_shared()); EXPECT_CALL(this->mockMutex, unlock_shared()); EXPECT_CALL(this->mockMutex, lock()).Times(0); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))).Times(0); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))).Times(0); EXPECT_CALL(this->mockMutex, unlock()).Times(0); this->cache.id("foo"); @@ -358,7 +358,7 @@ TYPED_TEST(StorageCache, value_with_storage_function_is_read_and_write_locked_fo EXPECT_CALL(this->mockMutex, lock_shared()); EXPECT_CALL(this->mockMutex, unlock_shared()); EXPECT_CALL(this->mockMutex, lock()); - EXPECT_CALL(this->mockStorage, fetchSourceContextPath(Eq(this->id41))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(this->id41))); EXPECT_CALL(this->mockMutex, unlock()); this->cache.value(this->id41); @@ -372,7 +372,7 @@ TYPED_TEST(StorageCache, value_with_storage_function_is_read_locked_for_known_id EXPECT_CALL(this->mockMutex, lock_shared()); EXPECT_CALL(this->mockMutex, unlock_shared()); EXPECT_CALL(this->mockMutex, lock()).Times(0); - EXPECT_CALL(this->mockStorage, fetchSourceContextPath(Eq(this->id41))).Times(0); + EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(this->id41))).Times(0); EXPECT_CALL(this->mockMutex, unlock()).Times(0); this->cache.value(this->id41); @@ -380,7 +380,7 @@ TYPED_TEST(StorageCache, value_with_storage_function_is_read_locked_for_known_id TYPED_TEST(StorageCache, id_with_storage_function_which_has_no_entry_is_calling_storage_function) { - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))); this->cache.id("foo"); } @@ -389,7 +389,7 @@ TYPED_TEST(StorageCache, id_with_storage_function_which_has_entry_is_not_calling { this->cache.id("foo"); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))).Times(0); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))).Times(0); this->cache.id("foo"); } @@ -419,24 +419,24 @@ TYPED_TEST(StorageCache, get_entry_by_index_after_inserting_by_custom_index) ASSERT_THAT(value, Eq("foo")); } -TYPED_TEST(StorageCache, call_fetch_source_context_path_for_lower_index) +TYPED_TEST(StorageCache, call_fetch_directory_path_path_for_lower_index) { auto index = this->cache.id("foo"); - SourceContextId lowerIndex{SourceContextId::create(index.internalId() - 1)}; + DirectoryPathId lowerIndex{DirectoryPathId::create(index.internalId() - 1)}; - EXPECT_CALL(this->mockStorage, fetchSourceContextPath(Eq(lowerIndex))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(lowerIndex))); this->cache.value(lowerIndex); } -TYPED_TEST(StorageCache, call_fetch_source_context_path_for_unknown_index) +TYPED_TEST(StorageCache, call_fetch_directory_path_path_for_unknown_index) { - EXPECT_CALL(this->mockStorage, fetchSourceContextPath(Eq(this->id1))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(this->id1))); this->cache.value(this->id1); } -TYPED_TEST(StorageCache, fetch_source_context_path_for_unknown_index) +TYPED_TEST(StorageCache, fetch_directory_path_path_for_unknown_index) { auto value = this->cache.value(this->id41); @@ -445,9 +445,9 @@ TYPED_TEST(StorageCache, fetch_source_context_path_for_unknown_index) TYPED_TEST(StorageCache, add_calls) { - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("bar"))); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("poo"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("bar"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("poo"))); this->cache.add({"foo", "bar", "poo"}); } @@ -456,8 +456,8 @@ TYPED_TEST(StorageCache, add_calls_only_for_new_values) { this->cache.add({"foo", "poo"}); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("taa"))); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("bar"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("taa"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("bar"))); this->cache.add({"foo", "bar", "poo", "taa"}); } @@ -504,12 +504,12 @@ TYPED_TEST(StorageCache, fetch_ids_from_storage_calls) EXPECT_CALL(this->mockMutex, lock_shared()); EXPECT_CALL(this->mockMutex, unlock_shared()); EXPECT_CALL(this->mockMutex, lock()); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("foo"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("foo"))); EXPECT_CALL(this->mockMutex, unlock()); EXPECT_CALL(this->mockMutex, lock_shared()); EXPECT_CALL(this->mockMutex, unlock_shared()); EXPECT_CALL(this->mockMutex, lock()); - EXPECT_CALL(this->mockStorage, fetchSourceContextId(Eq("bar"))); + EXPECT_CALL(this->mockStorage, fetchDirectoryPathId(Eq("bar"))); EXPECT_CALL(this->mockMutex, unlock()); this->cache.ids({"foo", "bar"}); From 6dc24c0b5c761daffcfa20e20583c7317fd1eb2b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 8 Apr 2025 11:55:56 +0200 Subject: [PATCH 24/82] QmlDesigner: Add missing include for QPixmap Change-Id: I465ce73e6548dda29b69496185c8df59a8641550 Reviewed-by: Mahmoud Badri --- .../components/contentlibrary/usertexturecategory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp index ec603068505..2a88557f180 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp @@ -8,6 +8,8 @@ #include #include +#include + namespace QmlDesigner { UserTextureCategory::UserTextureCategory(const QString &title, const Utils::FilePath &bundlePath) From 7904c434a043769ffee4fc46bd465df6be9e273d Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 8 Apr 2025 14:44:26 +0200 Subject: [PATCH 25/82] QmlDesigner: add v1 to the ProjectStorage database name This is a quick fix, because the initlized tables got changed. A proper database update mechanism needs to be implemented. Change-Id: I825447e18c940996dc7c80ff9ff31aded7d8bc6b Reviewed-by: Miikka Heikkinen Reviewed-by: Marco Bubke --- src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp index 84d515e8cb8..25e92fe2ab0 100644 --- a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp @@ -294,7 +294,7 @@ public: class QmlDesignerProjectManager::Data { public: - Sqlite::Database sourcePathDatabase{createDatabasePath("source_path.db"), + Sqlite::Database sourcePathDatabase{createDatabasePath("source_path_v1.db"), Sqlite::JournalMode::Wal, Sqlite::LockingMode::Normal}; QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, From 1ff575f93c7e58a4ffe89f73bed4b0c9eb93f070 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 8 Apr 2025 13:49:49 +0000 Subject: [PATCH 26/82] QmlDesigner: Revert "QMLRewriter: Fix the very first child position case This reverts commit 398b783f1a8b279082f1098408bdb836095f616b. Reason for revert: This crashes on Linux/macOS. Change-Id: I71068e22bccfc9bcf5f1ada287aa86194c133f5f Reviewed-by: Ali Kianian --- .../libs/designercore/filemanager/qmlrewriter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp index aa2f794e4da..77021f02324 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp @@ -275,6 +275,9 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder, int pos) { + if (pos < 0) + return searchMemberToInsertAfter(members, propertyOrder); + // An empty property name should be available in the propertyOrder List, which is the right place // to define the objects there. const int objectDefinitionInsertionPoint = propertyOrder.indexOf(PropertyName()); @@ -288,8 +291,6 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( int idx = -1; if (QmlJS::AST::cast(member)) { - if (pos < 0) - break; lastObjectDef = iter; if (objectPos++ == pos) break; From feab217705656e313c11462f69a2dc795ff32fd1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 31 Mar 2025 13:57:16 +0200 Subject: [PATCH 27/82] QmlDesigner: Do not remove imports is parsing virtual files Since we use the same url as the QML file currently edited, if we remove imports this breaks the imports. This is because when parsing the "virtual file" imports could be removed (which is disabled by this patch). The verification step triggered by the merger does not check for "temporarily" removed imports, because this was done on a different model. The project storage cannot handle this. The alternative would be to use a different "virtual" file URL. This patch also sets all imports of the current document on the template. Task-number: QDS-15046 Change-Id: Id8826c28232eeba347af191f04a92872e1833c4e Reviewed-by: Miikka Heikkinen --- .../libs/designercore/include/rewriterview.h | 2 ++ .../libs/designercore/rewriter/rewriterview.cpp | 5 +++++ .../libs/designercore/rewriter/texttomodelmerger.cpp | 11 +++++++++-- .../libs/designercore/rewriter/texttomodelmerger.h | 3 +++ src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp | 3 +++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h b/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h index 9672fdc35d2..ac64b97cd3f 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h @@ -179,6 +179,8 @@ public: void setIsDocumentRewriterView(bool b); #endif + void setRemoveImports(bool removeImports); + signals: void modelInterfaceProjectUpdated(); diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp index 02f5c2f05d3..d94846d234a 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp @@ -678,6 +678,11 @@ void RewriterView::setIsDocumentRewriterView(bool b) } #endif +void RewriterView::setRemoveImports(bool removeImports) +{ + m_textToModelMerger->setRemoveImports(removeImports); +} + Internal::ModelNodePositionStorage *RewriterView::positionStorage() const { return m_positionStorage.get(); diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp index 57785a1a570..f9f56923378 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp @@ -702,8 +702,10 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc, } } - for (const Import &import : std::as_const(existingImports)) - differenceHandler.importAbsentInQMl(import); + if (m_removeImports) { + for (const Import &import : std::as_const(existingImports)) + differenceHandler.importAbsentInQMl(import); + } } namespace { @@ -2439,6 +2441,11 @@ void TextToModelMerger::clearPossibleImportKeys() m_previousPossibleModulesSize = -1; } +void TextToModelMerger::setRemoveImports(bool removeImports) +{ + m_removeImports = removeImports; +} + QString TextToModelMerger::textAt(const Document::Ptr &doc, const SourceLocation &location) { diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.h b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.h index 897555c301d..9220f226703 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.h +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.h @@ -124,6 +124,8 @@ public: void clearPossibleImportKeys(); + void setRemoveImports(bool removeImports); + private: void setupCustomParserNode(const ModelNode &node); void setupComponent(const ModelNode &node); @@ -160,6 +162,7 @@ private: Imports m_possibleModules; int m_previousPossibleModulesSize = -1; bool m_hasVersionlessImport = false; + bool m_removeImports = true; }; class DifferenceHandler diff --git a/src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp b/src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp index 61f6833dd59..1e17c2e2fac 100644 --- a/src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp +++ b/src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp @@ -289,6 +289,8 @@ static QmlObjectNode createQmlObjectNodeFromSource(AbstractView *view, auto inputModel = Model::create("QtQuick.Item", 1, 0, view->model()); #endif inputModel->setFileUrl(view->model()->fileUrl()); + inputModel->changeImports(view->model()->imports(), {}); + QPlainTextEdit textEdit; textEdit.setPlainText(source); @@ -300,6 +302,7 @@ static QmlObjectNode createQmlObjectNodeFromSource(AbstractView *view, rewriterView->setTextModifier(&modifier); rewriterView->setAllowComponentRoot(true); rewriterView->setPossibleImportsEnabled(false); + rewriterView->setRemoveImports(false); inputModel->setRewriterView(rewriterView.get()); if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) { From b4cbea34a76a96ff895b8a4264c44c43c4315fa8 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 8 Apr 2025 15:30:41 +0200 Subject: [PATCH 28/82] QmlDesigner: Add independent corner radii section * Add independent corner radii section to RectangleSpecifics * Remove limit on radius control * Set decimals on the independent corner radii controls to 0 * Move CornerRadiusSection component to HelperWidgets Task-number: QDS-15161 Change-Id: Iac4f644ebdb6a530e05605997d8d4cb24a1471f5 Reviewed-by: Thomas Hartmann --- .../QtQuick/RectangleSpecifics.qml | 20 ++++++++++++++----- .../HelperWidgets}/CornerRadiusSection.qml | 10 +++++----- .../imports/HelperWidgets/qmldir | 1 + 3 files changed, 21 insertions(+), 10 deletions(-) rename share/qtcreator/qmldesigner/propertyEditorQmlSources/{QtQuick/Studio/Components => imports/HelperWidgets}/CornerRadiusSection.qml (96%) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml index cdcea69e066..f5d0b6ec017 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml @@ -1,10 +1,10 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import HelperWidgets 2.0 -import StudioTheme 1.0 as StudioTheme +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme Column { anchors.left: parent.left @@ -68,11 +68,21 @@ Column { width: implicitWidth backendValue: backendValues.radius minimumValue: 0 - maximumValue: Math.min(backendValues.height.value, backendValues.width.value) / 2 + maximumValue: 0xffff } ExpandingSpacer {} } } } + + CornerRadiusSection { + id: cornerRadiusSection + property bool radiiAvailable: backendValues.topLeftRadius.isAvailable + // && backendValues.topRightRadius.isAvailable + // && backendValues.bottomLeftRadius.isAvailable + // && backendValues.bottomRightRadius.isAvailable + + visible: majorQtQuickVersion >= 6 && minorQtQuickVersion >= 7 && cornerRadiusSection.radiiAvailable + } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Studio/Components/CornerRadiusSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CornerRadiusSection.qml similarity index 96% rename from share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Studio/Components/CornerRadiusSection.qml rename to share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CornerRadiusSection.qml index b51c7b2dcdf..824881ce2b6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Studio/Components/CornerRadiusSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CornerRadiusSection.qml @@ -21,7 +21,7 @@ Section { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.topLeftRadius - decimals: 1 + decimals: 0 minimumValue: 0 maximumValue: 0xffff stepSize: 1 @@ -40,7 +40,7 @@ Section { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.topRightRadius - decimals: 1 + decimals: 0 minimumValue: 0 maximumValue: 0xffff stepSize: 1 @@ -67,7 +67,7 @@ Section { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.bottomLeftRadius - decimals: 1 + decimals: 0 minimumValue: 0 maximumValue: 0xffff stepSize: 1 @@ -87,7 +87,7 @@ Section { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.bottomRightRadius - decimals: 1 + decimals: 0 minimumValue: 0 maximumValue: 0xffff stepSize: 1 @@ -114,7 +114,7 @@ Section { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.radius - decimals: 1 + decimals: 0 minimumValue: 0 maximumValue: 0xffff stepSize: 1 diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir index 29675dfde5b..3b0c5424448 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir @@ -18,6 +18,7 @@ ComponentButton 2.0 ComponentButton.qml ComponentSection 2.0 ComponentSection.qml ControlLabel 2.0 ControlLabel.qml singleton Controller 2.0 Controller.qml +CornerRadiusSection 2.0 CornerRadiusSection.qml DoubleSpinBox 2.0 DoubleSpinBox.qml DynamicPropertiesSection 2.0 DynamicPropertiesSection.qml EditableListView 2.0 EditableListView.qml From e577855972bdec7fb34f711876bd903d73b13ffa Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 8 Apr 2025 16:32:05 +0200 Subject: [PATCH 29/82] QmlDesigner: call resetSelectionLocked() when attaching new model This ensures that the property editor is not staying locked, when switching files. Change-Id: Iaa2b6333fb51b61eaeb78b973704d0f6546dec3e Reviewed-by: Miikka Heikkinen --- .../qmldesigner/components/propertyeditor/propertyeditorview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index d532a2b2e83..6aef3705439 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -890,6 +890,7 @@ void PropertyEditorView::modelAttached(Model *model) if (debug) qDebug() << Q_FUNC_INFO; + resetSelectionLocked(); resetView(); } From 9b6198b11c5b9372f4021010ff18865d68ceb4a7 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 8 Apr 2025 16:57:37 +0200 Subject: [PATCH 30/82] QmlDesigner: Fix Design Tokens light color theme Task-number: QDS-15169 Change-Id: Iad6ac5cda434ccf14ef97700a07864cc8815acd3 Reviewed-by: Thomas Hartmann --- share/qtcreator/qmldesigner/designsystem/Main.qml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/qmldesigner/designsystem/Main.qml b/share/qtcreator/qmldesigner/designsystem/Main.qml index ae082adef4d..7b2344ecc67 100644 --- a/share/qtcreator/qmldesigner/designsystem/Main.qml +++ b/share/qtcreator/qmldesigner/designsystem/Main.qml @@ -23,12 +23,11 @@ Rectangle { readonly property int cellWidth: 200 readonly property int cellHeight: 40 - readonly property color textColor: "#ffffff" - readonly property color iconColor: "#959595" - readonly property color backgroundColor: "#2c2c2c" - readonly property color borderColor: "#444444" + readonly property color backgroundColor: StudioTheme.Values.themePanelBackground + // TODO This is not a proper color value, but will be fixed with new design + readonly property color borderColor: StudioTheme.Values.themeControlBackground_topToolbarHover - readonly property int borderWidth: 1 + readonly property int borderWidth: StudioTheme.Values.border readonly property int textSize: 18 readonly property int iconSize: 16 From e0cc2a3ebe9478873921e665520857cef37e9174 Mon Sep 17 00:00:00 2001 From: Andrzej Biniek Date: Wed, 2 Apr 2025 07:32:22 +0200 Subject: [PATCH 31/82] QMLDesigner: Create widget registration interface Task-number: QDS-14898 Change-Id: I19936f19e0158808bc736ed04b4d8fd12562c508 Reviewed-by: Thomas Hartmann --- .../components/componentcore/viewmanager.cpp | 47 ++++++++----------- .../components/componentcore/viewmanager.h | 17 ++++--- .../contentlibrary/contentlibraryview.cpp | 7 +++ .../contentlibrary/contentlibraryview.h | 2 +- src/plugins/qmldesigner/designmodewidget.cpp | 2 + .../libs/designercore/include/abstractview.h | 31 +++--------- .../libs/designercore/include/widgetinfo.h | 32 +++++++++++++ .../designercore/include/widgetregistration.h | 17 +++++++ .../libs/designercore/model/abstractview.cpp | 10 ++++ 9 files changed, 105 insertions(+), 60 deletions(-) create mode 100644 src/plugins/qmldesigner/libs/designercore/include/widgetinfo.h create mode 100644 src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 379ff6d423c..63fea75f1ae 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -438,36 +438,19 @@ void ViewManager::setNodeInstanceViewTarget(ProjectExplorer::Target *target) d->nodeInstanceView.setTarget(target); } -QList ViewManager::widgetInfos() const +void ViewManager::initializeWidgetInfos() { - QList widgetInfoList; - -#ifndef QTC_USE_QML_DESIGNER_LITE - widgetInfoList.append(d->edit3DView.widgetInfo()); -#endif - widgetInfoList.append(d->formEditorView.widgetInfo()); - widgetInfoList.append(d->textEditorView.widgetInfo()); - widgetInfoList.append(d->assetsLibraryView.widgetInfo()); - widgetInfoList.append(d->itemLibraryView.widgetInfo()); - widgetInfoList.append(d->navigatorView.widgetInfo()); - widgetInfoList.append(d->propertyEditorView.widgetInfo()); -#ifndef QTC_USE_QML_DESIGNER_LITE - widgetInfoList.append(d->materialBrowserView.widgetInfo()); -#endif - widgetInfoList.append(d->statesEditorView.widgetInfo()); - - if (checkEnterpriseLicense()) - widgetInfoList.append(d->contentLibraryView.widgetInfo()); - - if (d->debugView.hasWidget()) - widgetInfoList.append(d->debugView.widgetInfo()); - - for (auto &view : d->additionalViews) { - if (view->hasWidget()) - widgetInfoList.append(view->widgetInfo()); + for (const auto &view : views()) { + if (view->hasWidget()) { + view->setWidgetRegistration(this); + view->registerWidgetInfo(); + } } +} - return widgetInfoList; +QList ViewManager::widgetInfos() +{ + return m_widgetInfo; } void ViewManager::disableWidgets() @@ -599,4 +582,14 @@ void ViewManager::addView(std::unique_ptr &&view) registerViewAction(*d->additionalViews.back()); } +void ViewManager::registerWidgetInfo(WidgetInfo info) +{ + m_widgetInfo.append(info); +} + +void ViewManager::deregisterWidgetInfo(WidgetInfo info) +{ + m_widgetInfo.removeIf(Utils::equal(&WidgetInfo::uniqueId, info.uniqueId)); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.h b/src/plugins/qmldesigner/components/componentcore/viewmanager.h index 1ca067f213d..76d214981c7 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.h @@ -5,10 +5,11 @@ #include -#include - #include +#include +#include + #include #include @@ -31,13 +32,12 @@ namespace Internal { class DesignModeWidget; } class ViewManagerData; -class QMLDESIGNERCOMPONENTS_EXPORT ViewManager +class QMLDESIGNERCOMPONENTS_EXPORT ViewManager : private WidgetRegistrationInterface { public: ViewManager(class AsynchronousImageCache &imageCache, class ExternalDependenciesInterface &externalDependencies); ~ViewManager(); - void attachRewriterView(); void detachRewriterView(); @@ -50,7 +50,6 @@ public: void setComponentNode(const ModelNode &componentNode); void setComponentViewToMaster(); void setNodeInstanceViewTarget(ProjectExplorer::Target *target); - void resetPropertyEditorView(); void registerFormEditorTool(std::unique_ptr &&tool); @@ -61,8 +60,7 @@ public: addView(std::move(view)); return notOwningPointer; } - - QList widgetInfos() const; + QList widgetInfos(); void disableWidgets(); void enableWidgets(); @@ -99,6 +97,9 @@ public: void hideView(AbstractView &view); void showView(AbstractView &view); + void registerWidgetInfo(WidgetInfo info) override; + void deregisterWidgetInfo(WidgetInfo info) override; + void initializeWidgetInfos(); private: // functions Q_DISABLE_COPY(ViewManager) @@ -123,10 +124,12 @@ private: // functions void registerViewActions(); void registerViewAction(AbstractView &view); void enableView(AbstractView &view); + void disableView(AbstractView &view); private: // variables std::unique_ptr d; + QList m_widgetInfo; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 2a181dfbc54..95c60def4ad 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,12 @@ bool ContentLibraryView::hasWidget() const return true; } +void ContentLibraryView::registerWidgetInfo() +{ + if (QmlDesigner::checkEnterpriseLicense()) + AbstractView::registerWidgetInfo(); +} + WidgetInfo ContentLibraryView::widgetInfo() { if (m_widget.isNull()) { diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index 0872d51a1bd..4fd21fafc2a 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -37,7 +37,7 @@ public: bool hasWidget() const override; WidgetInfo widgetInfo() override; - + void registerWidgetInfo() override; // AbstractView void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index b46ab8e161b..0778347ab2f 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -331,6 +331,8 @@ void DesignModeWidget::setup() viewCommands.append(command); } + viewManager().initializeWidgetInfos(); + // Afterwards get all the other widgets for (const auto &view : viewManager().views()) { if (!view->hasWidget()) diff --git a/src/plugins/qmldesigner/libs/designercore/include/abstractview.h b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h index 79f6267162a..aace9320aa1 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h @@ -6,6 +6,8 @@ #include "model.h" #include "modelnode.h" #include "qmldesignercorelib_global.h" +#include "widgetregistration.h" + #include #include @@ -37,30 +39,6 @@ class InternalNode; using InternalNodePointer = std::shared_ptr; } -enum DesignerWidgetFlags { - DisableOnError, - IgnoreErrors -}; - -class WidgetInfo { -public: - enum PlacementHint { - NoPane, - LeftPane, - RightPane, - BottomPane, - TopPane, // not used - CentralPane - }; - - QString uniqueId; - QString tabName; - QString feedbackDisplayName; - QWidget *widget = nullptr; - PlacementHint placementHint; - DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError; -}; - class QMLDESIGNERCORE_EXPORT AbstractViewAction : public QAction { Q_OBJECT @@ -94,6 +72,8 @@ public: , m_action{Utils::makeUniqueObjectPtr(*this)} {} + void setWidgetRegistration(WidgetRegistrationInterface *interface); + virtual void registerWidgetInfo(); ~AbstractView() override; Model *model() const { return m_model.data(); } @@ -310,6 +290,7 @@ public: protected: void setModel(Model *model); void removeModel(); + static WidgetInfo createWidgetInfo( QWidget *widget = nullptr, const QString &uniqueId = QString(), @@ -319,7 +300,6 @@ protected: DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError); void setKind(Kind kind) { m_kind = kind; } - private: QList toModelNodeList(Utils::span nodeList) const; @@ -329,6 +309,7 @@ private: bool m_visible = true; bool m_isBlockingNotifications = false; Kind m_kind = Kind::Other; + WidgetRegistrationInterface *m_widgetRegistration = nullptr; }; QMLDESIGNERCORE_EXPORT QList toModelNodeList( diff --git a/src/plugins/qmldesigner/libs/designercore/include/widgetinfo.h b/src/plugins/qmldesigner/libs/designercore/include/widgetinfo.h new file mode 100644 index 00000000000..a73fbc6ee29 --- /dev/null +++ b/src/plugins/qmldesigner/libs/designercore/include/widgetinfo.h @@ -0,0 +1,32 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +namespace QmlDesigner { + +enum DesignerWidgetFlags { DisableOnError, IgnoreErrors }; + +class WidgetInfo +{ +public: + enum PlacementHint { + NoPane, + LeftPane, + RightPane, + BottomPane, + TopPane, // not used + CentralPane + }; + + QString uniqueId; + QString tabName; + QString feedbackDisplayName; + QWidget *widget = nullptr; + PlacementHint placementHint = PlacementHint::NoPane; + DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError; +}; + +} // namespace QmlDesigner + +Q_DECLARE_METATYPE(QmlDesigner::WidgetInfo) diff --git a/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h b/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h new file mode 100644 index 00000000000..c741831e12d --- /dev/null +++ b/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "widgetinfo.h" + +namespace QmlDesigner { + +class WidgetRegistrationInterface +{ +public: + virtual void registerWidgetInfo(WidgetInfo) = 0; + virtual void deregisterWidgetInfo(WidgetInfo) = 0; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp index c19ff88219e..c0a39e5879c 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp @@ -59,6 +59,16 @@ void AbstractView::setModel(Model *model) m_model = model; } +void AbstractView::setWidgetRegistration(WidgetRegistrationInterface *interface) +{ + m_widgetRegistration = interface; +} + +void AbstractView::registerWidgetInfo() +{ + if (m_widgetRegistration) + m_widgetRegistration->registerWidgetInfo(widgetInfo()); +} RewriterTransaction AbstractView::beginRewriterTransaction(const QByteArray &identifier) { return RewriterTransaction(this, identifier); From 581afd3350dff51cf1dfa9bcc034c5ba4c60d483 Mon Sep 17 00:00:00 2001 From: Andrzej Biniek Date: Wed, 26 Mar 2025 11:21:29 +0100 Subject: [PATCH 32/82] Add ExtraPropertyEditorManager plugin Task-number: QDS-14898 Change-Id: Ie6cd7fcd33e792574f7ea7fbae979e3eb4a61b4c Reviewed-by: Thomas Hartmann Reviewed-by: Miikka Heikkinen --- src/plugins/CMakeLists.txt | 1 + .../extrapropertyeditormanager/CMakeLists.txt | 12 ++++++++ .../ExtraPropertyEditorManager.json.in | 19 +++++++++++++ .../extrapropertyeditormanagerplugin.cpp | 28 +++++++++++++++++++ .../extrapropertyeditormanagerplugin.h | 18 ++++++++++++ .../extrapropertyeditorview.cpp | 19 +++++++++++++ .../extrapropertyeditorview.h | 23 +++++++++++++++ 7 files changed, 120 insertions(+) create mode 100644 src/plugins/extrapropertyeditormanager/CMakeLists.txt create mode 100644 src/plugins/extrapropertyeditormanager/ExtraPropertyEditorManager.json.in create mode 100644 src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.cpp create mode 100644 src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.h create mode 100644 src/plugins/extrapropertyeditormanager/extrapropertyeditorview.cpp create mode 100644 src/plugins/extrapropertyeditormanager/extrapropertyeditorview.h diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 2ec7c5a3795..4d3499fdf0b 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -111,6 +111,7 @@ if (WITH_QMLDESIGNER) endif() add_subdirectory(qmldesigner ${qmldesigner_builddir}) add_subdirectory(qmldesignerlite) + add_subdirectory(extrapropertyeditormanager) add_subdirectory(effectcomposer) add_subdirectory(studiowelcome) add_subdirectory(insight) diff --git a/src/plugins/extrapropertyeditormanager/CMakeLists.txt b/src/plugins/extrapropertyeditormanager/CMakeLists.txt new file mode 100644 index 00000000000..5959fb20e2a --- /dev/null +++ b/src/plugins/extrapropertyeditormanager/CMakeLists.txt @@ -0,0 +1,12 @@ +add_qtc_plugin(ExtraPropertyEditorManager + CONDITION TARGET QtCreator::QmlDesigner AND NOT QTC_USE_QML_DESIGNER_LITE + PLUGIN_DEPENDS + QtCreator::QmlDesigner + DEPENDS + Qt::Core Qt::CorePrivate QtCreator::Utils + SOURCES + extrapropertyeditormanagerplugin.cpp + extrapropertyeditormanagerplugin.h + extrapropertyeditorview.cpp + extrapropertyeditorview.h +) diff --git a/src/plugins/extrapropertyeditormanager/ExtraPropertyEditorManager.json.in b/src/plugins/extrapropertyeditormanager/ExtraPropertyEditorManager.json.in new file mode 100644 index 00000000000..a6caddc919b --- /dev/null +++ b/src/plugins/extrapropertyeditormanager/ExtraPropertyEditorManager.json.in @@ -0,0 +1,19 @@ +{ + "Id" : "extrapropertyeditormanager", + "DisplayName" : "Extra Property Editor Manager", + "Name" : "ExtraPropertyEditorManager", + "Version" : "${IDE_VERSION}", + "CompatVersion" : "${IDE_VERSION_COMPAT}", + "VendorId" : "theqtcompany", + "Vendor" : "The Qt Company Ltd", + "Copyright" : "${IDE_COPYRIGHT}", + "License" : [ "Commercial Usage", + "", + "Licensees holding valid Qt Enterprise licenses may use this plugin in accordance with the Qt Enterprise License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company." + ], + "Description" : "Plugin for displaying additional instances of property editor.", + "Url" : "https://www.qt.io", + "DocumentationUrl" : "https://doc.qt.io/qtdesignstudio", + "DisabledByDefault": "${NOT_BUILDING_DESIGNSTUDIO}", + ${IDE_PLUGIN_DEPENDENCIES} +} diff --git a/src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.cpp b/src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.cpp new file mode 100644 index 00000000000..3af6d7e6522 --- /dev/null +++ b/src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "extrapropertyeditormanagerplugin.h" +#include "extrapropertyeditorview.h" + +#include +#include + +namespace ExtraPropertyEditorManager { + +bool ExtraPropertyEditorManagerPlugin::initialize(const QStringList &arguments, QString *errorString) +{ + return ExtensionSystem::IPlugin::initialize(arguments, errorString); +} + +bool ExtraPropertyEditorManagerPlugin::delayedInitialize() +{ + auto *designerPlugin = QmlDesigner::QmlDesignerPlugin::instance(); + auto &viewManager = designerPlugin->viewManager(); + viewManager.registerView(std::make_unique( + designerPlugin->imageCache(), + QmlDesigner::QmlDesignerPlugin::externalDependenciesForPluginInitializationOnly())); + + return true; +} + +} // namespace ExtraPropertyEditorManager diff --git a/src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.h b/src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.h new file mode 100644 index 00000000000..42acfd64957 --- /dev/null +++ b/src/plugins/extrapropertyeditormanager/extrapropertyeditormanagerplugin.h @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +namespace ExtraPropertyEditorManager { + +class ExtraPropertyEditorManagerPlugin : public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE + "ExtraPropertyEditorManager.json") + public: + bool initialize(const QStringList &arguments, QString *errorString) override; + bool delayedInitialize() override; +}; + +} // namespace ExtraPropertyEditorManager diff --git a/src/plugins/extrapropertyeditormanager/extrapropertyeditorview.cpp b/src/plugins/extrapropertyeditormanager/extrapropertyeditorview.cpp new file mode 100644 index 00000000000..31744775811 --- /dev/null +++ b/src/plugins/extrapropertyeditormanager/extrapropertyeditorview.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "extrapropertyeditorview.h" + +#include + +namespace QmlDesigner { + +ExtraPropertyEditorView::ExtraPropertyEditorView(class AsynchronousImageCache &imageCache, + ExternalDependenciesInterface &externalDependencies) + : AbstractView{externalDependencies} + , m_imageCache{imageCache} + , m_externalDependencies{externalDependencies} +{} + +ExtraPropertyEditorView::~ExtraPropertyEditorView() {}; + +} // namespace QmlDesigner diff --git a/src/plugins/extrapropertyeditormanager/extrapropertyeditorview.h b/src/plugins/extrapropertyeditormanager/extrapropertyeditorview.h new file mode 100644 index 00000000000..4a09c2cbdeb --- /dev/null +++ b/src/plugins/extrapropertyeditormanager/extrapropertyeditorview.h @@ -0,0 +1,23 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace QmlDesigner { + +class ExtraPropertyEditorView : public AbstractView +{ + Q_OBJECT +public: + ExtraPropertyEditorView(class AsynchronousImageCache &imageCache, + ExternalDependenciesInterface &externalDependencies); + ~ExtraPropertyEditorView() override; + +private: + AsynchronousImageCache &m_imageCache; + ExternalDependenciesInterface &m_externalDependencies; +}; + +} // namespace QmlDesigner From e5a44265d4023f6e82da2fca6a30fa30333ef74e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 8 Apr 2025 16:14:56 +0200 Subject: [PATCH 33/82] QmlDesigner: SourceId has now fileNameId() and directoryPathId() getter Change-Id: I9f75e9b149ee6c47930a16b2d3501e38a97709e7 Reviewed-by: Thomas Hartmann --- src/libs/sqlite/sqliteids.h | 2 +- .../libs/designercore/include/sourcepathids.h | 75 ++++++++++++++++++- .../projectstorage/filesystem.cpp | 4 +- .../projectstorage/projectstorage.cpp | 25 ++++--- .../projectstoragepathwatcher.h | 2 +- .../projectstorage/projectstorageupdater.cpp | 16 ++-- .../sourcepathstorage/sourcepathcache.h | 8 +- .../tests/printers/gtest-creator-printing.cpp | 6 ++ .../tests/printers/gtest-creator-printing.h | 2 + .../projectstorage/projectstorage-test.cpp | 14 ++-- .../projectstoragepathwatcher-test.cpp | 12 +-- .../projectstorageupdater-test.cpp | 66 ++++++++-------- .../projectstorage/qmldocumentparser-test.cpp | 2 +- .../projectstorage/qmltypesparser-test.cpp | 6 +- .../sourcepathcache-test.cpp | 12 +-- 15 files changed, 167 insertions(+), 85 deletions(-) diff --git a/src/libs/sqlite/sqliteids.h b/src/libs/sqlite/sqliteids.h index 15c42505925..2228f7372aa 100644 --- a/src/libs/sqlite/sqliteids.h +++ b/src/libs/sqlite/sqliteids.h @@ -70,7 +70,7 @@ public: explicit operator std::size_t() const { return static_cast(id); } - InternalIntegerType internalId() const { return id; } + constexpr InternalIntegerType internalId() const { return id; } [[noreturn, deprecated]] InternalIntegerType operator&() const { throw std::exception{}; } diff --git a/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h b/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h index 3857ef01410..8cf22df5a10 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h +++ b/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h @@ -27,7 +27,80 @@ using FileNameIds = std::vector; template using SmallFileNameIds = QVarLengthArray; -using SourceId = Sqlite::CompoundBasicId; +class SourceId + +{ +public: + using IsBasicId = std::true_type; + using DatabaseType = long long; + + constexpr explicit SourceId() = default; + + static constexpr SourceId create(DirectoryPathId directoryPathId, FileNameId fileNameId) + { + SourceId compoundId; + compoundId.id = (static_cast(directoryPathId.internalId()) << 32) + | static_cast(fileNameId.internalId()); + + return compoundId; + } + + static constexpr SourceId create(long long idNumber) + { + SourceId id; + id.id = idNumber; + + return id; + } + + constexpr FileNameId fileNameId() const { return FileNameId::create(static_cast(id)); } + + constexpr DirectoryPathId directoryPathId() const { return DirectoryPathId::create(id >> 32); } + + friend constexpr bool compareInvalidAreTrue(SourceId first, SourceId second) + { + return first.id == second.id; + } + + friend constexpr bool operator==(SourceId first, SourceId second) + { + return first.id == second.id && first.isValid(); + } + + friend constexpr auto operator<=>(SourceId first, SourceId second) = default; + + constexpr bool isValid() const { return id != 0; } + + constexpr bool isNull() const { return id == 0; } + + explicit operator bool() const { return isValid(); } + + long long internalId() const { return id; } + + explicit operator std::size_t() const { return static_cast(id) | 0xFFFFFFFFULL; } + + template + friend void convertToString(String &string, SourceId id) + { + using NanotraceHR::dictonary; + using NanotraceHR::keyValue; + + int fileNameId = static_cast(id.id); + int directoryPathId = id.id >> 32; + + auto dict = dictonary(keyValue("directory path id", directoryPathId), + keyValue("source name id", fileNameId), + keyValue("source id", id.id)); + + convertToString(string, dict); + } + + friend bool compareId(SourceId first, SourceId second) { return first.id == second.id; } + +private: + long long id = 0; +}; + using SourceIds = std::vector; template using SmallSourceIds = QVarLengthArray; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp index 67124c4387a..feef28c5a35 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp @@ -50,8 +50,8 @@ long long FileSystem::lastModified(SourceId sourceId) const FileStatus FileSystem::fileStatus(SourceId sourceId) const { - auto path = sourceId.mainId() ? m_sourcePathCache.sourcePath(sourceId) - : m_sourcePathCache.directoryPath(sourceId.contextId()); + auto path = sourceId.fileNameId() ? m_sourcePathCache.sourcePath(sourceId) + : m_sourcePathCache.directoryPath(sourceId.directoryPathId()); QFileInfo fileInfo(QString{path}); fileInfo.refresh(); diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp index 79f0a103016..402be920f5b 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp @@ -2270,7 +2270,7 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos( auto directoryInfos = s->selectDirectoryInfosForDirectoryIdsStatement .valuesWithTransaction( - toIntegers(directoryIds)); + Sqlite::toIntegers(directoryIds)); tracer.end(keyValue("directory infos", directoryInfos)); @@ -2290,7 +2290,7 @@ SmallDirectoryPathIds<32> ProjectStorage::fetchSubdirectoryIds(DirectoryPathId d SmallDirectoryPathIds<32> directoryIds; for (SourceId sourceId : sourceIds) - directoryIds.push_back(sourceId.contextId()); + directoryIds.push_back(sourceId.directoryPathId()); tracer.end(keyValue("directory ids", directoryIds)); @@ -2422,7 +2422,7 @@ TypeIds ProjectStorage::fetchTypeIds(const SourceIds &sourceIds) projectStorageCategory(), keyValue("source ids", sourceIds)}; - return s->selectTypeIdsForSourceIdsStatement.values(toIntegers(sourceIds)); + return s->selectTypeIdsForSourceIdsStatement.values(Sqlite::toIntegers(sourceIds)); } void ProjectStorage::unique(SourceIds &sourceIds) @@ -2467,7 +2467,7 @@ void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAn std::ranges::sort(typeAnnotations, {}, &TypeAnnotation::typeId); auto range = s->selectTypeAnnotationsForSourceIdsStatement.range( - toIntegers(updatedTypeAnnotationSourceIds)); + Sqlite::toIntegers(updatedTypeAnnotationSourceIds)); auto insert = [&](const TypeAnnotation &annotation) { if (!annotation.sourceId) @@ -2625,7 +2625,7 @@ void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::Directo auto range = s->selectDirectoryInfosForDirectoryIdsStatement .range( - toIntegers(updatedDirectoryInfoDirectoryIds)); + Sqlite::toIntegers(updatedDirectoryInfoDirectoryIds)); auto insert = [&](const Storage::Synchronization::DirectoryInfo &directoryInfo) { using NanotraceHR::keyValue; @@ -2687,7 +2687,7 @@ void ProjectStorage::synchronizeFileStatuses(FileStatuses &fileStatuses, std::ranges::sort(fileStatuses, {}, &FileStatus::sourceId); auto range = s->selectFileStatusesForSourceIdsStatement.range( - toIntegers(updatedSourceIds)); + Sqlite::toIntegers(updatedSourceIds)); auto insert = [&](const FileStatus &fileStatus) { using NanotraceHR::keyValue; @@ -2775,7 +2775,7 @@ void ProjectStorage::synchromizeModuleExportedImports( auto range = s->selectModuleExportedImportsForSourceIdStatement .range( - toIntegers(updatedModuleIds)); + Sqlite::toIntegers(updatedModuleIds)); auto compareKey = [](const Storage::Synchronization::ModuleExportedImportView &view, const Storage::Synchronization::ModuleExportedImport &import) { @@ -3193,8 +3193,8 @@ void ProjectStorage::deleteNotUpdatedTypes(const TypeIds &updatedTypeIds, }; s->selectNotUpdatedTypesInSourcesStatement.readCallback(callback, - toIntegers(updatedSourceIds), - toIntegers(updatedTypeIds)); + Sqlite::toIntegers(updatedSourceIds), + Sqlite::toIntegers(updatedTypeIds)); for (TypeId typeIdToBeDeleted : typeIdsToBeDeleted) callback(typeIdToBeDeleted); } @@ -3368,7 +3368,8 @@ void ProjectStorage::synchronizeExportedTypes( }); auto range = s->selectExportedTypesForSourceIdsStatement - .range(toIntegers(updatedTypeIds)); + .range( + Sqlite::toIntegers(updatedTypeIds)); auto compareKey = [](const Storage::Synchronization::ExportedTypeView &view, const Storage::Synchronization::ExportedType &type) { @@ -3915,7 +3916,7 @@ void ProjectStorage::synchronizeDocumentImports(Storage::Imports &imports, }); auto range = s->selectDocumentImportForSourceIdStatement - .range(toIntegers(updatedSourceIds), + .range(Sqlite::toIntegers(updatedSourceIds), importKind); auto compareKey = [](const Storage::Synchronization::ImportView &view, @@ -4063,7 +4064,7 @@ void ProjectStorage::synchronizePropertyEditorPaths( std::ranges::sort(paths, {}, &PropertyEditorQmlPath::typeId); auto range = s->selectPropertyEditorPathsForForSourceIdsStatement.range( - toIntegers(updatedPropertyEditorQmlPathsDirectoryPathIds)); + Sqlite::toIntegers(updatedPropertyEditorQmlPathsDirectoryPathIds)); auto compareKey = [](const PropertyEditorQmlPathView &view, const PropertyEditorQmlPath &value) { return view.typeId <=> value.typeId; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index 674ff189f39..cb01fefcb10 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -118,7 +118,7 @@ public: std::ranges::transform(idPath.sourceIds, std::back_inserter(entries), [&](SourceId sourceId) { auto fileStatus = m_fileStatusCache.find(sourceId); return WatcherEntry{id, - sourceId.contextId(), + sourceId.directoryPathId(), sourceId, fileStatus.lastModified, fileStatus.size}; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index 1c63bbfba45..e5e0a8f2335 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -551,7 +551,7 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct if (isInsideProject == IsInsideProject::Yes) { static FileNameId ignoreInQdsFileNameId = m_pathCache.fileNameId("ignore-in-qds"); - SourceId ignoreInQdsSourceId = SourceId::create(ignoreInQdsFileNameId, directoryPathId); + SourceId ignoreInQdsSourceId = SourceId::create(directoryPathId, ignoreInQdsFileNameId); auto ignoreInQdsState = fileState(ignoreInQdsSourceId, package, notUpdatedSourceIds); @@ -598,7 +598,7 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct if (isChangedOrAdded(directoryState)) { for (const auto &[subdirectoryPath, subdirectoryId] : existingSubdirecories) { package.directoryInfos.emplace_back(directoryId, - SourceId::create(FileNameId{}, subdirectoryId), + SourceId::create(subdirectoryId, FileNameId{}), ModuleId{}, Storage::Synchronization::FileType::Directory); } @@ -669,11 +669,11 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa SourcePath qmldirPath{directoryPath + "/qmldir"}; SourceId qmldirSourceId = m_pathCache.sourceId(qmldirPath); - DirectoryPathId directoryId = qmldirSourceId.contextId(); + DirectoryPathId directoryId = qmldirSourceId.directoryPathId(); auto directoryState = fileState(directoryId, package, notUpdatedSourceIds); if (isExisting(directoryState)) - WatchedSourceIds.directoryIds.push_back(SourceId::create(FileNameId{}, directoryId)); + WatchedSourceIds.directoryIds.push_back(SourceId::create(directoryId, FileNameId{})); auto qmldirState = fileState(qmldirSourceId, package, notUpdatedSourceIds); if (isExisting(qmldirState)) @@ -962,7 +962,7 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath( namespace { DirectoryPathIds filterUniqueDirectoryPathIds(const SourceIds &sourceIds) { - auto directoryPathIds = Utils::transform(sourceIds, &SourceId::contextId); + auto directoryPathIds = Utils::transform(sourceIds, &SourceId::directoryPathId); std::sort(directoryPathIds.begin(), directoryPathIds.end()); auto newEnd = std::unique(directoryPathIds.begin(), directoryPathIds.end()); @@ -1070,7 +1070,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan const DirectoryPathIds &directoryIds, IsInsideProject isInsideProject) { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmlDocumentSourceIds))) { - if (!contains(directoryIds, sourceId.contextId())) + if (!contains(directoryIds, sourceId.directoryPathId())) this->parseQmlComponent(sourceId, package, notUpdatedSourceIds, isInsideProject); } }; @@ -1082,7 +1082,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan const DirectoryPathIds &directoryIds, IsInsideProject isInsideProject) { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) { - if (!contains(directoryIds, sourceId.contextId())) { + if (!contains(directoryIds, sourceId.directoryPathId())) { QString qmltypesPath{m_pathCache.sourcePath(sourceId)}; auto directoryInfo = m_projectStorage.fetchDirectoryInfo(sourceId); if (directoryInfo) @@ -1515,7 +1515,7 @@ ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState( Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds) const { - auto sourceId = SourceId::create(FileNameId{}, directoryPathId); + auto sourceId = SourceId::create(directoryPathId, FileNameId{}); return fileState(sourceId, package, notUpdatedSourceIds); } diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h index e35e4a04857..ed0cc900f23 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h @@ -59,7 +59,7 @@ public: auto fileNameId = m_fileNameCache.id(fileName); - return SourceId::create(fileNameId, directoryPathId); + return SourceId::create(directoryPathId, fileNameId); } FileNameId fileNameId(Utils::SmallStringView fileName) const override @@ -71,7 +71,7 @@ public: { FileNameId fileNameId = m_fileNameCache.id(fileName); - return SourceId::create(fileNameId, directoryPathId); + return SourceId::create(directoryPathId, fileNameId); } DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const override @@ -88,9 +88,9 @@ public: if (!sourceId) [[unlikely]] throw NoSourcePathForInvalidSourceId(); - auto fileName = m_fileNameCache.value(sourceId.mainId()); + auto fileName = m_fileNameCache.value(sourceId.fileNameId()); - Utils::PathString directoryPath = m_directoryPathCache.value(sourceId.contextId()); + Utils::PathString directoryPath = m_directoryPathCache.value(sourceId.directoryPathId()); return SourcePath{directoryPath, fileName}; } diff --git a/tests/unit/tests/printers/gtest-creator-printing.cpp b/tests/unit/tests/printers/gtest-creator-printing.cpp index 231348b7f8b..66dbf2f91ad 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.cpp +++ b/tests/unit/tests/printers/gtest-creator-printing.cpp @@ -598,6 +598,12 @@ std::ostream &operator<<(std::ostream &out, AuxiliaryDataType type) return out; } +std::ostream &operator<<(std::ostream &out, SourceId sourceId) +{ + return out << "id=(" << sourceId.fileNameId().internalId() << ", " + << sourceId.directoryPathId().internalId() << ")"; +} + namespace Cache { std::ostream &operator<<(std::ostream &out, const DirectoryPath &directoryPath) diff --git a/tests/unit/tests/printers/gtest-creator-printing.h b/tests/unit/tests/printers/gtest-creator-printing.h index b0ef8395a6a..d0ad6524876 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.h +++ b/tests/unit/tests/printers/gtest-creator-printing.h @@ -139,6 +139,7 @@ struct CompoundPropertyMetaInfo; enum class FlagIs : unsigned int; template class BasicAuxiliaryDataKey; +class SourceId; void PrintTo(const ThemeProperty &prop, std::ostream *os); std::ostream &operator<<(std::ostream &out, const ThemeProperty &prop); @@ -162,6 +163,7 @@ std::ostream &operator<<(std::ostream &out, FlagIs flagIs); std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey &key); std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey &key); std::ostream &operator<<(std::ostream &out, AuxiliaryDataType type); +std::ostream &operator<<(std::ostream &out, SourceId sourceId); namespace Cache { class DirectoryPath; diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 45b2a3e56a4..00db8c92486 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -1253,13 +1253,13 @@ protected: SourceId sourceId5{sourcePathCache.sourceId(path5)}; SourceId sourceId6{sourcePathCache.sourceId(path6)}; SourceId sourceIdPath1{sourcePathCache.sourceId(pathPath1)}; - DirectoryPathId directoryPathIdPath1{sourceIdPath1.contextId()}; + DirectoryPathId directoryPathIdPath1{sourceIdPath1.directoryPathId()}; SourceId sourceIdPath6{sourcePathCache.sourceId(pathPath6)}; - DirectoryPathId directoryPathIdPath6{sourceIdPath6.contextId()}; + DirectoryPathId directoryPathIdPath6{sourceIdPath6.directoryPathId()}; SourceId qmlProjectSourceId{sourcePathCache.sourceId("/path1/qmldir")}; - DirectoryPathId qmlProjectDirectoryPathId = qmlProjectSourceId.contextId(); + DirectoryPathId qmlProjectDirectoryPathId = qmlProjectSourceId.directoryPathId(); SourceId qtQuickProjectSourceId{sourcePathCache.sourceId("/path2/qmldir")}; - DirectoryPathId qtQuickProjectDirectoryPathId = qtQuickProjectSourceId.contextId(); + DirectoryPathId qtQuickProjectDirectoryPathId = qtQuickProjectSourceId.directoryPathId(); ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; ModuleId qmlNativeModuleId{storage.moduleId("Qml", ModuleKind::CppLibrary)}; ModuleId qtQuickModuleId{storage.moduleId("QtQuick", ModuleKind::QmlLibrary)}; @@ -6065,7 +6065,7 @@ TEST_F(ProjectStorage, fetch_subdirectory_directory_path_ids) sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - auto directory1Id = SourceId::create(FileNameId{}, sourceId2.contextId()); + auto directory1Id = SourceId::create(sourceId2.directoryPathId(), FileNameId{}); Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectDirectoryPathId, directory1Id, ModuleId{}, @@ -6074,7 +6074,7 @@ TEST_F(ProjectStorage, fetch_subdirectory_directory_path_ids) sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; - auto directory2Id = SourceId::create(FileNameId{}, sourceId4.contextId()); + auto directory2Id = SourceId::create(sourceId4.directoryPathId(), FileNameId{}); Storage::Synchronization::DirectoryInfo directoryInfo4{qmlProjectDirectoryPathId, directory2Id, ModuleId{}, @@ -6086,7 +6086,7 @@ TEST_F(ProjectStorage, fetch_subdirectory_directory_path_ids) auto directoryInfo = storage.fetchSubdirectoryIds(qmlProjectDirectoryPathId); ASSERT_THAT(directoryInfo, - UnorderedElementsAre(directory1Id.contextId(), directory2Id.contextId())); + UnorderedElementsAre(directory1Id.directoryPathId(), directory2Id.directoryPathId())); } TEST_F(ProjectStorage, fetch_directory_info_by_source_id) diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index ee6d99c27f4..a4b67aa7efb 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -108,9 +108,9 @@ protected: pathCache.sourceId(path3), pathCache.sourceId(path4), pathCache.sourceId(path5)}; - DirectoryPathIds directoryPathIds = {sourceIds[0].contextId(), - sourceIds[2].contextId(), - sourceIds[4].contextId()}; + DirectoryPathIds directoryPathIds = {sourceIds[0].directoryPathId(), + sourceIds[2].directoryPathId(), + sourceIds[4].directoryPathId()}; ProjectChunkIds ids{projectChunkId1, projectChunkId2, projectChunkId3}; WatcherEntry watcherEntry1{projectChunkId1, directoryPathIds[0], sourceIds[0]}; WatcherEntry watcherEntry2{projectChunkId2, directoryPathIds[0], sourceIds[0]}; @@ -460,7 +460,7 @@ TEST_F(ProjectStoragePathWatcher, trigger_manual_two_notify_file_changes) ElementsAre(IdPaths{projectChunkId1, {sourceIds[0], sourceIds[1]}}, IdPaths{projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}))); - watcher.checkForChangeInDirectory({sourceIds[0].contextId(), sourceIds[2].contextId()}); + watcher.checkForChangeInDirectory({sourceIds[0].directoryPathId(), sourceIds[2].directoryPathId()}); } TEST_F(ProjectStoragePathWatcher, trigger_manual_notify_for_path_changes) @@ -474,7 +474,7 @@ TEST_F(ProjectStoragePathWatcher, trigger_manual_notify_for_path_changes) EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); - watcher.checkForChangeInDirectory({sourceIds[0].contextId()}); + watcher.checkForChangeInDirectory({sourceIds[0].directoryPathId()}); } TEST_F(ProjectStoragePathWatcher, trigger_manual_no_notify_for_unwatched_path_changes) @@ -483,7 +483,7 @@ TEST_F(ProjectStoragePathWatcher, trigger_manual_no_notify_for_unwatched_path_ch EXPECT_CALL(notifier, pathsChanged(IsEmpty())); - watcher.checkForChangeInDirectory({sourceIds[0].contextId()}); + watcher.checkForChangeInDirectory({sourceIds[0].directoryPathId()}); } TEST_F(ProjectStoragePathWatcher, update_context_id_paths_adds_entry_in_new_directory) diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index f10635cc2a1..191429fa47a 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -355,7 +355,7 @@ public: SourceId createDirectorySourceId(Utils::SmallStringView path) const { auto directoryId = sourcePathCache.directoryPathId(path); - return SourceId::create(FileNameId{}, directoryId); + return SourceId::create(directoryId, FileNameId{}); } SourceId createDirectorySourceIdFromQString(const QString &path) const @@ -470,8 +470,8 @@ protected: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); - DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.directoryPathId(); + SourceId directoryPathSourceId = SourceId::create(directoryPathId, QmlDesigner::FileNameId{}); SourceId annotationDirectorySourceId = createDirectorySourceId("/path/designer"); SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml"); SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First2.qml"); @@ -480,11 +480,11 @@ protected: UNITTEST_DIR "/../../../../share/qtcreator/qmldesigner/itemLibrary/"); DirectoryPathId itemLibraryPathDirectoryPathId = sourcePathCache.directoryPathId( Utils::PathString{itemLibraryPath}); - SourceId itemLibraryPathSourceId = SourceId::create(FileNameId{}, itemLibraryPathDirectoryPathId); + SourceId itemLibraryPathSourceId = SourceId::create(itemLibraryPathDirectoryPathId, FileNameId{}); const QString qmlImportsPath = QDir::cleanPath(UNITTEST_DIR "/projectstorage/data/qml"); DirectoryPathId qmlImportsPathDirectoryPathId = sourcePathCache.directoryPathId( Utils::PathString{itemLibraryPath}); - SourceId qmlImportsPathSourceId = SourceId::create(FileNameId{}, qmlImportsPathDirectoryPathId); + SourceId qmlImportsPathSourceId = SourceId::create(qmlImportsPathDirectoryPathId, FileNameId{}); ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; ModuleId qmlCppNativeModuleId{storage.moduleId("Qml", ModuleKind::CppLibrary)}; ModuleId exampleModuleId{storage.moduleId("Example", ModuleKind::QmlLibrary)}; @@ -537,11 +537,11 @@ protected: QmlDesigner::ProjectChunkId otherQmltypesProjectChunkId{otherProjectPartId, QmlDesigner::SourceType::QmlTypes}; DirectoryPathId path1DirectoryPathId = sourcePathCache.directoryPathId("/path/one"); - SourceId path1SourceId = SourceId::create(QmlDesigner::FileNameId{}, path1DirectoryPathId); + SourceId path1SourceId = SourceId::create(path1DirectoryPathId, QmlDesigner::FileNameId{}); DirectoryPathId path2DirectoryPathId = sourcePathCache.directoryPathId("/path/two"); - SourceId path2SourceId = SourceId::create(QmlDesigner::FileNameId{}, path2DirectoryPathId); + SourceId path2SourceId = SourceId::create(path2DirectoryPathId, QmlDesigner::FileNameId{}); DirectoryPathId path3DirectoryPathId = sourcePathCache.directoryPathId("/path/three"); - SourceId path3SourceId = SourceId::create(QmlDesigner::FileNameId{}, path3DirectoryPathId); + SourceId path3SourceId = SourceId::create(path3DirectoryPathId, QmlDesigner::FileNameId{}); SourceId qmldir1SourceId = sourcePathCache.sourceId("/path/one/qmldir"); SourceId qmldir2SourceId = sourcePathCache.sourceId("/path/two/qmldir"); SourceId qmldir3SourceId = sourcePathCache.sourceId("/path/three/qmldir"); @@ -608,8 +608,8 @@ public: QStringList directories = {"/path"}; SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); - DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.directoryPathId(); + SourceId directoryPathSourceId = SourceId::create(directoryPathId, QmlDesigner::FileNameId{}); }; TEST_F(ProjectStorageUpdater_get_content_for_qml_types, added_qml_types_file_provides_content) @@ -669,8 +669,8 @@ public: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/root/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/root/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/root/path/qmldir"); - DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.directoryPathId(); + SourceId directoryPathSourceId = SourceId::create(directoryPathId, QmlDesigner::FileNameId{}); }; TEST_F(ProjectStorageUpdater_parse_qml_types, add_directory) @@ -782,8 +782,8 @@ public: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/root/path/example.qmltypes"); SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/root/path/example2.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/root/path/qmldir"); - DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.directoryPathId(); + SourceId directoryPathSourceId = SourceId::create(directoryPathId, QmlDesigner::FileNameId{}); SourceId annotationDirectoryId = createDirectorySourceId("/root/path/designer"); SourceId rootQmlDirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); SourceId rootDirectoryPathSourceId = createDirectorySourceId("/root"); @@ -877,13 +877,13 @@ public: public: SourceId rootDirectoryPathSourceId = createDirectorySourceId("/root"); - DirectoryPathId rootDirectoryPathId = rootDirectoryPathSourceId.contextId(); + DirectoryPathId rootDirectoryPathId = rootDirectoryPathSourceId.directoryPathId(); SourceId path1SourceId = createDirectorySourceId("/root/one"); - DirectoryPathId path1DirectoryPathId = path1SourceId.contextId(); + DirectoryPathId path1DirectoryPathId = path1SourceId.directoryPathId(); SourceId path2SourceId = createDirectorySourceId("/root/two"); - DirectoryPathId path2DirectoryPathId = path2SourceId.contextId(); + DirectoryPathId path2DirectoryPathId = path2SourceId.directoryPathId(); SourceId path3SourceId = createDirectorySourceId("/root/one/three"); - DirectoryPathId path3DirectoryPathId = path3SourceId.contextId(); + DirectoryPathId path3DirectoryPathId = path3SourceId.directoryPathId(); }; TEST_F(ProjectStorageUpdater_synchronize_subdirectories, added_qt_subdircectories) @@ -1092,8 +1092,8 @@ public: public: SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes"); SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir"); - DirectoryPathId directoryPathId = qmlDirPathSourceId.contextId(); - SourceId directoryPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryPathId); + DirectoryPathId directoryPathId = qmlDirPathSourceId.directoryPathId(); + SourceId directoryPathSourceId = SourceId::create(directoryPathId, QmlDesigner::FileNameId{}); SourceId annotationDirectorySourceId = createDirectorySourceId("/path/designer"); ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; ModuleId exampleModuleId{storage.moduleId("Example", ModuleKind::QmlLibrary)}; @@ -3244,7 +3244,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_subdirectories) SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); DirectoryPathId rootPathId = sourcePathCache.directoryPathId("/root"); - SourceId rootPathSourceId = SourceId::create(QmlDesigner::FileNameId{}, rootPathId); + SourceId rootPathSourceId = SourceId::create(rootPathId, QmlDesigner::FileNameId{}); SourceId rootQmldirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); setFilesChanged({directoryPathSourceId, rootPathSourceId}); setFilesUnchanged({qmlDirPathSourceId, rootQmldirPathSourceId}); @@ -3356,7 +3356,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_directory_change setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); setFilesUnchanged({qmlDirPathSourceId}); - auto directoryDirectoryPathId = directoryPathSourceId.contextId(); + auto directoryDirectoryPathId = directoryPathSourceId.directoryPathId(); EXPECT_CALL(patchWatcherMock, updateContextIdPaths( @@ -3471,7 +3471,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_qmldir_changes) FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - auto directoryDirectoryPathId = qmlDirPathSourceId.contextId(); + auto directoryDirectoryPathId = qmlDirPathSourceId.directoryPathId(); EXPECT_CALL(patchWatcherMock, updateContextIdPaths( @@ -4794,7 +4794,7 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes) QmlDesigner::SourcePath{propertyEditorQmlPath + "/QML/QtObjectPane.qml"}); auto directoryId = sourcePathCache.directoryPathId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QML"}); - auto directorySourceId = SourceId::create(QmlDesigner::FileNameId{}, directoryId); + auto directorySourceId = SourceId::create(directoryId, QmlDesigner::FileNameId{}); setFilesChanged({directorySourceId}); auto qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); @@ -4829,12 +4829,12 @@ TEST_F(ProjectStorageUpdater, update_property_editor_specifics) QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/TextSpecifics.qml"}); auto qtQuickDirectoryId = sourcePathCache.directoryPathId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick"}); - auto qtQuickDirectorySourceId = SourceId::create(QmlDesigner::FileNameId{}, qtQuickDirectoryId); + auto qtQuickDirectorySourceId = SourceId::create(qtQuickDirectoryId, QmlDesigner::FileNameId{}); auto buttonSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/Controls/ButtonSpecifics.qml"}); auto controlsDirectoryId = sourcePathCache.directoryPathId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/Controls"}); - auto controlsDirectorySourceId = SourceId::create(QmlDesigner::FileNameId{}, controlsDirectoryId); + auto controlsDirectorySourceId = SourceId::create(controlsDirectoryId, QmlDesigner::FileNameId{}); setFilesChanged({qtQuickDirectorySourceId, controlsDirectorySourceId}); auto qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto controlsModuleId = storage.moduleId("QtQuick.Controls", ModuleKind::QmlLibrary); @@ -5072,7 +5072,7 @@ TEST_F(ProjectStorageUpdater, synchronize_added_property_editor_qml_paths_direct { setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(designer1DirectoryId, QmlDesigner::FileNameId{}); setFilesUnchanged({path1SourceId}); setFilesAdded({designer1SourceId}); @@ -5106,7 +5106,7 @@ TEST_F(ProjectStorageUpdater, synchronize_changed_property_editor_qml_paths_dire { setFileSystemSubdirectories(u"/path/one", {"/path/one/designer"}); DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(designer1DirectoryId, QmlDesigner::FileNameId{}); setFilesUnchanged({path1SourceId}); setFilesChanged({designer1SourceId}); @@ -5140,7 +5140,7 @@ TEST_F(ProjectStorageUpdater, dont_synchronize_empty_property_editor_qml_paths_d { setFileSystemSubdirectories(u"/path/two", {}); DirectoryPathId designer2DirectoryId = sourcePathCache.directoryPathId("/path/two/designer"); - SourceId designer2SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer2DirectoryId); + SourceId designer2SourceId = SourceId::create(designer2DirectoryId, QmlDesigner::FileNameId{}); setFilesChanged({path2SourceId}); setFilesNotExists({designer2SourceId}); @@ -5172,7 +5172,7 @@ TEST_F(ProjectStorageUpdater, dont_synchronize_empty_property_editor_qml_paths_d TEST_F(ProjectStorageUpdater, remove_property_editor_qml_paths_if_designer_directory_is_removed) { DirectoryPathId designer1DirectoryId = sourcePathCache.directoryPathId("/path/one/designer"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(designer1DirectoryId, QmlDesigner::FileNameId{}); setFilesUnchanged({path1SourceId, qmldir1SourceId}); setFilesRemoved({designer1SourceId}); @@ -5213,7 +5213,7 @@ TEST_F(ProjectStorageUpdater, "/path/one/designer/HuoSpecificsDynamic.qml"); SourceId propertyEditorPaneSourceId = sourcePathCache.sourceId( "/path/one/designer/CaoPane.qml"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(designer1DirectoryId, QmlDesigner::FileNameId{}); setFilesChanged({designer1SourceId}); setFilesUnchanged({path1SourceId, qmldir1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); @@ -5257,7 +5257,7 @@ TEST_F(ProjectStorageUpdater, "/path/one/designer/HuoSpecificsDynamic.qml"); SourceId propertyEditorPaneSourceId = sourcePathCache.sourceId( "/path/one/designer/CaoPane.qml"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(designer1DirectoryId, QmlDesigner::FileNameId{}); setFilesChanged({path1SourceId}); setFilesUnchanged({qmldir1SourceId, designer1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); @@ -5300,7 +5300,7 @@ TEST_F(ProjectStorageUpdater, synchronize_property_editor_qml_paths_directory_if "/path/one/designer/HuoSpecificsDynamic.qml"); SourceId propertyEditorPaneSourceId = sourcePathCache.sourceId( "/path/one/designer/CaoPane.qml"); - SourceId designer1SourceId = SourceId::create(QmlDesigner::FileNameId{}, designer1DirectoryId); + SourceId designer1SourceId = SourceId::create(designer1DirectoryId, QmlDesigner::FileNameId{}); setFilesChanged({qmldir1SourceId}); setFilesUnchanged({path1SourceId, designer1SourceId}); auto barModuleId = storage.moduleId("Bar", ModuleKind::QmlLibrary); diff --git a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp index a4fbde175d9..fb1df11c115 100644 --- a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp @@ -158,7 +158,7 @@ protected: QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; Storage::Imports imports; SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")}; - DirectoryPathId qmlFileDirectoryPathId{qmlFileSourceId.contextId()}; + DirectoryPathId qmlFileDirectoryPathId{qmlFileSourceId.directoryPathId()}; Utils::PathString directoryPath{sourcePathCache.directoryPath(qmlFileDirectoryPathId)}; ModuleId directoryModuleId{storage.moduleId(directoryPath, ModuleKind::PathLibrary)}; }; diff --git a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp index 74800191cf8..089e65b9188 100644 --- a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp @@ -196,11 +196,11 @@ protected: Synchronization::Types types; SourceId qmltypesFileSourceId{sourcePathCache.sourceId("path/to/types.qmltypes")}; ModuleId qtQmlNativeModuleId = storage.moduleId("QtQml", ModuleKind::CppLibrary); - Synchronization::DirectoryInfo directoryInfo{qmltypesFileSourceId.contextId(), + Synchronization::DirectoryInfo directoryInfo{qmltypesFileSourceId.directoryPathId(), qmltypesFileSourceId, qtQmlNativeModuleId, Synchronization::FileType::QmlTypes}; - DirectoryPathId qmltypesFileDirectoryPathId{qmltypesFileSourceId.contextId()}; + DirectoryPathId qmltypesFileDirectoryPathId{qmltypesFileSourceId.directoryPathId()}; }; TEST_F(QmlTypesParser, imports) @@ -893,7 +893,7 @@ TEST_F(QmlTypesParser, default_property) TEST_F(QmlTypesParser, skip_template_item) { ModuleId moduleId = storage.moduleId("QtQuick.Templates", ModuleKind::CppLibrary); - Synchronization::DirectoryInfo directoryInfo{qmltypesFileSourceId.contextId(), + Synchronization::DirectoryInfo directoryInfo{qmltypesFileSourceId.directoryPathId(), qmltypesFileSourceId, moduleId, Synchronization::FileType::QmlTypes}; diff --git a/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp index d7def11d0a6..70c9062e3fd 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp @@ -48,9 +48,9 @@ protected: FileNameId fileNameId63 = FileNameId::create(63); DirectoryPathId directoryPathId5 = DirectoryPathId::create(5); DirectoryPathId directoryPathId6 = DirectoryPathId::create(6); - SourceId sourceId542 = SourceId::create(fileNameId42, directoryPathId5); - SourceId sourceId563 = SourceId::create(fileNameId63, directoryPathId5); - SourceId sourceId642 = SourceId::create(fileNameId42, directoryPathId6); + SourceId sourceId542 = SourceId::create(directoryPathId5, fileNameId42); + SourceId sourceId563 = SourceId::create(directoryPathId5, fileNameId63); + SourceId sourceId642 = SourceId::create(directoryPathId6, fileNameId42); NiceMock storageMock; Cache cache{storageMock}; NiceMock storageMockFilled; @@ -278,7 +278,7 @@ TEST_F(SourcePathCache, second_directory_path_calls_not_fetch_directory_path) TEST_F(SourcePathCache, fetch_directory_path_from_source_id) { - auto directoryPathId = sourceId542.contextId(); + auto directoryPathId = sourceId542.directoryPathId(); ASSERT_THAT(directoryPathId, Eq(directoryPathId5)); } @@ -287,7 +287,7 @@ TEST_F(SourcePathCache, fetch_directory_path_id_after_fetching_file_path_by_sour { cache.sourcePath(sourceId542); - auto directoryPathId = sourceId542.contextId(); + auto directoryPathId = sourceId542.directoryPathId(); ASSERT_THAT(directoryPathId, Eq(directoryPathId5)); } @@ -313,7 +313,7 @@ TEST_F(SourcePathCache, get_directory_path_id_in_filled_cache) { Cache cacheFilled{storageMockFilled}; - auto id = sourceId542.contextId(); + auto id = sourceId542.directoryPathId(); ASSERT_THAT(id, Eq(directoryPathId5)); } From c4a8272734f9be32247434c1384daa2c3baf6f9a Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Apr 2025 13:54:57 +0200 Subject: [PATCH 34/82] QmlDesigner: Fix crash The items in selection tool can be dangling. Therefore we check it against all items in the scene. Task-number: QDS-15146 Change-Id: I1008e6855f874bf4f9d6c2f615ecf6b628747666 Reviewed-by: Tim Jenssen --- .../qmldesigner/components/formeditor/selectiontool.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp index d30539d52b6..13a26252877 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp @@ -223,9 +223,12 @@ void SelectionTool::itemsAboutToRemoved(const QList &itemList) { const QList current = items(); - QList remaining = Utils::filtered(current, [&itemList](FormEditorItem *item) { - return !itemList.contains(item); - }); + const auto allItems = scene()->items(); + QList remaining = Utils::filtered(current, + [&itemList, &allItems](FormEditorItem *item) { + return !itemList.contains(item) + && allItems.contains(item); + }); if (!remaining.isEmpty()) { m_selectionIndicator.setItems(remaining); From 2a545db890c9fa8411881e2416506c20f45a52b0 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Fri, 28 Mar 2025 14:38:48 +0100 Subject: [PATCH 35/82] QmlProjectExporter: Add writer to compile the project as a library This writer writes cmake files to compile the project as a library. To enable set the property standaloneApp to false. Note that this writer can be enabled for DS version > 4.8 Change-Id: I24dc2b1a7a0f02648063ce11232c15a5b170f6b7 Reviewed-by: Thomas Hartmann --- src/plugins/qmlprojectmanager/CMakeLists.txt | 1 + .../qmlprojectexporter/boilerplate.qrc | 1 + .../qmlprojectexporter/cmakegenerator.cpp | 97 ++++++++++- .../qmlprojectexporter/cmakegenerator.h | 4 + .../qmlprojectexporter/cmakewriter.cpp | 60 ++++++- .../qmlprojectexporter/cmakewriter.h | 7 + .../qmlprojectexporter/cmakewriterlib.cpp | 112 ++++++++++++ .../qmlprojectexporter/cmakewriterlib.h | 26 +++ .../qmlprojectexporter/cmakewriterv0.cpp | 5 + .../qmlprojectexporter/cmakewriterv0.h | 1 + .../qmlprojectexporter/cmakewriterv1.cpp | 159 ++++++++++-------- .../qmlprojectexporter/cmakewriterv1.h | 8 +- .../qmlprojectexporter/exporter.cpp | 3 - .../qmlprojectexporter/filegenerator.cpp | 19 ++- .../qmlprojectexporter/filegenerator.h | 2 +- .../templates/cmakeroot_lib.tpl | 28 +++ 16 files changed, 447 insertions(+), 86 deletions(-) create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.cpp create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.h create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_lib.tpl diff --git a/src/plugins/qmlprojectmanager/CMakeLists.txt b/src/plugins/qmlprojectmanager/CMakeLists.txt index 4f6eb8eba41..2c7b143d901 100644 --- a/src/plugins/qmlprojectmanager/CMakeLists.txt +++ b/src/plugins/qmlprojectmanager/CMakeLists.txt @@ -48,6 +48,7 @@ extend_qtc_plugin(QmlProjectManager cmakewriter.cpp cmakewriter.h cmakewriterv0.cpp cmakewriterv0.h cmakewriterv1.cpp cmakewriterv1.h + cmakewriterlib.cpp cmakewriterlib.h exporter.cpp exporter.h filegenerator.cpp filegenerator.h filetypes.cpp filetypes.h diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/boilerplate.qrc b/src/plugins/qmlprojectmanager/qmlprojectexporter/boilerplate.qrc index 50e9909a17c..822a2f807bd 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/boilerplate.qrc +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/boilerplate.qrc @@ -2,6 +2,7 @@ templates/cmakeroot_v0.tpl templates/cmakeroot_v1.tpl + templates/cmakeroot_lib.tpl templates/main_cpp_v0.tpl templates/main_cpp_v1.tpl templates/cmakemodule_v1.tpl diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp index aeb065a4f17..31d1d75d834 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp @@ -11,10 +11,12 @@ #include "projectexplorer/projectnodes.h" #include "utils/filenamevalidatinglineedit.h" +#include "utils/persistentsettings.h" #include #include #include +#include #include @@ -60,7 +62,12 @@ void CMakeGenerator::updateProject(QmlProject *project) if (!isEnabled()) return; - m_writer = CMakeWriter::create(this); + if (!isActive()) + return; + + createWriter(); + if (!m_writer) + return; m_root = std::make_shared(); m_root->type = Node::Type::App; @@ -85,6 +92,14 @@ QString CMakeGenerator::projectName() const return m_projectName; } +Utils::FilePath CMakeGenerator::projectDir() const +{ + if (!m_root) + return {}; + + return m_root->dir; +} + bool CMakeGenerator::findFile(const Utils::FilePath& file) const { return findFile(m_root, file); @@ -440,6 +455,18 @@ void CMakeGenerator::removeFile(NodePtr &node, const Utils::FilePath &path) cons } } +void CMakeGenerator::removeAmbiguousFiles(const Utils::FilePath &rootPath) const +{ + const Utils::FilePath rootCMakeFile = rootPath.pathAppended("CMakeLists.txt"); + rootCMakeFile.removeFile(); + + const Utils::FilePath sourceDirPath = rootPath.pathAppended("App"); + if (sourceDirPath.exists()) { + const Utils::FilePath appCMakeFile = sourceDirPath.pathAppended("CMakeLists.txt"); + appCMakeFile.removeFile(); + } +} + void CMakeGenerator::printModules(const NodePtr &node) const { if (node->type == Node::Type::Module) @@ -470,11 +497,12 @@ void CMakeGenerator::printNodeTree(const NodePtr &generatorNode, size_t indent) case Node::Type::Module: typeString = "Node::Type::Module"; break; + case Node::Type::MockModule: + typeString = "Node::Type::MockModule"; + break; case Node::Type::Library: typeString = "Node::Type::Library"; break; - default: - typeString = "Node::Type::Undefined"; } qDebug() << addIndent(indent) << "GeneratorNode: " << generatorNode->name; @@ -517,7 +545,11 @@ void CMakeGenerator::parseSourceTree() { QTC_ASSERT(m_writer, return); - const Utils::FilePath srcDir = m_root->dir.pathAppended(m_writer->sourceDirName()); + QString srcDirName = m_writer->sourceDirName(); + if (srcDirName.isEmpty()) + return; + + const Utils::FilePath srcDir = m_root->dir.pathAppended(srcDirName); QDirIterator it(srcDir.path(), {"*.cpp"}, QDir::Files, QDirIterator::Subdirectories); NodePtr srcNode = std::make_shared(); @@ -560,5 +592,62 @@ void CMakeGenerator::compareWithFileSystem(const NodePtr &node) const logIssue(ProjectExplorer::Task::Warning, text, file); } +void CMakeGenerator::createWriter() +{ + auto writer = CMakeWriter::create(this); + + const QmlProject *project = qmlProject(); + QTC_ASSERT(project, return ); + + const Utils::FilePath rootPath = project->projectDirectory(); + const Utils::FilePath settingsFile = rootPath.pathAppended("CMakeLists.txt.shared"); + Utils::PersistentSettingsReader reader; + reader.load(settingsFile); + auto store = reader.restoreValues(); + + auto writeSettings = [settingsFile, &store](int identifier) { + store["CMake Generator"] = identifier; + QString error; + Utils::PersistentSettingsWriter settingsWriter(settingsFile, "QtCreatorProject"); + if (!settingsWriter.save(store, &error)) { + const QString text("Failed to write settings file"); + logIssue(ProjectExplorer::Task::Error, text, settingsFile); + } + }; + + QVariant idVariant = store["CMake Generator"]; + if (!idVariant.isValid()) { + writeSettings(writer->identifier()); + m_writer = writer; + return; + } + + int identifier = writer->identifier(); + int currentId = idVariant.toInt(); + if (currentId == identifier) { + m_writer = writer; + return; + } + + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.setText("The CmakeGenerator Has Changed"); + msgBox.setInformativeText( + "This operation will delete build files that may contain" + " user-made changes. Are you sure you want to proceed?"); + int ret = msgBox.exec(); + + if (ret == QMessageBox::Cancel) { + m_writer = CMakeWriter::createAndRecover(currentId, this); + return; + } + + removeAmbiguousFiles( rootPath ); + + writeSettings(writer->identifier()); + m_writer = writer; +} + } // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h index ed03b36994c..f1225f858e2 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h @@ -33,6 +33,8 @@ public: void updateMenuAction() override; QString projectName() const; + Utils::FilePath projectDir() const; + bool findFile(const Utils::FilePath &file) const; bool isRootNode(const NodePtr &node) const; bool hasChildModule(const NodePtr &node) const; @@ -57,6 +59,7 @@ private: bool findFile(const NodePtr &node, const Utils::FilePath &file) const; void insertFile(NodePtr &node, const Utils::FilePath &path) const; void removeFile(NodePtr &node, const Utils::FilePath &path) const; + void removeAmbiguousFiles(const Utils::FilePath &rootPath) const; void printModules(const NodePtr &generatorNode) const; void printNodeTree(const NodePtr &generatorNode, size_t indent = 0) const; @@ -66,6 +69,7 @@ private: void compareWithFileSystem(const NodePtr &node) const; + void createWriter(); CMakeWriter::Ptr m_writer = {}; QString m_projectName = {}; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp index 9385e40dd99..63384debddf 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp @@ -4,6 +4,7 @@ #include "cmakegenerator.h" #include "cmakewriterv0.h" #include "cmakewriterv1.h" +#include "cmakewriterlib.h" #include "qmlprojectmanager/buildsystem/qmlbuildsystem.h" #include "qmlprojectmanager/qmlproject.h" @@ -42,14 +43,24 @@ CMakeWriter::Ptr CMakeWriter::create(CMakeGenerator *parent) const QmlBuildSystem *buildSystem = parent->buildSystem(); QTC_ASSERT(buildSystem, return {}); - auto [major, minor, patch] = versionFromString(buildSystem->versionDesignStudio()); + auto version = versionFromString(buildSystem->versionDesignStudio()); + auto normalizedVersion = normalizeVersion(version); - bool useV1 = false; - if (major.has_value()) - useV1 = minor.has_value() ? *major >= 4 && *minor >= 5 : *major >= 5; - - if (useV1) + if (normalizedVersion >= std::make_tuple(4, 5, 0)) { + if (!buildSystem->standaloneApp()) { + if (normalizedVersion >= std::make_tuple(4, 8, 0)) { + return std::make_unique(parent); + } else { + CMakeGenerator::logIssue( + ProjectExplorer::Task::Error, + Tr::tr( + "Compiling the project as a library requires" + " Qt Design Studio 4.8 or later."), + buildSystem->projectFilePath()); + } + } return std::make_unique(parent); + } CMakeGenerator::logIssue( ProjectExplorer::Task::Warning, @@ -67,6 +78,24 @@ CMakeWriter::Ptr CMakeWriter::create(CMakeGenerator *parent) return std::make_unique(parent); } +CMakeWriter::Ptr CMakeWriter::createAndRecover(int id, CMakeGenerator *parent) +{ + switch (id) + { + case 1: + return std::make_unique(parent); + case 2: + parent->setStandaloneApp(true); + return std::make_unique(parent); + case 3: + parent->setStandaloneApp(false); + return std::make_unique(parent); + default: + break; + } + return {}; +} + CMakeWriter::Version CMakeWriter::versionFromString(const QString &versionString) { const QStringList versions = versionString.split('.', Qt::SkipEmptyParts); @@ -98,6 +127,12 @@ CMakeWriter::Version CMakeWriter::versionFromIgnoreFile(const Utils::FilePath &p return {}; } +CMakeWriter::NormalizedVersion CMakeWriter::normalizeVersion(const Version &version) +{ + auto [major, minor, patch] = version; + return {major.value_or(0), minor.value_or(0), patch.value_or(0)}; +} + QString CMakeWriter::readTemplate(const QString &templatePath) { QFile templatefile(templatePath); @@ -149,6 +184,19 @@ QString CMakeWriter::sourceDirName() const void CMakeWriter::transformNode(NodePtr &) const {} +bool CMakeWriter::hasNewComponents() const +{ + auto rootDir = m_parent->projectDir(); + auto componentsDir = rootDir.pathAppended("Dependencies/Components"); + + if (!componentsDir.exists()) + return false; + + auto ignoreFile = componentsDir.pathAppended("ignore-in-qds"); + auto version = normalizeVersion(versionFromIgnoreFile(ignoreFile)); + return version >= std::make_tuple(4, 8, 0); +} + std::vector CMakeWriter::files(const NodePtr &node, const FileGetter &getter) const { std::vector out = getter(node); diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h index 15f3e090b91..481f702909f 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h @@ -63,10 +63,14 @@ class CMakeWriter public: using Ptr = std::shared_ptr; using Version = std::tuple, std::optional, std::optional>; + using NormalizedVersion = std::tuple; static Ptr create(CMakeGenerator *parent); + static Ptr createAndRecover(int id, CMakeGenerator *parent); + static Version versionFromString(const QString &versionString); static Version versionFromIgnoreFile(const Utils::FilePath &path); + static NormalizedVersion normalizeVersion(const Version &version); static QString readTemplate(const QString &templatePath); static void writeFile(const Utils::FilePath &path, const QString &content); @@ -79,11 +83,14 @@ public: virtual QString sourceDirName() const; virtual void transformNode(NodePtr &) const; + virtual int identifier() const = 0; virtual void writeRootCMakeFile(const NodePtr &node) const = 0; virtual void writeModuleCMakeFile(const NodePtr &node, const NodePtr &root) const = 0; virtual void writeSourceFiles(const NodePtr &node, const NodePtr &root) const = 0; protected: + bool hasNewComponents() const; + std::vector files(const NodePtr &node, const FileGetter &getter) const; std::vector qmlFiles(const NodePtr &node) const; std::vector singletons(const NodePtr &node) const; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.cpp new file mode 100644 index 00000000000..7a2985a7b96 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.cpp @@ -0,0 +1,112 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "cmakewriterlib.h" +#include "cmakegenerator.h" + +#include "qmlprojectmanager/buildsystem/qmlbuildsystem.h" + +#include + +namespace QmlProjectManager { + +namespace QmlProjectExporter { + +CMakeWriterLib::CMakeWriterLib(CMakeGenerator *parent) + : CMakeWriterV1(parent) +{ } + +QString CMakeWriterLib::mainLibName() const +{ + QTC_ASSERT(parent(), return {}); + return parent()->projectName() + "Lib"; +} + +void CMakeWriterLib::transformNode(NodePtr &node) const +{ + CMakeWriterV1::transformNode(node); +} + +int CMakeWriterLib::identifier() const +{ + return 3; +} + +void CMakeWriterLib::writeRootCMakeFile(const NodePtr &node) const +{ + QTC_ASSERT(parent(), return); + + const Utils::FilePath cmakeFolderPath = node->dir.pathAppended("cmake"); + if (!cmakeFolderPath.exists()) + cmakeFolderPath.createDir(); + + const Utils::FilePath insightPath = cmakeFolderPath.pathAppended("insight.cmake"); + if (!insightPath.exists()) { + const QString insightTemplate = readTemplate(":/templates/insight"); + writeFile(insightPath, insightTemplate); + } + + createDependencies(node->dir); + + const Utils::FilePath sharedFile = node->dir.pathAppended("CMakeLists.txt.shared"); + if (!sharedFile.exists()) { + const QString sharedTemplate = readTemplate(":/templates/cmake_shared"); + writeFile(sharedFile, sharedTemplate); + } + + const Utils::FilePath file = node->dir.pathAppended("CMakeLists.txt"); + if (!file.exists()) { + QString fileSection = ""; + const QString configFile = getEnvironmentVariable(ENV_VARIABLE_CONTROLCONF); + if (!configFile.isEmpty()) + fileSection = QString("\t\t%1").arg(configFile); + + const QString fileTemplate = readTemplate(":/templates/cmakeroot_lib"); + const QString fileContent = fileTemplate.arg(mainLibName(), fileSection); + writeFile(file, fileContent); + } +} + +void CMakeWriterLib::writeModuleCMakeFile(const NodePtr &node, const NodePtr &root) const +{ + CMakeWriterV1::writeModuleCMakeFile(node, root); +} + +void CMakeWriterLib::writeSourceFiles(const NodePtr &node, const NodePtr &root) const +{ + QTC_ASSERT(parent(), return); + QTC_ASSERT(parent()->buildSystem(), return); + + const QmlBuildSystem *buildSystem = parent()->buildSystem(); + + const Utils::FilePath srcDir = node->dir; + if (!srcDir.exists()) + srcDir.createDir(); + + const Utils::FilePath cmakePath = srcDir.pathAppended("CMakeLists.txt"); + if (!cmakePath.exists()) { + const QString includeAutogen = + "\ntarget_include_directories(%1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})"; + writeFile(cmakePath, includeAutogen.arg(mainLibName())); + } + + const Utils::FilePath autogenDir = srcDir.pathAppended("autogen"); + if (!autogenDir.exists()) + autogenDir.createDir(); + + const Utils::FilePath headerPath = autogenDir.pathAppended("environment.h"); + + QString environmentPrefix; + for (const QString &module : plugins(root)) + environmentPrefix.append(QString("Q_IMPORT_QML_PLUGIN(%1)\n").arg(module + "Plugin")); + + const QString mainFile("const char mainQmlFile[] = \"qrc:/qt/qml/%1\";"); + environmentPrefix.append("\n"); + environmentPrefix.append(mainFile.arg(buildSystem->mainFile())); + + const QString environmentPostfix = makeSetEnvironmentFn(); + const QString headerTemplate = readTemplate(":/templates/environment_h"); + writeFile(headerPath, headerTemplate.arg(environmentPrefix, environmentPostfix)); +} + +} // namespace QmlProjectExporter +} // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.h new file mode 100644 index 00000000000..5b957d47937 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterlib.h @@ -0,0 +1,26 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + +#include "cmakewriterv1.h" + +namespace QmlProjectManager { + +namespace QmlProjectExporter { + +class CMakeWriterLib final : public CMakeWriterV1 +{ +public: + CMakeWriterLib(CMakeGenerator *parent); + + QString mainLibName() const override; + void transformNode(NodePtr &node) const override; + + int identifier() const override; + void writeRootCMakeFile(const NodePtr &node) const override; + void writeModuleCMakeFile(const NodePtr &node, const NodePtr &root) const override; + void writeSourceFiles(const NodePtr &node, const NodePtr &root) const override; +}; + +} // namespace QmlProjectExporter +} // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp index 41cd2e52e9a..7b4cb9984f8 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp @@ -46,6 +46,11 @@ void CMakeWriterV0::transformNode(NodePtr &node) const } } +int CMakeWriterV0::identifier() const +{ + return 1; +} + void CMakeWriterV0::writeRootCMakeFile(const NodePtr &node) const { QTC_ASSERT(parent(), return); diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h index b7f47f0d547..747b0389e7a 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h @@ -16,6 +16,7 @@ public: bool isPlugin(const NodePtr &node) const override; void transformNode(NodePtr &node) const override; + int identifier() const override; void writeRootCMakeFile(const NodePtr &node) const override; void writeModuleCMakeFile(const NodePtr &node, const NodePtr &root) const override; void writeSourceFiles(const NodePtr &node, const NodePtr &root) const override; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp index 5593f556178..1cfbdb8add8 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp @@ -33,6 +33,11 @@ CMakeWriterV1::CMakeWriterV1(CMakeGenerator *parent) : CMakeWriter(parent) {} +QString CMakeWriterV1::mainLibName() const +{ + return "${CMAKE_PROJECT_NAME}"; +} + QString CMakeWriterV1::sourceDirName() const { return "App"; @@ -47,6 +52,11 @@ void CMakeWriterV1::transformNode(NodePtr &node) const node->type = Node::Type::Module; } +int CMakeWriterV1::identifier() const +{ + return 2; +} + void CMakeWriterV1::writeRootCMakeFile(const NodePtr &node) const { QTC_ASSERT(parent(), return); @@ -62,72 +72,7 @@ void CMakeWriterV1::writeRootCMakeFile(const NodePtr &node) const writeFile(insightPath, insightTemplate); } - const Utils::FilePath dependenciesPath = node->dir.pathAppended(DEPENDENCIES_DIR); - const Utils::FilePath componentsPath = dependenciesPath.pathAppended(COMPONENTS_DIR); - const Utils::FilePath componentsIgnoreFile = componentsPath.pathAppended(COMPONENTS_IGNORE_FILE); - - bool copyComponents = false; - // Note: If dependencies directory exists but not the components directory, we assunme - // the user has intentionally deleted it because he has the components installed in Qt. - if (!dependenciesPath.exists()) { - dependenciesPath.createDir(); - copyComponents = true; - } else if (componentsIgnoreFile.exists()) { - auto normalizeVersion = [](const auto &version) -> std::tuple { - auto [major, minor, patch] = version; - return {major.value_or(0), minor.value_or(0), patch.value_or(0)}; - }; - auto *bs = parent()->buildSystem(); - auto versionDS = normalizeVersion(versionFromString(bs->versionDesignStudio())); - auto versionIgnore = normalizeVersion(versionFromIgnoreFile(componentsIgnoreFile)); - if (versionDS > versionIgnore) { - copyComponents = true; - if (componentsPath.exists()) - componentsPath.removeRecursively(); - } - } - - if (copyComponents) { - if (!componentsPath.exists()) - componentsPath.createDir(); - - const Utils::FilePath componentsSrc = - Core::ICore::resourcePath("qmldesigner/Dependencies/qtquickdesigner-components"); - - if (componentsSrc.exists()) { - auto cpyResult = componentsSrc.copyRecursively(componentsPath); - if (cpyResult) { - QString depsTemplate = - QString::fromUtf8(TEMPLATE_DEPENDENCIES_CMAKELISTS, -1).arg(COMPONENTS_DIR); - writeFile(dependenciesPath.pathAppended("CMakeLists.txt"), depsTemplate); - - const Utils::FilePath qmlComponentsFilePath = - cmakeFolderPath.pathAppended("qmlcomponents.cmake"); - - if (qmlComponentsFilePath.exists()) { - - const QString warningMsg = Tr::tr( - "The project structure has changed.\n" - "Please clean the build folder before rebuilding\n"); - - CMakeGenerator::logIssue( - ProjectExplorer::Task::Warning, warningMsg, componentsPath); - - auto removeResult = qmlComponentsFilePath.removeFile(); - if (!removeResult) { - QString removeMsg = Tr::tr("Failed to remove the qmlcomponents.cmake file.\n"); - removeMsg.append(removeResult.error()); - - CMakeGenerator::logIssue( - ProjectExplorer::Task::Warning, removeMsg, qmlComponentsFilePath); - } - } - } else { - CMakeGenerator::logIssue( - ProjectExplorer::Task::Error, cpyResult.error(), componentsSrc); - } - } - } + createDependencies(node->dir); const Utils::FilePath sharedFile = node->dir.pathAppended("CMakeLists.txt.shared"); if (!sharedFile.exists()) { @@ -179,12 +124,15 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c pluginNames.append("\n"); } + if (hasNewComponents()) + pluginNames.append(QString("\n\t") + "QtQuickDesignerComponents"); + QString linkLibrariesTemplate( - "target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE\n" - "%1)"); + "target_link_libraries(%1 PRIVATE\n" + "%2)"); userFileContent.append("\n"); - userFileContent.append(linkLibrariesTemplate.arg(pluginNames)); + userFileContent.append(linkLibrariesTemplate.arg(mainLibName(), pluginNames)); writeFile(userFile, userFileContent); return; } @@ -265,5 +213,78 @@ void CMakeWriterV1::writeSourceFiles(const NodePtr &node, const NodePtr &root) c writeFile(headerPath, headerTemplate.arg(environmentPrefix, environmentPostfix)); } +void CMakeWriterV1::createDependencies(const Utils::FilePath &rootDir) const +{ + const Utils::FilePath dependenciesPath = rootDir.pathAppended(DEPENDENCIES_DIR); + const Utils::FilePath componentsPath = dependenciesPath.pathAppended(COMPONENTS_DIR); + const Utils::FilePath componentsIgnoreFile = componentsPath.pathAppended(COMPONENTS_IGNORE_FILE); + + bool copyComponents = false; + // Note: If dependencies directory exists but not the components directory, we assunme + // the user has intentionally deleted it because he has the components installed in Qt. + if (!dependenciesPath.exists()) { + dependenciesPath.createDir(); + copyComponents = true; + } else if (componentsIgnoreFile.exists()) { + auto *bs = parent()->buildSystem(); + auto versionDS = normalizeVersion(versionFromString(bs->versionDesignStudio())); + auto versionIgnore = normalizeVersion(versionFromIgnoreFile(componentsIgnoreFile)); + if (versionDS > versionIgnore) { + copyComponents = true; + if (componentsPath.exists()) + componentsPath.removeRecursively(); + } + } + + if (copyComponents) { + if (!componentsPath.exists()) + componentsPath.createDir(); + + Utils::FilePath componentsSrc = + Core::ICore::resourcePath("qmldesigner/Dependencies/qtquickdesigner-components"); + + const Utils::FilePath unifiedPath = + Core::ICore::resourcePath("qmldesigner/Dependencies/qtquickdesigner-components/components"); + + if (unifiedPath.exists( )) + componentsSrc = unifiedPath; + + if (componentsSrc.exists()) { + auto cpyResult = componentsSrc.copyRecursively(componentsPath); + if (cpyResult) { + QString depsTemplate = + QString::fromUtf8(TEMPLATE_DEPENDENCIES_CMAKELISTS, -1).arg(COMPONENTS_DIR); + writeFile(dependenciesPath.pathAppended("CMakeLists.txt"), depsTemplate); + + const Utils::FilePath cmakeFolderPath = rootDir.pathAppended("cmake"); + const Utils::FilePath qmlComponentsFilePath = + cmakeFolderPath.pathAppended("qmlcomponents.cmake"); + + if (qmlComponentsFilePath.exists()) { + + const QString warningMsg = Tr::tr( + "The project structure has changed.\n" + "Please clean the build folder before rebuilding\n"); + + CMakeGenerator::logIssue( + ProjectExplorer::Task::Warning, warningMsg, componentsPath); + + auto removeResult = qmlComponentsFilePath.removeFile(); + if (!removeResult) { + QString removeMsg = Tr::tr("Failed to remove the qmlcomponents.cmake file.\n"); + removeMsg.append(removeResult.error()); + + CMakeGenerator::logIssue( + ProjectExplorer::Task::Warning, removeMsg, qmlComponentsFilePath); + } + } + } else { + CMakeGenerator::logIssue( + ProjectExplorer::Task::Error, cpyResult.error(), componentsSrc); + } + } + } +} + } // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h index ed51eb070e6..4b6a515cea9 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h @@ -8,17 +8,23 @@ namespace QmlProjectManager { namespace QmlProjectExporter { -class CMakeWriterV1 final : public CMakeWriter +class CMakeWriterV1 : public CMakeWriter { public: CMakeWriterV1(CMakeGenerator *parent); + virtual QString mainLibName() const; + QString sourceDirName() const override; void transformNode(NodePtr &node) const override; + int identifier() const override; void writeRootCMakeFile(const NodePtr &node) const override; void writeModuleCMakeFile(const NodePtr &node, const NodePtr &root) const override; void writeSourceFiles(const NodePtr &node, const NodePtr &root) const override; + +protected: + void createDependencies(const Utils::FilePath &rootDir) const; }; } // namespace QmlProjectExporter diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp index 40de901c4fe..0763f2a442c 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp @@ -36,9 +36,6 @@ void Exporter::updateProjectItem(QmlProjectItem *item, bool updateEnabled) if (updateEnabled) { m_cmakeGen->setEnabled(item->enableCMakeGeneration()); m_pythonGen->setEnabled(item->enablePythonGeneration()); - - m_cmakeGen->setStandaloneApp(item->standaloneApp()); - m_pythonGen->setStandaloneApp(item->standaloneApp()); } } diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp index 39cfbad5876..3c3d54571cf 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp @@ -8,6 +8,7 @@ #include "../qmlprojectmanagertr.h" #include +#include #include #include @@ -68,6 +69,17 @@ bool FileGenerator::isEnabled() const return m_enabled; } +bool FileGenerator::isActive() const +{ + if (!m_buildSystem) + return false; + + if (auto *target = m_buildSystem->target()) + return target->isActive(); + + return false; +} + void FileGenerator::setEnabled(bool enabled) { m_enabled = enabled; @@ -75,12 +87,15 @@ void FileGenerator::setEnabled(bool enabled) bool FileGenerator::standaloneApp() const { - return m_standaloneApp; + if (m_buildSystem) + return m_buildSystem->standaloneApp(); + return false; } void FileGenerator::setStandaloneApp(bool value) { - m_standaloneApp = value; + if (m_buildSystem) + m_buildSystem->setStandaloneApp(value); } void FileGenerator::updateMenuAction(const Utils::Id &id, std::function isEnabled) diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h index a617d4448cf..7914aee527e 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h @@ -32,6 +32,7 @@ public: const QmlBuildSystem *buildSystem() const; bool isEnabled() const; + bool isActive() const; void setEnabled(bool enabled); bool standaloneApp() const; @@ -42,7 +43,6 @@ protected: private: bool m_enabled = false; - bool m_standaloneApp = false; QmlBuildSystem *m_buildSystem = nullptr; }; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_lib.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_lib.tpl new file mode 100644 index 00000000000..b98746e425e --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_lib.tpl @@ -0,0 +1,28 @@ + +cmake_minimum_required(VERSION 3.21.1) + +option(LINK_INSIGHT "Link Qt Insight Tracker library" ON) +option(BUILD_QDS_COMPONENTS "Build design studio components" ON) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml) +set(QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY} + CACHE STRING "Import paths for Qt Creator's code model" + FORCE +) + +qt_add_library(%1) +qt_add_resources(%1 "configuration" + PREFIX "/" + FILES +%2) + +include(qds) + +if (LINK_INSIGHT) + include(insight OPTIONAL) +endif () + From 75d6354a372ebe223f0fc31248949727291dbc41 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 3 Apr 2025 20:02:52 +0200 Subject: [PATCH 36/82] QmlDesigner: use transition.ensureIdExists() The noId fallback in displayName generates a wrong id and after the error it goes back to the wrong fallback -> reslting in a loop. Task-number: QDS-15129 Pick-to: qds/4.7 Change-Id: I984d5043c6f1edf6526e55148da2750f91632173 Reviewed-by: Thomas Hartmann --- .../transitioneditor/transitioneditorsettingsdialog.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp index b57a2b4e6de..375eb974f63 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp @@ -132,8 +132,10 @@ void TransitionEditorSettingsDialog::setupTransitions(const ModelNode &newTransi return; } - for (const auto &transition : transitions) + for (const auto &transition : transitions) { + transition.ensureIdExists(); addTransitionTab(transition); + } if (newTransition.isValid()) { m_currentTransition = newTransition; @@ -146,8 +148,10 @@ void TransitionEditorSettingsDialog::setupTransitions(const ModelNode &newTransi void TransitionEditorSettingsDialog::addTransitionTab(const QmlTimeline &node) { + QTC_ASSERT(node.modelNode().hasId(), return); + auto transitionForm = new TransitionForm(this); - ui->timelineTab->addTab(transitionForm, node.modelNode().displayName()); + ui->timelineTab->addTab(transitionForm, node.modelNode().id()); transitionForm->setTransition(node); connect(transitionForm, &TransitionForm::stateGroupChanged, this, [this](const ModelNode &transition, const ModelNode &stateGroup){ From 974a51ff806402aadb1fc01cdff56852e6e50c30 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Apr 2025 13:29:26 +0200 Subject: [PATCH 37/82] QmlDesigner: Add Model::projectStorageDependencies() Change-Id: I6294dfb2483943de52a31e5939cff993f97d4666 Reviewed-by: Marco Bubke --- src/plugins/qmldesigner/libs/designercore/include/model.h | 2 ++ src/plugins/qmldesigner/libs/designercore/model/model.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 6266a31b012..202f597eda2 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -285,6 +285,8 @@ public: PathCacheType &pathCache(); ProjectStorageTriggerUpdateInterface &projectStorageTriggerUpdate() const; + ProjectStorageDependencies projectStorageDependencies() const; + void emitInstancePropertyChange(AbstractView *view, const QList> &propertyList); void emitInstanceErrorChange(AbstractView *view, const QVector &instanceIds); diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index d6a80e05c36..d1169fbc3be 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2025,6 +2025,13 @@ ProjectStorageTriggerUpdateInterface &Model::projectStorageTriggerUpdate() const return *d->projectStorageTriggerUpdate; } +ProjectStorageDependencies Model::projectStorageDependencies() const +{ + return ProjectStorageDependencies{*d->projectStorage, + *d->pathCache, + *d->projectStorageTriggerUpdate}; +} + void Model::emitInstancePropertyChange(AbstractView *view, const QList> &propertyList) { From 03cbd190e7988672c8e0a081e01c1200fb8ac799 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 8 Apr 2025 19:27:41 +0200 Subject: [PATCH 38/82] QmlDesigner: Add Model::moduleIdsStartsWith() Get modul ids that start with that string and are of that kind. If no string is given there are no ids returned. The returned ids are not sorted. auto moduleIds = model->moduleIdsStartsWith("QtQuick", Storage::ModuleKind::QmlLibrary); std::ranges::sort(moduleIds); auto isQtQuickModule = Utils::set_has_common_element(otherSortedModuleIds, moduleIds); Change-Id: I85f7dadca5be88885e54237b5d560ba02b61c75b Reviewed-by: Thomas Hartmann Reviewed-by: Burak Hancerli --- .../libs/designercore/include/model.h | 2 + .../designercore/include/projectstorageids.h | 2 + .../libs/designercore/model/model.cpp | 9 ++++ .../projectstorage/projectstorage.cpp | 24 ++++++++- .../projectstorage/projectstorage.h | 7 ++- .../projectstorage/projectstorageinterface.h | 2 + .../sourcepathstorage/storagecache.h | 53 +++++++++++-------- tests/unit/tests/mocks/projectstoragemock.h | 4 ++ .../unit/tests/unittests/model/model-test.cpp | 10 ++++ .../projectstorage/projectstorage-test.cpp | 24 +++++++++ .../sourcepathstorage/storagecache-test.cpp | 37 +++++++++++++ 11 files changed, 149 insertions(+), 25 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 202f597eda2..286e203e704 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -148,6 +148,8 @@ public: #endif Module module(Utils::SmallStringView moduleName, Storage::ModuleKind moduleKind); + SmallModuleIds<128> moduleIdsStartsWith(Utils::SmallStringView startsWith, + Storage::ModuleKind kind) const; NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const; NodeMetaInfo metaInfo(Module module, Utils::SmallStringView typeName, diff --git a/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h index 1b875cefbbb..fb6c56a5407 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h +++ b/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h @@ -45,6 +45,8 @@ using EnumerationDeclarationIds = std::vector; using ModuleId = Sqlite::BasicId; using ModuleIds = std::vector; using ModuleIdSpan = Utils::span; +template +using SmallModuleIds = QVarLengthArray; using ProjectPartId = Sqlite::BasicId; using ProjectPartIds = std::vector; diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index d1169fbc3be..f2fbf45c5a9 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2917,6 +2917,15 @@ Module Model::module(Utils::SmallStringView moduleName, Storage::ModuleKind modu return {}; } +SmallModuleIds<128> Model::moduleIdsStartsWith(Utils::SmallStringView startsWith, + Storage::ModuleKind kind) const +{ + if constexpr (useProjectStorage()) + return d->projectStorage->moduleIdsStartsWith(startsWith, kind); + + return {}; +} + /*! \name View related functions */ //\{ diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp index 402be920f5b..c342d5667a1 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp @@ -1424,7 +1424,8 @@ ModuleId ProjectStorage::moduleId(Utils::SmallStringView moduleName, Storage::Mo using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get module id", projectStorageCategory(), - keyValue("module name", moduleName)}; + keyValue("module name", moduleName), + keyValue("module kind", kind)}; if (moduleName.empty()) return ModuleId{}; @@ -1436,6 +1437,27 @@ ModuleId ProjectStorage::moduleId(Utils::SmallStringView moduleName, Storage::Mo return moduleId; } +SmallModuleIds<128> ProjectStorage::moduleIdsStartsWith(Utils::SmallStringView startsWith, + Storage::ModuleKind kind) const +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"get module ids that starts with", + projectStorageCategory(), + keyValue("module name starts with", startsWith), + keyValue("module kind", kind)}; + + if (startsWith.isEmpty()) + return {}; + + auto projection = [&](ModuleView view) -> ModuleView { + return {view.name.substr(0, startsWith.size()), view.kind}; + }; + + auto moduleIds = moduleCache.ids<128>({startsWith, kind}, projection); + + return moduleIds; +} + Storage::Module ProjectStorage::module(ModuleId moduleId) const { using NanotraceHR::keyValue; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index 441dc72c705..ba09dac0ca5 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -62,6 +62,9 @@ public: ModuleId moduleId(Utils::SmallStringView moduleName, Storage::ModuleKind kind) const override; + SmallModuleIds<128> moduleIdsStartsWith(Utils::SmallStringView startsWith, + Storage::ModuleKind kind) const override; + Storage::Module module(ModuleId moduleId) const override; TypeId typeId(ModuleId moduleId, @@ -252,9 +255,9 @@ private: Utils::SmallStringView name; Storage::ModuleKind kind; - friend bool operator<(ModuleView first, ModuleView second) + friend std::strong_ordering operator<=>(ModuleView first, ModuleView second) { - return std::tie(first.kind, first.name) < std::tie(second.kind, second.name); + return std::tie(first.kind, first.name) <=> std::tie(second.kind, second.name); } friend bool operator==(const Storage::Module &first, ModuleView second) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h index 4591530e0c8..947bcf73980 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h @@ -32,6 +32,8 @@ public: virtual void removeObserver(ProjectStorageObserver *observer) = 0; virtual ModuleId moduleId(::Utils::SmallStringView name, Storage::ModuleKind kind) const = 0; + virtual SmallModuleIds<128> + moduleIdsStartsWith(Utils::SmallStringView startsWith, Storage::ModuleKind kind) const = 0; virtual QmlDesigner::Storage::Module module(ModuleId moduleId) const = 0; virtual std::optional propertyDeclaration(PropertyDeclarationId propertyDeclarationId) const = 0; diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h index 07ac6ff52f9..ef29ab9b08e 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h @@ -201,38 +201,50 @@ public: { std::shared_lock sharedLock(m_mutex); - auto found = find(view); + auto [iter, found] = find(view); - if (found != m_entries.end()) - return found->id; + if (found) + return iter->id; sharedLock.unlock(); std::lock_guard exclusiveLock(m_mutex); if constexpr (!std::is_base_of_v) - found = find(view); - if (found == m_entries.end()) - found = insertEntry(found, view, m_storage.fetchId(view)); + std::tie(iter, found) = find(view); + if (!found) + iter = insertEntry(iter, view, m_storage.fetchId(view)); - return found->id; + return iter->id; } - template - std::vector ids(const Container &values) + template + std::vector ids(Utils::span values) { std::vector ids; ids.reserve(values.size()); - std::ranges::transform(values, std::back_inserter(ids), [&](const auto &values) { - return this->id(values); + std::ranges::transform(values, std::back_inserter(ids), [&](ViewType value) { + return this->id(value); }); return ids; } - std::vector ids(std::initializer_list values) + template Proj> + using projected_value_t = std::remove_cvref_t &>>; + + template, Projection>> + QVarLengthArray ids(Value value, Projection projection) { - return ids>(values); + std::shared_lock sharedLock(m_mutex); + + auto range = std::ranges::equal_range(m_entries, value, Compare{}, projection); + + QVarLengthArray ids; + std::ranges::transform(range, std::back_inserter(ids), &CacheEntry::id); + return ids; } ResultType value(IndexType id) @@ -250,7 +262,7 @@ public: std::lock_guard exclusiveLock(m_mutex); Type value{m_storage.fetchValue(id)}; - auto interator = insertEntry(find(value), value, id); + auto interator = insertEntry(std::get<0>(find(value)), value, id); return interator->value; } @@ -290,24 +302,21 @@ private: } template - static auto find(Entries &&entries, ViewType view) + static std::tuple, bool> find(Entries &&entries, ViewType view) { auto found = std::ranges::lower_bound(entries, view, Compare{}); - if (found != entries.end() && *found == view) - return found; - - return entries.end(); + return {found, found != entries.end() && *found == view}; } IndexType id(ViewType view) const { std::shared_lock sharedLock(m_mutex); - auto found = find(view); + auto [iter, found] = find(view); - if (found != m_entries.end()) - return found->id; + if (found) + return iter->id; return IndexType(); } diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index 404e00f0e72..8fc77ddd5e8 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -133,6 +133,10 @@ public: moduleId, (::Utils::SmallStringView, QmlDesigner::Storage::ModuleKind moduleKind), (const, override)); + MOCK_METHOD(QmlDesigner::SmallModuleIds<128>, + moduleIdsStartsWith, + (::Utils::SmallStringView, QmlDesigner::Storage::ModuleKind moduleKind), + (const, override)); MOCK_METHOD(QmlDesigner::Storage::Module, module, (QmlDesigner::ModuleId), (const, override)); MOCK_METHOD(std::optional, diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 3d41c0ff3d5..7066e27782d 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -1137,6 +1137,16 @@ TEST_F(Model_MetaInfo, get_invalid_meta_info_by_module_for_wrong_module) ASSERT_THAT(metaInfo, IsFalse()); } +TEST_F(Model_MetaInfo, get_module_ids_that_starts_with) +{ + ON_CALL(projectStorageMock, moduleIdsStartsWith(Eq("Q"), ModuleKind::QmlLibrary)) + .WillByDefault(Return(QmlDesigner::SmallModuleIds<128>{qtQuickModuleId})); + + auto moduleIds = model.moduleIdsStartsWith("Q", ModuleKind::QmlLibrary); + + ASSERT_THAT(moduleIds, Contains(qtQuickModuleId)); +} + TEST_F(Model_MetaInfo, add_project_storage_observer_to_project_storage) { EXPECT_CALL(projectStorageMock, addObserver(_)); diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 00db8c92486..aab9d2ff473 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -5827,6 +5827,30 @@ TEST_F(ProjectStorage, populate_module_cache) ASSERT_THAT(newStorage.module(id), IsModule("Qml", ModuleKind::QmlLibrary)); } +TEST_F(ProjectStorage, get_no_module_ids_if_they_starts_with_nothing) +{ + storage.moduleId("QtQml", ModuleKind::QmlLibrary); + + auto ids = storage.moduleIdsStartsWith("", ModuleKind::QmlLibrary); + + ASSERT_THAT(ids, IsEmpty()); +} + +TEST_F(ProjectStorage, get_module_ids_if_they_starts_with_New) +{ + auto quickId = storage.moduleId("NewQuick", ModuleKind::QmlLibrary); + storage.moduleId("NewQuick", ModuleKind::CppLibrary); + auto quick3dId = storage.moduleId("NewQuick3D", ModuleKind::QmlLibrary); + storage.moduleId("NewQml", ModuleKind::CppLibrary); + auto qmlId = storage.moduleId("NewQml", ModuleKind::QmlLibrary); + storage.moduleId("Foo", ModuleKind::QmlLibrary); + storage.moduleId("Zoo", ModuleKind::QmlLibrary); + + auto ids = storage.moduleIdsStartsWith("New", ModuleKind::QmlLibrary); + + ASSERT_THAT(ids, UnorderedElementsAre(qmlId, quickId, quick3dId)); +} + TEST_F(ProjectStorage, add_directory_infoes) { Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId, diff --git a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp index 161aac89f29..feb521ddf52 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp @@ -514,4 +514,41 @@ TYPED_TEST(StorageCache, fetch_ids_from_storage_calls) this->cache.ids({"foo", "bar"}); } + +TYPED_TEST(StorageCache, getting_ids_that_start_with_po) +{ + ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq("poh"))).WillByDefault(Return(this->id43)); + this->cache.add({"poo", "foo", "poh", "taa"}); + auto projection = [](Utils::SmallStringView text) -> Utils::SmallStringView { + return text.substr(0, 2); + }; + + auto ids = this->cache.template ids<4>("po", projection); + + ASSERT_THAT(ids, UnorderedElementsAre(this->id43, this->id44)); +} + +TYPED_TEST(StorageCache, getting_no_ids_if_there_is_no_entry_starts_with_oh) +{ + this->cache.add({"poo", "taa", "foo", "bar"}); + auto projection = [](Utils::SmallStringView text) -> Utils::SmallStringView { + return text.substr(0, 2); + }; + + auto ids = this->cache.template ids<4>("oh", projection); + + ASSERT_THAT(ids, IsEmpty()); +} + +TYPED_TEST(StorageCache, get_all_ids_if_the_string_is_empty) +{ + this->cache.add({"foo", "bar", "poo", "taa"}); + auto projection = [](Utils::SmallStringView text) -> Utils::SmallStringView { + return text.substr(0, 0); + }; + + auto ids = this->cache.template ids<4>("", projection); + + ASSERT_THAT(ids, UnorderedElementsAre(this->id42, this->id43, this->id44, this->id45)); +} } // namespace From d916d077ba31f5634fcb90014650a4dd809d5ea5 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 8 Apr 2025 17:09:24 +0300 Subject: [PATCH 39/82] QmlDesigner: Add id generation for newly added imported instances Fixes: QDS-15044 Change-Id: I4237cec54e3b8ec8edbb74880475b92998262be6 Reviewed-by: Mahmoud Badri --- .../components/contentlibrary/contentlibraryview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 95c60def4ad..62400bbeea4 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -220,6 +220,8 @@ void ContentLibraryView::connectImporter() ModelNode newNode = createModelNode( typeName, -1, -1, {{"x", pos.x()}, {"y", pos.y()}, {"z", pos.z()}}); m_bundleItemTarget.defaultNodeListProperty().reparentHere(newNode); + newNode.setIdWithoutRefactoring(model()->generateNewId( + newNode.simplifiedTypeName(), "node")); clearSelectedModelNodes(); selectModelNode(newNode); }); From e37e9b6a8448837844dd32a1c418f6462f1504c9 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Apr 2025 19:46:04 +0200 Subject: [PATCH 40/82] QmlDesigner: Create directory imports on demand This function is only used on demand in the item library. Task-number: QDS-15165 Change-Id: I784d15f1cf6be37885336259a434abe7dfe09b66 Reviewed-by: Marco Bubke --- .../libs/designercore/model/model.cpp | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index f2fbf45c5a9..fb30f30e074 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -1801,6 +1801,31 @@ Storage::Info::ExportedTypeName Model::exportedTypeNameForMetaInfo(const NodeMet namespace { +QmlDesigner::Imports createPossibleFileImports(const Utils::FilePath &path) +{ + auto folder = path.parentDir(); + QmlDesigner::Imports imports; + + /* Creates imports for all sub folder that contain a qml file. */ + folder.iterateDirectory( + [&](const Utils::FilePath &item) { + bool append = false; + + item.iterateDirectory( + [&](const Utils::FilePath &item) { + append = true; + return Utils::IterationPolicy::Stop; + }, + {{"*.qml"}, QDir::Files}); + if (append) + imports.append(QmlDesigner::Import::createFileImport(item.fileName())); + return Utils::IterationPolicy::Continue; + }, + {{}, QDir::Dirs | QDir::NoDotAndDotDot}); + + return imports; +} + QmlDesigner::Imports createQt6ModulesForProjectStorage() { QmlDesigner::Imports imports = { @@ -1854,7 +1879,10 @@ QmlDesigner::Imports createQt6ModulesForProjectStorage() Imports Model::possibleImports() const { #ifdef QDS_USE_PROJECTSTORAGE - static auto imports = createQt6ModulesForProjectStorage(); + static auto qt6Imports = createQt6ModulesForProjectStorage(); + auto imports = createPossibleFileImports(Utils::FilePath::fromUrl(fileUrl())); + imports.append(qt6Imports); + return imports; #else return d->m_possibleImportList; From 489230d0efd664e30e6c9a3b9311a7f8aa3caade Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 9 Apr 2025 14:57:33 +0300 Subject: [PATCH 41/82] QmlDesigner: Add "show in graphical shell" option ...to content library user tab's custom categories Fixes: QDS-15153 Change-Id: If899ca6ff3f8416205718bb4ae6f5570ed2ab312 Reviewed-by: Miikka Heikkinen Reviewed-by: Ali Kianian --- .../ContentLibraryTextureContextMenu.qml | 20 ++++++++++++++++++- .../ContentLibraryUserView.qml | 6 +++++- .../contentlibrary/contentlibrarywidget.cpp | 10 +++++++++- .../contentlibrary/contentlibrarywidget.h | 3 +++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml index 3dba67243fe..f64306743f7 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml @@ -13,12 +13,14 @@ StudioControls.Menu { property var targetTexture: null property bool hasSceneEnv: false property bool showRemoveAction: false // true: adds an option to remove targetTexture + property bool showInGraphicalShellVisible: false property bool canUse3D: targetTexture && ContentLibraryBackend.rootView.hasQuick3DImport && ContentLibraryBackend.rootView.hasMaterialLibrary - function popupMenu(targetTexture = null) + function popupMenu(targetTexture = null, showInGraphicalShellItemVisible = false) { this.targetTexture = targetTexture + root.showInGraphicalShellVisible = showInGraphicalShellItemVisible ContentLibraryBackend.rootView.updateSceneEnvState(); popup() } @@ -49,4 +51,20 @@ StudioControls.Menu { height: visible ? implicitHeight : 0 onTriggered: ContentLibraryBackend.userModel.removeTexture(root.targetTexture) } + + StudioControls.MenuSeparator { + visible: root.showInGraphicalShellVisible + height: visible ? StudioTheme.Values.border : 0 + } + + StudioControls.MenuItem { + text: ContentLibraryBackend.rootView.showInGraphicalShellMsg + + visible: root.showInGraphicalShellVisible + height: visible ? implicitHeight : 0 + + onTriggered: { + ContentLibraryBackend.rootView.showInGraphicalShell(root.targetTexture.textureParentPath) + } + } } diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml index 91d131bb9aa..9a8eda0a5e7 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml @@ -191,10 +191,14 @@ Item { } Grid { + id: grid + width: section.width - section.leftPadding - section.rightPadding spacing: StudioTheme.Values.sectionGridSpacing columns: root.numColumns + property int catIdx: index + Repeater { id: repeater @@ -220,7 +224,7 @@ Item { width: root.cellWidth height: root.cellWidth // for textures use a square size since there is no name row - onShowContextMenu: ctxMenuTexture.popupMenu(modelData) + onShowContextMenu: ctxMenuTexture.popupMenu(modelData, grid.catIdx > 2) } } DelegateChoice { diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index 9b3860cebf1..793b35a675d 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -13,7 +13,6 @@ #include "contentlibraryusermodel.h" #include -#include #include #include #include @@ -27,6 +26,9 @@ #include #include +#include +#include + #include #include #include @@ -135,6 +137,7 @@ ContentLibraryWidget::ContentLibraryWidget() , m_environmentsModel(new ContentLibraryTexturesModel("Environments", this)) , m_effectsModel(new ContentLibraryEffectsModel(this)) , m_userModel(new ContentLibraryUserModel(this)) + , m_showInGraphicalShellMsg(Core::FileUtils::msgGraphicalShellAction()) { qmlRegisterType("WebFetcher", 1, 0, "FileDownloader"); qmlRegisterType("WebFetcher", 1, 0, "FileExtractor"); @@ -946,4 +949,9 @@ void ContentLibraryWidget::setHasModelSelection(bool b) emit hasModelSelectionChanged(); } +void ContentLibraryWidget::showInGraphicalShell(const QString &path) +{ + Core::FileUtils::showInGraphicalShell(Utils::FilePath::fromString(path)); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h index ee7cb3509d2..7509b94d361 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h @@ -42,6 +42,7 @@ class ContentLibraryWidget : public QFrame Q_PROPERTY(bool isQt6Project READ isQt6Project NOTIFY isQt6ProjectChanged) Q_PROPERTY(bool importerRunning READ importerRunning WRITE setImporterRunning NOTIFY importerRunningChanged) Q_PROPERTY(bool hasModelSelection READ hasModelSelection NOTIFY hasModelSelectionChanged) + Q_PROPERTY(QString showInGraphicalShellMsg MEMBER m_showInGraphicalShellMsg CONSTANT) // Needed for a workaround for a bug where after drag-n-dropping an item, the ScrollView scrolls to a random position Q_PROPERTY(bool isDragging MEMBER m_isDragging NOTIFY isDraggingChanged) @@ -105,6 +106,7 @@ public: Q_INVOKABLE bool hasTexture(const QString &format, const QVariant &data) const; Q_INVOKABLE void addQtQuick3D(); Q_INVOKABLE void browseBundleFolder(); + Q_INVOKABLE void showInGraphicalShell(const QString &path); QSize sizeHint() const override; @@ -180,6 +182,7 @@ private: bool m_hasModelSelection = false; QString m_textureBundleUrl; QString m_bundlePath; + QString m_showInGraphicalShellMsg; }; } // namespace QmlDesigner From fc34c61913292e7a06ad0cfd3ef6aafe1248f46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Thu, 10 Apr 2025 10:26:16 +0200 Subject: [PATCH 42/82] QmlDesigner: fix misssing includes in dev packages In case of snapshot builds telemetry build uses dev packages. Without the build complains missing widgetregistration.h include. Change-Id: I9ff5b78b9cf2d8522b99875bb30c2daeb1dd781f Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/libs/designercore/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt index 5cfc58be14a..b5f529c8e3a 100644 --- a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt +++ b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt @@ -242,6 +242,8 @@ extend_qtc_library(QmlDesignerCore stringutils.h synchronousimagecache.h variantproperty.h + widgetregistration.h + widgetinfo.h ) extend_qtc_library(QmlDesignerCore From ed1bece5ec9eba93a2cdcfbfc6599e2dc7dccd56 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Wed, 9 Apr 2025 17:39:29 +0300 Subject: [PATCH 43/82] ModelNode: Set type id when node type changes Fixes: QDS-14946 Change-Id: If5c98db8b2e677a1fd5ad24671bfedda1348a968 Reviewed-by: Marco Bubke --- .../libs/designercore/include/modelnode.h | 2 +- .../qmldesigner/libs/designercore/model/model.cpp | 1 + tests/unit/tests/unittests/model/model-test.cpp | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h index e9e060117ea..3053fe10258 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h @@ -104,7 +104,7 @@ public: NodeAbstractProperty parentProperty() const; void setParentProperty(NodeAbstractProperty parent); - void changeType(const TypeName &typeName, int majorVersion, int minorVersion); + void changeType(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); void setParentProperty(const ModelNode &newParentNode, const PropertyName &propertyName); bool hasParentProperty() const; diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index fb30f30e074..98d3e7f6669 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -303,6 +303,7 @@ void ModelPrivate::changeNodeType(const InternalNodePointer &node, const TypeNam node->typeName = typeName; node->majorVersion = majorVersion; node->minorVersion = minorVersion; + setTypeId(node.get(), typeName); try { notifyNodeTypeChanged(node, typeName, majorVersion, minorVersion); diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 7066e27782d..3e9fd1bc5c3 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -1066,6 +1066,18 @@ TEST_F(Model_Node, create_qualified_model_node_has_meta_info) ASSERT_THAT(node.metaInfo(), model.qtQmlModelsListModelMetaInfo()); } +TEST_F(Model_Node, change_node_type_changes_meta_info) +{ + projectStorageMock.createImportedTypeNameId(filePathId, + "QtObject", + model.qmlQtObjectMetaInfo().id()); + auto node = model.createModelNode("Item"); + + node.changeType("QtObject"); + + ASSERT_THAT(node.metaInfo(), model.qmlQtObjectMetaInfo()); +} + TEST_F(Model_Node, change_root_node_type_changes_meta_info) { projectStorageMock.createImportedTypeNameId(filePathId, From e205ddac12bb2d84ebd1291c3695dbbe2fbb4f9e Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 10 Apr 2025 13:24:56 +0300 Subject: [PATCH 44/82] EffectComposer: Fix infoText timer InfoText timer is now properly stopped and started as required. Fixes: QDS-15052 Change-Id: I1ca9db9f11698c5e6e459e3569c75c3f66ca2797 Reviewed-by: Mahmoud Badri --- .../EffectCompositionNode.qml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml index 243cd1ea317..33c8fe9d3fe 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml @@ -80,9 +80,10 @@ HelperWidgets.Section { function showNodeExistsWarning(enable) { infoText.text = qsTr("An effect with this name already exists.\nSuffix was added to make the name unique.") - infoTimer.restart() - infoText.visible = enable infoText.color = StudioTheme.Values.themeWarning + infoText.visible = enable + if (infoText.visible) + infoTimer.restart() } function showNodeAddedToLibraryInfo(message) @@ -95,15 +96,17 @@ HelperWidgets.Section { infoText.text = message infoText.color = StudioTheme.Values.themeInteraction } - infoTimer.restart() infoText.visible = message !== "" + if (infoText.visible) + infoTimer.restart() } function showNeedRenameInfo() { + infoTimer.stop() infoText.text = qsTr("A built-in effect with this name already exists in the library.\nPlease rename the effect before adding it to the library.") - infoText.visible = true infoText.color = StudioTheme.Values.themeWarning + infoText.visible = true } onVisibleChanged: { @@ -120,7 +123,7 @@ HelperWidgets.Section { onTriggered: { infoText.visible = false - infoTimer.running = false + infoTimer.stop() } } } From 7e902d3c77fab90a44ff5585537a563a68bc4803 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Wed, 26 Mar 2025 13:46:47 +0200 Subject: [PATCH 45/82] ListModelEditor: Fix table action issues * Disable delete actions when no row/column is selected * Disable move row actions when no row is selected * Provide an action for adding row below/above * Update the current item selecion after moving rows * Fix shortcut action for moving up * Select rows and columns after inserting Fixes: QDS-15011 Change-Id: If03e083ffee3446341a37b8fd8fd8978bfc20745 Reviewed-by: Marco Bubke --- .../listmodeleditor/listmodeleditordialog.cpp | 93 ++++++- .../listmodeleditor/listmodeleditordialog.h | 11 +- .../listmodeleditor/listmodeleditormodel.cpp | 59 +++- .../listmodeleditor/listmodeleditormodel.h | 11 +- .../designercore/model/nodelistproperty.cpp | 3 +- .../listmodeleditor/listmodeleditor-test.cpp | 262 +++++++++++++++++- 6 files changed, 407 insertions(+), 32 deletions(-) diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp index 11440ea11da..bbbda2e095f 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp @@ -20,8 +20,6 @@ #include #include -#include - namespace QmlDesigner { namespace { @@ -46,7 +44,8 @@ ListModelEditorDialog::ListModelEditorDialog(QWidget *parent) m_tableView = new QTableView; mainLayout->addWidget(m_tableView); - m_addRowAction = toolBar->addAction(getIcon(Theme::Icon::addRowAfter), tr("Add Row")); + m_addRowAboveAction = toolBar->addAction(getIcon(Theme::Icon::addRowBefore), tr("Add Row Above")); + m_addRowBelowAction = toolBar->addAction(getIcon(Theme::Icon::addRowAfter), tr("Add Row Below")); m_removeRowsAction = toolBar->addAction(getIcon(Theme::Icon::deleteRow), tr("Remove Rows")); m_addColumnAction = toolBar->addAction(getIcon(Theme::Icon::addColumnAfter), tr("Add Column")); m_removeColumnsAction = toolBar->addAction(getIcon(Theme::Icon::deleteColumn), @@ -54,7 +53,7 @@ ListModelEditorDialog::ListModelEditorDialog(QWidget *parent) m_moveDownAction = toolBar->addAction(Icons::ARROW_DOWN.icon(), tr("Move Down (Ctrl + Down)")); m_moveDownAction->setShortcut(QKeySequence(Qt::Key_Down | Qt::CTRL)); m_moveUpAction = toolBar->addAction(Icons::ARROW_UP.icon(), tr("Move Up (Ctrl + Up)")); - m_moveDownAction->setShortcut(QKeySequence(Qt::Key_Up | Qt::CTRL)); + m_moveUpAction->setShortcut(QKeySequence(Qt::Key_Up | Qt::CTRL)); } ListModelEditorDialog::~ListModelEditorDialog() = default; @@ -63,7 +62,8 @@ void ListModelEditorDialog::setModel(ListModelEditorModel *model) { m_model = model; - connect(m_addRowAction, &QAction::triggered, m_model, &ListModelEditorModel::addRow); + connect(m_addRowAboveAction, &QAction::triggered, this, &ListModelEditorDialog::addRowAbove); + connect(m_addRowBelowAction, &QAction::triggered, this, &ListModelEditorDialog::addRowBelow); connect(m_addColumnAction, &QAction::triggered, this, &ListModelEditorDialog::openColumnDialog); connect(m_removeRowsAction, &QAction::triggered, this, &ListModelEditorDialog::removeRows); connect(m_removeColumnsAction, &QAction::triggered, this, &ListModelEditorDialog::removeColumns); @@ -79,16 +79,48 @@ void ListModelEditorDialog::setModel(ListModelEditorModel *model) m_tableView->verticalHeader()->setMinimumSectionSize(25); m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); m_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + connect(model, + &ListModelEditorModel::rowsInserted, + this, + &ListModelEditorDialog::onRowsInserted, + Qt::ConnectionType::UniqueConnection); + + connect(model, + &ListModelEditorModel::columnsInserted, + this, + &ListModelEditorDialog::onColumnsInserted, + Qt::ConnectionType::UniqueConnection); + + connect(m_tableView->selectionModel(), + &QItemSelectionModel::selectionChanged, + this, + &ListModelEditorDialog::updateSelection, + Qt::ConnectionType::UniqueConnection); + updateSelection(); } void ListModelEditorDialog::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) { - for (const QModelIndex index : m_tableView->selectionModel()->selectedIndexes()) + const QModelIndexList selectedIndexes = m_tableView->selectionModel()->selectedIndexes(); + for (const QModelIndex index : selectedIndexes) m_model->setData(index, QVariant(), Qt::EditRole); } } +void ListModelEditorDialog::addRowAbove() +{ + // If there's no items in the model, or nothing is selected, The item should be prepended. + int curInteractionRow = ListModelEditorModel::currentInteractionRow(*m_tableView->selectionModel()); + m_model->addRow(std::max(0, curInteractionRow)); +} + +void ListModelEditorDialog::addRowBelow() +{ + m_model->addRow(ListModelEditorModel::nextInteractionRow(*m_tableView->selectionModel())); +} + void ListModelEditorDialog::openColumnDialog() { bool ok; @@ -126,13 +158,58 @@ void ListModelEditorDialog::changeHeader(int column) void ListModelEditorDialog::moveRowsDown() { QItemSelection selection = m_model->moveRowsDown(m_tableView->selectionModel()->selectedRows()); - m_tableView->selectionModel()->select(selection, QItemSelectionModel::Select); + m_tableView->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); + if (!selection.isEmpty()) { + m_tableView->selectionModel()->setCurrentIndex(selection.first().topLeft(), + QItemSelectionModel::Current); + } } void ListModelEditorDialog::moveRowsUp() { QItemSelection selection = m_model->moveRowsUp(m_tableView->selectionModel()->selectedRows()); - m_tableView->selectionModel()->select(selection, QItemSelectionModel::Select); + m_tableView->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); + if (!selection.isEmpty()) { + m_tableView->selectionModel()->setCurrentIndex(selection.first().topLeft(), + QItemSelectionModel::Current); + } +} + +void ListModelEditorDialog::updateSelection() +{ + QItemSelectionModel *selection = m_tableView->selectionModel(); + bool hasRowSelection = !selection->selectedRows().isEmpty(); + bool hasColumnSelection = !selection->selectedColumns().isEmpty(); + const int rows = m_tableView->model()->rowCount(); + + m_moveUpAction->setEnabled(hasRowSelection && !selection->isRowSelected(0)); + m_moveDownAction->setEnabled(hasRowSelection && !selection->isRowSelected(rows - 1)); + m_removeRowsAction->setEnabled(hasRowSelection); + m_removeColumnsAction->setEnabled(hasColumnSelection); +} + +void ListModelEditorDialog::onRowsInserted(const QModelIndex &parent, int first, int last) +{ + QItemSelectionModel *selection = m_tableView->selectionModel(); + auto model = selection->model(); + const int cols = model->columnCount(parent); + auto topLeft = model->index(first, 0, parent); + auto bottomRight = model->index(last, cols - 1, parent); + QItemSelection rowsSelection{topLeft, bottomRight}; + + selection->select(rowsSelection, QItemSelectionModel::ClearAndSelect); +} + +void ListModelEditorDialog::onColumnsInserted(const QModelIndex &parent, int first, int last) +{ + QItemSelectionModel *selection = m_tableView->selectionModel(); + auto model = selection->model(); + const int rows = model->rowCount(parent); + auto topLeft = model->index(0, first, parent); + auto bottomRight = model->index(rows - 1, last, parent); + QItemSelection columnSelection{topLeft, bottomRight}; + + selection->select(columnSelection, QItemSelectionModel::ClearAndSelect); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h index 8afafad79d7..d881c45b871 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h @@ -8,6 +8,7 @@ QT_BEGIN_NAMESPACE class QAbstractItemModel; class QTableView; +class QModelIndex; QT_END_NAMESPACE namespace Ui { @@ -32,17 +33,23 @@ protected: void keyPressEvent(QKeyEvent *) override; private: - void addRow(); + void addRowAbove(); + void addRowBelow(); void openColumnDialog(); void removeRows(); void removeColumns(); void changeHeader(int column); void moveRowsDown(); void moveRowsUp(); + void updateSelection(); + + void onRowsInserted(const QModelIndex &parent, int first, int last); + void onColumnsInserted(const QModelIndex &parent, int first, int last); private: ListModelEditorModel *m_model{}; - QAction *m_addRowAction{}; + QAction *m_addRowBelowAction{}; + QAction *m_addRowAboveAction{}; QAction *m_removeRowsAction{}; QAction *m_addColumnAction{}; QAction *m_removeColumnsAction{}; diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp index 0eb654bf0d0..02c1de2e0ad 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -213,14 +214,23 @@ void ListModelEditorModel::createItems(const QList &listElementNodes) appendItems(listElementNode); } -void ListModelEditorModel::appendItems(const ModelNode &listElementNode) +static QList createRow(const auto &propertyNames, const auto &listElementNode) { QList row; - row.reserve(m_propertyNames.size()); - for (const PropertyName &propertyName : propertyNames()) + row.reserve(propertyNames.size()); + for (const PropertyName &propertyName : propertyNames) row.push_back(createItem(listElementNode, propertyName).release()); + return row; +} - appendRow(row); +void ListModelEditorModel::insertItems(const ModelNode &listElementNode, int index) +{ + insertRow(index, createRow(m_propertyNames, listElementNode)); +} + +void ListModelEditorModel::appendItems(const ModelNode &listElementNode) +{ + appendRow(createRow(m_propertyNames, listElementNode)); } void ListModelEditorModel::setListModel(ModelNode node) @@ -234,12 +244,18 @@ void ListModelEditorModel::setListView(ModelNode listView) setListModel(listModelNode(listView, m_createModelCallback, m_goIntoComponentCallback)); } -void ListModelEditorModel::addRow() +void ListModelEditorModel::addRow(int rowIndex) { - auto newElement = m_createElementCallback(); - m_listModelNode.defaultNodeListProperty().reparentHere(newElement); + if (rowIndex < 0 || rowIndex > rowCount()) + return; - appendItems(newElement); + NodeListProperty defaultNodeListProperty = m_listModelNode.defaultNodeListProperty(); + defaultNodeListProperty.view()->executeInTransaction(__FUNCTION__, [&] { + auto newElement = m_createElementCallback(); + defaultNodeListProperty.reparentHere(newElement); + defaultNodeListProperty.slide(defaultNodeListProperty.count() - 1, rowIndex); + insertItems(newElement, rowIndex); + }); } void ListModelEditorModel::addColumn(const QString &columnName) @@ -271,7 +287,7 @@ bool ListModelEditorModel::setValue(int row, int column, QVariant value, Qt::Ite void ListModelEditorModel::removeColumn(int column) { - QList columnItems = QStandardItemModel::takeColumn(column); + QList columnItems = Super::takeColumn(column); m_propertyNames.removeAt(column); for (QStandardItem *columnItem : columnItems) { @@ -302,7 +318,7 @@ void ListModelEditorModel::removeRows(const QList &indices) void ListModelEditorModel::removeRow(int row) { - QList rowItems = QStandardItemModel::takeRow(row); + QList rowItems = Super::takeRow(row); if (rowItems.size()) static_cast(rowItems.front())->node.destroy(); @@ -409,4 +425,27 @@ std::vector ListModelEditorModel::filterRows(const QList &indi return rows; } +static int interactionRow(const QItemSelectionModel &selectionModel, + QModelIndex &(QModelIndexList::*defaultRowSelector)()) +{ + QModelIndexList selectedRows = selectionModel.selectedRows(); + auto defaultRow = std::mem_fn(defaultRowSelector); + int index = !selectedRows.isEmpty() ? defaultRow(selectedRows).row() : -1; + if (index < 0 && selectionModel.hasSelection()) + index = defaultRow(selectionModel.selectedIndexes()).row(); + if (index < 0 && selectionModel.currentIndex().isValid()) + index = selectionModel.currentIndex().row(); + return index; +} + +int ListModelEditorModel::currentInteractionRow(const QItemSelectionModel &selectionModel) +{ + return interactionRow(selectionModel, &QModelIndexList::first); +} + +int ListModelEditorModel::nextInteractionRow(const QItemSelectionModel &selectionModel) +{ + return interactionRow(selectionModel, &QModelIndexList::last) + 1; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h index 049c7e888d2..017d8acb334 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h @@ -12,8 +12,9 @@ namespace QmlDesigner { class ListModelEditorModel : public QStandardItemModel { - using QStandardItemModel::removeColumns; - using QStandardItemModel::removeRows; + using Super = QStandardItemModel; + using Super::removeColumns; + using Super::removeRows; public: ListModelEditorModel(std::function createModelCallback, @@ -28,7 +29,7 @@ public: void setListView(ModelNode listView); - void addRow(); + void addRow(int rowIndex); void addColumn(const QString &columnName); const QList &propertyNames() const { return m_propertyNames; } @@ -44,11 +45,15 @@ public: static std::vector filterColumns(const QList &indices); static std::vector filterRows(const QList &indices); + static int currentInteractionRow(const QItemSelectionModel &selectionModel); + static int nextInteractionRow(const QItemSelectionModel &selectionModel); + private: void removeRow(int row); void removeColumn(int column); void populateModel(); void createItems(const QList &listElementNodes); + void insertItems(const ModelNode &listElementNode, int index); void appendItems(const ModelNode &listElementNode); private: diff --git a/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp index c77771a52da..2428c6542ca 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp @@ -67,7 +67,8 @@ void NodeListProperty::slide(int from, int to) const if (!isValid()) return; - if (to < 0 || to > count() - 1 || from < 0 || from > count() - 1) + const int count = this->count(); + if (to < 0 || to > count - 1 || from < 0 || from > count - 1) return; privateModel()->changeNodeOrder(internalNodeSharedPointer(), name(), from, to); diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index 12013dfaeb9..be2741b8d5d 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -178,11 +178,31 @@ public: QModelIndex index(int row, int column) const { return model.index(row, column); } + int rowCount() const { return model.rowCount(); } + QList elements(const ModelNode &node) const { return node.defaultNodeListProperty().toModelNodeList(); } + QItemSelection rowSelection(std::initializer_list rows) const + { + QItemSelection selection; + for (int row : rows) + selection.select(model.index(row, 0), model.index(row, model.columnCount() - 1)); + return selection; + } + + QItemSelection itemSelection(std::initializer_list> items) const + { + QItemSelection selection; + for (const auto [row, column] : items) { + QModelIndex idx = index(row, column); + selection.select(idx, idx); + } + return selection; + } + protected: NiceMock projectStorageTriggerUpdateMock; NiceMock pathCacheMock{"/path/foo.qml"}; @@ -200,6 +220,7 @@ protected: QmlDesigner::ListModelEditorModel model{[&] { return mockView.createModelNode("ListModel"); }, [&] { return mockView.createModelNode("ListElement"); }, goIntoComponentMock.AsStdFunction()}; + QItemSelectionModel selectionModel{&model}; ModelNode listViewNode; ModelNode listModelNode; ModelNode emptyListModelNode; @@ -293,7 +314,7 @@ TEST_F(ListModelEditor, add_row_added_invalid_row) { model.setListModel(listModelNode); - model.addRow(); + model.addRow(rowCount()); ASSERT_THAT(displayValues(), ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42), @@ -302,6 +323,67 @@ TEST_F(ListModelEditor, add_row_added_invalid_row) ElementsAre(IsInvalid(), IsInvalid(), IsInvalid(), IsInvalid()))); } +TEST_F(ListModelEditor, add_row_to_zero_index_on_empty_model_works) +{ + model.setListModel(emptyListModelNode); + model.addColumn("foo"); + model.addColumn("bar"); + + model.addRow(0); + + ASSERT_THAT(displayValues(), ElementsAre(ElementsAre(IsInvalid(), IsInvalid()))); +} + +TEST_F(ListModelEditor, add_row_to_zero_index_on_non_empty_model_works) +{ + model.setListModel(listModelNode); + + model.addRow(0); + + ASSERT_THAT(displayValues(), + ElementsAre(ElementsAre(IsInvalid(), IsInvalid(), IsInvalid(), IsInvalid()), + ElementsAre(IsInvalid(), "foo", 1, 42), + ElementsAre("pic.png", "bar", 4, IsInvalid()), + ElementsAre("pic.png", "poo", 111, IsInvalid()))); +} + +TEST_F(ListModelEditor, add_row_to_index_one_works) +{ + model.setListModel(listModelNode); + + model.addRow(1); + + ASSERT_THAT(displayValues(), + ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42), + ElementsAre(IsInvalid(), IsInvalid(), IsInvalid(), IsInvalid()), + ElementsAre("pic.png", "bar", 4, IsInvalid()), + ElementsAre("pic.png", "poo", 111, IsInvalid()))); +} + +TEST_F(ListModelEditor, add_row_to_negative_index_does_nothing) +{ + model.setListModel(listModelNode); + + model.addRow(-1); + + ASSERT_THAT(displayValues(), + ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42), + ElementsAre("pic.png", "bar", 4, IsInvalid()), + ElementsAre("pic.png", "poo", 111, IsInvalid()))); +} + +TEST_F(ListModelEditor, add_row_to_int_max_index_does_nothing) +{ + model.setListModel(listModelNode); + + model.addRow(std::numeric_limits::max()); + + ASSERT_THAT(displayValues(), + ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42), + ElementsAre("pic.png", "bar", 4, IsInvalid()), + ElementsAre("pic.png", "poo", 111, IsInvalid()))); +} + TEST_F(ListModelEditor, add_row_creates_new_model_node_and_reparents) { model.setListModel(listModelNode); @@ -313,13 +395,177 @@ TEST_F(ListModelEditor, add_row_creates_new_model_node_and_reparents) _, _)); - model.addRow(); + model.addRow(rowCount()); +} + +TEST_F(ListModelEditor, current_interaction_row_returns_invalid_on_empty_selection) +{ + QItemSelectionModel emptySelection; + + int currentRow = ListModelEditorModel::currentInteractionRow(emptySelection); + + ASSERT_THAT(currentRow, Eq(-1)); +} + +TEST_F(ListModelEditor, current_interaction_row_returns_0_when_first_row_is_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(rowSelection({0}), QItemSelectionModel::Select); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(0)); +} + +TEST_F(ListModelEditor, current_interaction_row_returns_1_when_second_row_is_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(rowSelection({1}), QItemSelectionModel::Select); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(1)); +} + +TEST_F(ListModelEditor, current_interaction_row_returns_first_selected_row_when_multiple_rows_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(rowSelection({1, 2}), QItemSelectionModel::Select); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(1)); +} + +TEST_F(ListModelEditor, current_interaction_row_returns_first_selected_item_row_when_no_row_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(itemSelection({{2, 2}, {1, 2}}), QItemSelectionModel::Select); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(2)); +} + +TEST_F(ListModelEditor, current_interaction_row_returns_current_row_when_nothing_selected) +{ + model.setListModel(listModelNode); + selectionModel.setCurrentIndex(index(2, 2), QItemSelectionModel::Current); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(2)); +} + +TEST_F(ListModelEditor, current_interaction_row_prefers_selected_index_to_current_index) +{ + model.setListModel(listModelNode); + selectionModel.select(itemSelection({{2, 2}}), QItemSelectionModel::Select); + selectionModel.setCurrentIndex(index(1, 1), QItemSelectionModel::Current); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(2)); +} + +TEST_F(ListModelEditor, current_interaction_row_prefers_selected_row_to_selected_index) +{ + model.setListModel(listModelNode); + selectionModel.select(itemSelection({{1, 1}}), QItemSelectionModel::Select); + selectionModel.select(rowSelection({2}), QItemSelectionModel::Select); + + int currentRow = ListModelEditorModel::currentInteractionRow(selectionModel); + + ASSERT_THAT(currentRow, Eq(2)); +} + +TEST_F(ListModelEditor, next_interaction_row_returns_zero_on_empty_selection) +{ + QItemSelectionModel emptySelection; + + int nextRow = ListModelEditorModel::nextInteractionRow(emptySelection); + + ASSERT_THAT(nextRow, Eq(0)); +} + +TEST_F(ListModelEditor, next_interaction_row_returns_1_when_first_row_is_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(rowSelection({0}), QItemSelectionModel::Select); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(1)); +} + +TEST_F(ListModelEditor, next_interaction_row_returns_2_when_second_row_is_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(rowSelection({1}), QItemSelectionModel::Select); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(2)); +} + +TEST_F(ListModelEditor, + next_interaction_row_returns_next_row_after_last_selected_row_when_multiple_rows_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(rowSelection({1, 2}), QItemSelectionModel::Select); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(3)); +} + +TEST_F(ListModelEditor, + next_interaction_row_returns_next_row_after_last_selected_item_row_when_no_row_selected) +{ + model.setListModel(listModelNode); + selectionModel.select(itemSelection({{2, 2}, {1, 2}}), QItemSelectionModel::Select); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(2)); +} + +TEST_F(ListModelEditor, next_interaction_row_returns_next_row_after_current_row_when_nothing_selected) +{ + model.setListModel(listModelNode); + selectionModel.setCurrentIndex(index(2, 2), QItemSelectionModel::Current); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(3)); +} + +TEST_F(ListModelEditor, next_interaction_row_prefers_selected_index_to_current_index) +{ + model.setListModel(listModelNode); + selectionModel.select(itemSelection({{2, 2}}), QItemSelectionModel::Select); + selectionModel.setCurrentIndex(index(1, 1), QItemSelectionModel::Current); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(3)); +} + +TEST_F(ListModelEditor, next_interaction_row_prefers_selected_row_to_selected_index) +{ + model.setListModel(listModelNode); + selectionModel.select(itemSelection({{1, 1}}), QItemSelectionModel::Select); + selectionModel.select(rowSelection({2}), QItemSelectionModel::Select); + + int nextRow = ListModelEditorModel::nextInteractionRow(selectionModel); + + ASSERT_THAT(nextRow, Eq(3)); } TEST_F(ListModelEditor, change_added_row_propery) { model.setListModel(listModelNode); - model.addRow(); + model.addRow(rowCount()); model.setValue(3, 2, 22); @@ -335,7 +581,7 @@ TEST_F(ListModelEditor, change_added_row_propery_calls_variant_properties_change model.setListModel(listModelNode); ModelNode element4; ON_CALL(mockView, nodeReparented(_, _, _, _)).WillByDefault(SaveArg<0>(&element4)); - model.addRow(); + model.addRow(rowCount()); EXPECT_CALL(mockView, variantPropertiesChanged(ElementsAre(IsVariantProperty(element4, "value", 22)), @@ -940,7 +1186,7 @@ TEST_F(ListModelEditor, remove_last_row) { model.setListModel(emptyListModelNode); model.addColumn("mood"); - model.addRow(); + model.addRow(rowCount()); model.removeRows({index(0, 0)}); @@ -951,7 +1197,7 @@ TEST_F(ListModelEditor, remove_last_empty_row) { model.setListModel(emptyListModelNode); model.addColumn("mood"); - model.addRow(); + model.addRow(rowCount()); model.removeColumns({index(0, 0)}); model.removeRows({index(0, 0)}); @@ -963,7 +1209,7 @@ TEST_F(ListModelEditor, remove_last_column) { model.setListModel(emptyListModelNode); model.addColumn("mood"); - model.addRow(); + model.addRow(rowCount()); model.removeColumns({index(0, 0)}); @@ -974,7 +1220,7 @@ TEST_F(ListModelEditor, remove_last_empty_column) { model.setListModel(emptyListModelNode); model.addColumn("mood"); - model.addRow(); + model.addRow(rowCount()); model.removeRows({index(0, 0)}); model.removeColumns({index(0, 0)}); From 4e4ffd3cc9c4b27550642c6233ed8a3177065bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Fri, 4 Apr 2025 17:47:44 +0200 Subject: [PATCH 46/82] QmlDesigner: fix windowHandle() is nullptr warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib5ec37ebce4899cc0af2be44a58928d43ce4c757 Reviewed-by: Henning Gründl --- .../qmldesignerbase/utils/windowmanager.cpp | 31 ++++++++++++++++--- .../qmldesignerbase/utils/windowmanager.h | 3 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/plugins/qmldesignerbase/utils/windowmanager.cpp b/src/plugins/qmldesignerbase/utils/windowmanager.cpp index a254da69ab0..5b7ed2131fc 100644 --- a/src/plugins/qmldesignerbase/utils/windowmanager.cpp +++ b/src/plugins/qmldesignerbase/utils/windowmanager.cpp @@ -19,11 +19,32 @@ WindowManager::WindowManager() connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &WindowManager::focusWindowChanged); connect( Core::ICore::instance(), &Core::ICore::coreAboutToClose, this, &WindowManager::aboutToQuit); - connect( - Core::ICore::instance()->mainWindow()->windowHandle(), - &QWindow::visibleChanged, - this, - &WindowManager::mainWindowVisibleChanged); + + if (!connectMainWindowHandle()) + Core::ICore::instance()->mainWindow()->installEventFilter(this); +} + +bool WindowManager::connectMainWindowHandle() +{ + if (QWindow *windowHandle = Core::ICore::instance()->mainWindow()->windowHandle()) { + QMetaObject::Connection success = connect( + windowHandle, + &QWindow::visibleChanged, + this, + &WindowManager::mainWindowVisibleChanged, + Qt::UniqueConnection); + return success; + } + return false; +} + +bool WindowManager::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == Core::ICore::instance()->mainWindow() && event->type() == QEvent::WinIdChange) { + connectMainWindowHandle(); + Core::ICore::instance()->mainWindow()->removeEventFilter(this); + } + return QObject::eventFilter(watched, event); } void WindowManager::registerDeclarativeType() diff --git a/src/plugins/qmldesignerbase/utils/windowmanager.h b/src/plugins/qmldesignerbase/utils/windowmanager.h index 1e74c721bc6..d329b53dc98 100644 --- a/src/plugins/qmldesignerbase/utils/windowmanager.h +++ b/src/plugins/qmldesignerbase/utils/windowmanager.h @@ -35,6 +35,7 @@ signals: private: WindowManager(); + bool connectMainWindowHandle(); + bool eventFilter(QObject *watched, QEvent *event) override; }; - } // namespace QmlDesigner From c4efb9c96c3ba2d25334222af11340074d41e3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Thu, 10 Apr 2025 15:51:53 +0200 Subject: [PATCH 47/82] QmlDesigner: fix QML warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I955c6b8ae5cdefbbe1e414ebfca1c7fac5df9abe Reviewed-by: Henning Gründl Reviewed-by: Tim Jenssen --- .../contentLibraryQmlSource/ContentLibraryUserView.qml | 5 ++++- .../qmldesigner/effectComposerQmlSources/BlurHelper.qml | 4 ++-- .../effectComposerQmlSources/EffectComposerPreview.qml | 4 ++-- .../newprojectdialog/imports/NewProjectDialog/Styles.qml | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml index 9a8eda0a5e7..eb708a80872 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml @@ -96,7 +96,10 @@ Item { HelperWidgets.AbstractButton { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.add_medium - enabled: hasMaterial && hasModelSelection && hasQuick3DImport && hasMaterialLibrary + enabled: (this.hasMaterial ?? false) + && hasModelSelection + && hasQuick3DImport + && hasMaterialLibrary tooltip: qsTr("Add a custom bundle folder.") onClicked: ContentLibraryBackend.rootView.browseBundleFolder() x: 5 // left margin diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml index da68339603a..80577e932a1 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml @@ -20,8 +20,8 @@ Item { visible: false layer.enabled: true layer.smooth: true - vertexShader: g_propertyData.blur_vs_path - fragmentShader: g_propertyData.blur_fs_path + vertexShader: g_propertyData?.blur_vs_path ?? "" + fragmentShader: g_propertyData?.blur_fs_path ?? "" } QtObject { diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml index d8c36e34c22..920d02a304b 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml @@ -298,8 +298,8 @@ Column { BlurHelper { id: blurHelper source: source - property int blurMax: g_propertyData.blur_helper_max_level ? g_propertyData.blur_helper_max_level : 64 - property real blurMultiplier: g_propertyData.blurMultiplier ? g_propertyData.blurMultiplier : 0 + property int blurMax: g_propertyData?.blur_helper_max_level ?? 64 + property real blurMultiplier: g_propertyData?.blurMultiplier ?? 0 } Item { diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml index 6e1467dd2f7..87c9f623536 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml @@ -132,7 +132,7 @@ Item { delegate: ItemDelegate { id: delegateId - readonly property string styleName: model.display + readonly property string styleName: model?.display ?? "" width: stylesList.width height: DialogValues.styleListItemHeight hoverEnabled: true @@ -180,7 +180,7 @@ Item { width: DialogValues.styleImageWidth height: DialogValues.styleImageHeight asynchronous: false - source: "image://newprojectdialog_library/" + model.iconName + source: model?.iconName ? "image://newprojectdialog_library/" + model.iconName : "" } } // Rectangle From 5982ab8074d0cc6e82a65599294343fd7350b8c6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 10 Apr 2025 17:13:01 +0300 Subject: [PATCH 48/82] QmlDesigner: Fix root item effect rendering ShaderEffects affecting root item are now correctly triggering root item render if they have changes. Fixes: QDS-15085 Change-Id: I7e675a9514e0de0a45d0709ff5e59e8371700b45 Reviewed-by: Thomas Hartmann --- .../instances/qt5nodeinstanceserver.cpp | 17 ++++++++++++++--- .../instances/qt5rendernodeinstanceserver.cpp | 4 +++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5nodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5nodeinstanceserver.cpp index 85b5021f5ed..f4a11b1a2b8 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5nodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5nodeinstanceserver.cpp @@ -189,10 +189,21 @@ QList subItems(QQuickItem *parentItem) const QList Qt5NodeInstanceServer::allItems() const { - if (rootNodeInstance().isValid()) - return rootNodeInstance().allItemsRecursive(); + if (!rootNodeInstance().isValid()) + return {}; - return {}; + QList allItems = rootNodeInstance().allItemsRecursive(); + + // ShaderEffects affecting root item will be root item siblings, so add those as well + QQuickItem *rootItem = rootNodeInstance().rootQuickItem(); + if (rootItem && rootItem->parentItem()) { + const QList siblings = rootItem->parentItem()->childItems(); + for (QQuickItem *sibling : siblings) { + if (sibling != rootItem) + allItems.append(sibling); + } + } + return allItems; } bool Qt5NodeInstanceServer::rootIsRenderable3DObject() const diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp index c8f1d489e3e..37b1e3faaec 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp @@ -163,7 +163,9 @@ ServerNodeInstance Qt5RenderNodeInstanceServer::findNodeInstanceForItem(QQuickIt if (item) { if (hasInstanceForObject(item)) return instanceForObject(item); - else if (item->parentItem()) + else if (item == rootNodeInstance().rootQuickItem()->parentItem()) + return rootNodeInstance(); + else return findNodeInstanceForItem(item->parentItem()); } From aa3d61da93269db35024be73b433f75ccdf03c33 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Apr 2025 12:45:04 +0200 Subject: [PATCH 49/82] QmlDesigner: Fix DesignSystemView for project storage The projectStorageDependencies are only available if actually a project is opened. DSStore is part of a library and also used in the importer. Instead of changing DSStore, we create the DSStore in the first attach after a project was opened. DesignSystemInterface is the interface to the QML UI. We guard access in case no DSStore is created, yet. TODO: We should only load the DesignSystem on demand if the view is actually active. Task-number: QDS-15070 Change-Id: I6f52375d029e575582dc8f16abc50c157666f287 Reviewed-by: Marco Bubke --- .../designsysteminterface.cpp | 21 +++++++++++++-- .../designsystemview/designsysteminterface.h | 4 ++- .../designsystemview/designsystemview.cpp | 26 +++++++++++++++---- .../designsystemview/designsystemview.h | 8 ++++-- src/plugins/qmldesigner/qmldesignerplugin.cpp | 4 +-- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp index 820ec51e5ad..7b27bbb52d8 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp +++ b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp @@ -11,8 +11,7 @@ #include namespace QmlDesigner { -DesignSystemInterface::DesignSystemInterface(DSStore *store) - : m_store(store) +DesignSystemInterface::DesignSystemInterface() { qmlRegisterUncreatableMetaObject( QmlDesigner::staticMetaObject, "QmlDesigner.DesignSystem", 1, 0, "GroupType", ""); @@ -23,6 +22,8 @@ DesignSystemInterface::~DesignSystemInterface() {} void DesignSystemInterface::loadDesignSystem() { + QTC_ASSERT(m_store, return); + m_models.clear(); if (auto err = m_store->load()) @@ -33,6 +34,8 @@ void DesignSystemInterface::loadDesignSystem() CollectionModel *DesignSystemInterface::model(const QString &typeName) { + QTC_ASSERT(m_store, return nullptr); + if (auto collection = m_store->collection(typeName)) return createModel(typeName, collection); @@ -41,17 +44,22 @@ CollectionModel *DesignSystemInterface::model(const QString &typeName) QString DesignSystemInterface::generateCollectionName(const QString &hint) const { + QTC_ASSERT(m_store, return {}); return m_store->uniqueCollectionName(hint); } void DesignSystemInterface::addCollection(const QString &name) { + QTC_ASSERT(m_store, return); + if (m_store->addCollection(name)) emit collectionsChanged(); } void DesignSystemInterface::removeCollection(const QString &name) { + QTC_ASSERT(m_store, return); + if (m_store->collection(name)) { m_models.erase(name); m_store->removeCollection(name); @@ -61,6 +69,8 @@ void DesignSystemInterface::removeCollection(const QString &name) void DesignSystemInterface::renameCollection(const QString &oldName, const QString &newName) { + QTC_ASSERT(m_store, return); + if (m_store->renameCollection(oldName, newName)) emit collectionsChanged(); } @@ -74,9 +84,16 @@ ThemeProperty DesignSystemInterface::createThemeProperty(const QString &name, QStringList DesignSystemInterface::collections() const { + QTC_ASSERT(m_store, return {}); + return m_store->collectionNames(); } +void DesignSystemInterface::setDSStore(DSStore *store) +{ + m_store = store; +} + CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection) { auto [iterator, inserted] = m_models.try_emplace(typeName, collection, m_store); diff --git a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h index 6aaa7e92023..6f4f8c1e0a5 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h +++ b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h @@ -18,7 +18,7 @@ class DesignSystemInterface : public QObject Q_PROPERTY(QStringList collections READ collections NOTIFY collectionsChanged FINAL) public: - DesignSystemInterface(DSStore *store); + DesignSystemInterface(); ~DesignSystemInterface(); Q_INVOKABLE void loadDesignSystem(); @@ -35,6 +35,8 @@ public: QStringList collections() const; + void setDSStore(DSStore *store); + signals: void collectionsChanged(); diff --git a/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp b/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp index 29e8cf49f49..a7f9ef33a52 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp +++ b/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp @@ -21,17 +21,14 @@ namespace QmlDesigner { -DesignSystemView::DesignSystemView(ExternalDependenciesInterface &externalDependencies, - ProjectStorageDependencies projectStorageDependencies) +DesignSystemView::DesignSystemView(ExternalDependenciesInterface &externalDependencies) : AbstractView(externalDependencies) , m_externalDependencies(externalDependencies) - , m_dsStore(std::make_unique(m_externalDependencies, projectStorageDependencies)) - , m_dsInterface(m_dsStore.get()) { connect(ProjectExplorer::ProjectManager::instance(), &ProjectExplorer::ProjectManager::startupProjectChanged, this, - [this](ProjectExplorer::Project *) { loadDesignSystem(); }); + [this](ProjectExplorer::Project *) { resetDesignSystem(); }); connect(Core::EditorManager::instance(), &Core::EditorManager::saved, @@ -63,12 +60,31 @@ bool DesignSystemView::hasWidget() const return true; } +void DesignSystemView::modelAttached(Model *model) +{ + AbstractView::modelAttached(model); + /* Only load on first attach */ + if (!m_dsStore) + loadDesignSystem(); +} + void DesignSystemView::loadDesignSystem() { /*This is only used to load internally - when saving we have to take care of reflection. * Saving should not trigger a load again. */ + + m_dsStore = std::make_unique(m_externalDependencies, + model()->projectStorageDependencies()); + m_dsInterface.setDSStore(m_dsStore.get()); + m_dsInterface.loadDesignSystem(); } +void DesignSystemView::resetDesignSystem() +{ + m_dsStore.reset(); + m_dsInterface.setDSStore(nullptr); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/designsystemview/designsystemview.h b/src/plugins/qmldesigner/components/designsystemview/designsystemview.h index b3c44cfb873..42332c13819 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsystemview.h +++ b/src/plugins/qmldesigner/components/designsystemview/designsystemview.h @@ -4,6 +4,7 @@ #pragma once #include "designsysteminterface.h" +#include "qmldesignerprojectmanager.h" #include #include @@ -13,21 +14,24 @@ namespace QmlDesigner { class DSStore; class ExternalDependenciesInterface; class DesignSystemWidget; +class QmlDesignerProjectManager; class DesignSystemView : public AbstractView { Q_OBJECT public: - explicit DesignSystemView(ExternalDependenciesInterface &externalDependencies, - ProjectStorageDependencies projectStorageDependencies); + explicit DesignSystemView(ExternalDependenciesInterface &externalDependencies); ~DesignSystemView() override; WidgetInfo widgetInfo() override; bool hasWidget() const override; + void modelAttached(Model *model) override; + private: void loadDesignSystem(); + void resetDesignSystem(); QWidget *createViewWidget(); private: diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index fdf8b9e94d9..55be25b7c2a 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -677,9 +677,7 @@ void QmlDesignerPlugin::enforceDelayedInitialize() transitionEditorView->registerActions(); if (QmlDesignerBasePlugin::experimentalFeaturesEnabled()) - d->viewManager.registerView( - std::make_unique(d->externalDependencies, - d->projectManager.projectStorageDependencies())); + d->viewManager.registerView(std::make_unique(d->externalDependencies)); d->viewManager.registerFormEditorTool(std::make_unique()); d->viewManager.registerFormEditorTool(std::make_unique()); From 4d93a8b663480582948b612516b7a471812e9b92 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Apr 2025 14:33:18 +0200 Subject: [PATCH 50/82] QmlDesigner: Fix crash in project storage builds Display name does not work at all and makes no sense here. We use the first exported type name. Task-number: QDS-15029 Change-Id: I825447e18c940996dc7c80ff9ff31aded7d8b666 Reviewed-by: Marco Bubke --- .../components/bindingeditor/bindingeditor.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp index bb98db869c4..2a066343ca6 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp @@ -260,8 +260,12 @@ void BindingEditor::prepareBindings() } if (!binding.properties.isEmpty()) { - binding.item = metaInfo.displayName(); - bindings.append(binding); + for (auto &exportedType : + metaInfo.exportedTypeNamesForSourceId(model->fileUrlSourceId())) { + binding.item = exportedType.name.toQString(); + bindings.append(binding); + break; + } } } } From 9e995fe80155021ea92917063343f4dcb4b928d0 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 10 Apr 2025 18:36:34 +0200 Subject: [PATCH 51/82] QmlDesigner: Optimize condition isBasedOn() handles equality. This already handles equality of types. Change-Id: If03e083ff6e3446341a37b8fd8fd8978bfc20666 Reviewed-by: Marco Bubke --- .../qmldesigner/components/bindingeditor/bindingeditor.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp index 2a066343ca6..a62f507b943 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp @@ -177,10 +177,8 @@ bool isType(const TypeName &first, const TypeName &second, const Tuple &...types bool compareTypes(const NodeMetaInfo &sourceType, const NodeMetaInfo &targetType) { #ifdef QDS_USE_PROJECTSTORAGE - return targetType.isVariant() || sourceType.isVariant() || targetType == sourceType - || (targetType.isNumber() && sourceType.isNumber()) - || (targetType.isColor() && sourceType.isColor()) - || (targetType.isString() && sourceType.isString()); + return targetType.isVariant() || sourceType.isVariant() + || (targetType.isNumber() && sourceType.isNumber()) || sourceType.isBasedOn(targetType); #else const TypeName source = sourceType.simplifiedTypeName(); const TypeName target = targetType.simplifiedTypeName(); From 65b91c87e00c35986e0fb745991f707736fbd4f1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 10 Apr 2025 18:25:15 +0200 Subject: [PATCH 52/82] QmlDesigner: Set RemoveImports to false for copy and pase Task-number: QDS-15046 Change-Id: I1ca9db9f11698c5e6e466e3569c75c3f66ca2666 Reviewed-by: Marco Bubke --- .../qmldesigner/components/integration/designdocumentview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp index 22175921e99..37d4aae0552 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp @@ -123,6 +123,7 @@ QString DesignDocumentView::toText() const rewriterView->setCheckSemanticErrors(false); rewriterView->setPossibleImportsEnabled(false); rewriterView->setTextModifier(&modifier); + rewriterView->setRemoveImports(false); outputModel->setRewriterView(rewriterView.get()); ModelMerger merger(rewriterView.get()); From d692c3ba54232a6d0fced97921192960291d356e Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 10 Apr 2025 18:57:29 +0200 Subject: [PATCH 53/82] QmlDesigner: Inflate dot properties for binding editor Task-numbner: QDS-15183 Change-Id: If899ca6ff3f8416205718bb4ae6f5570e66ab666 Reviewed-by: Marco Bubke --- .../qmldesigner/components/bindingeditor/bindingeditor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp index a62f507b943..3b5461581c3 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp @@ -205,8 +205,9 @@ void BindingEditor::prepareBindings() for (const auto &objnode : allNodes) { BindingEditorDialog::BindingOption binding; - for (const auto &property : objnode.metaInfo().properties()) { - const auto &propertyType = property.propertyType(); + for (const auto &property : + MetaInfoUtils::addInflatedValueAndReadOnlyProperties(objnode.metaInfo().properties())) { + const auto &propertyType = property.property.propertyType(); if (compareTypes(m_backendValueType, propertyType)) { binding.properties.append(QString::fromUtf8(property.name())); From a94238d42b0ff1b6baeaa2e6353a4e5fcb00c452 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Thu, 10 Apr 2025 19:12:37 +0300 Subject: [PATCH 54/82] MaterialBrowser: Fix applying material to model The material should be applied to a selected model. Fixes: QDS-15038 Change-Id: I86f6c215ac90414dad21d7e4f62d99301b2486e1 Reviewed-by: Mahmoud Badri --- .../components/materialbrowser/materialbrowserview.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 3592066e125..cd3aed74ebe 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -46,6 +46,11 @@ static bool isTexture(const ModelNode &node) return node.metaInfo().isQtQuick3DTexture(); } +static bool isModel3D(const ModelNode &node) +{ + return node.metaInfo().isQtQuick3DModel(); +} + static QString propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH @@ -354,8 +359,10 @@ void MaterialBrowserView::selectedNodesChanged([[maybe_unused]] const QListmaterialBrowserModel()->notifySelectionChanges(selectedMaterials, deselectedMaterials); - m_widget->materialBrowserModel()->setHasModelSelection(!selectedMaterials.isEmpty()); + m_widget->materialBrowserModel()->setHasModelSelection(!selectedModels.isEmpty()); m_widget->materialBrowserTexturesModel()->notifySelectionChanges(selectedTextures, deselectedTextures); From a5da69fc3cdd69c6f9c3bf0348d08ac288f252d6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 8 Apr 2025 13:25:59 +0300 Subject: [PATCH 55/82] QmlDesigner: Take exportedTypeNamesChanged notifications into use Added exportedTypeNamesChanged triggers for 3d view context menu update and asset menu .q3d files sync. Fixes: QDS-15158 Change-Id: I1bcb1659d70e4c52c75b21ea578f45c9c413d063 Reviewed-by: Mahmoud Badri --- .../assetslibrary/assetslibraryview.cpp | 19 +++++++++++++------ .../assetslibrary/assetslibraryview.h | 3 +++ .../components/componentcore/utils3d.cpp | 19 +++++++++++++++++++ .../components/componentcore/utils3d.h | 4 +++- .../components/edit3d/edit3dview.cpp | 13 ++++++++++--- .../components/edit3d/edit3dview.h | 3 ++- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp index 1c555890f2d..0547d7267da 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace QmlDesigner { @@ -80,10 +81,13 @@ void AssetsLibraryView::customNotification(const AbstractView * /*view*/, const QList & /*nodeList*/, const QList & /*data*/) { - if (identifier == "delete_selected_assets") + if (identifier == "delete_selected_assets") { m_widget->deleteSelectedAssets(); - else if (identifier == "asset_import_finished") + } else if (identifier == "asset_import_finished") { + // TODO: This custom notification should be removed once QDS-15163 is fixed and + // exportedTypeNamesChanged notification is reliable m_3dImportsSyncTimer.start(); + } } void AssetsLibraryView::modelAttached(Model *model) @@ -104,6 +108,13 @@ void AssetsLibraryView::modelAboutToBeDetached(Model *model) m_3dImportsSyncTimer.stop(); } +void AssetsLibraryView::exportedTypeNamesChanged(const ExportedTypeNames &added, + const ExportedTypeNames &removed) +{ + if (Utils3D::hasImported3dType(this, added, removed)) + m_3dImportsSyncTimer.start(); +} + void AssetsLibraryView::setResourcePath(const QString &resourcePath) { if (resourcePath == m_lastResourcePath) @@ -148,10 +159,6 @@ void AssetsLibraryView::sync3dImports() if (!model()) return; - // TODO: Once project storage supports notifications for new and removed types, - // sync3dImports() should be called in that case as well. - // Also, custom notification "asset_import_finished" should not be necessary in that case. - // Sync generated 3d imports to .q3d files in project content const GeneratedComponentUtils &compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h index 2dc8f47cdf4..4eafc0f68cb 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h @@ -33,6 +33,9 @@ public: // AbstractView void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; + void exportedTypeNamesChanged(const ExportedTypeNames &added, + const ExportedTypeNames &removed) override; + void setResourcePath(const QString &resourcePath); private: diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index 3121ed9cdfb..11e3a9a4e21 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -566,5 +566,24 @@ void openNodeInPropertyEditor(const ModelNode &node) node.view()->emitCustomNotification("force_editing_node", {node}); // To PropertyEditor } +bool hasImported3dType(AbstractView *view, + const AbstractView::ExportedTypeNames &added, + const AbstractView::ExportedTypeNames &removed) +{ + QTC_ASSERT(view && view->model(), return false); + + using Storage::Info::ExportedTypeName; + + const QByteArray import3dPrefix = QmlDesignerPlugin::instance()->documentManager() + .generatedComponentUtils().import3dTypePrefix().toUtf8(); + + auto generatedModuleIds = view->model()->moduleIdsStartsWith(import3dPrefix, + Storage::ModuleKind::QmlLibrary); + std::ranges::sort(generatedModuleIds); + + return Utils::set_has_common_element(added, generatedModuleIds, {}, &ExportedTypeName::moduleId) + || Utils::set_has_common_element(removed, generatedModuleIds, {}, &ExportedTypeName::moduleId); +} + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.h b/src/plugins/qmldesigner/components/componentcore/utils3d.h index 2bc17366207..c1cacb9ac46 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.h +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.h @@ -52,7 +52,9 @@ void duplicateMaterial(AbstractView *view, const ModelNode &material); bool addQuick3DImportAndView3D(AbstractView *view, bool suppressWarningDialog = false); void assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode, const ModelNode &materialNode = {}); - +bool hasImported3dType(AbstractView *view, + const AbstractView::ExportedTypeNames &added, + const AbstractView::ExportedTypeNames &removed); } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index fdfecebdf58..11edda9005e 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -317,8 +317,6 @@ void Edit3DView::modelAttached(Model *model) m_isBakingLightsSupported = qtVer->qtVersion() >= QVersionNumber(6, 5, 0); } #ifdef QDS_USE_PROJECTSTORAGE - // TODO: Handle actual entries changed signal/notification once it is available. - // Until then, we simply get what entries are available at model attach time. onEntriesChanged(); #else connect(model->metaInfo().itemLibraryInfo(), @@ -462,7 +460,9 @@ void Edit3DView::customNotification([[maybe_unused]] const AbstractView *view, self->m_pickView3dNode = self->modelNodeForInternalId(qint32(data[1].toInt())); }); } else if (identifier == "asset_import_finished" || identifier == "assets_deleted") { - handleEntriesChanged(); + // TODO: These custom notifications should be removed once QDS-15163 is fixed and + // exportedTypeNamesChanged notification is reliable + onEntriesChanged(); } } @@ -571,6 +571,13 @@ void Edit3DView::variantPropertiesChanged(const QList &property maybeStoreCurrentSceneEnvironment(propertyList); } +void Edit3DView::exportedTypeNamesChanged(const ExportedTypeNames &added, + const ExportedTypeNames &removed) +{ + if (Utils3D::hasImported3dType(this, added, removed)) + onEntriesChanged(); +} + void Edit3DView::sendInputEvent(QEvent *e) const { if (isAttached()) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index e89cf8cac22..0cc421c8566 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -80,7 +80,8 @@ public: PropertyChangeFlags propertyChange) override; void variantPropertiesChanged(const QList &propertyList, PropertyChangeFlags propertyChange) override; - + void exportedTypeNamesChanged(const ExportedTypeNames &added, + const ExportedTypeNames &removed) override; void sendInputEvent(QEvent *e) const; void edit3DViewResized(const QSize &size) const; From 826ecdde6dbe071d3ebb7c06d1432b04618bf391 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 7 Apr 2025 15:47:50 +0300 Subject: [PATCH 56/82] QmlDesigner: Delay rebaking until exposed properties are seen It takes a moment for the code model to realize there are new exposed properties available, so add a timer to check. Fixes: QDS-15058 Change-Id: Iab2649f2f17100cdac5814122593b48f09c23eb1 Reviewed-by: Mahmoud Badri --- .../components/edit3d/bakelights.cpp | 51 +++++++++++++++++-- .../components/edit3d/bakelights.h | 6 +++ .../libs/designercore/include/model.h | 1 + .../libs/designercore/model/model.cpp | 10 ++++ 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp index 0410bbf3e5e..b715deb9c3c 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include namespace QmlDesigner { @@ -74,6 +73,9 @@ BakeLights::BakeLights(AbstractView *view) return; } + m_pendingRebakeTimer.setInterval(100); + connect(&m_pendingRebakeTimer, &QTimer::timeout, this, &BakeLights::handlePendingRebakeTimeout); + showSetupDialog(); } @@ -215,7 +217,8 @@ void BakeLights::rebake() void BakeLights::exposeModelsAndLights(const QString &nodeId) { ModelNode compNode = m_view->modelNodeForId(nodeId); - if (!compNode.isValid() || !compNode.isComponent()) { + if (!compNode.isValid() || !compNode.isComponent() + || (m_pendingRebakeTimer.isActive() && compNode == m_pendingRebakeCheckNode)) { return; } @@ -294,8 +297,9 @@ void BakeLights::exposeModelsAndLights(const QString &nodeId) compModel->setRewriterView({}); - // Rebake to relaunch setup dialog with updated properties - rebake(); + m_pendingRebakeTimerCount = 0; + m_pendingRebakeCheckNode = compNode; + m_pendingRebakeTimer.start(); } void BakeLights::showSetupDialog() @@ -376,6 +380,8 @@ void BakeLights::cleanup() m_model.reset(); } + pendingRebakeCleanup(); + delete m_setupDialog; delete m_progressDialog; delete m_rewriterView; @@ -386,6 +392,43 @@ void BakeLights::cleanup() m_manualMode = false; } +void BakeLights::handlePendingRebakeTimeout() +{ + QScopeGuard timerCleanup([this]() { + pendingRebakeCleanup(); + }); + + if (m_view.isNull() || !m_pendingRebakeCheckNode || !m_pendingRebakeCheckNode.isComponent()) + return; + + const Model *model = m_pendingRebakeCheckNode.model(); + if (!model) + return; + + const QList props = m_pendingRebakeCheckNode.properties(); + PropertyMetaInfos metaInfos = m_pendingRebakeCheckNode.metaInfo().properties(); + for (const PropertyMetaInfo &mi : metaInfos) { + if (mi.isValid() && !mi.isPrivate() && mi.isWritable()) { + if (mi.propertyType().isBasedOn(model->qtQuick3DModelMetaInfo(), + model->qtQuick3DLightMetaInfo())) { + // Rebake to relaunch setup dialog with updated properties + rebake(); + return; + } + } + } + + if (++m_pendingRebakeTimerCount < 100) + timerCleanup.dismiss(); +} + +void BakeLights::pendingRebakeCleanup() +{ + m_pendingRebakeTimer.stop(); + m_pendingRebakeTimerCount = 0; + m_pendingRebakeCheckNode = {}; +} + void BakeLights::cancel() { if (!m_setupDialog.isNull() && m_setupDialog->isVisible()) diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.h b/src/plugins/qmldesigner/components/edit3d/bakelights.h index 2b6848bd482..3bdb8bfec9d 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.h +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.h @@ -7,6 +7,7 @@ #include #include +#include QT_BEGIN_NAMESPACE class QQuickView; @@ -53,6 +54,8 @@ private: void showSetupDialog(); void showProgressDialog(); void cleanup(); + void handlePendingRebakeTimeout(); + void pendingRebakeCleanup(); // Separate dialogs for setup and progress, as setup needs to be modal QPointer m_setupDialog; @@ -66,6 +69,9 @@ private: ModelPointer m_model; QString m_view3dId; bool m_manualMode = false; + QTimer m_pendingRebakeTimer; + ModelNode m_pendingRebakeCheckNode; + int m_pendingRebakeTimerCount = 0; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 286e203e704..262b2078283 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -172,6 +172,7 @@ public: NodeMetaInfo qtQuick3DBakedLightmapMetaInfo() const; NodeMetaInfo qtQuick3DDefaultMaterialMetaInfo() const; NodeMetaInfo qtQuick3DDirectionalLightMetaInfo() const; + NodeMetaInfo qtQuick3DLightMetaInfo() const; NodeMetaInfo qtQuick3DMaterialMetaInfo() const; NodeMetaInfo qtQuick3DModelMetaInfo() const; NodeMetaInfo qtQuick3DNodeMetaInfo() const; diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 98d3e7f6669..9e1b6959c59 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2724,6 +2724,16 @@ NodeMetaInfo Model::qtQuick3DDefaultMaterialMetaInfo() const } } +NodeMetaInfo Model::qtQuick3DLightMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QtQuick3D.Light"); + } +} + NodeMetaInfo Model::qtQuick3DDirectionalLightMetaInfo() const { if constexpr (useProjectStorage()) { From b81f674f31f2fb3c0067ca38be0c4126555b7d16 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 3 Apr 2025 16:15:25 +0300 Subject: [PATCH 57/82] QmlDesigner: Add metainfo and specifics of various modules - Saferenderer - Charts - Graphs - VirtualKeyboard - Quick3DPhysics Various specifics were copied from modules into QDS with minimal updates to fix most glaring errors/layout issues. It is not guaranteed they are all up to date and fully functional. Charts and Graphs cannot be enabled for project storage yet, as their .qmltypes files contain duplicate entries. When they are fixed in Qt version QDS targets, these modules can be enabled for project storage. Fixes: QDS-15020 Change-Id: Id3e3c76c3940f2ee05359b9274c82791b8d95c38 Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../itemLibrary/images/areaseries-icon.png | Bin 0 -> 341 bytes .../images/areaseries-polar-icon.png | Bin 0 -> 447 bytes .../itemLibrary/images/bars3d-icon.png | Bin 0 -> 261 bytes .../itemLibrary/images/bars3d-icon16.png | Bin 0 -> 203 bytes .../itemLibrary/images/barseries-icon.png | Bin 0 -> 136 bytes .../itemLibrary/images/boxplotseries-icon.png | Bin 0 -> 162 bytes .../itemLibrary/images/boxshape.png | Bin 0 -> 473 bytes .../itemLibrary/images/boxshape16.png | Bin 0 -> 354 bytes .../itemLibrary/images/boxshape@2x.png | Bin 0 -> 657 bytes .../itemLibrary/images/capsuleshape.png | Bin 0 -> 404 bytes .../itemLibrary/images/capsuleshape16.png | Bin 0 -> 280 bytes .../itemLibrary/images/capsuleshape@2x.png | Bin 0 -> 877 bytes .../images/charactercontroller.png | Bin 0 -> 428 bytes .../images/charactercontroller16.png | Bin 0 -> 280 bytes .../images/charactercontroller@2x.png | Bin 0 -> 831 bytes .../itemLibrary/images/chartview-icon16.png | Bin 0 -> 244 bytes .../itemLibrary/images/convexmeshshape.png | Bin 0 -> 745 bytes .../itemLibrary/images/convexmeshshape16.png | Bin 0 -> 332 bytes .../itemLibrary/images/convexmeshshape@2x.png | Bin 0 -> 1904 bytes .../itemLibrary/images/dynamicrigidbody.png | Bin 0 -> 414 bytes .../itemLibrary/images/dynamicrigidbody16.png | Bin 0 -> 311 bytes .../images/dynamicrigidbody@2x.png | Bin 0 -> 778 bytes .../itemLibrary/images/heightfieldshape.png | Bin 0 -> 456 bytes .../itemLibrary/images/heightfieldshape16.png | Bin 0 -> 240 bytes .../images/heightfieldshape@2x.png | Bin 0 -> 1129 bytes .../images/horizontalbarseries-icon.png | Bin 0 -> 136 bytes .../horizontalpercentbarseries-icon.png | Bin 0 -> 151 bytes .../horizontalstackedbarseries-icon.png | Bin 0 -> 152 bytes .../itemLibrary/images/lineseries-icon.png | Bin 0 -> 258 bytes .../images/lineseries-polar-icon.png | Bin 0 -> 440 bytes .../images/percentbarseries-icon.png | Bin 0 -> 151 bytes .../itemLibrary/images/physicsmaterial.png | Bin 0 -> 559 bytes .../itemLibrary/images/physicsmaterial16.png | Bin 0 -> 357 bytes .../itemLibrary/images/physicsmaterial@2x.png | Bin 0 -> 1095 bytes .../itemLibrary/images/physicsworld.png | Bin 0 -> 441 bytes .../itemLibrary/images/physicsworld16.png | Bin 0 -> 316 bytes .../itemLibrary/images/physicsworld@2x.png | Bin 0 -> 846 bytes .../itemLibrary/images/pieseries-icon.png | Bin 0 -> 346 bytes .../itemLibrary/images/planeshape.png | Bin 0 -> 473 bytes .../itemLibrary/images/planeshape16.png | Bin 0 -> 299 bytes .../itemLibrary/images/planeshape@2x.png | Bin 0 -> 1084 bytes .../itemLibrary/images/scatter3d-icon.png | Bin 0 -> 244 bytes .../itemLibrary/images/scatter3d-icon16.png | Bin 0 -> 190 bytes .../itemLibrary/images/scatterseries-icon.png | Bin 0 -> 182 bytes .../images/scatterseries-polar-icon.png | Bin 0 -> 345 bytes .../itemLibrary/images/sphereshape.png | Bin 0 -> 567 bytes .../itemLibrary/images/sphereshape16.png | Bin 0 -> 336 bytes .../itemLibrary/images/sphereshape@2x.png | Bin 0 -> 1179 bytes .../itemLibrary/images/splineseries-icon.png | Bin 0 -> 303 bytes .../images/splineseries-polar-icon.png | Bin 0 -> 415 bytes .../images/stackedbarseries-icon.png | Bin 0 -> 154 bytes .../itemLibrary/images/staticrigidbody.png | Bin 0 -> 375 bytes .../itemLibrary/images/staticrigidbody16.png | Bin 0 -> 298 bytes .../itemLibrary/images/staticrigidbody@2x.png | Bin 0 -> 690 bytes .../itemLibrary/images/surface3d-icon.png | Bin 0 -> 314 bytes .../itemLibrary/images/surface3d-icon16.png | Bin 0 -> 215 bytes .../itemLibrary/images/trianglemeshshape.png | Bin 0 -> 621 bytes .../images/trianglemeshshape16.png | Bin 0 -> 396 bytes .../images/trianglemeshshape@2x.png | Bin 0 -> 1364 bytes .../itemLibrary/images/triggerbody.png | Bin 0 -> 594 bytes .../itemLibrary/images/triggerbody16.png | Bin 0 -> 463 bytes .../itemLibrary/images/triggerbody@2x.png | Bin 0 -> 1051 bytes .../qmldesigner/itemLibrary/qtcharts.metainfo | 166 +++++ .../qmldesigner/itemLibrary/qtgraphs.metainfo | 111 +++ .../itemLibrary/qtsaferenderer.metainfo | 47 ++ .../itemLibrary/qtvirtualkeyboard.metainfo | 35 + .../itemLibrary/quick3d_physics.metainfo | 261 +++++++ .../itemLibrary/source/AreaSeries.qml | 20 + .../itemLibrary/source/BarSeries.qml | 17 + .../qmldesigner/itemLibrary/source/Bars3D.qml | 28 + .../itemLibrary/source/BoxPlotSeries.qml | 17 + .../itemLibrary/source/Graphs2DAreaSeries.qml | 52 ++ .../itemLibrary/source/Graphs2DBarSeries.qml | 31 + .../itemLibrary/source/Graphs2DLineSeries.qml | 47 ++ .../itemLibrary/source/Graphs2DPieSeries.qml | 17 + .../source/Graphs2DScatterSeries.qml | 47 ++ .../source/Graphs2DSplineSeries.qml | 47 ++ .../source/HorizontalBarSeries.qml | 17 + .../source/HorizontalPercentBarSeries.qml | 17 + .../source/HorizontalStackedBarSeries.qml | 17 + .../itemLibrary/source/LineSeries.qml | 18 + .../itemLibrary/source/PercentBarSeries.qml | 17 + .../itemLibrary/source/PieSeries.qml | 17 + .../itemLibrary/source/PolarAreaSeries.qml | 48 ++ .../itemLibrary/source/PolarLineSeries.qml | 27 + .../itemLibrary/source/PolarScatterSeries.qml | 26 + .../itemLibrary/source/PolarSplineSeries.qml | 27 + .../itemLibrary/source/Scatter3D.qml | 28 + .../itemLibrary/source/ScatterSeries.qml | 18 + .../itemLibrary/source/SplineSeries.qml | 18 + .../itemLibrary/source/StackedBarSeries.qml | 17 + .../itemLibrary/source/Surface3D.qml | 28 + .../Qt/SafeRenderer/SafeImagePane.qml | 156 +++++ .../Qt/SafeRenderer/SafePicturePane.qml | 163 +++++ .../Qt/SafeRenderer/SafeTextPane.qml | 269 +++++++ .../QtCharts/ChartViewSpecifics.qml | 123 ++++ .../QtGraphs/Bars3DSpecifics.qml | 276 ++++++++ .../QtGraphs/GraphsCameraSection.qml | 189 +++++ .../QtGraphs/GraphsSection.qml | 124 ++++ .../QtGraphs/GraphsViewSpecifics.qml | 103 +++ .../QtGraphs/Scatter3DSpecifics.qml | 65 ++ .../QtGraphs/Surface3DSpecifics.qml | 192 +++++ .../QtQuick3D/Physics/BoxShapeSection.qml | 85 +++ .../QtQuick3D/Physics/BoxShapeSpecifics.qml | 22 + .../QtQuick3D/Physics/CapsuleShapeSection.qml | 50 ++ .../Physics/CapsuleShapeSpecifics.qml | 22 + .../Physics/CharacterControllerSection.qml | 188 +++++ .../Physics/CharacterControllerSpecifics.qml | 26 + .../Physics/CollisionShapeSection.qml | 34 + .../Physics/ConvexMeshShapeSection.qml | 28 + .../Physics/ConvexMeshShapeSpecifics.qml | 22 + .../Physics/DynamicRigidBodySection.qml | 658 ++++++++++++++++++ .../Physics/DynamicRigidBodySpecifics.qml | 26 + .../Physics/HeightFieldShapeSection.qml | 98 +++ .../Physics/HeightFieldShapeSpecifics.qml | 23 + .../QtQuick3D/Physics/NodeSection.qml | 350 ++++++++++ .../QtQuick3D/Physics/PhysicsBodySection.qml | 34 + .../Physics/PhysicsMaterialSection.qml | 69 ++ .../Physics/PhysicsMaterialSpecifics.qml | 13 + .../QtQuick3D/Physics/PhysicsNodeSection.qml | 103 +++ .../QtQuick3D/Physics/PhysicsWorldSection.qml | 266 +++++++ .../Physics/PhysicsWorldSpecifics.qml | 14 + .../QtQuick3D/Physics/PlaneShapeSpecifics.qml | 18 + .../QtQuick3D/Physics/SphereShapeSection.qml | 32 + .../Physics/SphereShapeSpecifics.qml | 22 + .../Physics/StaticRigidBodySpecifics.qml | 22 + .../Physics/TriangleMeshShapeSection.qml | 29 + .../Physics/TriangleMeshShapeSpecifics.qml | 22 + .../Physics/TriggerBodySpecifics.qml | 18 + .../project/qmldesignerprojectmanager.cpp | 5 + 130 files changed, 5242 insertions(+) create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/areaseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/areaseries-polar-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/bars3d-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/bars3d-icon16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/barseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/boxplotseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/boxshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/boxshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/boxshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/capsuleshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/capsuleshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/capsuleshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/chartview-icon16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/heightfieldshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/heightfieldshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/heightfieldshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/horizontalbarseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/horizontalpercentbarseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/horizontalstackedbarseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/lineseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/lineseries-polar-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/percentbarseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/physicsworld.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/physicsworld16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/physicsworld@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/pieseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/planeshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/planeshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/planeshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/scatter3d-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/scatter3d-icon16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/scatterseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/scatterseries-polar-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/sphereshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/sphereshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/sphereshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/splineseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/splineseries-polar-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/stackedbarseries-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/surface3d-icon.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/surface3d-icon16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/triggerbody.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/triggerbody16.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/images/triggerbody@2x.png create mode 100644 share/qtcreator/qmldesigner/itemLibrary/qtcharts.metainfo create mode 100644 share/qtcreator/qmldesigner/itemLibrary/qtgraphs.metainfo create mode 100644 share/qtcreator/qmldesigner/itemLibrary/qtsaferenderer.metainfo create mode 100644 share/qtcreator/qmldesigner/itemLibrary/qtvirtualkeyboard.metainfo create mode 100644 share/qtcreator/qmldesigner/itemLibrary/quick3d_physics.metainfo create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/AreaSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/BarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Bars3D.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/BoxPlotSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DAreaSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DBarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DLineSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DPieSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DScatterSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DSplineSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/HorizontalBarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/HorizontalPercentBarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/HorizontalStackedBarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/LineSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/PercentBarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/PieSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/PolarAreaSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/PolarLineSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/PolarScatterSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/PolarSplineSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Scatter3D.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/ScatterSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/SplineSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/StackedBarSeries.qml create mode 100644 share/qtcreator/qmldesigner/itemLibrary/source/Surface3D.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeImagePane.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafePicturePane.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeTextPane.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtCharts/ChartViewSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Bars3DSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsCameraSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsViewSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Scatter3DSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Surface3DSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CollisionShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/NodeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsBodySection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsNodeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PlaneShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/StaticRigidBodySpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSection.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSpecifics.qml create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriggerBodySpecifics.qml diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/areaseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/areaseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..590aaaa284747bc3a5b9c132752d20f7f4e486ca GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#aGM+AuAsWH86HogcN)T{6 zU;i*IiX&vA_k>LsA5{N1weIe&cc)yG7jSQxAtrEmX-UkK2`hTodDu7TrM%g1R3*mcDvvxb#?!?9tshQ!^5O zU%E0!|Ij(D#Jy@fj7PYXw=*sKS~Zucr7);5OT zDwEvR1|PDQO|%hFJ600g;8gr_PwwRd>l=&aT)gz6kul@#wpG7uWUnx2RQZRAGz9l7 wxT5|zfp2@zJ+B8HmUSEU-Tz>`NaW{FHuII0lXA@WIf25<)78&qol`;+0D4=T<^TWy literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/areaseries-polar-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/areaseries-polar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af72238d692a5b7a18494e30af9cec88a61c5bdf GIT binary patch literal 447 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#aZJsWUAsWHC7jNfXb`W5D zP=9Un?y@XtYk@0^ycGIYwKzP|tw@~LA}t^kFx5Guc$4h$*I%o4c+6V;C*1h+-LwAw zCVodZ*Vu5*k65?(_t6Q~PUkntpNP`?Syqr&KY{s3W`XZ#{TQE1%d8t1ro3FmzUb|r z=ZCwCgSi!Km`*HOdSG|q?B}!3-@hj!YOsl+W^++3fAuu=!apyrCyA8{hy`qnbA6tA zMYHFYncdoA^+haZOTzcO$+quWU+dy2uj9hGrulC`-CZVzTdx=&d^^DBp*R2RdlrTi zc8fL*LsjYERmb1|&dylNy^3eL+Y|v|LE)qCm&HdZ+3Z(Ln&c55^tyS6T}zSes|Azx zi}ZgjSC!DY;LFf+R#IU1OL=RDDF-4GmIp1kBqjVbXn$FC2Tw{e*XDC2%gnpw!>l>D zmzc&aioJ$Z)XX zocM!vy1?b6whE!hNBRQ#kFJC>RSQKjJ-KQ>zn??l=12B*%Z@Lvq6j!c3}#1>7M9Q;YGNFj--M#y^OX$FRD;S&8j<=65+ O{_}M8b6Mw<&;$S;sc7;5 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/bars3d-icon16.png b/share/qtcreator/qmldesigner/itemLibrary/images/bars3d-icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5d75ad4f31738d8179ac9279ac4c7cd478424f GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4h9AW2CEqh_A)RqO!9Pb43U_cJTb|ERp&ob zzz^w&fA&dkVn5D*dT-zH?9%1ERliLqeC&TJAMxn%tks`%coG`_3oNbwcX+FT!HK9p z`+sm`u|*u+m^|;z{)wS~*o^-DYhT&GX;AR;-@Y2*MNj!Xp8bzv^AB4wZNCCzTRexe zBU4q6y`bLJ-=F_zpEl=J;53~w^QUe=U*}t0m(zM7@0l5PANBaHAY%=39fPNi}<&D zQ8k=?g*ZIG3c8mWbd%n*46-w}P0ZN} nNz)ZYI$j5GGEIAbM30$)b-U^B@YjDPgRJm$^>bP0l+XkK39&B$ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/boxplotseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/boxplotseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..25e9fe692ec8ef73759c125fe2f6a1e2250f43ec GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^nVv3=AsXkCCnlvHV5{5w z=lc<@jlEC*E2rfM?T`4EeD%Nwd9{s_dQZ3~|KNXq@6Y1iC6DFH7XK66(%kU$`vl!~ ztFo^1je!wNg1aOCbFg*lbIRT6jAdi!eQ0;yewT7F O$Z}6tKbLh*2~7Za6+e^! literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/boxshape.png b/share/qtcreator/qmldesigner/itemLibrary/images/boxshape.png new file mode 100644 index 0000000000000000000000000000000000000000..23775571c50ad52efe2d7a87c66e171e20e17c6c GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJo7kIijhIn+oy<(ps5-4!| zqkmuUiG^j?q9T`W*dVC8Wdny4Q&{tj6}3{1(#gt#YglxzI6Xa(R7Yc3fUz zcc6Mt_Rf2cLeu2_1+y6R%l~Lt+3~~5>&HyX&d58b&P*0Gyg%ij)VqhK@6w z1&rxRkE*tx(^d*I-hAfC7RQgTx5!!>1mFDM!MuW<$8p}{7#E#uH$`Gigas#0{oDP+ zX(^lZ!v78R3<29-#=SXrCVA@Txi8Y6c{TqR>q$@3SIWxuI$(O|K&p+L)%(X<^UN5k zEbtUg%x5d?&k_*yw&=2+S-Ilnp;cXs zm0bGV9_z(6%oE7bI)Chyj8XCYgYTn`McPPByn0adjk~>4S~jEe1lAh;FzMW*hdV58 fTw1@kj%oA9jgt>Ps6N5Kz`)??>gTe~DWM4f$Pv-# literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/boxshape16.png b/share/qtcreator/qmldesigner/itemLibrary/images/boxshape16.png new file mode 100644 index 0000000000000000000000000000000000000000..18707ce24342168b3130a00721e186fe45de61b1 GIT binary patch literal 354 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7H9cJ%Lo9laUbfAi5-7m> zAl>>a5EjJT1>Pp(TCL zEv9=fcYa)%^93b#z4EjfmY+-Y|93iu>OPjXOD<}B&vsAE@`cp&=nI^6iRvfcS6&R= z+JAPHl$zxEH{Ngm^(ps6xpsfxx*clzM%bgMhI0~UT$$%NOEt@Nt9Jhg3XQKm_`N{h zes*2Q$2~stH%v-dpPgeYp=z1=>vys4AMJJX63m*fuDX@=N%qd07shuEY^@aaDUj~} zc%bCc_E~pq>o;7F|H!Z^OE&)llXk_W`%a&$TNKL*raXBmq+)qgFD^MZaKEQrQqM)5 zp9`iZ%F2IWelI3C({5F|=eqClk1|7Tk2}wabtp*tRsV-|k3#(9=3)&a1_lNOPgg&e IbxsLQ0ARtFQ~&?~ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/boxshape@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/boxshape@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..596be65ae0f4f629aee5524e82a37c29bae852fb GIT binary patch literal 657 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4rT@hhJ-tuTNxM_E(Q36xH2#>tQcOvTk8D| z1_lP#k|4ie21YhcE*?GsK_LlAX=N2P4Q(S+%ka#+lG5_p=Kcwjrp=tUa_y$AyY?P9 zc=*hP%U5sRzI*?{<0ns_zj*!r!{;wwzyJ94=WlM|mqZ2zMomu_#}JR>Z?CuqA2twZ zOKkMbZxe7be{jLcw;{xX>BsN?^_=1-r-j`*z-jTs_U+S|7tg)%==gubC$)N}?us=L z37o>!(aRGAJAT_P6TGnOkaN#Dw$Jwje7!3q;x{TCd1orh`5{tp(X-%*3n5J zUCj0>>(1fbynKZR-Y6WAX$v-Bt>=06QF5hRfxM*cqbp4JYmOamXu4^(%lhgbt3|6W z)^Xo$VAxpD{Y-0f^9Q}D8jWf>0bIOO4l!~qYYLbZki@bucp7IiL%N+=GF{zVUe6gf>Kwt zo}D^j^!{zN*2#IFtnb^Z$KTuie0Pb%q{K;y(~X;LJLC?<#vJ?|6?ahkj^5HgFLEb5 zF;J739whhn(X~S1)k~+W?>6Dv!c)L6z5D3GYi1j6F8Wxm66tAl)A@e)viC(B9=>tS zQLSu9jyN>&RP8}CyF~8k9~Q1Y=oxb?a?inNo1=Vwk7d?9lC}FbGoiscv}UK@hLG3i zKS<0kWL*AB;((uKYS+s}Z7R=av)uZ(sQ%c#gZmEFCtN7GxbJbrB;U_EQS0t(s}%Fi z&QEX7mw4DxDQ3I=j^t*YDC20S#dd7#12?=nuQMwlXPWEx?EG>SN%fuA4#fL^TH?7_ z_f1~nq$e4gPaozVVqWvO?Pd%2#nPAmqqLm&99fb3vfOEY`f2~vrw-S?(v~L@N`^p6k*SxgiJ*ysZ%-50qM@Pr%W$epmZ#VwD=n(tNou;S7 zwdLF;(w<4~NL;Qk>C zGJ?x58yK_im?!#QY}q=`8Q)A>R%QkG lRH+s2>+O)gFR_nd(RthAMcdzcGcYhPc)I$ztaD0e0sxJ=b>{#8 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/capsuleshape@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/capsuleshape@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..048883c8571af4a8a1651ef8194a5c78ffc0fc6c GIT binary patch literal 877 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?FM#!!Y!P2$y695eo^9^cTknZXStPbn&Ta3@gUzBM z`fSpxzn*tptE#jsW3`hqYxK3lXJ(n^OnUc5?e-x%gPPw5_q^Y8e$VH#8_rwLc`gyD zcU*I6VUFhd%Yua^md9R7H%__4G4Gi24(9MPuZx)GKhE7FC3v>3=e9VL=2F8wZPkX& z{)WBIOHYScN|z^zuzyT(IrGJ;>^w`5*W?Pu)gN`{^>-L^e~E34z0n+8p{B(5#i-7o zCCID%v2so0TfvWCBX8a9V&1{~-Q|e-R>Kfs56!g)1!J0KD?f6X{w@0>uU}HJ%b9CO z3LSd`561N*yKg_}>>_iVFQ)x@R`ZHe4qlnUbq8h(Zroe;;n8beo34)?7T4C+=CY}! zeEO~Z_V&j8KW42k+_$0V!rF{S1vj16AFRsJIR7>G{RNG;*SFp0{i8FV_w1w3Yo{t1 zG};@qN{hYx9$tBGtH=EJAC}j+mGnk2E&k+r+bXyI(DbFUnr|aq<}^*YbX4MSTIK7U zt%fo2H9c2Zg1i%S_Z?4-XzyKm_x`o#DPAiT_4|2ulrY90f65aRE9{}$xNJ|2TH)@U z`3r)jCmLUVaUtsdf!7ros+=4(Sgrr~x>vXSiAC?SibH4kS;Wrk_PvrAnKi$+DLi^Htc&VmFP`rl($KEw|~1spocGaIM(?BgT*^_|uuZ*OT|$ z6FRla?W&oSp#7s%n`uE+3y!fbnId<@Y)?qA^n&fh3F3W8@m`sAo~52s-j>gg(YP5a z?PA&(bh*kY?z#N3DS4LBw}YNocW4_%M$0d@PrY{h>R|Av&}Ln$c+(ljtOY-M?LQWK?zG(OCo|ifQ=dyE c+5KbX5%?}YGv#mdKI;Vst05gfABLDyZ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller.png b/share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller.png new file mode 100644 index 0000000000000000000000000000000000000000..ce18058d3aaa7cbe00bae80f87688302c3c5fc7c GIT binary patch literal 428 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJoi#=T&Lp(a)Uf$?EEl`B* z!+r6r2@e!fSQdIT2RC0(di3hi6@fX|elg!#a&nnKXHn54CyrM-i!NM?Xcl16-RjbO zLFI`+W7~!6AL2e7{!(lIHkwI($DQi)59d6eS3Li)TeR39^NJ<_*&xd*N%$d=?h-+N3Al;OYpn; zJ6mw$?GGE?aaeWKB{Hx_99!J+rRRD4T&PfhVt@Bp>xVj|r0 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/charactercontroller@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..faa94098d7a307e09a2209305c49c7e8057fa721 GIT binary patch literal 831 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F|tx^06#@8Qd$J|=}qxz13VEwkG z+gGjatE%v;fBsM^CqFnxgz?VJ4K=P?q#V-vByE0i$6Q;Mwwlr9h|NB^pxkA?X9IN> z*7BYXKcc}@!MdJbmR0o4R$3%@d8+9Wp=B@ncEu+%TpSXFOwi4-0<0%ynz+ zvHOCByFzvsGR*vGG4HLR?_*P$o(^H=TR8{vat_JJ^>mbbf01ULFw^|uXU4xWhof&u z3*Nu_H9S$eEWy|RZg7OS;PJ3m&L7p*&80qi+0_+aQ@2;zsIgVZb!sh>m;;uz9-8^KT5xvp`WVna^&0@n-{y&FHh-nMb^Pdix7il*}IUJ+G6$f8V9LQSIi7;8nN3FOvIwcGdnu zr6j5AtBo%0w2S={wd$^SrqTAetuenooo6L-PO&XSkGK{t$(;t=f3kwz6utu2&fixRd=jyk~vmt`;2+j@`w4k7TaQGsT2!WgnV88 pmccILlg0ZNFJ8R(;r~N?%fwTvIfb`P7#J8BJYD@<);T3K0RRqAk8l70 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/chartview-icon16.png b/share/qtcreator/qmldesigner/itemLibrary/images/chartview-icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..b135c25908c048315ec37ae9266ad5a1d939e175 GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4h9AW2CEqh_A)Rq?DlkV43UrwJ$TlODUgBn zLGfJUodtDW0;6&b5% literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape.png b/share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape.png new file mode 100644 index 0000000000000000000000000000000000000000..0837829fb5ac90a09e4e10bf29702b0962aa863e GIT binary patch literal 745 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuL8Hh8)?hIn+Iz3ROpJXM7C z!~L(33A0?A_c*$IX*%QX;;%i|B11v+h?Mx%BP(45Dml-{39(page<;sVa~7@0kCM2`R;s z{G)@q3+3Gk1?rRR@2y*<>MR*@RVwGmB$f8+=i!eJhV|9%2o3)|H)3|mnp*Rw?Hib` ztNyH-aPZ8ux06Fl>t~C39+O_}Tp=T`QmK6MUz`y4MydD*(sPX8&c4cQ(bVjDE%a(o z&YD&F8@Joe-~PsZ)vKsGJ)xnd!uwzU`phEs_3<~xWm4RpWy$5Cx`(+dmj4WUWbiG4 z+ikh`746F&_IdkV+}RjZZ?>-Wyry2s6TQ*aQ}t&0fm<`==K7TgB&>RG;VfNtuy1b9 zL3>7tWi0Bc1x}q+l5=}yOLwX9M}@{NxV-qb;r3O_Vz-B0UCR8|qVM2?8Ru55lH4J* z{lO-&FAR2v+JE?zXP>{^`+l!(qxj^Sax1pQR&#H*e*YkJO}%oRVPx<1(#6&@pG+*X zljje;$~3o(H}ymK>5xg`RZjy$i#LdvC-HC_Musl-tn)DH^yN*Mea}}etT~ zOy1JD8H#2qKT9>5eAVHHYcx~Oqz4?Qocj^!@t)q{O|wEYt-_WNt5MKIs*d(gQu&X%Q~lo FCIHOwSQ`KU literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape16.png b/share/qtcreator/qmldesigner/itemLibrary/images/convexmeshshape16.png new file mode 100644 index 0000000000000000000000000000000000000000..9a411ed9fa71aa9aa676e9683228aef80a0ccb29 GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4i*LmhONKMUokK+3VXUZhG+!$p0f3xTF7wh zVRXhS7p)QvgM}7>i4znYotqmKUG#q1xL>SUSj4H)*T@p&lz4*CckPt6V|wEDF01Ds zegELYa~HFp((j(`o3wfP?T%&q-@g2>|C%w|EHfxK{&ar#@(Ho)-$a$FemvA6JNsY7 zwVmyD-_Po_Tl^Nb^Gw*+8YTM&K=W^K3H0S+Ro@;gl z9mwL#l3q!$MW;sna0o0 zd_Qg#sh+K}_@8)p$}@{M{cj7xT=s0-RY1jpGx0`9u9}Jyq4J2j=cw^w@Fr~yX?7Slx}^e zwO0AjzB6-rRu>2^d$iP)(MYG^ObmZ`a&!#?e}ZH8!TxP}b7nr)KJe^kN$hjcJu&ky zhF;IP)A(K^&{Fn#KZ}PxL*H@p4Wf0;!OD+5{>pQ%*>d*5*}`|#HE=wXG^%_-K84rXP1*6Hc^Cnh`np}t^YYU;-e_poH~;aOj*3mErE1^4 zPI<<5gM~dor|f`*%p!|YzGaVRow3nSnpPfk&yZ0K5BLq7)pVwvXXTDTpzvHz(vQ58z-l49fmm~c@_>O?!^zw_9>i^mn7uLDR+_y_BY2VpB zm3J$nSlY9jGj~2Ukcd0LV$-dy^k_%N57)o7dlip;Fa5FCux^Ub#mtJBl{w8zE~~|@ zeDWemX4RDKt}`v8KOW(BK4ZD=-0UuIqtAz;*sLXYZ7Tg6HL2WmLe*pu_P(%lU5dGH zSr)9Xlo#|*a7&vP+^BQrjC^vK%bpPN`<|9PWrr6>^qutLj5~V4s!qi0(2+B90($=n z$Q{c4Vd@tW^rLdmwS%0o$_C3ygIsLd78@6<`5jfBSt(f8QfZ;ABo@w`{&)u00{&#< zV*k}u<=i?!ULQGkSSwB2#wZ*7RwAUUo%zCbz6Go&7F!q@m#=Y{7nJo=d8Q?|ei(a= zp|Nna=Jt!sYhK-b{2{_6=E6a?(DPNg_3kVWdiCDB9#Nh#ZRX!oUmvI)T^$|LJpbsl zAHx4c1=Y8oJAY=~>>cYqy2)O@I4w`pBx?ujDx1YIFP?3cwD8)=m$PclF6XruyZ?!v zvNU>f!!LEq%_DntF5GwYfBevI-n$vsb2m9n=ip&qFrC$^a{0#sbB4VZ8B3WGTm&=v z-o%N$c)eh`VL^aoZscR%{sXh;I_2Mz%TT(I&9ydq0r2k_(*D=C$t>{1|mRXtii#=()x!?LQkB-@jWJ)1Dt1^e9Y5N^t!) zh8q5D>%PyF*E(~jcjivRbqB61C)qtqf2PMZwJ0fVUblBt!H{t%*SPo`l;61I>JKs5-s|fQ#Le7kyRSc5>CvpT1eZI}rLs%5Ea*1+JmZW^ zwnD3$Ok=a?qnBRRN&RUn^2`)!sZ`d2FYYAFPdas_Ve2e*g zu+|YDpRNvLs~%~-1HY!q%x?LvC42j4SF)9t%bmu*ui}2{?ptP2G@-<6;ZCoW)|}Pp z&(y0JC(L|o{Q1DGt+L&VryQ#(Uur#jRls|0<6<|}9lIDaGiKCloxPy&(k-X=@L4aD zUj>~`akjzt^A{{RWWKs_3fnTpI`iW@IxKQH?oKY4<@Dj)kv$z1dvkr9Z^w7lCp=%c z>sv72s$;9q zZjL$mQtkNr&W_a5%k!2^dEHuJro{I$?Y77M3q7GL4hK)sK6KQ=Y32RDUDxB+ocAle zwR*?)qc?6VKUyg^ckO)%sfO7ad%vl-FE$N-EggCHz-1Am>_pb$1w|Zt*GxHcyFl$+ zo>_+PeA!z)a~C|RVlH45`}%8YTCd%wPzCo8h0{|{ZC)<4(606W%n07xp15mC8I$ea zF0VMhDa>y3wcVET`)H{CphTF}K-i_Q!k6v!wn5LZl)w+=N6SM03^@sk>wewjs gx%5-L(tpOl$QKU3yK>GkFfcH9y85}Sb4q9e0Ob~*asU7T literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody.png b/share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody.png new file mode 100644 index 0000000000000000000000000000000000000000..4cde7a3a27c0075f70fa36069dd1afa78a71220d GIT binary patch literal 414 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJoQ$1ZALp(a)PB!#D93bM> z9~HeZ?`6VfF22@9yd9I9x?MLexE;%SG5(>_KQ31Fc5{#RYez30T{Jm%&YF_dPVwT4 zFF15HuQbv1G;Iz(S8>1gdriSk0byZd!EX^-Q_~o@cdQRvou|?mlqDJ=Rkz}5R`%Jn z;`P^GFBR@=Irp?^`p=qwnJd;RDXo9Z!dAep^R0W`>ma@9g)+~V8%{nMpd;4)-=68U z(kD5U86twbIgI&#la^op$jhFw{kF1cg5-`MFJE>p2A3zSHyG`HWnO-{W&K4H-$^H* zoM1R!Xx8{yp)voY*UH=lOg>wqbYFe7ipt(}Q>WF5@%FY%6RCZS+j5gfhua%Y$roGSpr+xl_*NOxOBY8&#fvTs5{|}4LZ!9MFxc=TF+xBwQ>iHGhdkobNT&$X~>}6u)wBqZfuPyrWWskpX zzq+-#(ZpiB~tUj>m{qMOtr#TJ_EERDLteLfYopRSA^#>6yaqbO_ zMGQ6!?~c6BV-TEp^~GhSO)TdcwsRiPEZ92nf%hcu2Q^Han8bwV?O#wXYZI&;(dpa9 Qz`(%Z>FVdQ&MBb@08SQwj{pDw literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/dynamicrigidbody@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2a8579e4b04983051c031e6a010f2e4b89574549 GIT binary patch literal 778 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4rT@hhJ-tuTNxM_lLCA~Tp1V`R;*az>+8D$ z6<~_M<*`Z;BM4CgAt9zAv#~k@q70dwF=Ga@%IfNBWLac3n&JNb{t#JTUtd2zKYxG! zfPjGT@bIXpsJOVeS?mrsn46&d$#M z{{9IQCQP0@dCHV2Q>RXyHf`F>nKNh2nl*d&?74I2E?l^9(V|65mMmGibm_8X%a$)+ zzGB6SGXg)&7#J7=OM?7@85o(Em|595I63(QghZreWaSl}uyXriv*tSOm8reC!B0~r*gv|OW|>xfXtl|tkjKrRq*9&=oC-7bJR7hs zqPl%klv|K`l3(O**E>muoa^jd=5GAPk*hYn<%*(9O!1v_?E89CCrvQri>~OODzN3Z z0b8)giP_C>^-cu-zIHnG&d+zPSDk}S3gw(7lGb&>k7b_|9xh)l z{6pGf)pzAagAIYMLDD?ayggsF9jsyGJjrY@Fa-%-+$ZQFFwDtU2dAK)XbX)WNUP*XMf<9KUKvc z|55VwM#=LR55~CMStb0UyMu3Dl9|%Ehb*%!f+N z90~PFR=ze(=lk>tzi+gkuISmx<*%)@OuRH;X8iH$H^&kbZ+EY?XlagUmu{_*i}zA$ zo_TYPsK(N)MX?hmZV z_q4u;2ZNr^I9RA7BEGz9vUY`t;B>LlfWl7#$rioJ740j7rq$i`o88rMU-k3t3Q0ld zjPz$NYn!_!FTSxddR^j~N5MO*8P1n@Z(+>-lYM{cuK%F0vi`@=Ii+SkiGY|Ur%C5}As-`LaGZ9GHd zpu+r*cU9lanZY_O#n(pq$A=6( zA>Y{bMgF(e#h&clbHpUQOg78)h5L&WGMPtB%-ic`*0QZ@HS@nG%A6+U2&jzfAvkcBt;) z)L%NqZ_SpyE^-g2&z|&ddeAP_rB_tn_h)_bF6hfW{pO$A{n`q?-w!5FxpZ=`;Dt-E zsa`MRd@@(v>iPbpw!rM!<4;~Ul6P1unThx9oYCNGVWxC#>aWNha*qoc=4Cv(p|50i zi}j1j0@k_Kg8wbvb#&aHofKUtzO3wWonqb*nV(mrB?V8Pva1qgHn38%`lYf!<&whN zer}~l=a;c8e|YWE7sET9#T$1x8E^b?{SnKX$dBcZrgZ!;S!%+NpUAr|LxyRuSimIN zhVl=RYA!C}E9E;*8|s^jKvE$Z| z#3f1P!ffZ*$=!YdkYN;F>U$k3dd z6&thr{~DbUi~7kmuhD^I{x!`SWa4h z^m2r{{^WZJ>tD$&DrdU2Vd=^&W3iL++dMx7?c!*zTJVFHKPk*5M`O<0PpO-n_Z{Rr zVo@nMH~!JH#H7b6Z?-mEdYDjYvb|lm!gXKOp0>XqCf3MWS}I)&v*@4L|N5z*;i^a0 zBJUs1?3i&Wow4-`$In-P3tViXu6<#uWD$S(spH3Dp<)5Mqx(Jy{n_zIUOiq-zN2He z_P&J`;^k)X2di}#OyHYt{=!sn;yg7Iawb6ZpRVhJZ}#`KS4Q-kQ>8JoiueUpn?WzdLvR&Z(a+Z~a)4`{$pb p(!LwAJFkOtEI8|4tp3CMM`ohl!uzY%F)%PNc)I$ztaD0e0swLvA^-pY literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/horizontalbarseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/horizontalbarseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7d3ec403451a885d5af983c123e6daa08ee02d21 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^{+=$5AsXkCCng=>i}<&D zQ8k=?g*ZIG3c8mWbd%n(k2O|#G9NCT^?tQX9RIWXo#No7chLH7%tu?Ys n%l;hJ`^>-psmiZp^)g9@f0IprZ}`1I2V{k(tDnm{r-UW|e4;Xr literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/horizontalpercentbarseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/horizontalpercentbarseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..16783f7daf490eb1e018525e7527b6f949bcc70e GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^ah@)YAsXkCCng=>i}<&D zQ8k=?g*ZIG3c8mWbd%n(khfii5E2UV3W7v=UKe3T{ev8(f43o~=1$H-B zUu$e=Zg{Gp=de}gRb`Rx|Mu8t@~fV{*7$tf?~M_|w{@0TDJ*(QAR9eh{an^LB{Ts5 D=;Ap# literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/horizontalstackedbarseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/horizontalstackedbarseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b6fae651112b8f17c51415de4fdad7e0bf61197f GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^@t!V@AsXkCCng=>i}<&D zQ8k=?g*ZIG3c8mWbd%n(khfii5E2UUet{qhQH!+#rjx*GtT6WoyTn+vl zdzYj2w<7wI?7N2mx#G;~ zqIc6pmK|w7AN5CSd;LO>nm_snK0Kc&!_B<=SZ+$E{CCOwpY5KBGO$kh<=t{*{_dot z{(hs3MoS+7*?c?3sj-RElLG#Hp317}vF~15jsEXfv$ZDZf8*0!Q+FpYy|(7-{-6F^ zHvFn}_xUyV5xZMnN$2iAlN{O@(iDnLJmPS%bd&jb(4&aw-4Q)z1~!r8ubsbRXM;TF M>FVdQ&MBb@0A)OJod5s; literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/lineseries-polar-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/lineseries-polar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..611b09f9fe7ba851b3c4e91b6e1f2cfa2cd61830 GIT binary patch literal 440 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#a^`0({AsWG@fwBIF90X!m zAB$^cg{)!SKXHYNunQx%RPqw`caeLorIyOO*L(~V`uRUE^MLrA_Oq&+&37AfAA9E_ zvEi?&pyi1z1uTlk{m&c-^C@`x@}EO>*YP7_IeeT~xntb5j`LP!dE^{oTl{UEn6l== z-4~bhMyM~64v~H=Y4ai|w%xSN>+_<*w{7?B7kb}~nS4uXjnO^fijv}hs$kiN?R8zN=}RW6%>-~#qsf=j^4atUB%x?oI&RtPM$7v_j;MFwY)!QRin?rB$d)D zV!gjEv~PW$sIrxV`(nZ8)|orI!1^^|zy8!Dr=XPRyDFMBw_Nh3PNFu;PpIOW4Z zllM;XS2l(259;GRcTmT*Xn(M~-^3cZ`SYef@<>ZO=C&uv#xCUdA&sMo=Nu+=Jd1zx t^|r+~6_q!g?Oq4A*nZq{+2AXG9iwLG^d;6oO{YOo;_2$=vd$@?2>?SQyj%bP literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/percentbarseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/percentbarseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ef6221f6ef10eca9c4df6569aae7f8584d371bb1 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^ah@)YAsXkCCng=>i}<&D zQ8k=?g*ZIG3c8mWbd%n*48>N4mB}7?{ycS^DIZb$4M7#GRGlA8QOtNJ4 zIA@rxIARquZLx&^Hv4~nkBfI$^ai=AazyMC-p#|1dd)H`+MrhsWTU66pUXO@geCxF C?lm(2 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial.png b/share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial.png new file mode 100644 index 0000000000000000000000000000000000000000..9675b1dfde73a8e934833801c6c321a88161d3df GIT binary patch literal 559 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NILrI(6!_Y15`ppFU&8jF~fM&YCrA_Uzen=FFKpckcZ8^Or4KwtV^W6)RS- zS2*usU|>)w3GxeOU}R?H;NcSzmsU{IFtl_Jh|eyn?Vh=I%b~+p?mmD0=F5-Yf4?o8 z!OFnEu-?9*!NlUbJ?H8#2U#NwnCs6A|9ZrB zY|b4s@%4JUGJ0qQg9Wxju;x~4^*rsO}_4n_>W9|;(7g`KeGgfLU7dd@acyZ{G*Ai{N&}(-p z6{q}J&|Q}L^UC4l8(T7^#rGVLc)Z@bBo1Jd2=l+?xA&72q*7#KWV{an^L HB{Ts5uF(wu literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial16.png b/share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial16.png new file mode 100644 index 0000000000000000000000000000000000000000..951221e57a45f09482b0c6f9ac7787121c01f41d GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4rT@h1`S>QUC&Z3mMmGcXwixlE0!!-GI#FWIdkUBo;`csym_-`&04f*(M&LCZ*TAD=;-R| z>hA9D>FMd~>+A3DpDeOk|rp=f!W9H16vu4ejJ$v??IdkUDojY&d zy!rFzFI>2A$&w`@{goi6%ajE91v4tGHH(fMK5GLE}ZaYRw*+R&5inZSi&yP+cFfUGK*lWkwhM_SK0gH#eSdjyO1* d@xw~#31u81mNTBNWnf@n@O1TaS?83{1OS~nr6m9W literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/physicsmaterial@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e50ca8edaaa3f1698093850aa08c65a9d3977980 GIT binary patch literal 1095 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4rT@hhJ-tuTNxM__XqfdxH2#>tQb(ReED*$ z_G5}KTefV)iWLhMEI?L2fByUxD^~dW`uh3#`TP3^1_lNN1qBBOhlGTLhK7cPg@uQQ zM?^$KMn*U3S$0sBtBqb#!Cnu+*q@<;#rKhK7WMpJ!W@cq&WoKvS z%)Y6ciK|78Vs16&Dwml$4Z~mX?*3m6w-SR8&+}R#sJ2)z#J2*Vi{R zG&D6eH8(f6w6wIgwzjpkwYRr-baZreb#-@l_w@Ai_V)Jm_4W7nPna-a;>3xQCQX_= zdGeGgQ>IRxI&Ipt>C>mrm@#AK%$c)h&6+)X_MAC$=FXivZ{EE5^XD&EuwdcBg^Ly~ zTD*Aik|j%)E?v58*)mA@1j|oJWME)$DhcunW?*DuVP)gw;^yHO5tEQnP*T&-H!`ub z@$e1^PE5_tt8eP;nL2y^!lfIw?$~?$^tns7?%sd=^u^0JZ$E$i_Wk#tzkhjz);?!o zVEpRo;uzxL{r1xJ@LLHo#|qcn-CF&A@7sI3eOE4OD!CEnAgRQwd&^0|$R#aE$mx^X zlb_AMtJZ|)^Id;yX=8pr=1K9_>ezMve!YGle{b4DcH6Sb2GQN}Oi^x3vVyP7dZ(@~ zxn4Yvbse+++Q9GC_nAICTzmg`G)K|oeJdIn%wP6Sy3F_J#A#RIAF)RDFB_svj)+~* z%viK(*7f7EM>rk0&Ohh;Ybz&g-7t@b`&HB}eLm|BV~=0L9~}f|cJ4f~rD2o$A%Fc_ zr{`&$om|WJD9O8hS;i{OgA;fpO(S@J`Cc|zT5TO^P{CVi{=ED3ivEJfiL7r6^GvQd zRQD{a%$C;Pb}vWOBuF^Lcu_=ej;!EL?Wdr@*g&0bGTN`Sj4&Yyj6$u`RNRY*F;oSea>s0q9d?- zm3Zc^(7#KXExxfOo|9h9q`5tP8^eDJTM*87XxGVz?{UL9djz-s(&=S&A#d$mOq*Q;{O zyLn@}jL~Yr_iqx8E_*0d+djdx)lPLqSLE`SCsK6H%{C|f&i!)ZD({*brTeGvIKXuM k!oRrNFBE?LmjA}S`4218^*Fyf3=9kmp00i_>zopr03&cBpa1{> literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/physicsworld.png b/share/qtcreator/qmldesigner/itemLibrary/images/physicsworld.png new file mode 100644 index 0000000000000000000000000000000000000000..5d0c15e43545ddff103200ee6a5db41377f0e64b GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJo8$4YcLp(a)PPX=D4isqJ zzbAx)<=`=aponOWFt%=ygHDMD4<&_sV2_B*NX}fJkf<#vxJLR zW{W0mn!wtfqwr+oZcekN<-4Dso0-4kPGkLFP02PvL!RWsX+9}!&)N^LZeSB>TphGB zh4pEY;_UTIsS3!T&<(Np|Ro(>xAsMrt1#Z51 zhefH=<&p99(|6N1-(1wOhn-QZFsEP;M(3K2?K(fq}u()z4*}Q$iB}%%Zoo literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/physicsworld16.png b/share/qtcreator/qmldesigner/itemLibrary/images/physicsworld16.png new file mode 100644 index 0000000000000000000000000000000000000000..6ac979abf7bc1245aeb195f873347aafba6219b2 GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7nLS+`Lo9l)PTJ^oI6ztAK- zT@%Ax*{?qA=N>+ev-t4-YP86aLK}v>#@GjXo|D$Ei>v4S!zSVT*RJ4RXjC-Qjai>> zcYE1}?qygaYw_G?*0Ofjz!@4{_YN7zbe`D3eSuxB@p9RWRLN^muXY`adfgx__%maV zf|6z?!MsgaYOTi&bQ^PNHZz~oi$O!a0+hTdh2YZO?pN^4Friz7pWVOrQ{#>{)hJt#{%LO^v3G)+HM@1YBU0{`fx+`h+N!*K2D1YZVgnd3hb4{e?nD3Zt4v6FL0&Z!F#jN5Xf58P|`w7@Ffr>?Qr z!E8ZUw`OoMt3{tNFAw{adZVY=zvL^DBc6A^WXfZ>Uuz=YkQdxGZPhjAy$AG!89)E5 zS+#z>ezcC*b^W;P+}yu+Z{D=LdEr6;(>-Q&*A%_J`K$|8y*=Q5D%sv_X;A0Ghl!tl z+5`s℞1zx^?Ttix&qrt#UhGE4WkO_-Y~F(DI;vd(IXzG4=HIUAl9}$7=368)+SLoFVN2mQ_N(F zTamRwGd7zqhOO!l%V(SZg$ota($foLr#mfVXn4KL$ImZFL!=;fdsxTW1Ky!$S-!?> zZ20-FhU*2l)R|2>n{Mh%OP%PoG$SjEX~ioWU0vO}#4?7xpFf|xf7yS*s@WRi8+AP# z8j?18Sj}Dc>Zh@>am76M+S&zs80ImkyDUj_{&?4`;{;0qhs5X0dKYfo*in%X7#=RJ zR@v~_VfuWH3vnJUZViVIgv{XKDR2$dzb4dT6}0M=;sM5KZ;HbvT0WT3p>sRH>8+dV z6VZZmE@6rh>^4DH&rKC`R#dt><@~*{c(zDqhP}Pj*vW) zM=}}bnDrm0iA-91pg44GPI2;G?v+{0Po=lpe*DCBHv2(G$Dhv9B_b0uPrdy*d*YU+ yVu1>Vw!CK{rtX#Uo3GXUWS<94qnyuvaO?QpRJMQ7#=^kBz~JfX=d#Wzp$P!F1b6BH literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/pieseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/pieseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..51a61551e74a6a0229a3a1dfab312486dc3a5ca4 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#aik>cxAsXj>zRM zz)_E?uu(YdG)aA}D%dh#Oj)jF6t#)u|U3Jx28xXZtuu1O91dAoU-7Fuc zN!#stfBLtbQN*$rwWq&q5b#U6r7e2UWmzlhlKKN7j|$cp=6Ih|IQj45hIMMY1NT3! zW>PpAwe)V0_gA^8MbdBce9xr!obqjyWL#Bg_o=v}U6*lLpK3?5a`ZWcHQEkR6IoYO zy*QV!hqpm8lHuxUnJt_RA7dh!eg0-2Jb&=j$5U<(^mFoDxF&TcXjj(nz9u@g`EL0` zwRit!Lw@six^K|udS?83{1OPEG BoA&?! literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/planeshape.png b/share/qtcreator/qmldesigner/itemLibrary/images/planeshape.png new file mode 100644 index 0000000000000000000000000000000000000000..4d8f3b4136dc1328aad06341d356046fa3e830c6 GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJo7kIijhIn+oy=0xk7a(!$ z56Y;pONC-lkFkgNHq(p(*-eOm;XyOjkOMmei@Pf*AV zy52fLuc_5@iqyGGrCaNZ+uujdpYz@J{Qt_#6$>@jdwH$ocK^sHnsdax#$8zKk?u0_ z_sn$(nsrIuExJyv8>Uc|e51H;vhjDrkuE=T;{=-u1caihh2healnhvwM> zn?G%yo^j0V&SCvGhpYD-^2#~-_mQkazRR3B28=F8IKCwbwiSp?ztFV$g~krHLbmDL z>$Ef6qrEcy@3JI&X_`LfTz7g6|I~xFMdHr`CRf^sZ^slJI@2wBjDKOgr%=|FP4@wyy0mrwh1a zB|J1ueLG&*$K1WqZ+GU1qs>wEng6A}h_9FJH`MuVCcakC&`9r~y{A>7aIw-O3$tY1 zDy1ZLp)}F;qS67~9d9c_3a-Qt{%RjSz-ngn_aYVcH1MN3msH%v5=;H^?lYwoq4q2skNZnuZ5PLNS#B(K*b5ihUA4S{U>ckkFY z=FfduGH+fn-~W}J9f5lmFv?drOTW9=YHjjRYiY@6=>P|AuZ$x>aaga#05^HDi`~99j~JtGtTX!I=kn%} zg?9O4f#QgxI(?r`wNAP8so&96&9L`cjPZ^GT<46}NHz;@3`m`z`)Xq|Z_nd1*UQ;9 zOjk_xN!ZUdLD5y@V~^jRMauUV>doH&EcAbk9pl97wi}whT-(6Fz`)??>gTe~DWM4f DM74UR literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/planeshape@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/planeshape@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fb26159279819500e31ef1ceaaef785b5297c4 GIT binary patch literal 1084 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?Fq%?K>-DLd&HN1rDc8hf*UW1Y$h}0@G%$6b-Am=pf+2yfXLjqBSk= z*7Q8f5RlS1JY|a|>uI&ON$>r)EmwZ|b4A|0=kKcj@A(~lKCXK0)_5t?tSc)57rXUJ znf}^;Wn$2*4)%?*?-R0*vOj7$bnn=DQR$Y)8`o~QuVuDlgMD>^b3shx>pLAcE=*(e z(A?X?nR<~|^})2ZX$jkt9?NY={KWRBY5nev%!Lfs7HTW~d$G3BPC!t2qr~4QIz3$- z>pEUcDu3horu%wzg1_jtRbTfcoxUiqU7etPp_9Ez`VSwoYxpD8n2z1i{K`qzddF9D z+_~5r8`k6Nt$B9!4Ktsk(KF@+?OK{tpTu?VXsG5=>FVqSi~mgwl4>$94B<2htuPRK z$Z_WIrY>I1HNx8;%qKu1{-BdgQZaOL5sh?Xw*nzrR0e z-7ncNX7Hp~j_V zvo%{;rH|61$e8Yj5fg)?LN=!EkZTt;+mPh_bWQ1_pHnXV6OC56e&WO-wvac0mYZWE z<^{dlZ_QRVvvFFGm;M8rKONuS+&S+qE^PncZ(dGM%#QnyoAcg8^c*Pvu|Zl|JO7qc z&%fo88?9TdR_d57`BS*o-&?@h`@mK^&4c`h4e#DKzUd`%VTt*-iF+br%ig8gzLGa) zP@Su7$oE+($?quJiO-Kk&h&NM*4kztchGZ&q+oeijzZYU@V?hdNr^|1UorFP=?MLL*w*X-pYZn+<`*)5Y&-P)aapBXjFxzjxA=*f(cw4z zMR$ATZH%90nk`n8{m)0P#C{vdfKaAdabcw-@1xHig#FwxS5(kGJjX6?+Uu8ZI&MU5 zWc@THuC-X{(e*CfDbFu?{j`2$erv~jmm{(j9O}uLUMusDK6_+1r%hFJsh#L--S`K` zk^{X~-a8__Q6&Ar#=JLHKVQ{}$>rI;DP>bwx@EeJvem|$=Z-IR-k19AKC84|y?f52 z^h57934SU+eOl0Pqb~E&BOH4o#A0>%7f$ q)O0`gb$RChK)Dc_9jn&wXXvQOQn5c@*vi1bz~JfX=d#Wzp$Pyv5(U`+ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/scatter3d-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/scatter3d-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cef130816069c9661f525a0a22af5309372d4369 GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^yFFbTLp08pPO#=;G8Ax- zmlBjd=(k1C)@j3Mrg;bSmVWo#{Zz*3gTOrpog>F?IYp=@Pi!qcJ0s~+<;==6J8m*$ z@12w9TToE-HhMuB*MXAjm3r_ba@) w-WMCSpIFLP^ZCi`pzX)!pL_q!qwm`WyUsr$ZVOHb^MJhL>FVdQ&MBb@08gx8IRF3v literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/scatter3d-icon16.png b/share/qtcreator/qmldesigner/itemLibrary/images/scatter3d-icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..2c456788ca069c03bf9a756b6816eba90774bd4a GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4h9AW2CEqh_A)Rqw0gQYhDb=V9yIiF4isQG z(3qnW9Laj{bk1*wOH~WE{8u~l{*c@uiYY~x300t9)4W3 rUH{urm;U?K+}yHf%PCseeA%FQs3CLldu6{1-oD!M<%vVPe literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/scatterseries-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/scatterseries-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8be289d6deac39b2702fd714dba3b728e0690b11 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^wVp1HAsXjRd3U6$MR*eiprV~{suGme%HNWnCN-HU1!GoFYIfW z&pi)4sPsI6ZFF+t_FVdQ&MBb@07^PWqW}N^ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/scatterseries-polar-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/scatterseries-polar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..44cd8d72a66062794b2f7a57e3c5c02471a115d4 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#a3Z5>GAsQ1)CwgWxISRCD zOJ7_gb@ChE$@_&&@#zb8P}gw%ED)fd^@t)ww7T@>Gan#Ufo$M%;5hm!ZAYBe$S^(Tn84P)ru%hT(9Uj zp<$+N$PyuiCv~57StkhD+}OgE-M%Z|R(H?a><^_0S(CL&1%9dSII@ZVf~s0sys2an z_YRed zh4RXRhN6P@g%ZVr8^r{(D_Z|`{E!r!Y|;KQ#&5wQp7*z3MJ>JYX=c)pirZ)e%krmtdqj|<1#>`Gu{SAJBt zc=MD`9Og<%irDOr0WWAKWvz$c*YaaylE_j)! zdNYW(Sn{->;r6La5{F$hpI#8-nk5&PbiCN~=CbAUo3o|1hpew^&syQU9i2VBef<+APMSPt?!5U67A{)6Wa*~OTet1pwR_Lreftj_ zIeP5)sk7%VT)cMu#?4!|@7#U-<*!twPs_{; zvKwBfzvs8UKll94Lzd~!>-e3@pYQjZKHK|=_SBlD;_|J1X>*v^G#LNXCLBCz(l0OW z_{g?)=A#1#LU)}%?5)se&Y9kc`W-jJN{8@S<7;!pE`e)hs-}rnUVfs*0)5-ip6W1J_Nq( z2*^@jwpb?IO1v$!`Jclk=bx(=c^tf#|FnIrr^N5&|Eo8}Hu@j%cVv*$Ugy4P#eX@! z8$k=j=LLUY+OtZZg-_OTLeAGDHcg2&%kw5b+V%5b4R3Klf79;|3!n8QzKz*=F!=EN zg}y80>=std)8lPqo)q}|!<|cMUxei6i>a(EsOsUqcy{T|#7j@w4`gz5Dp~KGw{C*s zRBel``*&~NynFs3(U}!mFTZ+z^SU5#Nj#n5rbj~Es`iuh;d||ie9m8~QJBPPvD+h) zLt@iDLGGhV^;dm=EuW>UyiX=UR`I!fu8+jm*PJFxUz|Ervi@nB*R*>tTc@sY^t!r8 z{aR4g#hJ_#pC4`Ri7Ls;b&B6|>Dt1ZM|)4G+F4oZPe1S9SD?6QqlID5*wo(}#kh|O?%x^ki0_%0_UWUXDXE-uUW;kJekUmHm>Ol6Zw%{j4Uj#*^pnS`={MCWCmx@oGj4=y=4&FAr)tu>Ft_nJj} z{rS$QA!QBF`f{FXPRP*lp)E#&R3JFhFKbLh* G2~7Y~sDJnX literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/splineseries-polar-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/splineseries-polar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..293266df14080bf3c0f24f4a0987b86ce6d34da3 GIT binary patch literal 415 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#aX`U{QAsWG@fsy`)90cSn z5B17C+^|qa&M?qYh2;uElF}0HGf|s%hh2_3HM@V(iT~xg3+%4EPu#rw{uy)Q`wc-K zTbSJ6&(m-&?5Z~SSA0}SWE+dPNEofmkkRb!O+EtL-Yw!d9E zBe_ofse(4=Izl|%4mqf8$YFW3WZ=Xum=Y92|vrn86 zJ!-O~V?*kdqJ?~=xn0exa*m13XmU=H>^K&^{9nYnmHaneotoa-K0&3gZ%4}4yv>Jq zr(4)f+{LG+_;Jg#p4yJtZtu@s(#lzAaO}DcV_~hb#s8XRuMTW_&AV>8g}Ag_`wc%X z_o+oM=REjuXlj>ZNw`d*-?NU*mnTNsa0za|d+*KFxiwWc7v$|0i}<&D zQ8k=?g*ZIG3c8mWbd%n*4f-(Vt_05ItWEJq{s6m#jUgvFx zHM{t_S)9Za8?)>t@y)P0<@8;?Owy@wMVFVrh8p!UNrrtVEwlE!YcYc?^>p=fS?83{ F1OU8TH3|R# literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody.png b/share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody.png new file mode 100644 index 0000000000000000000000000000000000000000..f64beb8ec5ce2bb2d60ed071f9bc44ecd992f26f GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJo?L1u^Lp(a)Ub6Q->>$zb zae12Il}L@HheAIw-f=0I&No+v&!s>x=IBZN2TxwSn^9g=SWqBr#UjHcE2Z^UIo7D7 zgu^7sGA6GeW1Z@YY3V16zW@7l$T2eV=KgTOiLwuNJoxL8eYcQ_L8-`ouHX4%j}3d> zn3ql|ewARL;3?Fka3X8#t%cWqnZAG1_IKX(*I(1mf9`lZ<7Un?mMK9xV%$}G?>(!r zs~4IW`<$(;TlWF$jbgv}d(s69w*EVDn_+D!*OrFwOb!e-T^;keBUBjs8qPDFuv1Wa z^pr`gv(apVsKc!TbA>l}uv;+p7_udwiMssuCb!_uGA6M~20i!1f{7ABt{1%)+FVdQ&MBb@0CLx)Gynhq literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody16.png b/share/qtcreator/qmldesigner/itemLibrary/images/staticrigidbody16.png new file mode 100644 index 0000000000000000000000000000000000000000..a89997cbc26d472957258fca6827e8d37161b20c GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7K6<)1hFJ8zJ-5;8aDW8s zgUd;rs)j5^OBE{_6lW+li0TT6 z%SoyyCu|h4d2LxE^T59Se9O$~L8p9Uud6T1{P&gJYh`9=Xz^i#caJUVWEdDGsGMvT zNRn++lsW#AXV$Vt0j6oGD-}4xT)x;a%&260z#8jo zqMoRo{~R5Ay?k5l|8Kt+Y4B)1J@a|b?upBfPq1D0E->~qTl^;m1_lOCS3j3^P6+9?9 z?;j8l5EvL392^`H5)vI99TO9il$4a5oSc%9l9Q8@o12@Lmse0wP*_-4QBhGxc*Y)QU|@Ld>Eak7 zA^G;;)gWd^0oDtA2k*)@?PmSHp#-re*0de}|8wr~7yru>TFs{_)VV*mBzR)3 z;=&|8`D?erTfDB_D%#f9@=CS-V2p<1hq^;Gzjj8rI{kfhUGnosX(oO5GtcYHT%BHr z{j}*oeOmmL1>JW%seup;Hz?HGGc$s=cKS_3A| zeE)s7=d1(GhRZrG^ct$&%Trb~Wj-3k%sF-LEH|$|{`Tdz7h5?Nu|8*DU|{fc^>bP0 Hl+XkKE$>$S literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/surface3d-icon.png b/share/qtcreator/qmldesigner/itemLibrary/images/surface3d-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a2cdba06317f76c4898e86eadb060bde09b486fc GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhv#ajGiuzAsXj%CtmbBu=0A6f|^{576;t)p^^;@4$Vl_U4;;cXk>Vr`}ljHfOEf zmL~Vr>*J&~dbV)|+-5MJDjm$c*mP#B`upBPJEAs7#pKNjfBf-c`|9(HgG^r>Jo?D~ zL{Gzyo0;KHKUEj<3G8#(+i2TxHhNVDXcN=**D zbF($NfB)&k%0Fuwyg$zjpQ_q$WJTzr--*0VAXf1I2X zd4Bb(MLWKJ_YPsOzsR*fNBDn9=iH5Jy5~<-o4en!vi$X&x(m}10{$~;U7BaP|NX;? UqldVRq(Fh<>FVdQ&MBb@0H`605C8xG literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/surface3d-icon16.png b/share/qtcreator/qmldesigner/itemLibrary/images/surface3d-icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..f8f8a3ee78789799b8865422a82aa92a76107799 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4h9AW2CEqh_A)Rq%=2_{43UszJ$TydaDWKI zfs<#K3Qc}=sJHWh)4}&2ga1mEEA24Yw$&w|Mx?sW_$&*<@eY|JWJ%cKhqkepgKP2fU2mZ+3Zx>X{4)gKi-=nfr2P60W|F ze|?;B`qGqdRTE4l^5)-~eD&e?RmxtAcKiI(vr6eb68SghnA{?^7u60XtPCIcPvki1 Tn%5r}1-aPM)z4*}Q$iB}D0Eo~ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape.png b/share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb4a7bc69f36767990c49e55575cb9ba435766e GIT binary patch literal 621 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuL8Ogvp2Lp(aKUa`&bO_X5& zAn)j10DJ#X^o|5fw88(htfDxDbg>X6Ny{to{C%?||5B}i;G zY~cE(^yu+^g@}&Xf*0on&1zoz!i7EUkr>-Wc|qlRp9!AxlA>LDuG!vh$)3@j&(*H{ zBHW@zLNI=o;2Dj#?3+GStA3cjqj{@E=ktu?a&x>jYtN=kSAO)?g+7CyQ2TAMbqVomi~y&_?#zmEoR4dbjVjsT0d{fC7v_$brxB6)%!(r z*66#5My@~oKsfAh$EW=nI`c0`Rk-v#`TRjbTAexHYr<;(iRrw1-o>(7*R?N*do`l#c_zi<{`j_~wD(t?IxmP-V$ cu4DAud3XEDE0vcS7#J8lUHx3vIVCg!08FA1l>h($ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape16.png b/share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape16.png new file mode 100644 index 0000000000000000000000000000000000000000..d60b67f0f2e8352203bb71afc79b9cc69ab6d636 GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7gFRgwLo9mNUR;}fHBpB3 z!}+qcyA(P!R%CKD8R;~o@>~`R^A8me={~sNLH&Y*CTRlAT=&ytjb~1a`J%dWWihkw zZG(;#5AE#toO!K1@6(j`mgg%U)-PD~E$r&V`iJkb-pk!twTibVNs`<1-k+5RxXdQS ztXm~G=iuU1QAewF5)DuO@@t&fDDinm%ikUC(=EEBZyXcxOP0Mpx#r@VvWi=E?@ol@ z`j|3Fd`G|GoTD52Of)t$+?KUGc|EOm(WSgZGv!&L5?7!7c6ZgThU+)X9qgt* z(LL5~*}$*+x!C8C*0ll-|AGZ~b3;S(XB-gPHu=sG*P0`oa}Fi@gkP2Qd0=rr{mq7s zo2#M@JLe?HwNKu2NM_5*YMwJU7OvX0&Af2m&3S%C+dr2@uvD}+@0j)^c#`NG8Ml8k zn*;yOP5*NHUe?Uzx3=sTlTf;GS^rJsr1SfC|Ie;r_S;n8F@46pUIqpR22WQ%mvv4F FO#r6`y_f(1 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/trianglemeshshape@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..64b0bc2c8401f53b2b4608826b76301739ed0f9e GIT binary patch literal 1364 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?Ff#-=c-1$C&x@87A23_hv`={A=4O9= z`AnvJ3~{V-OvjjG|J`}ve2(Eh!`&GRWR;5YHk?#b^gZB|AiN>O<=*#gVhLQKhTIK? zc27kvIDc&^>pIcunEK8`_yXS_-ZjD#(}Rv}VYs}4YZw2EFYkB{u&z@7vbclCWa>`k zzy{$r$L{^G5ZpOsYe)LpuLt%XNb@8Tu>Z_wQezkWqinJ1gWsc0`2=mxtnh#vSY#-xKe5pD+r|Wq!9vs)(Q2 z|JRIt9s%YbvI89>6-{Jzv&VOw2xdLGo_!v}wVfT=4Of*mnWX-`IdQ?x16S|;wca2W zF;873v>|^J=MLc=ig6mUY*{!yzBL}DQx*C@|y4oen8owrZQ2Z_(-vk~?HSyDAEbDE9APu=dHF<~3e2 zV!IZsVxF=6l-zW%&z@qsUso-{MW97*Nm;NIKY8j`c{V9?XJ1@hfLkIq=i zA@Q{S^aS=Beaj0ILN7I(k&%8-c(1=!TEFks@nlUSj#)2apBpk)oH==)Nrox!sNWj) z9~{+&?3@4et*T=^!*Wb5@`Dpo&BF5=nJ#N8Jr6$S({rSR@u1TiCc7g!p5g}V8K3tZ z4tekI>cV$@?N6=`YR|gsR^8v6!SPVqhUv_qpga2&l-e6i4@ia9a#o0Quk}12AsG2^ ziIu^3$rd|qo9DHAH!5VkKbXqR!L7>0u|nB?qE)h*l6qtBzXhw54S&nB=rYdx{&4Tb zecG?TYY96Y-mvC#bBB(W<3E!!`DYA^U7v(B?sZFEX~i*%aSp?}^7)~04f=cdDg<_z zy}YlX`9wTPUQeE(+a)D=rfuzAKb^<5x=QMg_8BR%Ts>qWeOhJb6W5gOtLA-4jIFpa zrLjYX+0OTsc9Lq6iqsmNPj*ifrsWp>t&N-_x`BT;`$ogl%KguOausZkzp-rL6bAK6 zyk|nM3c8+fU%{|8Vq2!vsd)|xMl#wyt|!|oCwwZrtRW@J@QpEUicMT%b>=7A43`6p z5BR+%^an7et$elO&P3M0sD}H^{VT(61Rl@|t&I&8U-7D==cVZV;yUIS;lOQtEIRD> z7GK+OmOYFiJ+xFiRDQFqR#lHP zdvjNW@oRx&@XEi2Pj+RTP(5>9X7`=FY_1NrcR2i(fAh}k?5HVI{g!VPvUTgsnHe0; dKkOgNzxnJm{Y`!83I+xS22WQ%mvv4FO#tMEY5@QM literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/triggerbody.png b/share/qtcreator/qmldesigner/itemLibrary/images/triggerbody.png new file mode 100644 index 0000000000000000000000000000000000000000..e1abdeac434262fc716b30ba70dd285935690340 GIT binary patch literal 594 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NWD4*Jab;j&m^g7_Ck(W- zw6wOiHh@7*O-(fz)YR0JmzS58mKGNm7lA=>adCcreqLT)Zf37MIhSy@>* zIXU_H`2__9MMXu$#lh$T;XU&>5d-m)(bLPyQJ9qy4`3n{-Sh#TEqD6}qFJ8QK z>C$D(mMvete8q|tM?`u4F)%RbmIV0)GqAAn3(4!4TZV>ZWR`bLnmuR3mOcAUo;q{> z{FMifUw`=c@ynO5-@bkS@$=8$zg$20cQY_BT=H~r4ABT)d)D3gkb^+mL)YGp1r1F> zF1tLYw+L}-aJo75dOrLAU(|?ucjUQWa%p_$A1Xij-*rc(^qk_|nKi#Oe;Tuu-)`jI zqiTJIDe@mWpStE| zaK`VQ%NM8zT0JYO4jbikE>5;e^PF&XWr*OloN&60!Jz)R!#Z#Gqn3a6%3hHQTO4TqY%v1^ O1B0ilpUXO@geCyjk_`U< literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/triggerbody16.png b/share/qtcreator/qmldesigner/itemLibrary/images/triggerbody16.png new file mode 100644 index 0000000000000000000000000000000000000000..29a47afdc3bafa82e4f200496ef27885efcefbd7 GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4rT@h1`S>QUt*vcsZ4C_#H8nL=RaGS=B}GL=Wo2c#xw$1JCFNjHQc_Y12DxBR zQBjeTlarg9o1L9qRaI49Uf$5qP*6~ik&#hSQc_=E-`UxjmX?;BoSc%9($mwEk&%&| zon2g9TvAd}Sy@?KU0qXCQ(IeGS6A22(9qo6+}_^a)6>(}*Eea>q-oQp&73)N&YU@O z=gwWUXwl-ui32CgIo)qf7#y(n9);eJ?w=V+&1B0ilpUXO@geCx9 C_s`1! literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/images/triggerbody@2x.png b/share/qtcreator/qmldesigner/itemLibrary/images/triggerbody@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7b942d959b3bef134a361e9dbb1d049fb83196ad GIT binary patch literal 1051 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4rT@hhJ-tuTNxM__XPNaxH2#>RAB=ZU{DDL zRaI4B9*8I}FR!SmC@(KB1A|g9C@Coc)1@U~P+VMG1O|m*ke{EQ2L`#hx!Kv-nP8BS zk&y}pDJdz*$;k-`3Gpxx8yg!J7Z(Et(b3USQBl#+(UFmnQBhHmk&)ry;bCE6At525 zp`rf%{(*sk!NI{HAtAoLzJ7jw{{H>}0Re%5fk8n*5H(?8Vd3H75fKp(6QZM|V`5?; zR>a50CnO{!CMG5&B_$^(r=+B$rKP2(r)OkjWM*b&Wo2b&XXobT=H=z(=jRs`6ciQ~ z78Mm07Z*ePTUJ(9US3{VSy@$8Rb5?OQ&Ur0TU%FG*U-?=*x1)2+uPUI*WceiapJ_ulP6D^GG*%2sne!Sn?8N|j2Sa#&6+iP_Ut)x z=FFWtciy~t^XJcBuwcQ$g$oxgTC{la;w4L#EM2;E*|KHJmoHzjV#Th@5sVBB49+D% ze!&b(EF4@s0%GFQ^2#cjx_ZXuR`y;2!I6=%83mOM?Ol@=tz5hL(DBn3Zr^|S^!1x} z?>~P0{N>yC?>~P0{Qc+e-+%x9{recr+s(khc-qs&F~r0B?Un1n!hs^kKQe3Ga17Mx zFxkyywrb0UEq9L!Ts*=s$$`aDU`hawsshs`rpWK#`F~G%ad)n9yZQYe`{vI5dFIZ{ z&EJJ&zuQ~=-}I})%ksqA9Bv*j$=K}{2K)ElYYzC|^W2JkMqRZ=g_ss7z*5sd}cuu=+hC`wg?{stwKetYs2nD0P{KWDd|bz8rBJ=cwe?vgGpQ?6U=`m}z=$I7D@gUWq4wF~r1S4hv3fAxCWLkrdo zE7z}5eCU0DxzlsDYhMb}AND1hwrshr8TjaKc#_(KRm=CjYJK&yb;^#{HxA?!+zZ`d zy^76Ne{XMl7W3x$5AxRd$Lhb2FIZIL!cvye!E6<4s>>MhUfp8BoN#U-heP5|8`hZ| zQ*Dqfp2)oG<;@8Ub+58z0w(TMW<1iX%eUgq*+!NP5AHs1c*m~GneZxhQghGo#Aqf7 z$qkYVg8h%XCh*rhX*hSSRkdNse{S}Ym9E*7FPZc*@2Ys)@hSHFo5G-a21BRpr?zwE SU1wlmVDNPHb6Mw<&;$VEBil>> literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/itemLibrary/qtcharts.metainfo b/share/qtcreator/qmldesigner/itemLibrary/qtcharts.metainfo new file mode 100644 index 00000000000..42eea67b4e5 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/qtcharts.metainfo @@ -0,0 +1,166 @@ +MetaInfo { + Type { + name: "QtCharts.ChartView" + icon: "images/chartview-icon16.png" + + ItemLibraryEntry { + name: "Area" + category: "Qt Charts - ChartView" + libraryIcon: "images/areaseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/AreaSeries.qml" } + } + + ItemLibraryEntry { + name: "Bar" + category: "Qt Charts - ChartView" + libraryIcon: "images/barseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/BarSeries.qml" } + } + + ItemLibraryEntry { + name: "BoxPlot" + category: "Qt Charts - ChartView" + libraryIcon: "images/boxplotseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/BoxPlotSeries.qml" } + } + + ItemLibraryEntry { + name: "H.Bar" + category: "Qt Charts - ChartView" + libraryIcon: "images/horizontalbarseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/HorizontalBarSeries.qml" } + } + + ItemLibraryEntry { + name: "H.PercentBar" + category: "Qt Charts - ChartView" + libraryIcon: "images/horizontalpercentbarseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/HorizontalPercentBarSeries.qml" } + } + + ItemLibraryEntry { + name: "H.StackedBar" + category: "Qt Charts - ChartView" + libraryIcon: "images/horizontalstackedbarseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/HorizontalStackedBarSeries.qml" } + } + + ItemLibraryEntry { + name: "Line" + category: "Qt Charts - ChartView" + libraryIcon: "images/lineseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/LineSeries.qml" } + } + + ItemLibraryEntry { + name: "Percent" + category: "Qt Charts - ChartView" + libraryIcon: "images/percentbarseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/PercentBarSeries.qml" } + } + + ItemLibraryEntry { + name: "Pie" + category: "Qt Charts - ChartView" + libraryIcon: "images/pieseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/PieSeries.qml" } + } + + ItemLibraryEntry { + name: "Scatter" + category: "Qt Charts - ChartView" + libraryIcon: "images/scatterseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/ScatterSeries.qml" } + } + + ItemLibraryEntry { + name: "Spline" + category: "Qt Charts - ChartView" + libraryIcon: "images/splineseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/SplineSeries.qml" } + } + + ItemLibraryEntry { + name: "StackedBar" + category: "Qt Charts - ChartView" + libraryIcon: "images/stackedbarseries-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/StackedBarSeries.qml" } + } + + ItemLibraryEntry { + name: "Area" + category: "Qt Charts - PolarChartView" + libraryIcon: "images/areaseries-polar-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/PolarAreaSeries.qml" } + } + + ItemLibraryEntry { + name: "Line" + category: "Qt Charts - PolarChartView" + libraryIcon: "images/lineseries-polar-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/PolarLineSeries.qml" } + } + + ItemLibraryEntry { + name: "Scatter" + category: "Qt Charts - PolarChartView" + libraryIcon: "images/scatterseries-polar-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/PolarScatterSeries.qml" } + } + + ItemLibraryEntry { + name: "Spline" + category: "Qt Charts - PolarChartView" + libraryIcon: "images/splineseries-polar-icon.png" + version: "2.0" + requiredImport: "QtCharts" + + QmlSource { source: "source/PolarSplineSeries.qml" } + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/qtgraphs.metainfo b/share/qtcreator/qmldesigner/itemLibrary/qtgraphs.metainfo new file mode 100644 index 00000000000..6eb8754d9ee --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/qtgraphs.metainfo @@ -0,0 +1,111 @@ +MetaInfo { + Type { + name: "QtGraphs.Bars3D" + icon: "images/bars3d-icon16.png" + + ItemLibraryEntry { + name: "Bars3D" + category: "3D Graphs" + libraryIcon: "images/bars3d-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Bars3D.qml" } + } + } + + Type { + name: "QtGraphs.Scatter3D" + icon: "images/scatter3d-icon16.png" + + ItemLibraryEntry { + name: "Scatter3D" + category: "3D Graphs" + libraryIcon: "images/scatter3d-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Scatter3D.qml" } + } + } + + Type { + name: "QtGraphs.Surface3D" + icon: "images/surface3d-icon16.png" + + ItemLibraryEntry { + name: "Surface3D" + category: "3D Graphs" + libraryIcon: "images/surface3d-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Surface3D.qml" } + } + } + + Type { + name: "QtGraphs.GraphsView" + icon: "images/chartview-icon16.png" + + ItemLibraryEntry { + name: "Area" + category: "2D Graphs" + libraryIcon: "images/areaseries-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Graphs2DAreaSeries.qml" } + } + + ItemLibraryEntry { + name: "Bar" + category: "2D Graphs" + libraryIcon: "images/barseries-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Graphs2DBarSeries.qml" } + } + + ItemLibraryEntry { + name: "Line" + category: "2D Graphs" + libraryIcon: "images/lineseries-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Graphs2DLineSeries.qml" } + } + + ItemLibraryEntry { + name: "Pie" + category: "2D Graphs" + libraryIcon: "images/pieseries-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Graphs2DPieSeries.qml" } + } + + ItemLibraryEntry { + name: "Scatter" + category: "2D Graphs" + libraryIcon: "images/scatterseries-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Graphs2DScatterSeries.qml" } + } + + ItemLibraryEntry { + name: "Spline" + category: "2D Graphs" + libraryIcon: "images/splineseries-icon.png" + version: "1.0" + requiredImport: "QtGraphs" + + QmlSource { source: "source/Graphs2DSplineSeries.qml" } + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/qtsaferenderer.metainfo b/share/qtcreator/qmldesigner/itemLibrary/qtsaferenderer.metainfo new file mode 100644 index 00000000000..6fae3638a54 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/qtsaferenderer.metainfo @@ -0,0 +1,47 @@ +MetaInfo { + Type { + name: "Qt.SafeRenderer.SafePicture" + icon: "images/picture-icon16.png" + + ItemLibraryEntry { + name: "SafePicture" + category: "Qt Safe Renderer" + libraryIcon: "images/picture-icon.png" + version: "2.0" + requiredImport: "Qt.SafeRenderer" + + Property { name: "width"; type: "int"; value: 64; } + Property { name: "height"; type: "int"; value: 64; } + } + } + Type { + name: "Qt.SafeRenderer.SafeText" + icon: "images/text-16px.png" + + ItemLibraryEntry { + name: "SafeText" + category: "Qt Safe Renderer" + libraryIcon: "images/text-24px.png" + version: "2.0" + requiredImport: "Qt.SafeRenderer" + + Property { name: "width"; type: "int"; value: 128; } + Property { name: "height"; type: "int"; value: 64; } + } + } + Type { + name: "Qt.SafeRenderer.SafeImage" + icon: "images/image-icon16.png" + + ItemLibraryEntry { + name: "SafeImage" + category: "Qt Safe Renderer" + libraryIcon: "images/image-icon.png" + version: "2.0" + requiredImport: "Qt.SafeRenderer" + + Property { name: "width"; type: "int"; value: 64; } + Property { name: "height"; type: "int"; value: 64; } + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/qtvirtualkeyboard.metainfo b/share/qtcreator/qmldesigner/itemLibrary/qtvirtualkeyboard.metainfo new file mode 100644 index 00000000000..0aea30b869e --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/qtvirtualkeyboard.metainfo @@ -0,0 +1,35 @@ +MetaInfo { +Type { + name: "QtQuick.VirtualKeyboard.InputPanel" + icon: "images/text-input-icon16.png" + + ItemLibraryEntry { + name: "Input Panel" + category: "Virtual Keyboard" + libraryIcon: "images/text-input-icon.png" + version: "6.0" + requiredImport: "QtQuick.VirtualKeyboard" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + toolTip: qsTr("Provides the virtual keyboard UI.") + } +} + +Type { + name: "QtQuick.VirtualKeyboard.HandwritingInputPanel" + icon: "images/text-input-icon16.png" + + ItemLibraryEntry { + name: "Handwriting Input Panel" + category: "Virtual Keyboard" + libraryIcon: "images/text-input-icon.png" + version: "6.0" + requiredImport: "QtQuick.VirtualKeyboard" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + toolTip: qsTr("Provides a handwriting panel add-on for the virtual keyboard UI.") + } +} +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/quick3d_physics.metainfo b/share/qtcreator/qmldesigner/itemLibrary/quick3d_physics.metainfo new file mode 100644 index 00000000000..874e209dc52 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/quick3d_physics.metainfo @@ -0,0 +1,261 @@ +MetaInfo { + Type { + name: "QtQuick3D.Physics.PhysicsWorld" + icon: "images/physicsworld16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Physics World" + category: "Components" + libraryIcon: "images/physicsworld.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.TriggerBody" + icon: "images/triggerbody16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Trigger Body" + category: "Collision Bodies" + libraryIcon: "images/triggerbody.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.StaticRigidBody" + icon: "images/staticrigidbody16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Static Rigid Body" + category: "Collision Bodies" + libraryIcon: "images/staticrigidbody.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.DynamicRigidBody" + icon: "images/dynamicrigidbody16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Dynamic Rigid Body" + category: "Collision Bodies" + libraryIcon: "images/dynamicrigidbody.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.PhysicsMaterial" + icon: "images/physicsmaterial16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Physics Material" + category: "Components" + libraryIcon: "images/physicsmaterial.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.BoxShape" + icon: "images/boxshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Box Shape" + category: "Collision Shapes" + libraryIcon: "images/boxshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.CapsuleShape" + icon: "images/capsuleshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Capsule Shape" + category: "Collision Shapes" + libraryIcon: "images/capsuleshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.ConvexMeshShape" + icon: "images/convexmeshshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Convex Mesh Shape" + category: "Collision Shapes" + libraryIcon: "images/convexmeshshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.HeightFieldShape" + icon: "images/heightfieldshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Height Field Shape" + category: "Collision Shapes" + libraryIcon: "images/heightfieldshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.PlaneShape" + icon: "images/planeshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Plane Shape" + category: "Collision Shapes" + libraryIcon: "images/planeshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.SphereShape" + icon: "images/sphereshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Sphere Shape" + category: "Collision Shapes" + libraryIcon: "images/sphereshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.TriangleMeshShape" + icon: "images/trianglemeshshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Triangle Mesh Shape" + category: "Collision Shapes" + libraryIcon: "images/trianglemeshshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.CharacterController" + icon: "images/charactercontroller16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Character Controller" + category: "Collision Bodies" + libraryIcon: "images/charactercontroller.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/AreaSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/AreaSeries.qml new file mode 100644 index 00000000000..6aa9fae78ac --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/AreaSeries.qml @@ -0,0 +1,20 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + AreaSeries { + name: "AreaSeries" + upperSeries: LineSeries { + XYPoint { x: 0; y: 1.5 } + XYPoint { x: 1; y: 3 } + XYPoint { x: 3; y: 4.3 } + XYPoint { x: 6; y: 1.1 } + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/BarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/BarSeries.qml new file mode 100644 index 00000000000..07e5838ef9d --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/BarSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + BarSeries { + name: "BarSeries" + BarSet { label: "Set1"; values: [2, 2, 3] } + BarSet { label: "Set2"; values: [5, 1, 2] } + BarSet { label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Bars3D.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Bars3D.qml new file mode 100644 index 00000000000..e823c16ae7f --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Bars3D.qml @@ -0,0 +1,28 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick3D +import QtGraphs + +Bars3D { + id: bars3d + width: 300 + height: 300 + Bar3DSeries { + id: bars3dSeries + ItemModelBarDataProxy { + id: barsDataProxy + itemModel: ListModel { + ListElement{ row: "row 1"; column: "column 1"; value: "1"; } + ListElement{ row: "row 1"; column: "column 2"; value: "2"; } + ListElement{ row: "row 1"; column: "column 3"; value: "3"; } + } + + rowRole: "row" + columnRole: "column" + valueRole: "value" + } + } +} + diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/BoxPlotSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/BoxPlotSeries.qml new file mode 100644 index 00000000000..44d7041b358 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/BoxPlotSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + BoxPlotSeries { + name: "BoxPlotSeries" + BoxSet { label: "Set1"; values: [3, 4, 5.1, 6.2, 8.5] } + BoxSet { label: "Set2"; values: [5, 6, 7.5, 8.6, 11.8] } + BoxSet { label: "Set3"; values: [3.2, 5, 5.7, 8, 9.2] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DAreaSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DAreaSeries.qml new file mode 100644 index 00000000000..22c5835104b --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DAreaSeries.qml @@ -0,0 +1,52 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtGraphs + +GraphsView { + width: 300 + height: 300 + + axisX: valueAxisX + axisY: valueAxisY + + ValueAxis { + id: valueAxisX + min: 0 + max: 10 + } + ValueAxis { + id: valueAxisY + min: 0 + max: 10 + } + + AreaSeries { + name: "AreaSeries" + upperSeries: lineSeries + + LineSeries { + id: lineSeries + XYPoint { + x: 0 + y: 1.5 + } + + XYPoint { + x: 1 + y: 3 + } + + XYPoint { + x: 6 + y: 6.3 + } + + XYPoint { + x: 10 + y: 3.1 + } + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DBarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DBarSeries.qml new file mode 100644 index 00000000000..ece1718ab83 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DBarSeries.qml @@ -0,0 +1,31 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtGraphs + +GraphsView { + width: 300 + height: 300 + + axisX: barCategoryAxis + axisY: valueAxis + + BarCategoryAxis { + id: barCategoryAxis + categories: ["2023", "2024", "2025"] + } + + ValueAxis { + id: valueAxis + min: 0 + max: 10 + } + + BarSeries { + id: barSeries + BarSet { id: set1; label: "Set1"; values: [2, 2, 3] } + BarSet { id: set2; label: "Set2"; values: [5, 1, 2] } + BarSet { id: set3; label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DLineSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DLineSeries.qml new file mode 100644 index 00000000000..1f7d9595e47 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DLineSeries.qml @@ -0,0 +1,47 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtGraphs + +GraphsView { + width: 300 + height: 300 + + axisX: valueAxisX + axisY: valueAxisY + + ValueAxis { + id: valueAxisX + min: 0 + max: 10 + } + ValueAxis { + id: valueAxisY + min: 0 + max: 10 + } + + LineSeries { + id: lineSeries + XYPoint { + x: 0 + y: 2 + } + + XYPoint { + x: 3 + y: 1.2 + } + + XYPoint { + x: 7 + y: 3.3 + } + + XYPoint { + x: 10 + y: 2.1 + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DPieSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DPieSeries.qml new file mode 100644 index 00000000000..a8b8bcd806b --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DPieSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtGraphs + +GraphsView { + width: 300 + height: 300 + + PieSeries { + id: pieSeries + PieSlice { label: "Slice1"; value: 13.5 } + PieSlice { label: "Slice2"; value: 10.9 } + PieSlice { label: "Slice3"; value: 8.6 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DScatterSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DScatterSeries.qml new file mode 100644 index 00000000000..4d86d504117 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DScatterSeries.qml @@ -0,0 +1,47 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtGraphs + +GraphsView { + width: 300 + height: 300 + + axisX: valueAxisX + axisY: valueAxisY + + ValueAxis { + id: valueAxisX + min: 0 + max: 10 + } + ValueAxis { + id: valueAxisY + min: 0 + max: 10 + } + + ScatterSeries { + id: lineSeries + XYPoint { + x: 0 + y: 2 + } + + XYPoint { + x: 3 + y: 1.2 + } + + XYPoint { + x: 7 + y: 3.3 + } + + XYPoint { + x: 10 + y: 2.1 + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DSplineSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DSplineSeries.qml new file mode 100644 index 00000000000..baab8f14e72 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Graphs2DSplineSeries.qml @@ -0,0 +1,47 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtGraphs + +GraphsView { + width: 300 + height: 300 + + axisX: valueAxisX + axisY: valueAxisY + + ValueAxis { + id: valueAxisX + min: 0 + max: 10 + } + ValueAxis { + id: valueAxisY + min: 0 + max: 10 + } + + SplineSeries { + id: lineSeries + XYPoint { + x: 0 + y: 2 + } + + XYPoint { + x: 3 + y: 1.2 + } + + XYPoint { + x: 7 + y: 3.3 + } + + XYPoint { + x: 10 + y: 2.1 + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalBarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalBarSeries.qml new file mode 100644 index 00000000000..559cf2b7898 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalBarSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + HorizontalBarSeries { + name: "HorizontalBarSeries" + BarSet { label: "Set1"; values: [2, 2, 3] } + BarSet { label: "Set2"; values: [5, 1, 2] } + BarSet { label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalPercentBarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalPercentBarSeries.qml new file mode 100644 index 00000000000..68f7a0f532b --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalPercentBarSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + HorizontalPercentBarSeries { + name: "HorizontalPercentBarSeries" + BarSet { label: "Set1"; values: [2, 2, 3] } + BarSet { label: "Set2"; values: [5, 1, 2] } + BarSet { label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalStackedBarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalStackedBarSeries.qml new file mode 100644 index 00000000000..c80cd3cba8d --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/HorizontalStackedBarSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + HorizontalStackedBarSeries { + name: "HorizontalStackedBarSeries" + BarSet { label: "Set1"; values: [2, 2, 3] } + BarSet { label: "Set2"; values: [5, 1, 2] } + BarSet { label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/LineSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/LineSeries.qml new file mode 100644 index 00000000000..c0ce034505b --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/LineSeries.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + LineSeries { + name: "LineSeries" + XYPoint { x: 0; y: 2 } + XYPoint { x: 1; y: 1.2 } + XYPoint { x: 2; y: 3.3 } + XYPoint { x: 5; y: 2.1 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/PercentBarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/PercentBarSeries.qml new file mode 100644 index 00000000000..71e039f2d95 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/PercentBarSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + PercentBarSeries { + name: "PercentBarSeries" + BarSet { label: "Set1"; values: [2, 2, 3] } + BarSet { label: "Set2"; values: [5, 1, 2] } + BarSet { label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/PieSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/PieSeries.qml new file mode 100644 index 00000000000..eb803e68c64 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/PieSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + PieSeries { + name: "PieSeries" + PieSlice { label: "Slice1"; value: 13.5 } + PieSlice { label: "Slice2"; value: 10.9 } + PieSlice { label: "Slice3"; value: 8.6 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/PolarAreaSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/PolarAreaSeries.qml new file mode 100644 index 00000000000..581b7b20aa6 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/PolarAreaSeries.qml @@ -0,0 +1,48 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +PolarChartView { + width: 300 + height: 300 + legend.visible: false + + ValueAxis { + id: axis1 + tickCount: 9 + } + ValueAxis { + id: axis2 + } + LineSeries { + id: lowerLine + axisAngular: axis1 + axisRadial: axis2 + + XYPoint { x: 1; y: 5 } + XYPoint { x: 2; y: 10 } + XYPoint { x: 3; y: 12 } + XYPoint { x: 4; y: 17 } + XYPoint { x: 5; y: 20 } + } + LineSeries { + id: upperLine + axisAngular: axis1 + axisRadial: axis2 + + XYPoint { x: 1; y: 5 } + XYPoint { x: 2; y: 14 } + XYPoint { x: 3; y: 20 } + XYPoint { x: 4; y: 32 } + XYPoint { x: 5; y: 35 } + } + AreaSeries { + name: "AreaSeries" + axisAngular: axis1 + axisRadial: axis2 + lowerSeries: lowerLine + upperSeries: upperLine + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/PolarLineSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/PolarLineSeries.qml new file mode 100644 index 00000000000..a1d43c4554e --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/PolarLineSeries.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +PolarChartView { + width: 300 + height: 300 + + LineSeries { + name: "LineSeries" + axisRadial: CategoryAxis { + min: 0 + max: 20 + } + axisAngular: ValueAxis { + tickCount: 9 + } + XYPoint { x: 0; y: 4.3 } + XYPoint { x: 2; y: 4.7 } + XYPoint { x: 4; y: 5.2 } + XYPoint { x: 6; y: 6.1 } + XYPoint { x: 8; y: 12.9 } + XYPoint { x: 9; y: 19.2 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/PolarScatterSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/PolarScatterSeries.qml new file mode 100644 index 00000000000..26dd577b5ea --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/PolarScatterSeries.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +PolarChartView { + width: 300 + height: 300 + + ScatterSeries { + name: "ScatterSeries" + axisRadial: CategoryAxis { + min: 0 + max: 20 + } + axisAngular: ValueAxis { + tickCount: 9 + } + XYPoint { x: 0; y: 4.3 } + XYPoint { x: 2; y: 4.7 } + XYPoint { x: 4; y: 5.2 } + XYPoint { x: 8; y: 12.9 } + XYPoint { x: 9; y: 19.2 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/PolarSplineSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/PolarSplineSeries.qml new file mode 100644 index 00000000000..5f05ca9c622 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/PolarSplineSeries.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +PolarChartView { + width: 300 + height: 300 + + SplineSeries { + name: "SplineSeries" + axisRadial: CategoryAxis { + min: 0 + max: 20 + } + axisAngular: ValueAxis { + tickCount: 9 + } + XYPoint { x: 0; y: 4.3 } + XYPoint { x: 2; y: 4.7 } + XYPoint { x: 4; y: 5.2 } + XYPoint { x: 6; y: 6.1 } + XYPoint { x: 8; y: 12.9 } + XYPoint { x: 9; y: 19.2 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Scatter3D.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Scatter3D.qml new file mode 100644 index 00000000000..24c199ab406 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Scatter3D.qml @@ -0,0 +1,28 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick3D +import QtGraphs + +Scatter3D { + id: scatter3d + width: 300 + height: 300 + Scatter3DSeries { + id: scatter3dSeries + ItemModelScatterDataProxy { + id: scatterDataProxy + itemModel: ListModel { + ListElement{ x: "1"; y: "2"; z: "3"; } + ListElement{ x: "2"; y: "3"; z: "4"; } + ListElement{ x: "3"; y: "4"; z: "1"; } + } + + xPosRole: "x" + yPosRole: "y" + zPosRole: "z" + } + } +} + diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/ScatterSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/ScatterSeries.qml new file mode 100644 index 00000000000..3b73402e41b --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/ScatterSeries.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + ScatterSeries { + name: "ScatterSeries" + XYPoint { x: 1; y: 1 } + XYPoint { x: 2; y: 4 } + XYPoint { x: 4; y: 2 } + XYPoint { x: 5; y: 5 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/SplineSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/SplineSeries.qml new file mode 100644 index 00000000000..b400a99e535 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/SplineSeries.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + SplineSeries { + name: "SplineSeries" + XYPoint { x: 0; y: 1 } + XYPoint { x: 3; y: 4.3 } + XYPoint { x: 5; y: 3.1 } + XYPoint { x: 8; y: 5.8 } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/StackedBarSeries.qml b/share/qtcreator/qmldesigner/itemLibrary/source/StackedBarSeries.qml new file mode 100644 index 00000000000..45431cd8580 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/StackedBarSeries.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtCharts + +ChartView { + width: 300 + height: 300 + + StackedBarSeries { + name: "StackedBarSeries" + BarSet { label: "Set1"; values: [2, 2, 3] } + BarSet { label: "Set2"; values: [5, 1, 2] } + BarSet { label: "Set3"; values: [3, 5, 8] } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibrary/source/Surface3D.qml b/share/qtcreator/qmldesigner/itemLibrary/source/Surface3D.qml new file mode 100644 index 00000000000..d5c0a56fff6 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibrary/source/Surface3D.qml @@ -0,0 +1,28 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick3D +import QtGraphs + +Surface3D { + id: surface3d + width: 300 + height: 300 + Surface3DSeries { + id: surface3dSeries + ItemModelSurfaceDataProxy { + id: surfaceDataProxy + itemModel: ListModel { + ListElement{ row: "1"; column: "1"; y: "1"; } + ListElement{ row: "1"; column: "2"; y: "2"; } + ListElement{ row: "2"; column: "1"; y: "3"; } + ListElement{ row: "2"; column: "2"; y: "4"; } + } + + rowRole: "row" + columnRole: "column" + yPosRole: "y" + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeImagePane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeImagePane.qml new file mode 100644 index 00000000000..5f06bd79d89 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeImagePane.qml @@ -0,0 +1,156 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioTheme as StudioTheme + +Rectangle { + id: itemPane + width: 320 + height: 400 + color: Theme.qmlDesignerBackgroundColorDarkAlternate() + + Component.onCompleted: Controller.mainScrollView = mainScrollView + + MouseArea { + anchors.fill: parent + onClicked: forceActiveFocus() + } + + ScrollView { + id: mainScrollView + clip: true + anchors.fill: parent + + Column { + id: mainColumn + y: -1 + width: itemPane.width + + onWidthChanged: StudioTheme.Values.responsiveResize(itemPane.width) + Component.onCompleted: StudioTheme.Values.responsiveResize(itemPane.width) + + ComponentSection {} + + Section { + caption: qsTr("Safe Image") + anchors.left: parent.left + anchors.right: parent.right + + SectionLayout { + PropertyLabel { text: qsTr("Position") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.x + maximumValue: 0xffff + minimumValue: -0xffff + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "X" } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.y + maximumValue: 0xffff + minimumValue: -0xffff + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "Y" } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Size") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.width + maximumValue: 0xffff + minimumValue: 1 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The width of the object + text: qsTr("W", "width") + } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + id: heightSpinBox + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.height + maximumValue: 0xffff + minimumValue: 1 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The height of the object + text: qsTr("H", "height") + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Source") } + + SecondColumnLayout { + UrlChooser { + backendValue: backendValues.source + } + + ExpandingSpacer {} + } + PropertyLabel { text: qsTr("fillColor") } + + ColorEditor { + backendValue: backendValues.fillColor + supportGradient: false + } + + PropertyLabel { text: qsTr("Opacity") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + sliderIndicatorVisible: true + backendValue: backendValues.opacity + decimals: 2 + minimumValue: 0 + maximumValue: 1 + hasSlider: true + stepSize: 0.1 + } + + ExpandingSpacer {} + } + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafePicturePane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafePicturePane.qml new file mode 100644 index 00000000000..89aaccba29c --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafePicturePane.qml @@ -0,0 +1,163 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioTheme as StudioTheme + +Rectangle { + id: itemPane + width: 320 + height: 400 + color: Theme.qmlDesignerBackgroundColorDarkAlternate() + + Component.onCompleted: Controller.mainScrollView = mainScrollView + + MouseArea { + anchors.fill: parent + onClicked: forceActiveFocus() + } + + ScrollView { + id: mainScrollView + clip: true + anchors.fill: parent + + Column { + id: mainColumn + y: -1 + width: itemPane.width + + onWidthChanged: StudioTheme.Values.responsiveResize(itemPane.width) + Component.onCompleted: StudioTheme.Values.responsiveResize(itemPane.width) + + ComponentSection {} + + Section { + caption: qsTr("Safe Picture") + anchors.left: parent.left + anchors.right: parent.right + + SectionLayout { + PropertyLabel { text: qsTr("Position") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.x + maximumValue: 0xffff + minimumValue: -0xffff + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "X" } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.y + maximumValue: 0xffff + minimumValue: -0xffff + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "Y" } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Size") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.width + maximumValue: 0xffff + minimumValue: 1 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The width of the object + text: qsTr("W", "width") + } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + id: heightSpinBox + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.height + maximumValue: 0xffff + minimumValue: 1 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The height of the object + text: qsTr("H", "height") + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Source") } + + SecondColumnLayout { + UrlChooser { + backendValue: backendValues.source + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Color") } + + ColorEditor { + backendValue: backendValues.color + supportGradient: false + } + + PropertyLabel { text: qsTr("fillColor") } + + ColorEditor { + backendValue: backendValues.fillColor + supportGradient: false + } + PropertyLabel { text: qsTr("Opacity") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + sliderIndicatorVisible: true + backendValue: backendValues.opacity + decimals: 2 + minimumValue: 0 + maximumValue: 1 + hasSlider: true + stepSize: 0.1 + } + + ExpandingSpacer {} + } + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeTextPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeTextPane.qml new file mode 100644 index 00000000000..be097ee2738 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/Qt/SafeRenderer/SafeTextPane.qml @@ -0,0 +1,269 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioTheme as StudioTheme + +Rectangle { + id: itemPane + width: 320 + height: 400 + color: Theme.qmlDesignerBackgroundColorDarkAlternate() + + Component.onCompleted: Controller.mainScrollView = mainScrollView + + MouseArea { + anchors.fill: parent + onClicked: forceActiveFocus() + } + + ScrollView { + id: mainScrollView + clip: true + anchors.fill: parent + + Column { + id: mainColumn + y: -1 + width: itemPane.width + + onWidthChanged: StudioTheme.Values.responsiveResize(itemPane.width) + Component.onCompleted: StudioTheme.Values.responsiveResize(itemPane.width) + + ComponentSection {} + + Section { + caption: qsTr("Safe Text") + anchors.left: parent.left + anchors.right: parent.right + + SectionLayout { + PropertyLabel { text: qsTr("Position") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.x + maximumValue: 0xffff + minimumValue: -0xffff + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "X" } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.y + maximumValue: 0xffff + minimumValue: -0xffff + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "Y" } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Size") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.width + maximumValue: 0xffff + minimumValue: 1 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The width of the object + text: qsTr("W", "width") + } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + id: heightSpinBox + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.height + maximumValue: 0xffff + minimumValue: 1 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The height of the object + text: qsTr("H", "height") + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Text") } + + SecondColumnLayout { + LineEdit { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + backendValue: backendValues.text + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Color") } + + ColorEditor { + backendValue: backendValues.color + supportGradient: false + } + PropertyLabel { text: qsTr("fillColor") } + + ColorEditor { + backendValue: backendValues.fillColor + supportGradient: false + } + PropertyLabel { text: qsTr("Opacity") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + sliderIndicatorVisible: true + backendValue: backendValues.opacity + decimals: 2 + minimumValue: 0 + maximumValue: 1 + hasSlider: true + stepSize: 0.1 + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Font") } + + SecondColumnLayout { + FontComboBox { + id: fontComboBox + property string familyName: backendValue.value + backendValue: backendValues.font_family + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Size") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.font_pixelSize + minimumValue: 0 + maximumValue: 400 + decimals: 0 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { text: "px" } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Emphasis") } + + SecondColumnLayout { + BoolButtonRowButton { + id: boldButton + buttonIcon: StudioTheme.Constants.fontStyleBold + backendValue: backendValues.font_bold + } + + Spacer { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + - (boldButton.implicitWidth + italicButton.implicitWidth) + } + + BoolButtonRowButton { + id: italicButton + buttonIcon: StudioTheme.Constants.fontStyleItalic + backendValue: backendValues.font_italic + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Alignment H") } + + SecondColumnLayout { + AlignmentHorizontalButtons { + scope: "SafeText" + } + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Alignment V") } + + SecondColumnLayout { + AlignmentVerticalButtons { + scope: "SafeText" + } + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Wrap mode") } + + SecondColumnLayout { + ComboBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + backendValue: backendValues.wrapMode + scope: "SafeText" + model: ["NoWrap", "WordWrap", "WrapAnywhere", "Wrap"] + enabled: backendValue.isAvailable + } + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Dynamic") } + + SecondColumnLayout { + CheckBox { + text: backendValue.valueToString + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.runtimeEditable + } + + ExpandingSpacer {} + } + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtCharts/ChartViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtCharts/ChartViewSpecifics.qml new file mode 100644 index 00000000000..1397249460a --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtCharts/ChartViewSpecifics.qml @@ -0,0 +1,123 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + caption: qsTr("Title") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Title") + } + + SecondColumnLayout { + LineEdit { + backendValue: backendValues.title + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Color") + } + + ColorEditor { + backendValue: backendValues.titleColor + supportGradient: false + } + } + } + + Section { + width: parent.width + caption: qsTr("Background") + + SectionLayout { + PropertyLabel { + text: qsTr("Color") + } + + ColorEditor { + backendValue: backendValues.backgroundColor + supportGradient: false + } + + PropertyLabel { + text: qsTr("Roundness") + tooltip: qsTr("Diameter of the rounding circle at the corners") + } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.backgroundRoundness + minimumValue: 0.1 + maximumValue: 100.0 + stepSize: 0.1 + decimals: 1 + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + + PropertyLabel { + text: qsTr("Drop Shadow") + tooltip: qsTr("Enable border drop shadow") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.dropShadowEnabled.valueToString + backendValue: backendValues.dropShadowEnabled + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + } + } + + Section { + width: parent.width + caption: qsTr("Plot Area") + + SectionLayout { + PropertyLabel { + text: qsTr("Color") + } + + ColorEditor { + backendValue: backendValues.plotAreaColor + supportGradient: false + } + } + } + + Section { + width: parent.width + caption: qsTr("Localization") + + SectionLayout { + PropertyLabel { + text: qsTr("Localize Numbers") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.localizeNumbers.valueToString + backendValue: backendValues.localizeNumbers + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Bars3DSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Bars3DSpecifics.qml new file mode 100644 index 00000000000..9c822a726f9 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Bars3DSpecifics.qml @@ -0,0 +1,276 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets +import QtQuick.Layouts +import StudioTheme as StudioTheme +import QtQuick.Controls as Controls + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Bars") + + SectionLayout { + PropertyLabel { + text: qsTr("Uniform Scaling") + tooltip: qsTr("Proportionally scale multiple series") + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.multiSeriesUniform + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Thickness") + tooltip: qsTr("Thickness ratio between X and Z dimension") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.barThickness + minimumValue: 0.01 + maximumValue: 100.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + + PropertyLabel { + text: qsTr("Spacing") + tooltip: qsTr("Bar spacing in the X and Z dimensions") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.barSpacing_width + minimumValue: 0.0 + maximumValue: 10.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + - StudioTheme.Values.actionIndicatorWidth + } + ControlLabel { + text: qsTr("Col") + width: StudioTheme.Values.actionIndicatorWidth * 2 + } + } + + PropertyLabel {} + SecondColumnLayout { + SpinBox { + backendValue: backendValues.barSpacing_height + minimumValue: 0.0 + maximumValue: 10.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + - StudioTheme.Values.actionIndicatorWidth + } + ControlLabel { + text: qsTr("Row") + width: StudioTheme.Values.actionIndicatorWidth * 2 + } + + } + PropertyLabel { + text: qsTr("Relative Spacing") + tooltip: qsTr("Set bar spacing relative to thickness") + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.barSpacingRelative + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Series Margin") + tooltip: qsTr("Margin between series columns in X and Z dimensions") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.barSeriesMargin_width + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + - StudioTheme.Values.actionIndicatorWidth + } + ControlLabel { + text: qsTr("Col") + width: StudioTheme.Values.actionIndicatorWidth * 2 + } + } + PropertyLabel {} + SecondColumnLayout { + SpinBox { + backendValue: backendValues.barSeriesMargin_height + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + - StudioTheme.Values.actionIndicatorWidth + } + ControlLabel { + text: qsTr("Row") + width: StudioTheme.Values.actionIndicatorWidth * 2 + } + + } + PropertyLabel { + text: qsTr("Floor Level") + tooltip: qsTr("Floor level in Y-axis data coordinates") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.floorLevel + minimumValue: 0.0 + maximumValue: 999999 + stepSize: 0.1 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + - StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Selection Mode") + tooltip: qsTr("Bar selection mode") + } + SecondColumnLayout { + id: selectionLayout + property bool isInModel: backendValue.isInModel; + property bool isInSubState: backendValue.isInSubState; + property bool selectionChangedFlag: selectionChanged + property variant backendValue: backendValues.selectionMode + property variant valueFromBackend: backendValue.value + property string enumScope: "Graphs3D.SelectionFlag" + property string enumSeparator: " | " + property int checkedCount: 0 + property bool item: false + property bool row: false + property bool column: false + property bool slice: false + property bool multi: false + + function checkValue(checkedVariable, variableText, expressionBase) { + var expressionStr = expressionBase + if (checkedVariable) { + if (expressionStr !== "") { + expressionStr += enumSeparator + } + expressionStr += enumScope + expressionStr += "." + expressionStr += variableText + checkedCount++ + } + return expressionStr + } + + function composeSelectionMode() { + var expressionStr = "" + checkedCount = 0 + expressionStr = checkValue(item, "Item", expressionStr) + expressionStr = checkValue(row, "Row", expressionStr) + expressionStr = checkValue(column, "Column", expressionStr) + expressionStr = checkValue(slice, "Slice", expressionStr) + expressionStr = checkValue(multi, "MultiSeries", expressionStr) + + if (checkedCount === 0) + backendValue.expression = enumScope + ".None" + else + backendValue.expression = expressionStr + } + + function evaluate() { + if (backendValue.value === undefined) + return + + item = (backendValue.expression.indexOf("Item") !== -1) + row = (backendValue.expression.indexOf("Row") !== -1) + column = (backendValue.expression.indexOf("Column") !== -1) + slice = (backendValue.expression.indexOf("Slice") !== -1) + multi = (backendValue.expression.indexOf("MultiSeries") !== -1) + + itemBox.checked = item + rowBox.checked = row + columnBox.checked = column + sliceBox.checked = slice + multiSeriesBox.checked = multi + } + + onSelectionChangedFlagChanged: evaluate() + + onIsInModelChanged: evaluate() + + onIsInSubStateChanged: evaluate() + + onBackendValueChanged: evaluate() + + onValueFromBackendChanged: evaluate() + + ColumnLayout { + anchors.fill: parent + + Controls.CheckBox { + id: itemBox + text: "Item" + Layout.fillWidth: true + onClicked: { + selectionLayout.item = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: rowBox + text: "Row" + Layout.fillWidth: true + onClicked: { + selectionLayout.row = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: columnBox + text: "Column" + Layout.fillWidth: true + onClicked: { + selectionLayout.column = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: sliceBox + text: "Slice" + Layout.fillWidth: true + onClicked: { + selectionLayout.slice = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: multiSeriesBox + text: "MultiSeries" + Layout.fillWidth: true + onClicked: { + selectionLayout.multi = checked + selectionLayout.composeSelectionMode() + } + } + } + } + } + } + + GraphsSection {} + + GraphsCameraSection {} +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsCameraSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsCameraSection.qml new file mode 100644 index 00000000000..dd7d64ee911 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsCameraSection.qml @@ -0,0 +1,189 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets +import QtQuick.Layouts +import StudioTheme as StudioTheme + +Section { + width: parent.width + caption: qsTr("Camera") + + SectionLayout { + PropertyLabel { + text: qsTr("Preset") + tooltip: qsTr("Camera preset") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.cameraPreset + model: ["NoPreset", "FrontLow", "Front", "FrontHigh", "LeftLow", + "Left", "LeftHigh", "RightLow", "Right", "RightHigh", "BehindLow", + "Behind", "BehindHigh", "IsometricLeft", "IsometricLeftHigh", + "IsometricRight", "IsometricRightHigh", "DirectlyAbove", + "DirectlyAboveCW45", "DirectlyAboveCCW45", "FrontBelow", + "LeftBelow", "RightBelow", "BehindBelow", "DirectlyBelow"] + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + scope: "Graphs3D" + } + } + PropertyLabel { + text: qsTr("Target") + tooltip: qsTr("Camera target position") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.cameraTargetPosition_x + minimumValue: -1.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + } + ControlLabel { + text: "X" + width: StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel {} + SecondColumnLayout { + SpinBox { + backendValue: backendValues.cameraTargetPosition_y + minimumValue: -1.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + } + ControlLabel { + text:"Y" + width: StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel {} + SecondColumnLayout { + SpinBox { + backendValue: backendValues.cameraTargetPosition_z + minimumValue: -1.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + } + ControlLabel { + text: "Z" + width: StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Zoom") + tooltip: qsTr("Camera zoom level") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.cameraZoomLevel + minimumValue: 0 + maximumValue: 500 + stepSize: 1 + decimals: 0 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Min Zoom") + tooltip: qsTr("Camera minimum zoom") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.minCameraZoomLevel + minimumValue: 0 + maximumValue: 500 + stepSize: 1 + decimals: 0 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Max Zoom") + tooltip: qsTr("Camera maximum zoom") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.maxCameraZoomLevel + minimumValue: 0 + maximumValue: 500 + stepSize: 1 + decimals: 0 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("X Rotation") + tooltip: qsTr("Camera X rotation") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.cameraXRotation + minimumValue: -180 + maximumValue: 180 + stepSize: 1 + decimals: 0 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Wrap X") + tooltip: qsTr("Wrap camera X rotation") + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.wrapCameraXRotation + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Y Rotation") + tooltip: qsTr("Camera Y rotation") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.cameraYRotation + minimumValue: 0 + maximumValue: 90 + stepSize: 1 + decimals: 0 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Wrap Y") + tooltip: qsTr("Wrap camera Y rotation") + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.wrapCameraYRotation + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Orthographic") + tooltip: qsTr("Use orthographic camera") + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.orthoProjection + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsSection.qml new file mode 100644 index 00000000000..ee97514b6b1 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsSection.qml @@ -0,0 +1,124 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets +import QtQuick.Layouts +import StudioTheme as StudioTheme + +Section { + width: parent.width + caption: qsTr("Graph") + + SectionLayout { + PropertyLabel { + text: qsTr("Render Mode") + tooltip: qsTr("Rendering mode") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.renderingMode + model: ["Indirect", "DirectToBackground"] + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + scope: "Graphs3D" + } + } + PropertyLabel { + text: qsTr("Shadow Quality") + tooltip: qsTr("Quality and style of the shadows") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.shadowQuality + model: ["None", "Low", "Medium", + "High", "SoftLow", "SoftMedium", + "SoftHigh"] + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + scope: "Graphs3D" + } + } + PropertyLabel { + text: qsTr("Optimization") + tooltip: qsTr("Optimization hint") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.optimizationHint + model: ["Default", "Legacy"] + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + scope: "Graphs3D" + } + } + PropertyLabel { + text: qsTr("MSAA") + tooltip: qsTr("Multisample anti-aliasing sample count") + } + SpinBox { + backendValue: backendValues.msaaSamples + minimumValue: 0 + maximumValue: 8 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + PropertyLabel { + text: qsTr("Aspect Ratio") + tooltip: qsTr("Horizontal to vertical aspect ratio") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.aspectRatio + minimumValue: 0.1 + maximumValue: 10.0 + stepSize: 0.1 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Horizontal AR") + tooltip: qsTr("Horizontal aspect ratio") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.horizontalAspectRatio + minimumValue: 0.1 + maximumValue: 10.0 + stepSize: 0.1 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Margin") + tooltip: qsTr("Graph background margin") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.margin + minimumValue: -1.0 + maximumValue: 100.0 + stepSize: 0.1 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Measure FPS") + tooltip: qsTr("Measure rendering speed as Frames Per Second") + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.measureFps + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + } +} + diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsViewSpecifics.qml new file mode 100644 index 00000000000..cb23b168ec4 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/GraphsViewSpecifics.qml @@ -0,0 +1,103 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets +import QtQuick.Layouts +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Background") + + SectionLayout { + PropertyLabel { + text: qsTr("Color") + } + + ColorEditor { + backendValue: backendValues.backgroundColor + supportGradient: false + } + } + } + + Section { + width: parent.width + caption: qsTr("Margins") + + SectionLayout { + rows: 4 + PropertyLabel { + text: qsTr("Top") + tooltip: qsTr("The amount of empty space on the top of the graph.") + } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.marginTop + minimumValue: 0.0 + maximumValue: 9999.0 + stepSize: 1.0 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + + PropertyLabel { + text: qsTr("Bottom") + tooltip: qsTr("The amount of empty space on the bottom of the graph.") + } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.marginBottom + minimumValue: 0.0 + maximumValue: 9999.0 + stepSize: 1.0 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + + PropertyLabel { + text: qsTr("Left") + tooltip: qsTr("The amount of empty space on the left of the graph.") + } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.marginLeft + minimumValue: 0.0 + maximumValue: 9999.0 + stepSize: 1.0 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + + PropertyLabel { + text: qsTr("Right") + tooltip: qsTr("The amount of empty space on the right of the graph.") + } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.marginRight + minimumValue: 0.0 + maximumValue: 9999.0 + stepSize: 1.0 + decimals: 1 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Scatter3DSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Scatter3DSpecifics.qml new file mode 100644 index 00000000000..03e3ca6debc --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Scatter3DSpecifics.qml @@ -0,0 +1,65 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets +import QtQuick.Layouts +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Scatter") + + SectionLayout { + PropertyLabel { + text: qsTr("Polar Coordinates") + tooltip: qsTr("Use polar coordinates") + } + SecondColumnLayout { + CheckBox { + id: polarCheckbox + backendValue: backendValues.polar + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Label Offset") + tooltip: qsTr("Normalized horizontal radial label offset") + visible: polarCheckbox.checked + } + SecondColumnLayout { + visible: polarCheckbox.checked + SpinBox { + backendValue: backendValues.radialLabelOffset + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + } + PropertyLabel { + text: qsTr("Selection Mode") + tooltip: qsTr("Scatter item selection mode") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.selectionMode + model: ["None", "Item"] + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + scope: "Graphs3D" + } + } + } + } + + GraphsSection {} + + GraphsCameraSection {} +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Surface3DSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Surface3DSpecifics.qml new file mode 100644 index 00000000000..66a1d65f87c --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtGraphs/Surface3DSpecifics.qml @@ -0,0 +1,192 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets +import QtQuick.Layouts +import QtQuick.Controls as Controls + +Column { + anchors.left: parent.left + anchors.right: parent.right + + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Surface") + + SectionLayout { + PropertyLabel { + text: qsTr("Flip Grid") + tooltip: qsTr("Flip horizontal grid") + Layout.fillWidth: true + } + SecondColumnLayout { + CheckBox { + backendValue: backendValues.flipHorizontalGrid + Layout.fillWidth: true + } + } + PropertyLabel { + text: qsTr("Polar Coordinates") + tooltip: qsTr("Use polar coordinates") + Layout.fillWidth: true + } + SecondColumnLayout { + CheckBox { + id: polarCheckbox + backendValue: backendValues.polar + Layout.fillWidth: true + } + } + PropertyLabel { + text: qsTr("Label Offset") + tooltip: qsTr("Normalized horizontal radial label offset") + Layout.fillWidth: true + visible: polarCheckbox.checked + } + SecondColumnLayout { + visible: polarCheckbox.checked + SpinBox { + backendValue: backendValues.radialLabelOffset + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0.01 + decimals: 2 + Layout.fillWidth: true + } + } + PropertyLabel { + text: qsTr("Selection Mode") + tooltip: qsTr("Surface point selection mode") + Layout.fillWidth: true + } + SecondColumnLayout { + id: selectionLayout + property bool isInModel: backendValue.isInModel; + property bool isInSubState: backendValue.isInSubState; + property bool selectionChangedFlag: selectionChanged + property variant backendValue: backendValues.selectionMode + property variant valueFromBackend: backendValue.value + property string enumScope: "Graphs3D.SelectionFlag" + property string enumSeparator: " | " + property int checkedCount: 0 + property bool item: false + property bool row: false + property bool column: false + property bool slice: false + property bool multi: false + + function checkValue(checkedVariable, variableText, expressionBase) { + var expressionStr = expressionBase + if (checkedVariable) { + if (expressionStr !== "") { + expressionStr += enumSeparator + } + expressionStr += enumScope + expressionStr += "." + expressionStr += variableText + checkedCount++ + } + return expressionStr + } + + function composeSelectionMode() { + var expressionStr = "" + checkedCount = 0 + expressionStr = checkValue(item, "Item", expressionStr) + expressionStr = checkValue(row, "Row", expressionStr) + expressionStr = checkValue(column, "Column", expressionStr) + expressionStr = checkValue(slice, "Slice", expressionStr) + expressionStr = checkValue(multi, "MultiSeries", expressionStr) + + if (checkedCount === 0) + backendValue.expression = enumScope + ".None" + else + backendValue.expression = expressionStr + } + + function evaluate() { + if (backendValue.value === undefined) + return + + item = (backendValue.expression.indexOf("Item") !== -1) + row = (backendValue.expression.indexOf("Row") !== -1) + column = (backendValue.expression.indexOf("Column") !== -1) + slice = (backendValue.expression.indexOf("Slice") !== -1) + multi = (backendValue.expression.indexOf("MultiSeries") !== -1) + + itemBox.checked = item + rowBox.checked = row + columnBox.checked = column + sliceBox.checked = slice + multiSeriesBox.checked = multi + } + + onSelectionChangedFlagChanged: evaluate() + + onIsInModelChanged: evaluate() + + onIsInSubStateChanged: evaluate() + + onBackendValueChanged: evaluate() + + onValueFromBackendChanged: evaluate() + + ColumnLayout { + anchors.fill: parent + + Controls.CheckBox { + id: itemBox + text: "Item" + Layout.fillWidth: true + onClicked: { + selectionLayout.item = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: rowBox + text: "Row" + Layout.fillWidth: true + onClicked: { + selectionLayout.row = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: columnBox + text: "Column" + Layout.fillWidth: true + onClicked: { + selectionLayout.column = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: sliceBox + text: "Slice" + Layout.fillWidth: true + onClicked: { + selectionLayout.slice = checked + selectionLayout.composeSelectionMode() + } + } + Controls.CheckBox { + id: multiSeriesBox + text: "MultiSeries" + Layout.fillWidth: true + onClicked: { + selectionLayout.multi = checked + selectionLayout.composeSelectionMode() + } + } + } + } + } + } + + GraphsSection {} + + GraphsCameraSection {} +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSection.qml new file mode 100644 index 00000000000..6dfe93f83ee --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSection.qml @@ -0,0 +1,85 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Box Shape") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Extents") + tooltip: qsTr("The extents of the box shape in the X, Y and Z directions.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.extents_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.extents_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.extents_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSpecifics.qml new file mode 100644 index 00000000000..c6ac4e6964f --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/BoxShapeSpecifics.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + BoxShapeSection { + width: parent.width + } + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSection.qml new file mode 100644 index 00000000000..2283f934489 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSection.qml @@ -0,0 +1,50 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Capsule Shape") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Diameter") + tooltip: qsTr("Sets the diameter of the capsule.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.diameter + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Height") + tooltip: qsTr("Sets the height of the capsule.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.height + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSpecifics.qml new file mode 100644 index 00000000000..eedfbb37e33 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CapsuleShapeSpecifics.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + CapsuleShapeSection { + width: parent.width + } + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSection.qml new file mode 100644 index 00000000000..b7c1d82baa7 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSection.qml @@ -0,0 +1,188 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Character Controller") + width: parent.width + + SectionLayout { + PropertyLabel { + text: "Gravity" + tooltip: "The gravitational acceleration that applies to the character." + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.gravity_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.gravity_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.gravity_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Movement" + tooltip: "The controlled motion of the character." + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.movement_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.movement_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.movement_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Mid Air Control" + tooltip: "Enables movement property to have an effect when the character is in free fall." + } + + SecondColumnLayout { + CheckBox { + text: backendValues.midAirControl.valueToString + backendValue: backendValues.midAirControl + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Enable ShapeHit Callback" + tooltip: "Enables the shapeHit callback for this character controller." + } + + SecondColumnLayout { + CheckBox { + text: backendValues.midAirControl.valueToString + backendValue: backendValues.enableShapeHitCallback + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSpecifics.qml new file mode 100644 index 00000000000..bc65d7ca752 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CharacterControllerSpecifics.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + CharacterControllerSection { + width: parent.width + } + + PhysicsBodySection { + width: parent.width + } + + PhysicsNodeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CollisionShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CollisionShapeSection.qml new file mode 100644 index 00000000000..8ab32582cea --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/CollisionShapeSection.qml @@ -0,0 +1,34 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Collision Shape") + + SectionLayout { + PropertyLabel { + text: qsTr("Debug Draw") + tooltip: qsTr("Draws the collision shape in the scene view.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.enableDebugDraw.valueToString + backendValue: backendValues.enableDebugDraw + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSection.qml new file mode 100644 index 00000000000..cc7fb9cc04a --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSection.qml @@ -0,0 +1,28 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Section { + caption: qsTr("Convex Mesh Shape") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Source") + tooltip: qsTr("Defines the location of the mesh file used to define the shape.") + } + + SecondColumnLayout { + UrlChooser { + id: sourceUrlChooser + backendValue: backendValues.source + filter: "*.mesh" + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSpecifics.qml new file mode 100644 index 00000000000..c4f4e325f7d --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/ConvexMeshShapeSpecifics.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + ConvexMeshShapeSection { + width: parent.width + } + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySection.qml new file mode 100644 index 00000000000..8574a37a5de --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySection.qml @@ -0,0 +1,658 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Dynamic Rigid Body") + + SectionLayout { + id: baseSectionLayout + + property bool isDefaultDensityMode: massModeComboBox.currentIndex === 0 + property bool isCustomDensityMode: massModeComboBox.currentIndex === 1 + property bool isMassMode: massModeComboBox.currentIndex === 2 + property bool isMassAndInertiaTensorMode: massModeComboBox.currentIndex === 3 + property bool isMassAndInertiaMatrixMode: massModeComboBox.currentIndex === 4 + + PropertyLabel { + text: "Mass Mode" + tooltip: "Describes how mass and inertia are calculated for this body." + } + + SecondColumnLayout { + ComboBox { + id: massModeComboBox + scope: "DynamicRigidBody" + model: ["DefaultDensity", "CustomDensity", "Mass", "MassAndInertiaTensor", "MassAndInertiaMatrix"] + backendValue: backendValues.massMode + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: baseSectionLayout.isMassAndInertiaMatrixMode || baseSectionLayout.isMassAndInertiaTensorMode + } + + SecondColumnLayout { + visible: baseSectionLayout.isMassAndInertiaMatrixMode || baseSectionLayout.isMassAndInertiaTensorMode + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + Label { + text: qsTr("Tensor and Matrix modes require QML code.") + Layout.fillWidth: true + Layout.preferredWidth: StudioTheme.Values.singleControlColumnWidth + Layout.minimumWidth: StudioTheme.Values.singleControlColumnWidth + Layout.maximumWidth: StudioTheme.Values.singleControlColumnWidth + } + } + + PropertyLabel { + visible: !baseSectionLayout.isDefaultDensityMode && !baseSectionLayout.isCustomDensityMode + text: "Mass" + tooltip: "The mass of the body." + } + + SecondColumnLayout { + visible: !baseSectionLayout.isDefaultDensityMode && !baseSectionLayout.isCustomDensityMode + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 2 + stepSize: 0.01 + backendValue: backendValues.mass + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: baseSectionLayout.isCustomDensityMode + text: "Density" + tooltip: "The density of the body." + } + + SecondColumnLayout { + visible: baseSectionLayout.isCustomDensityMode + SpinBox { + minimumValue: -1 + maximumValue: 9999999 + decimals: 2 + stepSize: 0.01 + backendValue: backendValues.density + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Enable Gravity" + tooltip: "Sets if the body affected by gravity." + } + + SecondColumnLayout { + CheckBox { + text: backendValues.gravityEnabled.valueToString + backendValue: backendValues.gravityEnabled + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Linear Axis Lock" + tooltip: "Lock the linear axis of the body." + } + + SecondColumnLayout { + ActionIndicator { + id: linearAxisLockController + icon.color: extFuncLogic.color + icon.text: extFuncLogic.glyph + onClicked: extFuncLogic.show() + forceVisible: extFuncLogic.menuVisible + visible: true + + property var enableLockX: { "value": false, "isInModel": false} + property var enableLockY: { "value": false, "isInModel": false} + property var enableLockZ: { "value": false, "isInModel": false} + + property variant backendValue: backendValues.linearAxisLock + property variant valueFromBackend: backendValue === undefined ? 0 : backendValue.value + property bool blockLocks: false + + onBackendValueChanged: evaluateLocks() + onValueFromBackendChanged: evaluateLocks() + + Connections { + target: modelNodeBackend + function onSelectionChanged() { + evaluateLevels() + } + } + + Component.onCompleted: evaluateLocks() + + function evaluateLocks() { + blockLocks = true + enableLockX = { "value": valueFromBackend & 1, "isInModel": false} + enableLockY = { "value": valueFromBackend & 2, "isInModel": false} + enableLockZ = { "value": valueFromBackend & 4, "isInModel": false} + blockLocks = false + } + + function composeExpressionString() { + if (blockLocks) + return + + let expressionStr = ""; + + if (enableLockX.value || enableLockY.value || enableLockY.value) { + if (enableLockX.value) + expressionStr += " | DynamicRigidBody.LockX"; + if (enableLockY.value) + expressionStr += " | DynamicRigidBody.LockY"; + if (enableLockZ.value) + expressionStr += " | DynamicRigidBody.LockZ"; + + expressionStr = expressionStr.substring(3); + + backendValue.expression = expressionStr + } else { + expressionStr = "DynamicRigidBody.None"; + backendValue.expression = expressionStr + } + } + ExtendedFunctionLogic { + id: extFuncLogic + backendValue: backendValues.linearAxisLock + onReseted: { + linearAxisLockController.enableLockX = { "value": false, "isInModel": false} + linearAxisLockController.enableLockY = { "value": false, "isInModel": false} + linearAxisLockController.enableLockZ = { "value": false, "isInModel": false} + linearAxisLockController.evaluateLocks() + } + } + } + } + PropertyLabel { + // spacer + } + + SecondColumnLayout { + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + text: qsTr("Lock X") + backendValue: linearAxisLockController.enableLockX + actionIndicatorVisible: false + onCheckedChanged: linearAxisLockController.composeExpressionString() + implicitWidth: StudioTheme.Values.twoControlColumnWidth + } + + ExpandingSpacer {} + } + PropertyLabel { + // spacer + } + + SecondColumnLayout { + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + text: qsTr("Lock Y") + backendValue: linearAxisLockController.enableLockY + actionIndicatorVisible: false + onCheckedChanged: linearAxisLockController.composeExpressionString() + implicitWidth: StudioTheme.Values.twoControlColumnWidth + } + + ExpandingSpacer {} + } + PropertyLabel { + // spacer + } + + SecondColumnLayout { + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + text: qsTr("Lock Z") + backendValue: linearAxisLockController.enableLockZ + actionIndicatorVisible: false + onCheckedChanged: linearAxisLockController.composeExpressionString() + implicitWidth: StudioTheme.Values.twoControlColumnWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Angular Axis Lock" + tooltip: "Lock the angular axis of the body." + } + + SecondColumnLayout { + ActionIndicator { + id: angularAxisLockController + icon.color: extFuncLogicAngular.color + icon.text: extFuncLogicAngular.glyph + onClicked: extFuncLogicAngular.show() + forceVisible: extFuncLogic.menuVisible + visible: true + + property var enableLockX: { "value": false, "isInModel": false} + property var enableLockY: { "value": false, "isInModel": false} + property var enableLockZ: { "value": false, "isInModel": false} + + property variant backendValue: backendValues.angularAxisLock + property variant valueFromBackend: backendValue === undefined ? 0 : backendValue.value + property bool blockLocks: false + + onBackendValueChanged: evaluateLocks() + onValueFromBackendChanged: evaluateLocks() + + Connections { + target: modelNodeBackend + function onSelectionChanged() { + evaluateLevels() + } + } + + Component.onCompleted: evaluateLocks() + + function evaluateLocks() { + blockLocks = true + enableLockX = { "value": valueFromBackend & 1, "isInModel": false} + enableLockY = { "value": valueFromBackend & 2, "isInModel": false} + enableLockZ = { "value": valueFromBackend & 4, "isInModel": false} + blockLocks = false + } + + function composeExpressionString() { + if (blockLocks) + return + + let expressionStr = ""; + + if (enableLockX.value || enableLockY.value || enableLockY.value) { + if (enableLockX.value) + expressionStr += " | DynamicRigidBody.LockX"; + if (enableLockY.value) + expressionStr += " | DynamicRigidBody.LockY"; + if (enableLockZ.value) + expressionStr += " | DynamicRigidBody.LockZ"; + + expressionStr = expressionStr.substring(3); + + backendValue.expression = expressionStr + } else { + expressionStr = "DynamicRigidBody.None"; + backendValue.expression = expressionStr + } + } + ExtendedFunctionLogic { + id: extFuncLogicAngular + backendValue: backendValues.angularAxisLock + onReseted: { + angularAxisLockController.enableLockX = { "value": false, "isInModel": false} + angularAxisLockController.enableLockY = { "value": false, "isInModel": false} + angularAxisLockController.enableLockZ = { "value": false, "isInModel": false} + angularAxisLockController.evaluateLocks() + } + } + } + } + PropertyLabel { + // spacer + } + + SecondColumnLayout { + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + text: qsTr("Lock X") + backendValue: angularAxisLockController.enableLockX + actionIndicatorVisible: false + onCheckedChanged: angularAxisLockController.composeExpressionString() + implicitWidth: StudioTheme.Values.twoControlColumnWidth + } + + ExpandingSpacer {} + } + PropertyLabel { + // spacer + } + + SecondColumnLayout { + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + text: qsTr("Lock Y") + backendValue: angularAxisLockController.enableLockY + actionIndicatorVisible: false + onCheckedChanged: angularAxisLockController.composeExpressionString() + implicitWidth: StudioTheme.Values.twoControlColumnWidth + } + + ExpandingSpacer {} + } + PropertyLabel { + // spacer + } + + SecondColumnLayout { + + Item { + // spacer for the always hiden action indicator + width: StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + text: qsTr("Lock Z") + backendValue: angularAxisLockController.enableLockZ + actionIndicatorVisible: false + onCheckedChanged: angularAxisLockController.composeExpressionString() + implicitWidth: StudioTheme.Values.twoControlColumnWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: "Is Kinematic" + tooltip: "Kinematic objects are not influenced by external forces and can be seen as an object of infinite mass." + } + + SecondColumnLayout { + CheckBox { + id: isKinematicCheckBox + text: backendValues.isKinematic.valueToString + backendValue: backendValues.isKinematic + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + text: "Kinematic Position" + tooltip: "The position of the kinematic object." + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicPosition_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicPosition_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicPosition_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + text: "Kinematic Rotation" + tooltip: "The rotation of the kinematic object." + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicEulerRotation_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicEulerRotation_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicEulerRotation_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + text: "Kinematic Pivot" + tooltip: "The pivot point of the kinematic object." + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicPivot_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicPivot_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + visible: isKinematicCheckBox.checked + } + + SecondColumnLayout { + visible: isKinematicCheckBox.checked + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.kinematicPivot_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } + } +} + + // Other Properties Not covered by the UI + // QVector3D inertiaTensor + // QVector3D centerOfMassPosition + // QQuaternion centerOfMassRotation + // List inertiaMatrix (9 floats for a Mat3x3) + diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySpecifics.qml new file mode 100644 index 00000000000..7322d3339be --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/DynamicRigidBodySpecifics.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + DynamicRigidBodySection { + width: parent.width + } + + PhysicsBodySection { + width: parent.width + } + + PhysicsNodeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSection.qml new file mode 100644 index 00000000000..80c6f428e97 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSection.qml @@ -0,0 +1,98 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Height Field Shape") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Source") + tooltip: qsTr("Sets the location of an image file containing the heightmap data.") + } + + SecondColumnLayout { + UrlChooser { + backendValue: backendValues.source + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Extents") + tooltip: qsTr("The extents of the height field shape in the X, Y and Z directions.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.extents_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.extents_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.extents_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSpecifics.qml new file mode 100644 index 00000000000..22aa0348b71 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/HeightFieldShapeSpecifics.qml @@ -0,0 +1,23 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + HeightFieldShapeSection { + width: parent.width + } + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/NodeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/NodeSection.qml new file mode 100644 index 00000000000..45dfe72a77d --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/NodeSection.qml @@ -0,0 +1,350 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Node") + + SectionLayout { + PropertyLabel { + text: qsTr("Opacity") + tooltip: qsTr("Sets the local opacity value of the node.") + } + + SecondColumnLayout { + // ### should be a slider + SpinBox { + minimumValue: 0 + maximumValue: 1 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.opacity + sliderIndicatorVisible: true + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Visibility") + tooltip: qsTr("Sets the local visibility of the node.") + } + + SecondColumnLayout { + // ### should be a slider + CheckBox { + text: qsTr("Is Visible") + backendValue: backendValues.visible + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } + } + + Section { + id: transformSection + width: parent.width + caption: qsTr("Transform") + + ColumnLayout { + spacing: StudioTheme.Values.transform3DSectionSpacing + + SectionLayout { + PropertyLabel { + text: qsTr("Translation") + tooltip: qsTr("Sets the translation of the node.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } + + SectionLayout { + PropertyLabel { + text: qsTr("Rotation") + tooltip: qsTr("Sets the rotation of the node in degrees.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.eulerRotation_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.eulerRotation_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.eulerRotation_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } + + SectionLayout { + PropertyLabel { + text: qsTr("Scale") + tooltip: qsTr("Sets the scale of the node.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.scale_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.scale_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.scale_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } + + SectionLayout { + PropertyLabel { + text: qsTr("Pivot") + tooltip: qsTr("Sets the pivot of the node.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.pivot_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.pivot_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel {} + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.pivot_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsBodySection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsBodySection.qml new file mode 100644 index 00000000000..8f5d67f4a42 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsBodySection.qml @@ -0,0 +1,34 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + caption: qsTr("Physics Body") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Physics Material") + tooltip: qsTr("The physics material of the body.") + } + + SecondColumnLayout { + ItemFilterComboBox { + typeFilter: "QtQuick3D.Physics.PhysicsMaterial" + backendValue: backendValues.physicsMaterial + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSection.qml new file mode 100644 index 00000000000..3e0c08655ea --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSection.qml @@ -0,0 +1,69 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Physics Material") + width: parent.width + + SectionLayout { + PropertyLabel { + text: "Static Friction" + tooltip: "The friction coefficient of the material when it is not moving." + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 2 + stepSize: 0.01 + backendValue: backendValues.staticFriction + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + ExpandingSpacer {} + } + + PropertyLabel { + text: "Dynamic Friction" + tooltip: "The friction coefficient of the material when it is moving." + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 2 + stepSize: 0.01 + backendValue: backendValues.dynamicFriction + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + ExpandingSpacer {} + } + + PropertyLabel { + text: "Restitution" + tooltip: "The coefficient of restitution of the material." + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 1 + decimals: 2 + stepSize: 0.01 + sliderIndicatorVisible: true + backendValue: backendValues.restitution + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSpecifics.qml new file mode 100644 index 00000000000..95ebaf70127 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsMaterialSpecifics.qml @@ -0,0 +1,13 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + PhysicsMaterialSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsNodeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsNodeSection.qml new file mode 100644 index 00000000000..26fdf0e4d87 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsNodeSection.qml @@ -0,0 +1,103 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Physics Node") + + SectionLayout { + PropertyLabel { + text: qsTr("Collision Shapes") + Layout.alignment: Qt.AlignTop + Layout.topMargin: 5 + } + + SecondColumnLayout { + EditableListView { + backendValue: backendValues.collisionShapes + model: backendValues.collisionShapes.expressionAsList + Layout.fillWidth: true + typeFilter: "QtQuick3D.Physics.CollisionShape" + + onAdd: function(value) { backendValues.collisionShapes.idListAdd(value) } + onRemove: function(idx) { backendValues.collisionShapes.idListRemove(idx) } + onReplace: function (idx, value) { backendValues.collisionShapes.idListReplace(idx, value) } + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Receive Contact Reports") + tooltip: qsTr("Determines whether this body will receive contact reports when colliding with other bodies.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.receiveContactReports.valueToString + backendValue: backendValues.receiveContactReports + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Send Contact Reports") + tooltip: qsTr("Determines whether this body will send contact reports when colliding with other bodies.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.sendContactReports.valueToString + backendValue: backendValues.sendContactReports + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Receive Trigger Reports") + tooltip: qsTr("Determines whether this body will receive reports when entering or leaving a trigger body.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.receiveTriggerReports.valueToString + backendValue: backendValues.receiveTriggerReports + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Send Trigger Reports") + tooltip: qsTr("Determines whether this body will send contact reports when colliding with other bodies.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.sendTriggerReports.valueToString + backendValue: backendValues.sendTriggerReports + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSection.qml new file mode 100644 index 00000000000..3299e984bec --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSection.qml @@ -0,0 +1,266 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Physics World") + width: parent.width + + SectionLayout { + // Q_PROPERTY(QQuick3DNode *scene + PropertyLabel { + text: qsTr("Scene") + tooltip: qsTr("The scene node to which the physics world is attached.") + } + + SecondColumnLayout { + ItemFilterComboBox { + typeFilter: "QtQuick3D.Node" + backendValue: backendValues.scene + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(QQuick3DNode *viewport + PropertyLabel { + text: qsTr("Viewport") + tooltip: qsTr("The node to which the debug geometry of the physics world is added.") + } + + SecondColumnLayout { + ItemFilterComboBox { + typeFilter: "QtQuick3D.Node" + backendValue: backendValues.viewport + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(bool running) + PropertyLabel { + text: qsTr("Running") + tooltip: qsTr("Whether the physics world is running.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.running.valueToString + backendValue: backendValues.running + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(bool forceDebugDraw + PropertyLabel { + text: qsTr("Force Debug Draw") + tooltip: qsTr("Whether to force debug drawing of the physics world.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.forceDebugDraw.valueToString + backendValue: backendValues.forceDebugDraw + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(bool enableCCD + PropertyLabel { + text: qsTr("CCD") + tooltip: qsTr("Whether to enable continuous collision detection.") + } + + SecondColumnLayout { + CheckBox { + text: backendValues.enableCCD.valueToString + backendValue: backendValues.enableCCD + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(QVector3D gravity) + PropertyLabel { + text: qsTr("Gravity") + tooltip: qsTr("The gravity vector.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.gravity_x + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + color: StudioTheme.Values.theme3DAxisXColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.gravity_y + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + color: StudioTheme.Values.theme3DAxisYColor + } + + ExpandingSpacer {} + } + + PropertyLabel { + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 2 + backendValue: backendValues.gravity_z + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Z" + color: StudioTheme.Values.theme3DAxisZColor + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(float typicalLength) + PropertyLabel { + text: qsTr("Typical Length") + tooltip: qsTr("The typical length of objects in the scene.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0.00001 + maximumValue: 9999999 + decimals: 5 + backendValue: backendValues.typicalLength + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(float typicalSpeed + PropertyLabel { + text: qsTr("Typical Speed") + tooltip: qsTr("The typical speed of objects in the scene.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0.00001 + maximumValue: 9999999 + decimals: 5 + backendValue: backendValues.typicalSpeed + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(float defaultDensity) + PropertyLabel { + text: qsTr("Default Density") + tooltip: qsTr("The default density of objects in the scene.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0.00001 + maximumValue: 9999999 + decimals: 5 + backendValue: backendValues.defaultDensity + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(float minimumTimestep) + PropertyLabel { + text: qsTr("Min Timestep") + tooltip: qsTr("Defines the minimum simulation timestep in milliseconds.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0.001 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.minimumTimestep + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + + // Q_PROPERTY(float maximumTimestep) + PropertyLabel { + text: qsTr("Max Timestep") + tooltip: qsTr("Defines the maximum simulation timestep in milliseconds.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0.001 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.maximumTimestep + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSpecifics.qml new file mode 100644 index 00000000000..2c29985fd94 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PhysicsWorldSpecifics.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + PhysicsWorldSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PlaneShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PlaneShapeSpecifics.qml new file mode 100644 index 00000000000..0410b5fbf98 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/PlaneShapeSpecifics.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSection.qml new file mode 100644 index 00000000000..44db7cb322b --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSection.qml @@ -0,0 +1,32 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Sphere Shape") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Diameter") + tooltip: qsTr("Sets the diameter of the capsule.") + } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 3 + backendValue: backendValues.diameter + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSpecifics.qml new file mode 100644 index 00000000000..abee2e31069 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/SphereShapeSpecifics.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + SphereShapeSection { + width: parent.width + } + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/StaticRigidBodySpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/StaticRigidBodySpecifics.qml new file mode 100644 index 00000000000..1dc7c4806b0 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/StaticRigidBodySpecifics.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + PhysicsBodySection { + width: parent.width + } + + PhysicsNodeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSection.qml new file mode 100644 index 00000000000..53959a3aa25 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSection.qml @@ -0,0 +1,29 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme + +Section { + caption: qsTr("Triangle Mesh Shape") + width: parent.width + + SectionLayout { + PropertyLabel { + text: qsTr("Source") + tooltip: qsTr("Defines the location of the mesh file used to define the shape.") + } + + SecondColumnLayout { + UrlChooser { + id: sourceUrlChooser + backendValue: backendValues.source + filter: "*.mesh" + } + + ExpandingSpacer {} + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSpecifics.qml new file mode 100644 index 00000000000..a428872f294 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriangleMeshShapeSpecifics.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + TriangleMeshShapeSection { + width: parent.width + } + + CollisionShapeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriggerBodySpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriggerBodySpecifics.qml new file mode 100644 index 00000000000..f341e48b691 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Physics/TriggerBodySpecifics.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets + +Column { + width: parent.width + + PhysicsNodeSection { + width: parent.width + } + + NodeSection { + width: parent.width + } +} diff --git a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp index 25e92fe2ab0..3ae8a554585 100644 --- a/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/project/qmldesignerprojectmanager.cpp @@ -407,6 +407,11 @@ namespace { if constexpr (useProjectStorage()) { auto qmlRootPath = qmlPath(target); qmldirPaths.push_back(qmlRootPath + "/QML"); + qmldirPaths.push_back(qmlRootPath + "/Qt"); + // TODO: Charts plugins.qmltypes needs to be fixed before QtCharts can be added (QTBUG-115358) + //qmldirPaths.push_back(qmlRootPath + "/QtCharts"); + // TODO: Graphs plugins.qmltypes needs to be fixed before QtGraphs can be added (QTBUG-135402) + //qmldirPaths.push_back(qmlRootPath + "/QtGraphs"); qmldirPaths.push_back(qmlRootPath + "/QtQml"); qmldirPaths.push_back(qmlRootPath + "/QtQuick"); qmldirPaths.push_back(qmlRootPath + "/QtQuick3D"); From 7c11cd1a1eac5e6016aa04ed2bb617a3d172758b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Thu, 10 Apr 2025 21:46:43 +0200 Subject: [PATCH 58/82] QmlDesigner: fix shutdown crash via Q_GLOBAL_STATIC singleton - Ensures proper lazy initialization and destruction order - Prevents null accesses during shutdown (triggered by missing null-checks in qtddeclarative QQuickShaderEffect) Change-Id: Ibcce41441b7472e483a3f36c27cf8acfbf45b0c8 Reviewed-by: Mahmoud Badri Reviewed-by: Tim Jenssen --- .../qmldesigner/effectComposerQmlSources/BlurHelper.qml | 5 +++-- .../effectComposerQmlSources/EffectComposerPreview.qml | 5 +++-- src/plugins/effectcomposer/compositionnode.cpp | 6 +++--- src/plugins/effectcomposer/effectcomposermodel.cpp | 4 ++-- .../effectcomposer/effectcomposeruniformsmodel.cpp | 4 ++-- src/plugins/effectcomposer/effectcomposerwidget.cpp | 7 ++++--- src/plugins/effectcomposer/propertyhandler.cpp | 8 +++++++- src/plugins/effectcomposer/propertyhandler.h | 9 ++++++--- src/plugins/effectcomposer/uniform.cpp | 2 +- 9 files changed, 31 insertions(+), 19 deletions(-) diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml index 80577e932a1..733f0a15a0b 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml @@ -4,6 +4,7 @@ // This file should match the BlurHelper.qml in qtquickdesigner repository, except for shader paths import QtQuick +import EffectComposerPropertyData Item { id: rootItem @@ -20,8 +21,8 @@ Item { visible: false layer.enabled: true layer.smooth: true - vertexShader: g_propertyData?.blur_vs_path ?? "" - fragmentShader: g_propertyData?.blur_fs_path ?? "" + vertexShader: GlobalPropertyData?.blur_vs_path ?? "" + fragmentShader: GlobalPropertyData?.blur_fs_path ?? "" } QtObject { diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml index 920d02a304b..7c7f167e07b 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml @@ -7,6 +7,7 @@ import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme import EffectComposerBackend +import EffectComposerPropertyData Column { id: root @@ -298,8 +299,8 @@ Column { BlurHelper { id: blurHelper source: source - property int blurMax: g_propertyData?.blur_helper_max_level ?? 64 - property real blurMultiplier: g_propertyData?.blurMultiplier ?? 0 + property int blurMax: GlobalPropertyData?.blur_helper_max_level ?? 64 + property real blurMultiplier: GlobalPropertyData?.blurMultiplier ?? 0 } Item { diff --git a/src/plugins/effectcomposer/compositionnode.cpp b/src/plugins/effectcomposer/compositionnode.cpp index 1792952c3c9..ba3dd38cfcd 100644 --- a/src/plugins/effectcomposer/compositionnode.cpp +++ b/src/plugins/effectcomposer/compositionnode.cpp @@ -210,7 +210,7 @@ void CompositionNode::parse(const QString &effectName, const QString &qenPath, c for (const QJsonValueConstRef &prop : jsonProps) { const auto uniform = new Uniform(effectName, prop.toObject(), qenPath); m_uniformsModel.addUniform(uniform); - g_propertyData.insert(uniform->name(), uniform->value()); + g_propertyData()->insert(uniform->name(), uniform->value()); if (uniform->type() == Uniform::Type::Define) { // Changing defines requires rebaking the shaders connect(uniform, &Uniform::uniformValueChanged, this, &CompositionNode::rebakeRequested); @@ -335,7 +335,7 @@ void CompositionNode::openCodeEditor() void CompositionNode::addUniform(const QVariantMap &data) { const auto uniform = new Uniform({}, QJsonObject::fromVariantMap(data), {}); - g_propertyData.insert(uniform->name(), uniform->value()); + g_propertyData()->insert(uniform->name(), uniform->value()); m_uniformsModel.addUniform(uniform); updateAreUniformsInUse(true); } @@ -346,7 +346,7 @@ void CompositionNode::updateUniform(int index, const QVariantMap &data) const auto uniform = new Uniform({}, QJsonObject::fromVariantMap(data), {}); - g_propertyData.insert(uniform->name(), uniform->value()); + g_propertyData()->insert(uniform->name(), uniform->value()); m_uniformsModel.updateUniform(index, uniform); updateAreUniformsInUse(true); } diff --git a/src/plugins/effectcomposer/effectcomposermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp index b4dd306ad4d..e7c9d5e707a 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.cpp +++ b/src/plugins/effectcomposer/effectcomposermodel.cpp @@ -2547,8 +2547,8 @@ QString EffectComposerModel::getQmlComponentString(bool localFiles) s += l3 + "id: blurHelper\n"; s += l3 + "source: rootItem.source\n"; int blurMax = 32; - if (g_propertyData.contains("BLUR_HELPER_MAX_LEVEL")) - blurMax = g_propertyData["BLUR_HELPER_MAX_LEVEL"].toInt(); + if (g_propertyData()->contains("BLUR_HELPER_MAX_LEVEL")) + blurMax = g_propertyData()->value("BLUR_HELPER_MAX_LEVEL").toInt(); s += l3 + QString("property int blurMax: %1\n").arg(blurMax); s += l3 + "property real blurMultiplier: rootItem.blurMultiplier\n"; s += l2 + "}\n"; diff --git a/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp b/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp index 1a48cee7b99..47b37f08cf0 100644 --- a/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp +++ b/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp @@ -68,10 +68,10 @@ bool EffectComposerUniformsModel::setData(const QModelIndex &index, const QVaria updatedValue = QUrl::fromLocalFile(path).toString(); uniform->setValue(updatedValue); - g_propertyData.insert(uniform->name(), updatedValue); + g_propertyData()->insert(uniform->name(), updatedValue); } else { uniform->setValue(value); - g_propertyData.insert(uniform->name(), value); + g_propertyData()->insert(uniform->name(), value); } emit dataChanged(index, index, {role}); diff --git a/src/plugins/effectcomposer/effectcomposerwidget.cpp b/src/plugins/effectcomposer/effectcomposerwidget.cpp index 838b41ca7ae..2c953bc79bd 100644 --- a/src/plugins/effectcomposer/effectcomposerwidget.cpp +++ b/src/plugins/effectcomposer/effectcomposerwidget.cpp @@ -100,11 +100,12 @@ EffectComposerWidget::EffectComposerWidget(EffectComposerView *view) QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(this, QmlDesigner::Constants::EVENT_EFFECTCOMPOSER_TIME); - m_quickWidget->rootContext()->setContextProperty("g_propertyData", &g_propertyData); + qmlRegisterSingletonInstance( + "EffectComposerPropertyData", 1, 0, "GlobalPropertyData", g_propertyData()); QString blurPath = "file:" + EffectUtils::nodesSourcesPath() + "/common/"; - g_propertyData.insert(QString("blur_vs_path"), QString(blurPath + "bluritems.vert.qsb")); - g_propertyData.insert(QString("blur_fs_path"), QString(blurPath + "bluritems.frag.qsb")); + g_propertyData()->insert("blur_vs_path", QString(blurPath + "bluritems.vert.qsb")); + g_propertyData()->insert("blur_fs_path", QString(blurPath + "bluritems.frag.qsb")); auto map = m_quickWidget->registerPropertyMap("EffectComposerBackend"); map->setProperties({{"effectComposerNodesModel", QVariant::fromValue(effectComposerNodesModel().data())}, diff --git a/src/plugins/effectcomposer/propertyhandler.cpp b/src/plugins/effectcomposer/propertyhandler.cpp index b440410a0bf..44e04ce810f 100644 --- a/src/plugins/effectcomposer/propertyhandler.cpp +++ b/src/plugins/effectcomposer/propertyhandler.cpp @@ -3,8 +3,14 @@ #include "propertyhandler.h" +#include + namespace EffectComposer { -QQmlPropertyMap g_propertyData; +Q_GLOBAL_STATIC(QQmlPropertyMap, globalEffectComposerPropertyData) +QQmlPropertyMap *g_propertyData() +{ + return globalEffectComposerPropertyData(); +} } diff --git a/src/plugins/effectcomposer/propertyhandler.h b/src/plugins/effectcomposer/propertyhandler.h index 96bc49f78e0..5d685a1f948 100644 --- a/src/plugins/effectcomposer/propertyhandler.h +++ b/src/plugins/effectcomposer/propertyhandler.h @@ -3,13 +3,16 @@ #pragma once -#include +#include + +QT_BEGIN_NAMESPACE +class QQmlPropertyMap; +QT_END_NAMESPACE namespace EffectComposer { // This will be used for binding dynamic properties // changes between C++ and QML. -extern QQmlPropertyMap g_propertyData; - +QQmlPropertyMap *g_propertyData(); } diff --git a/src/plugins/effectcomposer/uniform.cpp b/src/plugins/effectcomposer/uniform.cpp index 149db291a70..aad3fc571b4 100644 --- a/src/plugins/effectcomposer/uniform.cpp +++ b/src/plugins/effectcomposer/uniform.cpp @@ -47,7 +47,7 @@ Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QS m_enableMipmap = getBoolValue(propObj.value("enableMipmap"), false); // Update the mipmap property QString mipmapProperty = mipmapPropertyName(m_name); - g_propertyData[mipmapProperty] = m_enableMipmap; + g_propertyData()->insert(mipmapProperty, m_enableMipmap); } QString controlType = propObj.value("controlType").toString(); From 13092d905c41a2bdeb43bf28ae9490c9788f8beb Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Fri, 11 Apr 2025 01:26:48 +0300 Subject: [PATCH 59/82] QmlDesigner: Add a tooltip option to HelperWidgets.Section's caption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic266daa53d1daab4b7b38927eafe4cc939bb3ac2 Reviewed-by: Henning Gründl --- .../imports/HelperWidgets/Section.qml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml index 0f192f8875f..4cc0c747f73 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml @@ -13,6 +13,7 @@ Item { readonly property bool __isSection: true // used by property search logic property string caption: "Title" + property string captionTooltip: "" property color labelColor: StudioTheme.Values.themeTextColor property int labelCapitalization: Font.AllUppercase property alias sectionHeight: header.height @@ -40,6 +41,20 @@ Item { font.capitalization: section.labelCapitalization anchors.verticalCenter: parent?.verticalCenter textFormat: Text.RichText + + MouseArea { + id: labelMouseArea + + anchors.fill: parent + acceptedButtons: Qt.NoButton + hoverEnabled: true + enabled: section.captionTooltip !== "" + } + + StudioControls.ToolTip { + visible: labelMouseArea.containsMouse + text: section.captionTooltip + } } property Item icons From 71c4762c99bbe5b625188b8b3546361934ae1fda Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 11 Apr 2025 11:48:10 +0200 Subject: [PATCH 60/82] QmlDesigner: Add missing publicly included header The public header nodemetainfo.h includes it, so it must be included in the dev package, otherwise building the qtquickdesigner repository fails when done against the dev package. Amends 58d2a88e9c3b9f5d21310b6e282a30fe63a24cae Change-Id: Ic3083e482b7deb15ed5f9d5ced0327b0f8589359 Reviewed-by: Marco Bubke --- src/plugins/qmldesigner/libs/designercore/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt index b5f529c8e3a..3a7196d412a 100644 --- a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt +++ b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt @@ -162,6 +162,7 @@ extend_qtc_library(QmlDesignerCore SOURCES_PREFIX tracing SOURCES qmldesignertracing.cpp qmldesignertracing.h + qmldesignertracingsourcelocation.h ) extend_qtc_library(QmlDesignerCore From a0f6adc12e28a66da3aa36acd4c8d81e5d24ff25 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Fri, 11 Apr 2025 12:37:06 +0300 Subject: [PATCH 61/82] QmlDesigner: Show full path in tooltips of the content lib categories For custom folder categories under user tab. Fixes: QDS-15154 Change-Id: I7760ebc3dcd5e2e67dad50f74b6d784e573f9750 Reviewed-by: Miikka Heikkinen --- .../contentLibraryQmlSource/ContentLibraryUserView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml index eb708a80872..15e36666d96 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml @@ -133,6 +133,7 @@ Item { bottomPadding: StudioTheme.Values.sectionPadding caption: categoryTitle + captionTooltip: section.isCustomCat ? categoryBundlePath : "" dropEnabled: true category: "ContentLib_User" showCloseButton: section.isCustomCat From 83a68d04ae8e48846a01c3b7e53b829d9f116440 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Apr 2025 14:36:56 +0300 Subject: [PATCH 62/82] QmlDesigner: Fix invalid section caption on complex properties Custom generated sections for complex exposed local properties now show the proper section caption instead of default "Title". Fixes: QDS-15045 Change-Id: I9e4d5b9c7731eaecece16c6b187496748b755bee Reviewed-by: Mahmoud Badri --- .../components/componentcore/propertycomponentgenerator.cpp | 2 +- .../componentcore/propertycomponentgenerator-test.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp index 1b9e7c409e2..9c349f3dec6 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp @@ -128,7 +128,7 @@ QString PropertyComponentGenerator::generateComplexComponentText(Utils::SmallStr static QString templateText = QStringLiteral( R"xy( Section { - caption: %1 - %2 + caption: "%1 - %2" anchors.left: parent.left anchors.right: parent.right leftPadding: 8 diff --git a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp index 2a5f5cd87e3..facce0fa5e9 100644 --- a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp @@ -223,7 +223,7 @@ TEST_F(PropertyComponentGenerator, QString expectedText = QStringLiteral( R"xy( Section { - caption: foo - Foo + caption: "foo - Foo" anchors.left: parent.left anchors.right: parent.right leftPadding: 8 @@ -256,7 +256,7 @@ TEST_F(PropertyComponentGenerator, QString expectedText = QStringLiteral( R"xy( Section { - caption: foo - Foo + caption: "foo - Foo" anchors.left: parent.left anchors.right: parent.right leftPadding: 8 From 8dbc5475c6cb280ca593b108402d8ec1a17efaf6 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 11 Apr 2025 14:42:19 +0200 Subject: [PATCH 63/82] QmlDesigner: Add more ids to discouraged ids These ids match type names and likely collide with properties. Change-Id: I1ca9db9f11698c5e6e459e3569c75c3f66ca2777 Reviewed-by: Marco Bubke --- .../libs/designercore/designercoreutils/modelutils.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp index c22b9175c55..7e3d703db9e 100644 --- a/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp @@ -116,6 +116,8 @@ constexpr auto qmlDiscouragedIds = toSortedArray(u"action", u"baseState", u"border", u"bottom", + u"button", + u"checkbox", u"clip", u"data", u"enabled", @@ -128,9 +130,11 @@ constexpr auto qmlDiscouragedIds = toSortedArray(u"action", u"layer", u"left", u"margin", + u"mouseArea", u"opacity", u"padding", u"parent", + u"rectangle", u"right", u"scale", u"shaderInfo", @@ -139,7 +143,10 @@ constexpr auto qmlDiscouragedIds = toSortedArray(u"action", u"spriteSequence", u"state", u"stateGroup", + u"switch", u"text", + u"textedit", + u"textinput", u"texture", u"time", u"top", From 21a6368db5de2fb660cb5bb1c7bbf6e3583b8086 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Apr 2025 12:53:30 +0300 Subject: [PATCH 64/82] QmlDesigner: Reset old QMLJS code model when new types are added Code view warnings/errors still come from the old QMLJS code model, so we need to reset it after importing new types. Fixes: QDS-15167 Change-Id: Ifd80f69bac29108702b0d98bfa3c6ac353a12424 Reviewed-by: Thomas Hartmann --- .../componentcore/bundleimporter.cpp | 19 ++++++++++++++----- .../components/componentcore/bundleimporter.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp b/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp index e83757a549a..7a5b5e69532 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp @@ -12,9 +12,7 @@ #include #include -#ifndef QDS_USE_PROJECTSTORAGE #include -#endif #include #include @@ -54,9 +52,9 @@ QString BundleImporter::importComponent(const QString &bundleDir, if (!bundleImportPath.exists() && !bundleImportPath.createDir()) return QStringLiteral("Failed to create bundle import folder: '%1'").arg(bundleImportPath.toUrlishString()); + bool doReset = false; #ifndef QDS_USE_PROJECTSTORAGE bool doScan = false; - bool doReset = false; #endif FilePath qmldirPath = bundleImportPath.pathAppended("qmldir"); QString qmldirContent = QString::fromUtf8(qmldirPath.fileContents().value_or(QByteArray())); @@ -81,9 +79,7 @@ QString BundleImporter::importComponent(const QString &bundleDir, qmldirContent.append(qmlFile); qmldirContent.append('\n'); qmldirPath.writeFileContents(qmldirContent.toUtf8()); -#ifndef QDS_USE_PROJECTSTORAGE doReset = true; -#endif } QStringList allFiles; @@ -129,6 +125,7 @@ QString BundleImporter::importComponent(const QString &bundleDir, Import import = Import::createLibraryImport(module, "1.0"); #ifdef QDS_USE_PROJECTSTORAGE model->changeImports({import}, {}); + m_pendingFullReset = doReset; #else if (doScan) data.pathToScan = bundleImportPath; @@ -163,6 +160,7 @@ void BundleImporter::handleImportTimer() auto handleFailure = [this] { m_importTimer.stop(); m_importTimerCount = 0; + m_pendingFullReset = false; // Emit dummy finished signals for all pending types const QList pendingTypes = m_pendingImports.keys(); @@ -198,6 +196,17 @@ void BundleImporter::handleImportTimer() } } + if (keys.size() > 0) + return; // Do the code model reset/cleanup on next timer tick + + if (m_pendingFullReset) { + m_pendingFullReset = false; + // Force code model reset to notice changes to existing module + auto modelManager = QmlJS::ModelManagerInterface::instance(); + if (modelManager) + modelManager->resetCodeModel(); + } + if (m_pendingImports.isEmpty()) { m_bundleId.clear(); m_importTimer.stop(); diff --git a/src/plugins/qmldesigner/components/componentcore/bundleimporter.h b/src/plugins/qmldesigner/components/componentcore/bundleimporter.h index 3c743bfe55b..9a346225894 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundleimporter.h +++ b/src/plugins/qmldesigner/components/componentcore/bundleimporter.h @@ -56,6 +56,7 @@ private: bool isImport = true; // false = unimport TypeName type; }; + bool m_pendingFullReset = false; // Reset old QMLJS code model (it's used for code view warnings) #else struct ImportData { From dae1d22c2a21ed0964f95d38411dc6c64c78e241 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Apr 2025 16:06:36 +0300 Subject: [PATCH 65/82] QmlDesigner: Allow removing modules in item library Since we have no information currently about modules being in use, we allow removing any module except QtQuick in item library, as it must be possible to remove modules somehow. Fixes: QDS-15123 Change-Id: Id0ad463f4fa580e8585335f0d01b693e4a15c4e7 Reviewed-by: Thomas Hartmann --- .../components/itemlibrary/itemlibraryimport.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp index bdac4a78cb5..80f4dd7405d 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp @@ -239,8 +239,12 @@ ItemLibraryImport::SectionType ItemLibraryImport::sectionType() const void ItemLibraryImport::updateRemovable() { +#ifdef QDS_USE_PROJECTSTORAGE + bool importRemovable = m_sectionType == SectionType::Default && m_import.url() != "QtQuick"; +#else bool importRemovable = !m_importUsed && m_sectionType == SectionType::Default - && m_import.url() != "QtQuick"; + && m_import.url() != "QtQuick"; +#endif if (importRemovable != m_importRemovable) { m_importRemovable = importRemovable; emit importRemovableChanged(); From e9919c5e4ccf5b8a174b1b918a6a9c5173329549 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Thu, 3 Apr 2025 14:59:25 +0300 Subject: [PATCH 66/82] QmlDesigner: Update paste action on clipboard changes Fixes: QDS-10999 Change-Id: I03e477be64036ffbd3baf2c2286406f3ef2ae2b7 Reviewed-by: David Schulz --- src/plugins/texteditor/texteditor.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 2560315ad70..8bd65c7018f 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -877,6 +877,7 @@ public: void updateRedoAction(); void updateUndoAction(); void updateCopyAction(bool on); + void updatePasteAction(); public: TextEditorWidget *q; @@ -1074,6 +1075,7 @@ public: QAction *m_copyAction = nullptr; QAction *m_copyHtmlAction = nullptr; QAction *m_cutAction = nullptr; + QAction *m_pasteAction = nullptr; QAction *m_autoIndentAction = nullptr; QAction *m_autoFormatAction = nullptr; QAction *m_visualizeWhitespaceAction = nullptr; @@ -1272,6 +1274,8 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) connect(q, &QPlainTextEdit::copyAvailable, this, &TextEditorWidgetPrivate::updateCopyAction); + connect(qApp->clipboard(), &QClipboard::changed, this, &TextEditorWidgetPrivate::updatePasteAction); + m_parenthesesMatchingTimer.setSingleShot(true); m_parenthesesMatchingTimer.setInterval(50); connect(&m_parenthesesMatchingTimer, &QTimer::timeout, @@ -4257,11 +4261,13 @@ void TextEditorWidgetPrivate::registerActions() .addOnTriggered([this] { q->cut(); }) .setScriptable(true) .contextAction(); - m_modifyingActions << ActionBuilder(this, PASTE) - .setContext(m_editorContext) - .addOnTriggered([this] { q->paste(); }) - .setScriptable(true) - .contextAction(); + m_pasteAction = ActionBuilder(this, PASTE) + .setContext(m_editorContext) + .addOnTriggered([this] { q->paste(); }) + .setScriptable(true) + .contextAction(); + m_modifyingActions << m_pasteAction; + ActionBuilder(this, SELECTALL) .setContext(m_editorContext) .setScriptable(true) @@ -4710,7 +4716,7 @@ void TextEditorWidgetPrivate::updateActions() updateRedoAction(); updateUndoAction(); updateCopyAction(q->textCursor().hasSelection()); - + updatePasteAction(); updateOptionalActions(); } @@ -4755,6 +4761,12 @@ void TextEditorWidgetPrivate::updateCopyAction(bool hasCopyableText) m_copyHtmlAction->setEnabled(hasCopyableText); } +void TextEditorWidgetPrivate::updatePasteAction() +{ + if (m_pasteAction) + m_pasteAction->setEnabled(!q->isReadOnly() && !qApp->clipboard()->text(QClipboard::Mode::Clipboard).isEmpty()); +} + bool TextEditorWidget::codeFoldingVisible() const { return d->m_codeFoldingVisible; From 95d2bc5c41de063a04ec4267ec030a02c071cd97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Fri, 11 Apr 2025 18:01:28 +0200 Subject: [PATCH 67/82] QmlDesigner: add nodesSourcesPath to warning Pick-to: qds/4.7 Change-Id: Iee8f7eb9f652d2a75c44e6c4fd5ea08baa4cdb40 Reviewed-by: Tim Jenssen --- src/plugins/effectcomposer/effectcomposernodesmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/effectcomposer/effectcomposernodesmodel.cpp b/src/plugins/effectcomposer/effectcomposernodesmodel.cpp index 6b0eea8f615..18733a776a9 100644 --- a/src/plugins/effectcomposer/effectcomposernodesmodel.cpp +++ b/src/plugins/effectcomposer/effectcomposernodesmodel.cpp @@ -52,7 +52,7 @@ void EffectComposerNodesModel::loadModel() auto nodesPath = Utils::FilePath::fromString(EffectUtils::nodesSourcesPath()); if (!nodesPath.exists()) { - qWarning() << __FUNCTION__ << "Effects not found."; + qWarning() << __FUNCTION__ << "Effects not found in: " << nodesPath; return; } From a8541126c49fd1653ff22ce6f3dad4431f427196 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 12 Apr 2025 01:15:46 +0200 Subject: [PATCH 68/82] QmlDesigner: Use std::ranges in ListModelEditorModel Change-Id: Icd0bfb1bf468169ecd90c17ab9946d6ceab88f8a Reviewed-by: Ali Kianian --- .../listmodeleditor/listmodeleditormodel.cpp | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp index 02c1de2e0ad..6d5197b1bb5 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp @@ -15,9 +15,12 @@ #include #include #include +#include namespace QmlDesigner { +namespace { + class ListModelItem : public QStandardItem { public: @@ -92,7 +95,6 @@ public: bool hasInvalidValue = false; }; -namespace { QList getPropertyNames(const ModelNode &listElementNode) { auto properties = listElementNode.variantProperties(); @@ -103,7 +105,7 @@ QList getPropertyNames(const ModelNode &listElementNode) for (const auto &property : properties) names.push_back(property.name().toByteArray()); - std::sort(names.begin(), names.end()); + std::ranges::sort(names); return names; } @@ -114,11 +116,7 @@ QList mergeProperyNames(const QList &first, QList merged; merged.reserve(first.size() + second.size()); - std::set_union(first.begin(), - first.end(), - second.begin(), - second.end(), - std::back_inserter(merged)); + std::ranges::set_union(first, second, std::back_inserter(merged)); return merged; } @@ -262,7 +260,7 @@ void ListModelEditorModel::addColumn(const QString &columnName) { PropertyName propertyName = columnName.toUtf8(); - auto found = std::lower_bound(m_propertyNames.begin(), m_propertyNames.end(), propertyName); + auto found = std::ranges::lower_bound(m_propertyNames, propertyName); if (found != m_propertyNames.end() && *found == propertyName) return; @@ -298,21 +296,21 @@ void ListModelEditorModel::removeColumn(int column) void ListModelEditorModel::removeColumns(const QList &indices) { + using std::ranges::views::reverse; + std::vector columns = filterColumns(indices); - std::reverse(columns.begin(), columns.end()); - - for (int column : columns) + for (int column : columns | reverse) removeColumn(column); } void ListModelEditorModel::removeRows(const QList &indices) { + using std::ranges::views::reverse; + std::vector rows = filterRows(indices); - std::reverse(rows.begin(), rows.end()); - - for (int row : rows) + for (int row : rows | reverse) removeRow(row); } @@ -330,7 +328,7 @@ void ListModelEditorModel::renameColumn(int oldColumn, const QString &newColumnN { const PropertyName newPropertyName = newColumnName.toUtf8(); - auto found = std::lower_bound(m_propertyNames.begin(), m_propertyNames.end(), newPropertyName); + auto found = std::ranges::lower_bound(m_propertyNames, newPropertyName); if (found != m_propertyNames.end() && *found == newPropertyName) return; @@ -374,6 +372,8 @@ QItemSelection ListModelEditorModel::moveRowsUp(const QList &indice QItemSelection ListModelEditorModel::moveRowsDown(const QList &indices) { + using std::ranges::views::reverse; + std::vector rows = filterRows(indices); if (rows.empty() || rows.back() >= (rowCount() - 1)) @@ -381,29 +381,35 @@ QItemSelection ListModelEditorModel::moveRowsDown(const QList &indi auto nodeListProperty = m_listModelNode.defaultNodeListProperty(); - std::reverse(rows.begin(), rows.end()); - - for (int row : rows) { + for (int row : rows | reverse) { insertRow(row + 1, takeRow(row)); nodeListProperty.slide(row, row + 1); } - return {index(rows.front() + 1, 0), index(rows.back() + 1, columnCount() - 1)}; + return {index(rows.back() + 1, 0), index(rows.front() + 1, columnCount() - 1)}; } +namespace { +void removeDuplicates(std::vector &container) +{ + std::ranges::sort(container); + + auto removed = std::ranges::unique(container); + container.erase(removed.begin(), removed.end()); +} +} // namespace + std::vector ListModelEditorModel::filterColumns(const QList &indices) { std::vector columns; - columns.reserve(indices.size()); + columns.reserve(Utils::usize(indices)); for (QModelIndex index : indices) { if (index.column() >= 0) columns.push_back(index.column()); } - std::sort(columns.begin(), columns.end()); - - columns.erase(std::unique(columns.begin(), columns.end()), columns.end()); + removeDuplicates(columns); return columns; } @@ -411,16 +417,14 @@ std::vector ListModelEditorModel::filterColumns(const QList &i std::vector ListModelEditorModel::filterRows(const QList &indices) { std::vector rows; - rows.reserve(indices.size()); + rows.reserve(Utils::usize(indices)); for (QModelIndex index : indices) { if (index.row() >= 0) rows.push_back(index.row()); } - std::sort(rows.begin(), rows.end()); - - rows.erase(std::unique(rows.begin(), rows.end()), rows.end()); + removeDuplicates(rows); return rows; } From e871146b29415ab8cffef41c04e2f1bb50c6c777 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 12 Apr 2025 11:40:43 +0200 Subject: [PATCH 69/82] Utils: Use likely attribute Change-Id: Iace372facd11c101a0f0a1b11ca585b374f42f1e Reviewed-by: Thomas Hartmann --- src/libs/utils/smallstringlayout.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/libs/utils/smallstringlayout.h b/src/libs/utils/smallstringlayout.h index 6e33e3010c4..e4c0f1f9176 100644 --- a/src/libs/utils/smallstringlayout.h +++ b/src/libs/utils/smallstringlayout.h @@ -119,7 +119,7 @@ struct alignas(16) StringDataLayout StringDataLayout(const char *string, size_type size, size_type capacity) noexcept { - if (Q_LIKELY(capacity <= shortStringCapacity())) { + if (capacity <= shortStringCapacity()) [[likely]] { control = Internal::ControlBlock(size, false, false); std::char_traits::copy(shortString, string, size); } else { @@ -181,11 +181,20 @@ struct alignas(16) StringDataLayout constexpr bool isReadOnlyReference() const noexcept { return control.isReadOnlyReference(); } - char *data() noexcept { return Q_LIKELY(isShortString()) ? shortString : reference.pointer; } + char *data() noexcept + { + if (isShortString()) [[likely]] + return shortString; + else + return reference.pointer; + } const char *data() const noexcept { - return Q_LIKELY(isShortString()) ? shortString : reference.pointer; + if (isShortString()) [[likely]] + return shortString; + else + return reference.pointer; } void setPointer(char *p) noexcept { reference.pointer = p; } @@ -266,7 +275,7 @@ struct alignas(16) StringDataLayout(size)} , capacity_{static_cast(std::max(capacity, MaximumShortStringDataAreaSize))} { - if (Q_LIKELY(capacity <= shortStringCapacity())) { + if (capacity <= shortStringCapacity()) [[likely]] { std::char_traits::copy(buffer, string, size); pointer = buffer; } else { From 3fb47c674a61ba385f7cc7c7d944c9b0b4246c98 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 12 Apr 2025 22:40:08 +0200 Subject: [PATCH 70/82] QmlDesigner: Use span for model nodes parameter So we can support other container like QVarLenghtArray and std::vector. Change-Id: I2853eddc5b1cc3f1cc65ef1ceacaa6ed4bdea6c6 Reviewed-by: Aleksei German --- .../libs/designercore/include/abstractview.h | 4 +- .../libs/designercore/include/model.h | 16 ++-- .../libs/designercore/model/model.cpp | 79 ++++++++++--------- .../libs/designercore/model/model_p.h | 18 ++--- 4 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/abstractview.h b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h index aace9320aa1..0a684162f4d 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h @@ -225,11 +225,11 @@ public: void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion); void emitCustomNotification(const QString &identifier, - const QList &nodeList = {}, + Utils::span nodes = {}, const QList &data = {}) { if (isAttached()) - model()->emitCustomNotification(this, identifier, nodeList, data); + model()->emitCustomNotification(this, identifier, nodes, data); } const AbstractView *nodeInstanceView() const; diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 262b2078283..fe4c5b74a55 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -266,7 +266,7 @@ public: const QList &warnings); QList selectedNodes(AbstractView *view) const; - void setSelectedModelNodes(const QList &selectedNodeList); + void setSelectedModelNodes(Utils::span selectedNodes); void clearMetaInfoCache(); @@ -291,14 +291,14 @@ public: ProjectStorageDependencies projectStorageDependencies() const; void emitInstancePropertyChange(AbstractView *view, - const QList> &propertyList); - void emitInstanceErrorChange(AbstractView *view, const QVector &instanceIds); - void emitInstancesCompleted(AbstractView *view, const QVector &nodeList); + Utils::span> properties); + void emitInstanceErrorChange(AbstractView *view, Utils::span instanceIds); + void emitInstancesCompleted(AbstractView *view, Utils::span nodes); void emitInstanceInformationsChange( AbstractView *view, const QMultiHash &informationChangeHash); - void emitInstancesRenderImageChanged(AbstractView *view, const QVector &nodeList); - void emitInstancesPreviewImageChanged(AbstractView *view, const QVector &nodeList); - void emitInstancesChildrenChanged(AbstractView *view, const QVector &nodeList); + void emitInstancesRenderImageChanged(AbstractView *view, Utils::span nodes); + void emitInstancesPreviewImageChanged(AbstractView *view, Utils::span nodes); + void emitInstancesChildrenChanged(AbstractView *view, Utils::span nodes); void emitInstanceToken(AbstractView *view, const QString &token, int number, @@ -318,7 +318,7 @@ public: void emitDocumentMessage(const QString &error); void emitCustomNotification(AbstractView *view, const QString &identifier, - const QList &nodeList = {}, + Utils::span nodes = {}, const QList &data = {}); void sendCustomNotificationTo(AbstractView *to, const CustomNotificationPackage &package); diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 9e1b6959c59..31ae2875df6 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -664,12 +664,12 @@ void ModelPrivate::notifyRootNodeTypeChanged(const QString &type, int majorVersi [&](AbstractView *view) { view->rootNodeTypeChanged(type, majorVersion, minorVersion); }); } -void ModelPrivate::notifyInstancePropertyChange(const QList> &propertyPairList) +void ModelPrivate::notifyInstancePropertyChange(Utils::span> properties) { notifyInstanceChanges([&](AbstractView *view) { using ModelNodePropertyPair = QPair; QList> adaptedPropertyList; - for (const ModelNodePropertyPair &propertyPair : propertyPairList) { + for (const ModelNodePropertyPair &propertyPair : properties) { ModelNodePropertyPair newPair(ModelNode{propertyPair.first.internalNode(), m_model, view}, propertyPair.second); adaptedPropertyList.append(newPair); } @@ -677,20 +677,20 @@ void ModelPrivate::notifyInstancePropertyChange(const QList &instanceIds) +void ModelPrivate::notifyInstanceErrorChange(Utils::span instanceIds) { notifyInstanceChanges([&](AbstractView *view) { QVector errorNodeList; - errorNodeList.reserve(instanceIds.size()); + errorNodeList.reserve(std::ssize(instanceIds)); for (qint32 instanceId : instanceIds) errorNodeList.emplace_back(m_model->d->nodeForInternalId(instanceId), m_model, view); view->instanceErrorChanged(errorNodeList); }); } -void ModelPrivate::notifyInstancesCompleted(const QVector &modelNodeVector) +void ModelPrivate::notifyInstancesCompleted(Utils::span modelNodes) { - auto internalNodes = toInternalNodeList(modelNodeVector); + auto internalNodes = toInternalNodeList(modelNodes); notifyInstanceChanges([&](AbstractView *view) { view->instancesCompleted(toModelNodeList(internalNodes, view)); @@ -718,27 +718,27 @@ void ModelPrivate::notifyInstancesInformationsChange( }); } -void ModelPrivate::notifyInstancesRenderImageChanged(const QVector &modelNodeVector) +void ModelPrivate::notifyInstancesRenderImageChanged(Utils::span nodes) { - auto internalNodes = toInternalNodeList(modelNodeVector); + auto internalNodes = toInternalNodeList(nodes); notifyInstanceChanges([&](AbstractView *view) { view->instancesRenderImageChanged(toModelNodeList(internalNodes, view)); }); } -void ModelPrivate::notifyInstancesPreviewImageChanged(const QVector &modelNodeVector) +void ModelPrivate::notifyInstancesPreviewImageChanged(Utils::span nodes) { - auto internalNodes = toInternalNodeList(modelNodeVector); + auto internalNodes = toInternalNodeList(nodes); notifyInstanceChanges([&](AbstractView *view) { view->instancesPreviewImageChanged(toModelNodeList(internalNodes, view)); }); } -void ModelPrivate::notifyInstancesChildrenChanged(const QVector &modelNodeVector) +void ModelPrivate::notifyInstancesChildrenChanged(Utils::span nodes) { - auto internalNodes = toInternalNodeList(modelNodeVector); + auto internalNodes = toInternalNodeList(nodes); notifyInstanceChanges([&](AbstractView *view) { view->instancesChildrenChanged(toModelNodeList(internalNodes, view)); @@ -812,10 +812,11 @@ void ModelPrivate::notifyRewriterEndTransaction() notifyNodeInstanceViewLast([&](AbstractView *view) { view->rewriterEndTransaction(); }); } -void ModelPrivate::notifyInstanceToken(const QString &token, int number, - const QVector &modelNodeVector) +void ModelPrivate::notifyInstanceToken(const QString &token, + int number, + Utils::span nodes) { - auto internalNodes = toInternalNodeList(modelNodeVector); + auto internalNodes = toInternalNodeList(nodes); notifyInstanceChanges([&](AbstractView *view) { view->instancesToken(token, number, toModelNodeList(internalNodes, view)); @@ -824,10 +825,10 @@ void ModelPrivate::notifyInstanceToken(const QString &token, int number, void ModelPrivate::notifyCustomNotification(const AbstractView *senderView, const QString &identifier, - const QList &modelNodeList, + Utils::span nodes, const QList &data) { - auto internalList = toInternalNodeList(modelNodeList); + auto internalList = toInternalNodeList(nodes); notifyNodeInstanceViewLast([&](AbstractView *view) { view->customNotification(senderView, identifier, toModelNodeList(internalList, view), data); }); @@ -1229,22 +1230,22 @@ void ModelPrivate::removeAuxiliaryData(const InternalNodePointer &node, const Au notifyAuxiliaryDataChanged(node, key, QVariant()); } -QList ModelPrivate::toModelNodeList(Utils::span nodeList, +QList ModelPrivate::toModelNodeList(Utils::span nodes, AbstractView *view) const { QList modelNodeList; - modelNodeList.reserve(nodeList.size()); - for (const InternalNodePointer &node : nodeList) + modelNodeList.reserve(std::ssize(nodes)); + for (const InternalNodePointer &node : nodes) modelNodeList.emplace_back(node, m_model, view); return modelNodeList; } -ModelPrivate::ManyNodes ModelPrivate::toInternalNodeList(const QList &modelNodeList) const +ModelPrivate::ManyNodes ModelPrivate::toInternalNodeList(Utils::span modelNodes) const { ManyNodes newNodeList; - newNodeList.reserve(modelNodeList.size()); - for (const ModelNode &modelNode : modelNodeList) + newNodeList.reserve(std::ssize(modelNodes)); + for (const ModelNode &modelNode : modelNodes) newNodeList.append(modelNode.internalNode()); return newNodeList; @@ -1813,7 +1814,7 @@ QmlDesigner::Imports createPossibleFileImports(const Utils::FilePath &path) bool append = false; item.iterateDirectory( - [&](const Utils::FilePath &item) { + [&](const Utils::FilePath &) { append = true; return Utils::IterationPolicy::Stop; }, @@ -2062,22 +2063,22 @@ ProjectStorageDependencies Model::projectStorageDependencies() const } void Model::emitInstancePropertyChange(AbstractView *view, - const QList> &propertyList) + Utils::span> properties) { if (d->nodeInstanceView() == view) // never remove check - d->notifyInstancePropertyChange(propertyList); + d->notifyInstancePropertyChange(properties); } -void Model::emitInstanceErrorChange(AbstractView *view, const QVector &instanceIds) +void Model::emitInstanceErrorChange(AbstractView *view, Utils::span instanceIds) { if (d->nodeInstanceView() == view) // never remove check d->notifyInstanceErrorChange(instanceIds); } -void Model::emitInstancesCompleted(AbstractView *view, const QVector &nodeVector) +void Model::emitInstancesCompleted(AbstractView *view, Utils::span nodes) { if (d->nodeInstanceView() == view) // never remove check - d->notifyInstancesCompleted(nodeVector); + d->notifyInstancesCompleted(nodes); } void Model::emitInstanceInformationsChange( @@ -2087,22 +2088,22 @@ void Model::emitInstanceInformationsChange( d->notifyInstancesInformationsChange(informationChangeHash); } -void Model::emitInstancesRenderImageChanged(AbstractView *view, const QVector &nodeVector) +void Model::emitInstancesRenderImageChanged(AbstractView *view, Utils::span nodes) { if (d->nodeInstanceView() == view) // never remove check - d->notifyInstancesRenderImageChanged(nodeVector); + d->notifyInstancesRenderImageChanged(nodes); } -void Model::emitInstancesPreviewImageChanged(AbstractView *view, const QVector &nodeVector) +void Model::emitInstancesPreviewImageChanged(AbstractView *view, Utils::span nodes) { if (d->nodeInstanceView() == view) // never remove check - d->notifyInstancesPreviewImageChanged(nodeVector); + d->notifyInstancesPreviewImageChanged(nodes); } -void Model::emitInstancesChildrenChanged(AbstractView *view, const QVector &nodeVector) +void Model::emitInstancesChildrenChanged(AbstractView *view, Utils::span nodes) { if (d->nodeInstanceView() == view) // never remove check - d->notifyInstancesChildrenChanged(nodeVector); + d->notifyInstancesChildrenChanged(nodes); } void Model::emitInstanceToken(AbstractView *view, @@ -2165,10 +2166,10 @@ void Model::emitDocumentMessage(const QList &errors, void Model::emitCustomNotification(AbstractView *view, const QString &identifier, - const QList &nodeList, + Utils::span nodes, const QList &data) { - d->notifyCustomNotification(view, identifier, nodeList, data); + d->notifyCustomNotification(view, identifier, nodes, data); } void Model::sendCustomNotificationTo(AbstractView *to, const CustomNotificationPackage &package) @@ -2300,11 +2301,11 @@ QList Model::selectedNodes(AbstractView *view) const return d->toModelNodeList(d->selectedNodes(), view); } -void Model::setSelectedModelNodes(const QList &selectedNodeList) +void Model::setSelectedModelNodes(Utils::span selectedNodes) { QList unlockedNodes; - for (const auto &modelNode : selectedNodeList) { + for (const auto &modelNode : selectedNodes) { if (!ModelUtils::isThisOrAncestorLocked(modelNode)) unlockedNodes.push_back(modelNode); } diff --git a/src/plugins/qmldesigner/libs/designercore/model/model_p.h b/src/plugins/qmldesigner/libs/designercore/model/model_p.h index b2a8a31d692..1dc8c0de2ab 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/libs/designercore/model/model_p.h @@ -195,17 +195,17 @@ public: void notifyCustomNotification(const AbstractView *senderView, const QString &identifier, - const QList &modelNodeList, + Utils::span nodes, const QList &data); void notifyCustomNotificationTo(AbstractView *view, const CustomNotificationPackage &package); - void notifyInstancePropertyChange(const QList> &propertyList); - void notifyInstanceErrorChange(const QVector &instanceIds); - void notifyInstancesCompleted(const QVector &modelNodeVector); + void notifyInstancePropertyChange(Utils::span> properties); + void notifyInstanceErrorChange(Utils::span instanceIds); + void notifyInstancesCompleted(Utils::span modelNodes); void notifyInstancesInformationsChange(const QMultiHash &informationChangeHash); - void notifyInstancesRenderImageChanged(const QVector &modelNodeVector); - void notifyInstancesPreviewImageChanged(const QVector &modelNodeVector); - void notifyInstancesChildrenChanged(const QVector &modelNodeVector); - void notifyInstanceToken(const QString &token, int number, const QVector &modelNodeVector); + void notifyInstancesRenderImageChanged(Utils::span nodes); + void notifyInstancesPreviewImageChanged(Utils::span nodes); + void notifyInstancesChildrenChanged(Utils::span nodes); + void notifyInstanceToken(const QString &token, int number, Utils::span nodes); void notifyCurrentStateChanged(const ModelNode &node); void notifyCurrentTimelineChanged(const ModelNode &node); @@ -334,7 +334,7 @@ private: void removePropertyWithoutNotification(InternalProperty *property); void removeAllSubNodes(const InternalNodePointer &node); void removeNodeFromModel(const InternalNodePointer &node); - ManyNodes toInternalNodeList(const QList &modelNodeList) const; + ManyNodes toInternalNodeList(Utils::span modelNodes) const; QList toModelNodeList(Utils::span nodeList, AbstractView *view) const; static QList toInternalProperties(const AbstractProperties &properties); From e257904359639a0d67aa5a08c554f87b46190273 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 12 Apr 2025 01:56:47 +0200 Subject: [PATCH 71/82] QmlDesigner: Use span for static property names Since we change much of the API to PropertyNameView we can generate it at compile time. Change-Id: Ifb4482c346b6e50af74987a9c2ec03a6e75e6e1d Reviewed-by: Aleksei German --- .../filemanager/addobjectvisitor.cpp | 2 +- .../filemanager/addobjectvisitor.h | 4 +- .../filemanager/addpropertyvisitor.cpp | 2 +- .../filemanager/addpropertyvisitor.h | 4 +- .../filemanager/moveobjectvisitor.cpp | 6 +- .../filemanager/moveobjectvisitor.h | 4 +- .../filemanager/qmlrefactoring.cpp | 10 +- .../designercore/filemanager/qmlrefactoring.h | 6 +- .../designercore/filemanager/qmlrewriter.cpp | 51 +++++++---- .../designercore/filemanager/qmlrewriter.h | 9 +- .../rewriter/modeltotextmerger.cpp | 91 ++++++++++--------- .../designercore/rewriter/modeltotextmerger.h | 2 +- .../rewriter/qmltextgenerator.cpp | 4 +- .../designercore/rewriter/qmltextgenerator.h | 4 +- .../rewriter/rewriteactioncompressor.h | 9 +- 15 files changed, 116 insertions(+), 92 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp index 2edb8d8fcab..728686ff098 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp @@ -12,7 +12,7 @@ AddObjectVisitor::AddObjectVisitor(QmlDesigner::TextModifier &modifier, quint32 parentLocation, quint32 nodeLocation, const QString &content, - const PropertyNameList &propertyOrder) + Utils::span propertyOrder) : QMLRewriter(modifier) , m_parentLocation(parentLocation) , m_nodeLocation(nodeLocation) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h index b74a7c7d5bb..d63dcc35be7 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h @@ -15,7 +15,7 @@ public: quint32 parentLocation, quint32 nodeLocation, const QString &content, - const PropertyNameList &propertyOrder); + Utils::span propertyOrder); protected: bool visit(QmlJS::AST::UiObjectBinding *ast) override; @@ -28,7 +28,7 @@ private: quint32 m_parentLocation; quint32 m_nodeLocation; QString m_content; - PropertyNameList m_propertyOrder; + Utils::span m_propertyOrder; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.cpp index 76b36d16cd6..17ae83d782f 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.cpp @@ -13,7 +13,7 @@ AddPropertyVisitor::AddPropertyVisitor(TextModifier &modifier, PropertyNameView name, const QString &value, QmlRefactoring::PropertyType propertyType, - const PropertyNameList &propertyOrder, + Utils::span propertyOrder, const TypeName &dynamicTypeName) : QMLRewriter(modifier) , m_parentLocation(parentLocation) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.h index 4710ecfb54d..8a1ca4158d3 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.h @@ -18,7 +18,7 @@ public: PropertyNameView name, const QString &value, QmlRefactoring::PropertyType propertyType, - const PropertyNameList &propertyOrder, + Utils::span propertyOrder, const TypeName &dynamicTypeName); protected: @@ -33,7 +33,7 @@ private: PropertyNameView m_name; QString m_value; QmlRefactoring::PropertyType m_propertyType; - PropertyNameList m_propertyOrder; + Utils::span m_propertyOrder; TypeName m_dynamicTypeName; }; diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.cpp index 73165b3f14f..c3ac04a64bb 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.cpp @@ -21,7 +21,7 @@ public: PropertyNameView targetPropertyName, bool targetIsArrayBinding, TextModifier::MoveInfo moveInfo, - const PropertyNameList &propertyOrder) + Utils::span propertyOrder) : QMLRewriter(modifier) , targetParentObjectLocation(targetParentObjectLocation) , targetPropertyName(targetPropertyName) @@ -127,7 +127,7 @@ private: PropertyNameView targetPropertyName; bool targetIsArrayBinding; TextModifier::MoveInfo moveInfo; - PropertyNameList propertyOrder; + Utils::span propertyOrder; }; MoveObjectVisitor::MoveObjectVisitor(TextModifier &modifier, @@ -135,7 +135,7 @@ MoveObjectVisitor::MoveObjectVisitor(TextModifier &modifier, PropertyNameView targetPropertyName, bool targetIsArrayBinding, quint32 targetParentObjectLocation, - const PropertyNameList &propertyOrder) + Utils::span propertyOrder) : QMLRewriter(modifier) , objectLocation(objectLocation) , targetPropertyName(targetPropertyName) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.h index 5619261b540..68f61b5342f 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.h @@ -16,7 +16,7 @@ public: PropertyNameView targetPropertyName, bool targetIsArrayBinding, quint32 targetParentObjectLocation, - const PropertyNameList &propertyOrder); + Utils::span propertyOrder); bool operator ()(QmlJS::AST::UiProgram *ast) override; @@ -34,7 +34,7 @@ private: PropertyNameView targetPropertyName; bool targetIsArrayBinding; quint32 targetParentObjectLocation; - PropertyNameList propertyOrder; + Utils::span propertyOrder; QmlJS::AST::UiProgram *program; }; diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp index d71cf854e67..34c0aa331a5 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp @@ -20,10 +20,12 @@ using namespace QmlJS; using namespace QmlDesigner; using namespace QmlDesigner::Internal; -QmlRefactoring::QmlRefactoring(const Document::Ptr &doc, TextModifier &modifier, const PropertyNameList &propertyOrder): - qmlDocument(doc), - textModifier(&modifier), - m_propertyOrder(propertyOrder) +QmlRefactoring::QmlRefactoring(const Document::Ptr &doc, + TextModifier &modifier, + Utils::span propertyOrder) + : qmlDocument(doc) + , textModifier(&modifier) + , m_propertyOrder(propertyOrder) { } diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h index 34894eb76f8..18460db592b 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h @@ -25,7 +25,9 @@ public: }; public: - QmlRefactoring(const QmlJS::Document::Ptr &doc, QmlDesigner::TextModifier &modifier, const PropertyNameList &propertyOrder); + QmlRefactoring(const QmlJS::Document::Ptr &doc, + QmlDesigner::TextModifier &modifier, + Utils::span propertyOrder); bool reparseDocument(); @@ -57,7 +59,7 @@ public: private: QmlJS::Document::Ptr qmlDocument; TextModifier *textModifier; - PropertyNameList m_propertyOrder; + Utils::span m_propertyOrder; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp index 77021f02324..ae0fc1c56c2 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp @@ -197,10 +197,23 @@ void QMLRewriter::includeLeadingEmptyLine(int &start) const start = prevBlock.position(); } -// FIXME: duplicate code in the QmlJS::Rewriter class, remove this -QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, const QmlDesigner::PropertyNameList &propertyOrder) +namespace { +int indexOf(Utils::span properties, + QmlDesigner::PropertyNameView name) { - const int objectDefinitionInsertionPoint = propertyOrder.indexOf(PropertyName()); // XXX ???? + auto found = std::ranges::find(properties, name); + if (found == properties.end()) + return -1; + + return static_cast(std::distance(properties.begin(), found)); +} +} // namespace + +// FIXME: duplicate code in the QmlJS::Rewriter class, remove this +QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( + QmlJS::AST::UiObjectMemberList *members, Utils::span propertyOrder) +{ + const int objectDefinitionInsertionPoint = indexOf(propertyOrder, ""); // XXX ???? QmlJS::AST::UiObjectMemberList *lastObjectDef = nullptr; QmlJS::AST::UiObjectMemberList *lastNonObjectDef = nullptr; @@ -212,13 +225,13 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AS if (QmlJS::AST::cast(member)) lastObjectDef = iter; else if (auto arrayBinding = QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId).toUtf8()); + idx = indexOf(propertyOrder, toString(arrayBinding->qualifiedId).toUtf8()); else if (auto objectBinding = QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId).toUtf8()); + idx = indexOf(propertyOrder, toString(objectBinding->qualifiedId).toUtf8()); else if (auto scriptBinding = QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId).toUtf8()); + idx = indexOf(propertyOrder, toString(scriptBinding->qualifiedId).toUtf8()); else if (QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf("property"); + idx = indexOf(propertyOrder, "property"); if (idx < objectDefinitionInsertionPoint) lastNonObjectDef = iter; @@ -234,7 +247,7 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AS QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( QmlJS::AST::UiObjectMemberList *members, PropertyNameView propertyName, - const QmlDesigner::PropertyNameList &propertyOrder) + Utils::span propertyOrder) { if (!members) return nullptr; // empty members @@ -256,15 +269,15 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( orderedMembers[QStringLiteral("property")] = iter; } - int idx = propertyOrder.indexOf(propertyName); + int idx = indexOf(propertyOrder, propertyName); if (idx == -1) - idx = propertyOrder.indexOf(PropertyName()); + idx = indexOf(propertyOrder, ""); if (idx == -1) - idx = propertyOrder.size() - 1; + idx = static_cast(propertyOrder.size()) - 1; for (; idx > 0; --idx) { - const QString prop = QString::fromLatin1(propertyOrder.at(idx - 1)); - QmlJS::AST::UiObjectMemberList *candidate = orderedMembers.value(prop, 0); + const QString prop = QString::fromLatin1(propertyOrder[static_cast(idx - 1)]); + QmlJS::AST::UiObjectMemberList *candidate = orderedMembers.value(prop, nullptr); if (candidate != nullptr) return candidate; } @@ -273,14 +286,14 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( } QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( - QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder, int pos) + QmlJS::AST::UiObjectMemberList *members, Utils::span propertyOrder, int pos) { if (pos < 0) return searchMemberToInsertAfter(members, propertyOrder); // An empty property name should be available in the propertyOrder List, which is the right place // to define the objects there. - const int objectDefinitionInsertionPoint = propertyOrder.indexOf(PropertyName()); + const int objectDefinitionInsertionPoint = indexOf(propertyOrder, ""); QmlJS::AST::UiObjectMemberList *lastObjectDef = nullptr; QmlJS::AST::UiObjectMemberList *lastNonObjectDef = nullptr; @@ -295,13 +308,13 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( if (objectPos++ == pos) break; } else if (auto arrayBinding = QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId).toUtf8()); + idx = indexOf(propertyOrder, toString(arrayBinding->qualifiedId).toUtf8()); else if (auto objectBinding = QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId).toUtf8()); + idx = indexOf(propertyOrder, toString(objectBinding->qualifiedId).toUtf8()); else if (auto scriptBinding = QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId).toUtf8()); + idx = indexOf(propertyOrder, toString(scriptBinding->qualifiedId).toUtf8()); else if (QmlJS::AST::cast(member)) - idx = propertyOrder.indexOf("property"); + idx = indexOf(propertyOrder, "property"); if (idx < objectDefinitionInsertionPoint) lastNonObjectDef = iter; diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.h b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.h index e8486d2eddb..7f860ea3a2e 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.h @@ -51,13 +51,16 @@ protected: bool includeSurroundingWhitespace(int &start, int &end) const; void includeLeadingEmptyLine(int &start) const; - static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder); + static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter( + QmlJS::AST::UiObjectMemberList *members, Utils::span propertyOrder); static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter( QmlJS::AST::UiObjectMemberList *members, PropertyNameView propertyName, - const PropertyNameList &propertyOrder); + Utils::span propertyOrder); static QmlJS::AST::UiObjectMemberList *searchChildrenToInsertAfter( - QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder, int pos = -1); + QmlJS::AST::UiObjectMemberList *members, + Utils::span propertyOrder, + int pos = -1); protected: bool didRewriting() const diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.cpp index cd70e4e95b6..f045ad5a88d 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include namespace { enum { @@ -355,52 +357,53 @@ QmlRefactoring::PropertyType ModelToTextMerger::propertyType(const AbstractPrope return QmlRefactoring::Invalid; } -PropertyNameList ModelToTextMerger::propertyOrder() +Utils::span ModelToTextMerger::propertyOrder() { - static const PropertyNameList properties = {PropertyName("id"), - PropertyName("name"), - PropertyName("target"), - PropertyName("property"), - PropertyName("x"), - PropertyName("y"), - PropertyName("width"), - PropertyName("height"), - PropertyName("opacity"), - PropertyName("visible"), - PropertyName("position"), - PropertyName("color"), - PropertyName("radius"), - PropertyName("text"), - PropertyName("elide"), - PropertyName("value"), - PropertyName("border.color"), - PropertyName("border.width"), - PropertyName("anchors.verticalCenter"), - PropertyName("anchors.left"), - PropertyName("anchors.right"), - PropertyName("anchors.top"), - PropertyName("anchors.bottom"), - PropertyName("anchors.fill"), - PropertyName("anchors.margins"), - PropertyName("anchors.leftMargin"), - PropertyName("anchors.rightMargin"), - PropertyName("anchors.topMargin"), - PropertyName("anchors.bottomMargin"), - PropertyName("font.letterSpacing"), - PropertyName("font.pixelSize"), - PropertyName("horizontalAlignment"), - PropertyName("verticalAlignment"), - PropertyName("source"), - PropertyName("lineHeight"), - PropertyName("lineHeightMode"), - PropertyName("wrapMode"), - PropertyName(), - PropertyName("states"), - PropertyName("to"), - PropertyName("from"), - PropertyName("transitions")}; + static constexpr auto propertyNames = Utils::to_array( + "id", + "name", + "target", + "property", + "x", + "y", + "width", + "height", + "opacity", + "visible", + "position", + "color", + "radius", + "text", + "elide", + "value", + "border.color", + "border.width", + "anchors.verticalCenter", + "anchors.left", + "anchors.right", + "anchors.top", + "anchors.bottom", + "anchors.fill", + "anchors.margins", + "anchors.leftMargin", + "anchors.rightMargin", + "anchors.topMargin", + "anchors.bottomMargin", + "font.letterSpacing", + "font.pixelSize", + "horizontalAlignment", + "verticalAlignment", + "source", + "lineHeight", + "lineHeightMode", + "wrapMode", + "", + "states", + "to", + "from", + "transitions"); - return properties; + return propertyNames; } bool ModelToTextMerger::isInHierarchy(const AbstractProperty &property) { diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.h b/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.h index 75d7178039e..d542dad9549 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.h +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.h @@ -52,7 +52,7 @@ protected: { return m_rewriteActions; } static QmlDesigner::QmlRefactoring::PropertyType propertyType(const AbstractProperty &property, const QString &textValue = QString()); - static PropertyNameList propertyOrder(); + static Utils::span propertyOrder(); static bool isInHierarchy(const AbstractProperty &property); diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.cpp index d40d0fe4a94..a5a987b0fc5 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.cpp @@ -72,7 +72,7 @@ static QString unicodeEscape(const QString &stringValue) return stringValue; } -QmlTextGenerator::QmlTextGenerator(const PropertyNameList &propertyOrder, +QmlTextGenerator::QmlTextGenerator(Utils::span propertyOrder, const TextEditor::TabSettings &tabSettings, const int startIndentDepth) : m_propertyOrder(propertyOrder) @@ -220,7 +220,7 @@ QString QmlTextGenerator::propertiesToQml(const ModelNode &node, int indentDepth PropertyNameList nodePropertyNames = node.propertyNames(); bool addToTop = true; - for (const PropertyName &propertyName : std::as_const(m_propertyOrder)) { + for (const auto propertyName : m_propertyOrder) { if (propertyName == "id") { // the model handles the id property special, so: if (!node.id().isEmpty()) { diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.h b/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.h index 971d6a2d1d0..5b6376bb214 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.h +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.h @@ -16,7 +16,7 @@ namespace Internal { class QmlTextGenerator { public: - explicit QmlTextGenerator(const PropertyNameList &propertyOrder, + explicit QmlTextGenerator(Utils::span propertyOrder, const TextEditor::TabSettings &tabSettings, const int startIndentDepth = 0); @@ -33,7 +33,7 @@ private: QString propertyToQml(const AbstractProperty &property, int indentDepth) const; private: - PropertyNameList m_propertyOrder; + Utils::span m_propertyOrder; TextEditor::TabSettings m_tabSettings; const int m_startIndentDepth; }; diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.h b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.h index e7e13becbbf..26cf0394efa 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.h +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.h @@ -11,9 +11,10 @@ namespace Internal { class RewriteActionCompressor { public: - RewriteActionCompressor(const PropertyNameList &propertyOrder, ModelNodePositionStorage *positionStore) : - m_propertyOrder(propertyOrder), - m_positionStore(positionStore) + RewriteActionCompressor(Utils::span propertyOrder, + ModelNodePositionStorage *positionStore) + : m_propertyOrder(propertyOrder) + , m_positionStore(positionStore) {} void operator()(QList &actions, const TextEditor::TabSettings &tabSettings) const; @@ -31,7 +32,7 @@ private: void compressSlidesIntoNewNode(QList &actions) const; private: - PropertyNameList m_propertyOrder; + Utils::span m_propertyOrder; ModelNodePositionStorage *m_positionStore; }; From 4da98bd82b5ca52b7d1609d539b76abc5c87aba7 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 14 Apr 2025 15:41:59 +0200 Subject: [PATCH 72/82] QmlDesigner: Fix warning in tests Change-Id: I6339ec810d3dfc1c58e46e06d1cce181c0608289 Reviewed-by: Marco Bubke --- .../tests/unittests/listmodeleditor/listmodeleditor-test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index be2741b8d5d..9fd89d5e78d 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -196,7 +196,7 @@ public: QItemSelection itemSelection(std::initializer_list> items) const { QItemSelection selection; - for (const auto [row, column] : items) { + for (const auto &[row, column] : items) { QModelIndex idx = index(row, column); selection.select(idx, idx); } From c7b5f6a2688ca8e003f427600badee721da17ca0 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 9 Apr 2025 13:42:42 +0200 Subject: [PATCH 73/82] QmlPuppet: Replace QVector with QList and clean up includes QVector is only a type alias, QList the real thing in Qt 6. Change-Id: I61070fa42ce349808717d0c225a4cbe99584dcc8 Reviewed-by: Marco Bubke --- .../commands/captureddatacommand.h | 4 +- .../commands/changeauxiliarycommand.h | 4 +- .../commands/changebindingscommand.h | 4 +- .../commands/changeidscommand.h | 4 +- .../commands/changeselectioncommand.cpp | 4 +- .../commands/changeselectioncommand.h | 10 ++-- .../commands/changestatecommand.h | 4 +- .../commands/changevaluescommand.cpp | 4 +- .../commands/changevaluescommand.h | 8 +-- .../commands/childrenchangedcommand.cpp | 6 +-- .../commands/childrenchangedcommand.h | 13 ++--- .../commands/completecomponentcommand.cpp | 4 +- .../commands/completecomponentcommand.h | 8 +-- .../commands/componentcompletedcommand.cpp | 4 +- .../commands/componentcompletedcommand.h | 9 ++-- .../commands/createinstancescommand.cpp | 4 +- .../commands/createinstancescommand.h | 8 +-- .../commands/createscenecommand.h | 39 +++++++------- .../commands/debugoutputcommand.cpp | 4 +- .../commands/debugoutputcommand.h | 10 ++-- .../commands/informationchangedcommand.cpp | 6 +-- .../commands/informationchangedcommand.h | 8 +-- .../commands/pixmapchangedcommand.cpp | 4 +- .../commands/pixmapchangedcommand.h | 6 +-- .../commands/removeinstancescommand.cpp | 4 +- .../commands/removeinstancescommand.h | 12 ++--- .../commands/removepropertiescommand.cpp | 4 +- .../commands/removepropertiescommand.h | 8 +-- .../commands/removesharedmemorycommand.cpp | 4 +- .../commands/removesharedmemorycommand.h | 8 +-- .../commands/reparentinstancescommand.cpp | 4 +- .../commands/reparentinstancescommand.h | 8 +-- .../statepreviewimagechangedcommand.cpp | 4 +- .../statepreviewimagechangedcommand.h | 6 +-- .../commands/synchronizecommand.h | 2 +- .../commands/tokencommand.cpp | 4 +- .../commands/tokencommand.h | 13 +++-- .../commands/valueschangedcommand.cpp | 12 ++--- .../commands/valueschangedcommand.h | 12 ++--- .../container/idcontainer.h | 3 +- .../instances/nodeinstanceserver.cpp | 52 +++++++++---------- .../qmlpuppet/instances/nodeinstanceserver.h | 29 +++++------ .../qt5capturepreviewnodeinstanceserver.cpp | 4 +- .../qt5informationnodeinstanceserver.cpp | 34 ++++++------ .../qt5informationnodeinstanceserver.h | 16 +++--- .../qt5previewnodeinstanceserver.cpp | 2 +- .../instances/qt5rendernodeinstanceserver.cpp | 10 ++-- .../instances/qt5testnodeinstanceserver.cpp | 2 +- 48 files changed, 213 insertions(+), 223 deletions(-) diff --git a/src/libs/qmlpuppetcommunication/commands/captureddatacommand.h b/src/libs/qmlpuppetcommunication/commands/captureddatacommand.h index 9246317365b..12caf32ebd0 100644 --- a/src/libs/qmlpuppetcommunication/commands/captureddatacommand.h +++ b/src/libs/qmlpuppetcommunication/commands/captureddatacommand.h @@ -131,7 +131,7 @@ public: CapturedDataCommand() = default; - CapturedDataCommand(QVector &&stateData) + CapturedDataCommand(QList &&stateData) : stateData{std::move(stateData)} {} @@ -157,7 +157,7 @@ public: public: QImage image; - QVector stateData; + QList stateData; }; } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/commands/changeauxiliarycommand.h b/src/libs/qmlpuppetcommunication/commands/changeauxiliarycommand.h index d36b9e90c23..c74ad7f4eca 100644 --- a/src/libs/qmlpuppetcommunication/commands/changeauxiliarycommand.h +++ b/src/libs/qmlpuppetcommunication/commands/changeauxiliarycommand.h @@ -5,8 +5,8 @@ #include #include +#include #include -#include #include "propertyvaluecontainer.h" @@ -29,7 +29,7 @@ public: friend QDebug operator <<(QDebug debug, const ChangeAuxiliaryCommand &command); - QVector auxiliaryChanges; + QList auxiliaryChanges; }; } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/commands/changebindingscommand.h b/src/libs/qmlpuppetcommunication/commands/changebindingscommand.h index 5e9464bbc54..bbab2987c8b 100644 --- a/src/libs/qmlpuppetcommunication/commands/changebindingscommand.h +++ b/src/libs/qmlpuppetcommunication/commands/changebindingscommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "propertybindingcontainer.h" @@ -25,7 +25,7 @@ public: friend QDebug operator <<(QDebug debug, const ChangeBindingsCommand &command); - QVector bindingChanges; + QList bindingChanges; }; } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/commands/changeidscommand.h b/src/libs/qmlpuppetcommunication/commands/changeidscommand.h index b0325d96521..6e337012312 100644 --- a/src/libs/qmlpuppetcommunication/commands/changeidscommand.h +++ b/src/libs/qmlpuppetcommunication/commands/changeidscommand.h @@ -4,7 +4,7 @@ #pragma once #include -#include +#include #include #include "idcontainer.h" @@ -27,7 +27,7 @@ public: } friend QDebug operator <<(QDebug debug, const ChangeIdsCommand &command); - QVector ids; + QList ids; }; } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.cpp b/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.cpp index e12172da9dc..5ca9c89e4b7 100644 --- a/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.cpp @@ -10,12 +10,12 @@ namespace QmlDesigner { ChangeSelectionCommand::ChangeSelectionCommand() = default; -ChangeSelectionCommand::ChangeSelectionCommand(const QVector &idVector) +ChangeSelectionCommand::ChangeSelectionCommand(const QList &idVector) : m_instanceIdVector(idVector) { } -QVector ChangeSelectionCommand::instanceIds() const +QList ChangeSelectionCommand::instanceIds() const { return m_instanceIdVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.h b/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.h index 56e2cb38ccd..5b245c6cc6c 100644 --- a/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.h +++ b/src/libs/qmlpuppetcommunication/commands/changeselectioncommand.h @@ -3,12 +3,10 @@ #pragma once +#include #include -#include #include -#include "instancecontainer.h" - namespace QmlDesigner { class ChangeSelectionCommand @@ -20,12 +18,12 @@ class ChangeSelectionCommand public: ChangeSelectionCommand(); - explicit ChangeSelectionCommand(const QVector &idVector); + explicit ChangeSelectionCommand(const QList &idVector); - QVector instanceIds() const; + QList instanceIds() const; private: - QVector m_instanceIdVector; + QList m_instanceIdVector; }; QDataStream &operator<<(QDataStream &out, const ChangeSelectionCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/changestatecommand.h b/src/libs/qmlpuppetcommunication/commands/changestatecommand.h index 62cc39afc6d..fc6ce0dcaa2 100644 --- a/src/libs/qmlpuppetcommunication/commands/changestatecommand.h +++ b/src/libs/qmlpuppetcommunication/commands/changestatecommand.h @@ -3,10 +3,8 @@ #pragma once +#include #include -#include - -#include "propertyvaluecontainer.h" namespace QmlDesigner { diff --git a/src/libs/qmlpuppetcommunication/commands/changevaluescommand.cpp b/src/libs/qmlpuppetcommunication/commands/changevaluescommand.cpp index 0fb819d93c1..3a7765031f3 100644 --- a/src/libs/qmlpuppetcommunication/commands/changevaluescommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/changevaluescommand.cpp @@ -9,12 +9,12 @@ namespace QmlDesigner { ChangeValuesCommand::ChangeValuesCommand() = default; -ChangeValuesCommand::ChangeValuesCommand(const QVector &valueChangeVector) +ChangeValuesCommand::ChangeValuesCommand(const QList &valueChangeVector) : m_valueChangeVector (valueChangeVector) { } -const QVector ChangeValuesCommand::valueChanges() const +const QList ChangeValuesCommand::valueChanges() const { return m_valueChangeVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/changevaluescommand.h b/src/libs/qmlpuppetcommunication/commands/changevaluescommand.h index 6dcea149056..3608dde7ffd 100644 --- a/src/libs/qmlpuppetcommunication/commands/changevaluescommand.h +++ b/src/libs/qmlpuppetcommunication/commands/changevaluescommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "propertyvaluecontainer.h" @@ -17,12 +17,12 @@ class ChangeValuesCommand public: ChangeValuesCommand(); - explicit ChangeValuesCommand(const QVector &valueChangeVector); + explicit ChangeValuesCommand(const QList &valueChangeVector); - const QVector valueChanges() const; + const QList valueChanges() const; private: - QVector m_valueChangeVector; + QList m_valueChangeVector; }; QDataStream &operator<<(QDataStream &out, const ChangeValuesCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.cpp b/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.cpp index bd805a56aa3..51421d1637a 100644 --- a/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.cpp @@ -14,14 +14,14 @@ ChildrenChangedCommand::ChildrenChangedCommand() { } -ChildrenChangedCommand::ChildrenChangedCommand(qint32 parentInstanceId, const QVector &children, const QVector &informationVector) +ChildrenChangedCommand::ChildrenChangedCommand(qint32 parentInstanceId, const QList &children, const QList &informationVector) : m_parentInstanceId(parentInstanceId), m_childrenVector(children), m_informationVector(informationVector) { } -QVector ChildrenChangedCommand::childrenInstances() const +QList ChildrenChangedCommand::childrenInstances() const { return m_childrenVector; } @@ -31,7 +31,7 @@ qint32 ChildrenChangedCommand::parentInstanceId() const return m_parentInstanceId; } -QVector ChildrenChangedCommand::informations() const +QList ChildrenChangedCommand::informations() const { return m_informationVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.h b/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.h index f90383ef385..500593a435c 100644 --- a/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/childrenchangedcommand.h @@ -3,8 +3,9 @@ #pragma once +#include #include -#include + #include "informationcontainer.h" namespace QmlDesigner { @@ -16,18 +17,18 @@ class ChildrenChangedCommand public: ChildrenChangedCommand(); - explicit ChildrenChangedCommand(qint32 parentInstanceId, const QVector &childrenInstancesconst, const QVector &informationVector); + explicit ChildrenChangedCommand(qint32 parentInstanceId, const QList &childrenInstancesconst, const QList &informationVector); - QVector childrenInstances() const; + QList childrenInstances() const; qint32 parentInstanceId() const; - QVector informations() const; + QList informations() const; void sort(); private: qint32 m_parentInstanceId; - QVector m_childrenVector; - QVector m_informationVector; + QList m_childrenVector; + QList m_informationVector; }; QDataStream &operator<<(QDataStream &out, const ChildrenChangedCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.cpp b/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.cpp index 9eda245dbfb..b3832866ffc 100644 --- a/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.cpp @@ -10,12 +10,12 @@ namespace QmlDesigner { CompleteComponentCommand::CompleteComponentCommand() = default; -CompleteComponentCommand::CompleteComponentCommand(const QVector &container) +CompleteComponentCommand::CompleteComponentCommand(const QList &container) : m_instanceVector(container) { } -const QVector CompleteComponentCommand::instances() const +const QList CompleteComponentCommand::instances() const { return m_instanceVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.h b/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.h index 82955e8ca84..aaa5814844e 100644 --- a/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/completecomponentcommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include namespace QmlDesigner { @@ -16,12 +16,12 @@ class CompleteComponentCommand public: CompleteComponentCommand(); - explicit CompleteComponentCommand(const QVector &container); + explicit CompleteComponentCommand(const QList &container); - const QVector instances() const; + const QList instances() const; private: - QVector m_instanceVector; + QList m_instanceVector; }; QDataStream &operator<<(QDataStream &out, const CompleteComponentCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.cpp b/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.cpp index 725e6d72f82..313ece9cf4a 100644 --- a/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.cpp @@ -12,12 +12,12 @@ namespace QmlDesigner { ComponentCompletedCommand::ComponentCompletedCommand() = default; -ComponentCompletedCommand::ComponentCompletedCommand(const QVector &container) +ComponentCompletedCommand::ComponentCompletedCommand(const QList &container) : m_instanceVector(container) { } -QVector ComponentCompletedCommand::instances() const +QList ComponentCompletedCommand::instances() const { return m_instanceVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.h b/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.h index a0baee93a67..e612e6c2cb3 100644 --- a/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/componentcompletedcommand.h @@ -2,8 +2,9 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once + +#include #include -#include #include namespace QmlDesigner { @@ -15,14 +16,14 @@ class ComponentCompletedCommand public: ComponentCompletedCommand(); - explicit ComponentCompletedCommand(const QVector &container); + explicit ComponentCompletedCommand(const QList &container); - QVector instances() const; + QList instances() const; void sort(); private: - QVector m_instanceVector; + QList m_instanceVector; }; QDataStream &operator<<(QDataStream &out, const ComponentCompletedCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/createinstancescommand.cpp b/src/libs/qmlpuppetcommunication/commands/createinstancescommand.cpp index af18a2df00f..043b493489d 100644 --- a/src/libs/qmlpuppetcommunication/commands/createinstancescommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/createinstancescommand.cpp @@ -10,12 +10,12 @@ namespace QmlDesigner { CreateInstancesCommand::CreateInstancesCommand() = default; -CreateInstancesCommand::CreateInstancesCommand(const QVector &container) +CreateInstancesCommand::CreateInstancesCommand(const QList &container) : m_instanceVector(container) { } -QVector CreateInstancesCommand::instances() const +QList CreateInstancesCommand::instances() const { return m_instanceVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/createinstancescommand.h b/src/libs/qmlpuppetcommunication/commands/createinstancescommand.h index de056244452..110bdc9eb28 100644 --- a/src/libs/qmlpuppetcommunication/commands/createinstancescommand.h +++ b/src/libs/qmlpuppetcommunication/commands/createinstancescommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "instancecontainer.h" @@ -16,12 +16,12 @@ class CreateInstancesCommand public: CreateInstancesCommand(); - explicit CreateInstancesCommand(const QVector &container); + explicit CreateInstancesCommand(const QList &container); - QVector instances() const; + QList instances() const; private: - QVector m_instanceVector; + QList m_instanceVector; }; QDataStream &operator<<(QDataStream &out, const CreateInstancesCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/createscenecommand.h b/src/libs/qmlpuppetcommunication/commands/createscenecommand.h index 80456169db5..5f6b7836b49 100644 --- a/src/libs/qmlpuppetcommunication/commands/createscenecommand.h +++ b/src/libs/qmlpuppetcommunication/commands/createscenecommand.h @@ -3,12 +3,11 @@ #pragma once +#include +#include +#include #include #include -#include -#include -#include -#include #include "instancecontainer.h" #include "reparentcontainer.h" @@ -24,14 +23,14 @@ class CreateSceneCommand { public: CreateSceneCommand() = default; - explicit CreateSceneCommand(const QVector &instanceContainer, - const QVector &reparentContainer, - const QVector &idVector, - const QVector &valueChangeVector, - const QVector &bindingChangeVector, - const QVector &auxiliaryChangeVector, - const QVector &importVector, - const QVector &mockupTypeVector, + explicit CreateSceneCommand(const QList &instanceContainer, + const QList &reparentContainer, + const QList &idVector, + const QList &valueChangeVector, + const QList &bindingChangeVector, + const QList &auxiliaryChangeVector, + const QList &importVector, + const QList &mockupTypeVector, const QUrl &fileUrl, const QUrl &resourceUrl, const QHash &edit3dToolStates, @@ -91,14 +90,14 @@ public: } public: - QVector instances; - QVector reparentInstances; - QVector ids; - QVector valueChanges; - QVector bindingChanges; - QVector auxiliaryChanges; - QVector imports; - QVector mockupTypes; + QList instances; + QList reparentInstances; + QList ids; + QList valueChanges; + QList bindingChanges; + QList auxiliaryChanges; + QList imports; + QList mockupTypes; QUrl fileUrl; QUrl resourceUrl; QHash edit3dToolStates; diff --git a/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.cpp b/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.cpp index e10bce7cff7..b4124088373 100644 --- a/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.cpp @@ -9,7 +9,7 @@ namespace QmlDesigner { DebugOutputCommand::DebugOutputCommand() = default; -DebugOutputCommand::DebugOutputCommand(const QString &text, DebugOutputCommand::Type type, const QVector &instanceIds) +DebugOutputCommand::DebugOutputCommand(const QString &text, DebugOutputCommand::Type type, const QList &instanceIds) : m_instanceIds(instanceIds) , m_text(text) , m_type(type) @@ -26,7 +26,7 @@ QString DebugOutputCommand::text() const return m_text; } -QVector DebugOutputCommand::instanceIds() const +QList DebugOutputCommand::instanceIds() const { return m_instanceIds; } diff --git a/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.h b/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.h index 7818ce629be..05e0d240995 100644 --- a/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/debugoutputcommand.h @@ -3,10 +3,10 @@ #pragma once +#include +#include #include #include -#include -#include namespace QmlDesigner { @@ -24,14 +24,14 @@ public: }; DebugOutputCommand(); - explicit DebugOutputCommand(const QString &text, Type type, const QVector &instanceIds); + explicit DebugOutputCommand(const QString &text, Type type, const QList &instanceIds); qint32 type() const; QString text() const; - QVector instanceIds() const; + QList instanceIds() const; private: - QVector m_instanceIds; + QList m_instanceIds; QString m_text; quint32 m_type; }; diff --git a/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.cpp b/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.cpp index 80dda76b23b..5cf4f9fc52b 100644 --- a/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.cpp @@ -6,20 +6,18 @@ #include #include -#include "propertyvaluecontainer.h" - #include namespace QmlDesigner { InformationChangedCommand::InformationChangedCommand() = default; -InformationChangedCommand::InformationChangedCommand(const QVector &informationVector) +InformationChangedCommand::InformationChangedCommand(const QList &informationVector) : m_informationVector(informationVector) { } -QVector InformationChangedCommand::informations() const +QList InformationChangedCommand::informations() const { return m_informationVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.h b/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.h index 3181f185f34..c2dfcaa6381 100644 --- a/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/informationchangedcommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "informationcontainer.h" @@ -17,14 +17,14 @@ class InformationChangedCommand public: InformationChangedCommand(); - explicit InformationChangedCommand(const QVector &informationVector); + explicit InformationChangedCommand(const QList &informationVector); - QVector informations() const; + QList informations() const; void sort(); private: - QVector m_informationVector; + QList m_informationVector; }; QDataStream &operator<<(QDataStream &out, const InformationChangedCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.cpp b/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.cpp index 18f35043c11..57073722160 100644 --- a/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.cpp @@ -13,12 +13,12 @@ namespace QmlDesigner { PixmapChangedCommand::PixmapChangedCommand() = default; -PixmapChangedCommand::PixmapChangedCommand(const QVector &imageVector) +PixmapChangedCommand::PixmapChangedCommand(const QList &imageVector) : m_imageVector(imageVector) { } -QVector PixmapChangedCommand::images() const +QList PixmapChangedCommand::images() const { return m_imageVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.h b/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.h index 72247f0c57c..d66289f1394 100644 --- a/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/pixmapchangedcommand.h @@ -15,14 +15,14 @@ class PixmapChangedCommand public: PixmapChangedCommand(); - explicit PixmapChangedCommand(const QVector &imageVector); + explicit PixmapChangedCommand(const QList &imageVector); - QVector images() const; + QList images() const; void sort(); private: - QVector m_imageVector; + QList m_imageVector; }; QDataStream &operator<<(QDataStream &out, const PixmapChangedCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.cpp b/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.cpp index f2289a3b543..7d89261096f 100644 --- a/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.cpp @@ -10,12 +10,12 @@ namespace QmlDesigner { RemoveInstancesCommand::RemoveInstancesCommand() = default; -RemoveInstancesCommand::RemoveInstancesCommand(const QVector &idVector) +RemoveInstancesCommand::RemoveInstancesCommand(const QList &idVector) : m_instanceIdVector(idVector) { } -const QVector RemoveInstancesCommand::instanceIds() const +const QList RemoveInstancesCommand::instanceIds() const { return m_instanceIdVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.h b/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.h index 7c03a8970df..54766ba8d97 100644 --- a/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.h +++ b/src/libs/qmlpuppetcommunication/commands/removeinstancescommand.h @@ -3,11 +3,9 @@ #pragma once -#include -#include #include - -#include "instancecontainer.h" +#include +#include namespace QmlDesigner { @@ -18,12 +16,12 @@ class RemoveInstancesCommand public: RemoveInstancesCommand(); - explicit RemoveInstancesCommand(const QVector &idVector); + explicit RemoveInstancesCommand(const QList &idVector); - const QVector instanceIds() const; + const QList instanceIds() const; private: - QVector m_instanceIdVector; + QList m_instanceIdVector; }; QDataStream &operator<<(QDataStream &out, const RemoveInstancesCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.cpp b/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.cpp index b15e441c298..a19ee12c9f0 100644 --- a/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.cpp @@ -9,12 +9,12 @@ namespace QmlDesigner { RemovePropertiesCommand::RemovePropertiesCommand() = default; -RemovePropertiesCommand::RemovePropertiesCommand(const QVector &properties) +RemovePropertiesCommand::RemovePropertiesCommand(const QList &properties) : m_properties(properties) { } -const QVector RemovePropertiesCommand::properties() const +const QList RemovePropertiesCommand::properties() const { return m_properties; } diff --git a/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.h b/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.h index c5f32b4a5dd..f25e0947a58 100644 --- a/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.h +++ b/src/libs/qmlpuppetcommunication/commands/removepropertiescommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "propertyabstractcontainer.h" @@ -17,12 +17,12 @@ class RemovePropertiesCommand public: RemovePropertiesCommand(); - explicit RemovePropertiesCommand(const QVector &properties); + explicit RemovePropertiesCommand(const QList &properties); - const QVector properties() const; + const QList properties() const; private: - QVector m_properties; + QList m_properties; }; QDataStream &operator<<(QDataStream &out, const RemovePropertiesCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.cpp b/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.cpp index 65e16b4752f..d7dd1eba26c 100644 --- a/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.cpp @@ -10,7 +10,7 @@ namespace QmlDesigner { RemoveSharedMemoryCommand::RemoveSharedMemoryCommand() = default; -RemoveSharedMemoryCommand::RemoveSharedMemoryCommand(const QString &typeName, const QVector &keyNumberVector) +RemoveSharedMemoryCommand::RemoveSharedMemoryCommand(const QString &typeName, const QList &keyNumberVector) : m_typeName(typeName), m_keyNumberVector(keyNumberVector) { @@ -21,7 +21,7 @@ QString RemoveSharedMemoryCommand::typeName() const return m_typeName; } -QVector RemoveSharedMemoryCommand::keyNumbers() const +QList RemoveSharedMemoryCommand::keyNumbers() const { return m_keyNumberVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.h b/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.h index 60081608b3b..4d601234706 100644 --- a/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.h +++ b/src/libs/qmlpuppetcommunication/commands/removesharedmemorycommand.h @@ -3,9 +3,9 @@ #pragma once +#include #include #include -#include namespace QmlDesigner { @@ -16,14 +16,14 @@ class RemoveSharedMemoryCommand public: RemoveSharedMemoryCommand(); - explicit RemoveSharedMemoryCommand(const QString &typeName, const QVector &keyNumberVector); + explicit RemoveSharedMemoryCommand(const QString &typeName, const QList &keyNumberVector); QString typeName() const; - QVector keyNumbers() const; + QList keyNumbers() const; private: QString m_typeName; - QVector m_keyNumberVector; + QList m_keyNumberVector; }; QDataStream &operator<<(QDataStream &out, const RemoveSharedMemoryCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.cpp b/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.cpp index 3de6b4f90c5..b260cd4e711 100644 --- a/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.cpp @@ -10,12 +10,12 @@ namespace QmlDesigner { ReparentInstancesCommand::ReparentInstancesCommand() = default; -ReparentInstancesCommand::ReparentInstancesCommand(const QVector &container) +ReparentInstancesCommand::ReparentInstancesCommand(const QList &container) : m_reparentInstanceVector(container) { } -const QVector ReparentInstancesCommand::reparentInstances() const +const QList ReparentInstancesCommand::reparentInstances() const { return m_reparentInstanceVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.h b/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.h index 4a5e55c4839..46c74e20917 100644 --- a/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.h +++ b/src/libs/qmlpuppetcommunication/commands/reparentinstancescommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "reparentcontainer.h" @@ -17,12 +17,12 @@ class ReparentInstancesCommand public: ReparentInstancesCommand(); - explicit ReparentInstancesCommand(const QVector &container); + explicit ReparentInstancesCommand(const QList &container); - const QVector reparentInstances() const; + const QList reparentInstances() const; private: - QVector m_reparentInstanceVector; + QList m_reparentInstanceVector; }; QDataStream &operator<<(QDataStream &out, const ReparentInstancesCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.cpp b/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.cpp index 5d7f6e85663..75ce5c00b7a 100644 --- a/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.cpp @@ -11,12 +11,12 @@ namespace QmlDesigner { StatePreviewImageChangedCommand::StatePreviewImageChangedCommand() = default; -StatePreviewImageChangedCommand::StatePreviewImageChangedCommand(const QVector &imageVector) +StatePreviewImageChangedCommand::StatePreviewImageChangedCommand(const QList &imageVector) : m_previewVector(imageVector) { } -QVector StatePreviewImageChangedCommand::previews()const +QList StatePreviewImageChangedCommand::previews() const { return m_previewVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.h b/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.h index 81c55890110..3ffb0771840 100644 --- a/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/statepreviewimagechangedcommand.h @@ -16,14 +16,14 @@ class StatePreviewImageChangedCommand public: StatePreviewImageChangedCommand(); - explicit StatePreviewImageChangedCommand(const QVector &imageVector); + explicit StatePreviewImageChangedCommand(const QList &imageVector); - QVector previews() const; + QList previews() const; void sort(); private: - QVector m_previewVector; + QList m_previewVector; }; QDataStream &operator<<(QDataStream &out, const StatePreviewImageChangedCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/synchronizecommand.h b/src/libs/qmlpuppetcommunication/commands/synchronizecommand.h index e0c2c3a0397..da9f1ed6408 100644 --- a/src/libs/qmlpuppetcommunication/commands/synchronizecommand.h +++ b/src/libs/qmlpuppetcommunication/commands/synchronizecommand.h @@ -4,8 +4,8 @@ #pragma once #include +#include #include -#include namespace QmlDesigner { diff --git a/src/libs/qmlpuppetcommunication/commands/tokencommand.cpp b/src/libs/qmlpuppetcommunication/commands/tokencommand.cpp index 7d9aa45ad03..23892105ae0 100644 --- a/src/libs/qmlpuppetcommunication/commands/tokencommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/tokencommand.cpp @@ -15,7 +15,7 @@ TokenCommand::TokenCommand() { } -TokenCommand::TokenCommand(const QString &tokenName, qint32 tokenNumber, const QVector &instanceIdVector) +TokenCommand::TokenCommand(const QString &tokenName, qint32 tokenNumber, const QList &instanceIdVector) : m_tokenName(tokenName), m_tokenNumber(tokenNumber), m_instanceIdVector(instanceIdVector) @@ -32,7 +32,7 @@ qint32 TokenCommand::tokenNumber() const return m_tokenNumber; } -QVector TokenCommand::instances() const +QList TokenCommand::instances() const { return m_instanceIdVector; } diff --git a/src/libs/qmlpuppetcommunication/commands/tokencommand.h b/src/libs/qmlpuppetcommunication/commands/tokencommand.h index 1d249c20e9d..690c630fcb1 100644 --- a/src/libs/qmlpuppetcommunication/commands/tokencommand.h +++ b/src/libs/qmlpuppetcommunication/commands/tokencommand.h @@ -3,11 +3,10 @@ #pragma once - -#include -#include -#include #include +#include +#include +#include namespace QmlDesigner { @@ -18,18 +17,18 @@ class TokenCommand public: TokenCommand(); - explicit TokenCommand(const QString &tokenName, qint32 tokenNumber, const QVector &instances); + explicit TokenCommand(const QString &tokenName, qint32 tokenNumber, const QList &instances); QString tokenName() const; qint32 tokenNumber() const; - QVector instances() const; + QList instances() const; void sort(); private: QString m_tokenName; qint32 m_tokenNumber; - QVector m_instanceIdVector; + QList m_instanceIdVector; }; QDataStream &operator<<(QDataStream &out, const TokenCommand &command); diff --git a/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.cpp b/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.cpp index e36b7bb3519..e702efe6041 100644 --- a/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.cpp @@ -24,13 +24,13 @@ ValuesChangedCommand::ValuesChangedCommand() { } -ValuesChangedCommand::ValuesChangedCommand(const QVector &valueChangeVector) +ValuesChangedCommand::ValuesChangedCommand(const QList &valueChangeVector) : m_valueChangeVector (valueChangeVector), m_keyNumber(0) { } -const QVector ValuesChangedCommand::valueChanges() const +const QList ValuesChangedCommand::valueChanges() const { return m_valueChangeVector; } @@ -40,7 +40,7 @@ quint32 ValuesChangedCommand::keyNumber() const return m_keyNumber; } -void ValuesChangedCommand::removeSharedMemorys(const QVector &keyNumberVector) +void ValuesChangedCommand::removeSharedMemorys(const QList &keyNumberVector) { for (qint32 keyNumber : keyNumberVector) { SharedMemory *sharedMemory = globalSharedMemoryContainer()->take(keyNumber); @@ -75,7 +75,7 @@ QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command) { static const bool dontUseSharedMemory = qEnvironmentVariableIsSet("DESIGNER_DONT_USE_SHARED_MEMORY"); - QVector propertyValueContainer = command.valueChanges(); + QList propertyValueContainer = command.valueChanges(); if (command.transactionOption != ValuesChangedCommand::TransactionOption::None) { PropertyValueContainer optionContainer(command.transactionOption); @@ -114,7 +114,7 @@ QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command) return out; } -void readSharedMemory(qint32 key, QVector *valueChangeVector) +void readSharedMemory(qint32 key, QList *valueChangeVector) { SharedMemory sharedMemory(QString(valueKeyTemplateString).arg(key)); bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); @@ -135,7 +135,7 @@ QDataStream &operator>>(QDataStream &in, ValuesChangedCommand &command) { in >> command.m_keyNumber; - QVector valueChangeVector; + QList valueChangeVector; if (command.keyNumber() > 0) readSharedMemory(command.keyNumber(), &valueChangeVector); diff --git a/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.h b/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.h index 43ce0b7d59c..17e3e3be56c 100644 --- a/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/valueschangedcommand.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include "propertyvaluecontainer.h" @@ -19,18 +19,18 @@ class ValuesChangedCommand public: enum TransactionOption { Start = 1, End = 2, None = 0 }; ValuesChangedCommand(); - explicit ValuesChangedCommand(const QVector &valueChangeVector); + explicit ValuesChangedCommand(const QList &valueChangeVector); - const QVector valueChanges() const; + const QList valueChanges() const; quint32 keyNumber() const; - static void removeSharedMemorys(const QVector &keyNumberVector); + static void removeSharedMemorys(const QList &keyNumberVector); void sort(); TransactionOption transactionOption = TransactionOption::None; private: - QVector m_valueChangeVector; + QList m_valueChangeVector; mutable quint32 m_keyNumber; }; @@ -51,7 +51,7 @@ class ValuesModifiedCommand : public ValuesChangedCommand public: ValuesModifiedCommand() = default; - explicit ValuesModifiedCommand(const QVector &valueChangeVector) + explicit ValuesModifiedCommand(const QList &valueChangeVector) : ValuesChangedCommand(valueChangeVector) {} }; diff --git a/src/libs/qmlpuppetcommunication/container/idcontainer.h b/src/libs/qmlpuppetcommunication/container/idcontainer.h index 7e6c8260526..025e76fa05a 100644 --- a/src/libs/qmlpuppetcommunication/container/idcontainer.h +++ b/src/libs/qmlpuppetcommunication/container/idcontainer.h @@ -4,10 +4,9 @@ #pragma once #include -#include +#include #include - namespace QmlDesigner { class IdContainer diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp index 9d8e6e65f8e..eb8d2083e2e 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp @@ -182,7 +182,7 @@ NodeInstanceServer::~NodeInstanceServer() m_objectInstanceHash.clear(); } -QList NodeInstanceServer::createInstances(const QVector &containerVector) +QList NodeInstanceServer::createInstances(const QList &containerVector) { Q_ASSERT(declarativeView() || quickWindow()); QList instanceList; @@ -349,7 +349,7 @@ void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) if (activeStateInstance().isValid()) activeStateInstance().deactivateState(); - const QVector instanceIds = command.instanceIds(); + const QList instanceIds = command.instanceIds(); for (qint32 instanceId : instanceIds) removeInstanceRelationsip(instanceId); @@ -363,7 +363,7 @@ void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) void NodeInstanceServer::removeProperties(const RemovePropertiesCommand &command) { bool hasDynamicProperties = false; - const QVector props = command.properties(); + const QList props = command.properties(); for (const PropertyAbstractContainer &container : props) { hasDynamicProperties |= container.isDynamic(); resetInstanceProperty(container); @@ -375,7 +375,7 @@ void NodeInstanceServer::removeProperties(const RemovePropertiesCommand &command startRenderTimer(); } -void NodeInstanceServer::reparentInstances(const QVector &containerVector) +void NodeInstanceServer::reparentInstances(const QList &containerVector) { for (const ReparentContainer &container : containerVector) { if (hasInstanceForId(container.instanceId())) { @@ -418,7 +418,7 @@ void NodeInstanceServer::completeComponent(const CompleteComponentCommand &comma { QList instanceList; - const QVector instanceIds = command.instances(); + const QList instanceIds = command.instances(); for (qint32 instanceId : instanceIds) { if (hasInstanceForId(instanceId)) { ServerNodeInstance instance = instanceForId(instanceId); @@ -449,7 +449,7 @@ void NodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &/*c { } -void NodeInstanceServer::setupImports(const QVector &containerVector) +void NodeInstanceServer::setupImports(const QList &containerVector) { Q_ASSERT(quickWindow()); QSet importStatementSet; @@ -622,7 +622,7 @@ void NodeInstanceServer::changeFileUrl(const ChangeFileUrlCommand &command) void NodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command) { bool hasDynamicProperties = false; - const QVector valueChanges = command.valueChanges(); + const QList valueChanges = command.valueChanges(); for (const PropertyValueContainer &container : valueChanges) { hasDynamicProperties |= container.isDynamic(); setInstancePropertyVariant(container); @@ -636,7 +636,7 @@ void NodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command void NodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command) { - const QVector auxiliaryChanges = command.auxiliaryChanges; + const QList auxiliaryChanges = command.auxiliaryChanges; for (const PropertyValueContainer &container : auxiliaryChanges) setInstanceAuxiliaryData(container); @@ -646,7 +646,7 @@ void NodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &com void NodeInstanceServer::changePropertyBindings(const ChangeBindingsCommand &command) { bool hasDynamicProperties = false; - const QVector bindingChanges = command.bindingChanges; + const QList bindingChanges = command.bindingChanges; for (const PropertyBindingContainer &container : bindingChanges) { hasDynamicProperties |= container.isDynamic(); setInstancePropertyBinding(container); @@ -688,7 +688,7 @@ QQmlContext *NodeInstanceServer::rootContext() const return engine()->rootContext(); } -const QVector NodeInstanceServer::changedPropertyList() const +const QList NodeInstanceServer::changedPropertyList() const { return m_changedPropertyList; } @@ -724,7 +724,7 @@ static bool isTypeAvailable(const MockupTypeContainer &mockupType, QQmlEngine *e return !component.isError(); } -void NodeInstanceServer::setupMockupTypes(const QVector &container) +void NodeInstanceServer::setupMockupTypes(const QList &container) { for (const MockupTypeContainer &mockupType : container) { if (!isTypeAvailable(mockupType, engine())) { @@ -1082,9 +1082,9 @@ NodeInstanceClientInterface *NodeInstanceServer::nodeInstanceClient() const return m_nodeInstanceClient; } -static QVector createInformationVector(const QList &instanceList, bool initial) +static QList createInformationVector(const QList &instanceList, bool initial) { - QVector informationVector; + QList informationVector; for (const ServerNodeInstance &instance : instanceList) { if (instance.isValid()) { @@ -1166,7 +1166,7 @@ static QVector createInformationVector(const QList &instanceList) const { - QVector instanceVector; + QList instanceVector; for (const ServerNodeInstance &instance : instanceList) instanceVector.append(instance.instanceId()); @@ -1190,7 +1190,7 @@ static bool supportedVariantType(int type) ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList &instanceList) const { - QVector valueVector; + QList valueVector; for (const ServerNodeInstance &instance : instanceList) { const QList propertyNames = instance.propertyNames(); @@ -1208,7 +1208,7 @@ ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList< ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(const QList &instanceList) { - QVector idVector; + QList idVector; for (const ServerNodeInstance &instance : instanceList) { if (instance.instanceId() >= 0) idVector.append(instance.instanceId()); @@ -1219,7 +1219,7 @@ ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(co ChangeSelectionCommand NodeInstanceServer::createChangeSelectionCommand(const QList &instanceList) { - QVector idVector; + QList idVector; for (const ServerNodeInstance &instance : instanceList) { if (instance.instanceId() >= 0) idVector.append(instance.instanceId()); @@ -1228,9 +1228,9 @@ ChangeSelectionCommand NodeInstanceServer::createChangeSelectionCommand(const QL return ChangeSelectionCommand(idVector); } -ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector &propertyList) const +ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList &propertyList) const { - QVector valueVector; + QList valueVector; for (const InstancePropertyPair &property : propertyList) { const PropertyName propertyName = property.second; @@ -1257,9 +1257,9 @@ ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVecto } ValuesModifiedCommand NodeInstanceServer::createValuesModifiedCommand( - const QVector &propertyList) const + const QList &propertyList) const { - QVector valueVector; + QList valueVector; for (const InstancePropertyValueTriple &property : propertyList) { const PropertyName propertyName = property.propertyName; @@ -1322,7 +1322,7 @@ PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList< { NANOTRACE_SCOPE("Update", "createPixmapChangedCommand"); - QVector imageVector; + QList imageVector; for (const ServerNodeInstance &instance : instanceList) { if (!instance.isValid()) @@ -1440,13 +1440,13 @@ void NodeInstanceServer::loadDummyDataContext(const QString &directory) void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message, qint32 instanceId) { - QVector ids; + QList ids; ids.append(instanceId); sendDebugOutput(type, message, ids); } void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message, - const QVector &instanceIds) + const QList &instanceIds) { DebugOutputCommand command(message, type, instanceIds); nodeInstanceClient()->debugOutput(command); @@ -1532,7 +1532,7 @@ void NodeInstanceServer::sheduleRootItemRender() if (result) { connect(result.data(), &QQuickItemGrabResult::ready, [this, result, instanceId] { - QVector imageVector; + QList imageVector; ImageContainer container(instanceId, result->image(), instanceId); imageVector.append(container); nodeInstanceClient()->pixmapChanged(PixmapChangedCommand(imageVector)); @@ -1618,7 +1618,7 @@ void NodeInstanceServer::addAnimation(QQuickAbstractAnimation *animation) } } -QVector NodeInstanceServer::animations() const +QList NodeInstanceServer::animations() const { return m_animations; } diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.h b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.h index e7070a63bde..ac081cd7379 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.h +++ b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -153,7 +152,7 @@ public: ServerNodeInstance instanceForObject(QObject *object) const; bool hasInstanceForObject(QObject *object) const; - const QVector &nodeInstances() const { return m_idInstances; } + const QList &nodeInstances() const { return m_idInstances; } virtual QQmlEngine *engine() const = 0; QQmlContext *context() const; @@ -190,7 +189,7 @@ public: virtual void setRootItem(QQuickItem *item) = 0; void sendDebugOutput(DebugOutputCommand::Type type, const QString &message, qint32 instanceId = 0); - void sendDebugOutput(DebugOutputCommand::Type type, const QString &message, const QVector &instanceIds); + void sendDebugOutput(DebugOutputCommand::Type type, const QString &message, const QList &instanceIds); void removeInstanceRelationsipForDeletedObject(QObject *object, qint32 instanceId); @@ -213,7 +212,7 @@ public: virtual bool isInformationServer() const; virtual bool isPreviewServer() const; void addAnimation(QQuickAbstractAnimation *animation); - QVector animations() const; + QList animations() const; QVariant animationDefaultValue(int index) const; public slots: @@ -222,8 +221,8 @@ public slots: void emitParentChanged(QObject *child); protected: - virtual QList createInstances(const QVector &container); - void reparentInstances(const QVector &containerVector); + virtual QList createInstances(const QList &container); + void reparentInstances(const QList &containerVector); Internal::ChildrenChangeEventFilter *childrenChangeEventFilter(); void resetInstanceProperty(const PropertyAbstractContainer &propertyContainer); @@ -240,8 +239,8 @@ protected: void timerEvent(QTimerEvent *) override; ValuesChangedCommand createValuesChangedCommand(const QList &instanceList) const; - ValuesChangedCommand createValuesChangedCommand(const QVector &propertyList) const; - ValuesModifiedCommand createValuesModifiedCommand(const QVector &propertyList) const; + ValuesChangedCommand createValuesChangedCommand(const QList &propertyList) const; + ValuesModifiedCommand createValuesModifiedCommand(const QList &propertyList) const; PixmapChangedCommand createPixmapChangedCommand(const QList &instanceList) const; InformationChangedCommand createAllInformationChangedCommand(const QList &instanceList, bool initial = false) const; ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList &instanceList) const; @@ -276,16 +275,16 @@ protected: QQmlContext *rootContext() const; - const QVector changedPropertyList() const; + const QList changedPropertyList() const; void clearChangedPropertyList(); virtual void refreshBindings() = 0; void setupDummysForContext(QQmlContext *context); - void setupMockupTypes(const QVector &container); + void setupMockupTypes(const QList &container); void setupFileUrl(const QUrl &fileUrl); - void setupImports(const QVector &container); + void setupImports(const QList &container); void setupDummyData(const QUrl &fileUrl); void setupDefaultDummyData(); QList setupInstances(const CreateSceneCommand &command); @@ -301,7 +300,7 @@ private: void setupOnlyWorkingImports(const QStringList &workingImportStatementList); ServerNodeInstance m_rootNodeInstance; ServerNodeInstance m_activeStateInstance; - QVector m_idInstances; + QList m_idInstances; QHash m_objectInstanceHash; QMultiHash m_fileSystemWatcherHash; QList > > m_dummyObjectList; @@ -314,7 +313,7 @@ private: int m_renderTimerInterval = 16; TimerMode m_timerMode = TimerMode::NormalTimer; int m_timerModeInterval = 200; - QVector m_changedPropertyList; + QList m_changedPropertyList; QByteArray m_importCode; QPointer m_dummyContextObject; QPointer m_importComponent; @@ -322,8 +321,8 @@ private: std::unique_ptr multilanguageLink; int m_needsExtraRenderCount = 0; int m_extraRenderCurrentPass = 0; - QVector m_animations; - QVector m_defaultValues; + QList m_animations; + QList m_defaultValues; }; } diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5capturepreviewnodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5capturepreviewnodeinstanceserver.cpp index 22e0d92084f..f9d530ddd54 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5capturepreviewnodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5capturepreviewnodeinstanceserver.cpp @@ -29,7 +29,7 @@ QImage renderPreviewImage(ServerNodeInstance rootNodeInstance) } CapturedDataCommand::StateData collectStateData(ServerNodeInstance rootNodeInstance, - const QVector &nodeInstances, + const QList &nodeInstances, qint32 stateInstanceId) { CapturedDataCommand::StateData stateData; @@ -74,7 +74,7 @@ void Qt5CapturePreviewNodeInstanceServer::collectItemChangesAndSendChangeCommand QQuickDesignerSupport::polishItems(quickWindow()); - QVector stateDatas; + QList stateDatas; stateDatas.push_back(collectStateData(rootNodeInstance(), nodeInstances(), 0)); for (ServerNodeInstance stateInstance : rootNodeInstance().stateInstances()) { diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp index a85a8770dd9..2eb4d7f1cc7 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp @@ -327,7 +327,7 @@ void Qt5InformationNodeInstanceServer::updateActiveScenePreferredCamera() } void Qt5InformationNodeInstanceServer::updateMaterialPreviewData( - const QVector &valueChanges) + const QList &valueChanges) { for (const auto &container : valueChanges) { if (container.instanceId() == 0) { @@ -342,7 +342,7 @@ void Qt5InformationNodeInstanceServer::updateMaterialPreviewData( } void Qt5InformationNodeInstanceServer::updateRotationBlocks( - [[maybe_unused]] const QVector &valueChanges) + [[maybe_unused]] const QList &valueChanges) { #ifdef QUICK3D_MODULE auto helper = qobject_cast(m_3dHelper); @@ -372,7 +372,7 @@ void Qt5InformationNodeInstanceServer::updateRotationBlocks( } void Qt5InformationNodeInstanceServer::updateSnapAndCameraSettings( - [[maybe_unused]] const QVector &valueChanges) + [[maybe_unused]] const QList &valueChanges) { #ifdef QUICK3D_MODULE auto helper = qobject_cast(m_3dHelper); @@ -411,7 +411,7 @@ void Qt5InformationNodeInstanceServer::updateSnapAndCameraSettings( } void Qt5InformationNodeInstanceServer::updateColorSettings( - [[maybe_unused]] const QVector &valueChanges) + [[maybe_unused]] const QList &valueChanges) { #ifdef QUICK3D_MODULE if (m_editView3DData.rootItem) { @@ -430,7 +430,7 @@ void Qt5InformationNodeInstanceServer::updateColorSettings( } void Qt5InformationNodeInstanceServer::removeRotationBlocks( - [[maybe_unused]] const QVector &instanceIds) + [[maybe_unused]] const QList &instanceIds) { #ifdef QUICK3D_MODULE auto helper = qobject_cast(m_3dHelper); @@ -642,7 +642,7 @@ void Qt5InformationNodeInstanceServer::handleParticleSystemSelected(QQuick3DPart || ServerNodeInstance::isSubclassOf(o, "QQuickSequentialAnimation"); }; - const QVector anims = animations(); + const QList anims = animations(); QSet containers; for (auto a : anims) { // Stop all animations by default. We only want to run animations related to currently @@ -802,13 +802,13 @@ void Qt5InformationNodeInstanceServer::handleSelectionChanged(const QVariant &ob m_selectionChangeTimer.start(500); } -QVector +QList Qt5InformationNodeInstanceServer::propertyToPropertyValueTriples( const ServerNodeInstance &instance, const PropertyName &propertyName, const QVariant &variant) { - QVector result; + QList result; InstancePropertyValueTriple propTriple; if (variant.typeId() == QMetaType::QVector3D) { @@ -854,7 +854,7 @@ void Qt5InformationNodeInstanceServer::modifyVariantValue(const QObjectList &obj } if (!objects.isEmpty()) { - QVector valueVector; + QList valueVector; for (const auto listObj : objects) { ServerNodeInstance instance = instanceForObject(listObj); if (instance.isValid()) { @@ -865,7 +865,7 @@ void Qt5InformationNodeInstanceServer::modifyVariantValue(const QObjectList &obj instance.setModifiedFlag(false); for (const auto &propNamePair : propNamePairs) { // We do have to split vector3d props into foobar.x, foobar.y, foobar.z - const QVector triple + const QList triple = propertyToPropertyValueTriples(instance, propNamePair.targetPropName, listObj->property(propNamePair.origPropName)); for (const auto &property : triple) { @@ -1631,13 +1631,13 @@ void Qt5InformationNodeInstanceServer::selectInstances(const QList &properties) + const QList &properties) { nodeInstanceClient()->valuesModified(createValuesModifiedCommand(properties)); } QList Qt5InformationNodeInstanceServer::createInstances( - const QVector &container) + const QList &container) { const auto createdInstances = NodeInstanceServer::createInstances(container); @@ -2054,7 +2054,7 @@ void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() QQuickDesignerSupport::polishItems(quickWindow()); QSet informationChangedInstanceSet; - QVector propertyChangedList; + QList propertyChangedList; if (quickWindow()) { for (QQuickItem *item : allItems()) { @@ -2221,7 +2221,7 @@ void Qt5InformationNodeInstanceServer::completeComponent(const CompleteComponent Qt5NodeInstanceServer::completeComponent(command); QList instanceList; - const QVector instances = command.instances(); + const QList instances = command.instances(); for (qint32 instanceId : instances) { if (hasInstanceForId(instanceId)) { ServerNodeInstance instance = instanceForId(instanceId); @@ -2258,7 +2258,7 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm } // Find a scene root of the selection to update active scene shown - const QVector instanceIds = command.instanceIds(); + const QList instanceIds = command.instanceIds(); QVariantList selectedObjs; QObject *firstSceneRoot = nullptr; ServerNodeInstance firstInstance; @@ -2473,7 +2473,7 @@ bool Qt5InformationNodeInstanceServer::isSceneEnvironmentBgProperty(const Proper void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command) { bool hasDynamicProperties = false; - const QVector values = command.valueChanges(); + const QList values = command.valueChanges(); QSet sceneEnvs; for (const PropertyValueContainer &container : values) { if (!container.isReflected()) { @@ -2757,7 +2757,7 @@ void Qt5InformationNodeInstanceServer::changeState(const ChangeStateCommand &com void Qt5InformationNodeInstanceServer::removeProperties(const RemovePropertiesCommand &command) { - const QVector props = command.properties(); + const QList props = command.properties(); QSet sceneEnvs; for (const PropertyAbstractContainer &container : props) { diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h index f0d796f9003..4bd3c157533 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h @@ -80,8 +80,8 @@ protected: bool isDirtyRecursiveForNonInstanceItems(QQuickItem *item) const; bool isDirtyRecursiveForParentInstances(QQuickItem *item) const; void selectInstances(const QList &instanceList); - void modifyProperties(const QVector &properties); - QList createInstances(const QVector &container) override; + void modifyProperties(const QList &properties); + QList createInstances(const QList &container) override; void initializeAuxiliaryViews() override; private: @@ -98,7 +98,7 @@ private: QObject *findView3DForSceneRoot(QObject *sceneRoot) const; QObject *find3DSceneRoot(const ServerNodeInstance &instance) const; QObject *find3DSceneRoot(QObject *obj) const; - QVector propertyToPropertyValueTriples( + QList propertyToPropertyValueTriples( const ServerNodeInstance &instance, const PropertyName &propertyName, const QVariant &variant); @@ -122,11 +122,11 @@ private: void handleInputEvents(); void resolveImportSupport(); void updateActiveScenePreferredCamera(); - void updateMaterialPreviewData(const QVector &valueChanges); - void updateRotationBlocks(const QVector &valueChanges); - void updateSnapAndCameraSettings(const QVector &valueChanges); - void updateColorSettings(const QVector &valueChanges); - void removeRotationBlocks(const QVector &instanceIds); + void updateMaterialPreviewData(const QList &valueChanges); + void updateRotationBlocks(const QList &valueChanges); + void updateSnapAndCameraSettings(const QList &valueChanges); + void updateColorSettings(const QList &valueChanges); + void removeRotationBlocks(const QList &instanceIds); void getNodeAtPos(const QPointF &pos); void getNodeAtMainScenePos(const QPointF &pos, qint32 viewId); diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5previewnodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5previewnodeinstanceserver.cpp index d20d0534b02..5a67de15676 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5previewnodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5previewnodeinstanceserver.cpp @@ -52,7 +52,7 @@ void Qt5PreviewNodeInstanceServer::collectItemChangesAndSendChangeCommands() QQuickDesignerSupport::polishItems(quickWindow()); - QVector imageContainerVector; + QList imageContainerVector; // Base state needs to be rendered twice to properly render shared resources, // if there is more than one View3D and at least one of them is dirty. diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp index 37b1e3faaec..b055b70cbc7 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5rendernodeinstanceserver.cpp @@ -207,7 +207,7 @@ void Qt5RenderNodeInstanceServer::completeComponent(const CompleteComponentComma { Qt5NodeInstanceServer::completeComponent(command); - const QVector ids = command.instances(); + const QList ids = command.instances(); for (qint32 instanceId : ids) { if (hasInstanceForId(instanceId)) { ServerNodeInstance instance = instanceForId(instanceId); @@ -227,7 +227,7 @@ void Qt5RenderNodeInstanceServer::changePropertyValues(const ChangeValuesCommand { Qt5NodeInstanceServer::changePropertyValues(command); - const QVector values = command.valueChanges(); + const QList values = command.valueChanges(); for (const PropertyValueContainer &container : values) { // In case an effect item visibility changed to false, make sure all children are rendered // again as they might not have valid pixmaps yet @@ -255,7 +255,7 @@ void Qt5RenderNodeInstanceServer::changePropertyBindings(const ChangeBindingsCom { Qt5NodeInstanceServer::changePropertyBindings(command); - const QVector changes = command.bindingChanges; + const QList changes = command.bindingChanges; for (const PropertyBindingContainer &container : changes) { if (container.isDynamic() && hasInstanceForId(container.instanceId())) { // Changes to dynamic properties are not always noticed by normal signal spy mechanism @@ -269,7 +269,7 @@ void Qt5RenderNodeInstanceServer::reparentInstances(const ReparentInstancesComma { ServerNodeInstance effectNode; ServerNodeInstance oldParent; - const QVector containers = command.reparentInstances(); + const QList containers = command.reparentInstances(); for (const ReparentContainer &container : containers) { if (hasInstanceForId(container.instanceId())) { ServerNodeInstance instance = instanceForId(container.instanceId()); @@ -304,7 +304,7 @@ void Qt5RenderNodeInstanceServer::reparentInstances(const ReparentInstancesComma void Qt5RenderNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) { ServerNodeInstance oldParent; - const QVector ids = command.instanceIds(); + const QList ids = command.instanceIds(); for (qint32 id : ids) { if (hasInstanceForId(id)) { ServerNodeInstance instance = instanceForId(id); diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5testnodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5testnodeinstanceserver.cpp index ca501b5eb32..6176d108db3 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5testnodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5testnodeinstanceserver.cpp @@ -238,7 +238,7 @@ void QmlDesigner::Qt5TestNodeInstanceServer::collectItemChangesAndSendChangeComm QQuickDesignerSupport::polishItems(quickWindow()); QSet informationChangedInstanceSet; - QVector propertyChangedList; + QList propertyChangedList; QSet parentChangedSet; if (quickWindow()) { From a6fe24f554abf0d581c39ef03a12bca7d533e218 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 15 Apr 2025 14:57:30 +0200 Subject: [PATCH 74/82] QmlDesigner: Fix warning in WidgetRegistrationInterface Change-Id: I921f27f788de1d6601cde9cf6301b4fda1c3f0f0 Reviewed-by: Ali Kianian --- .../qmldesigner/libs/designercore/include/widgetregistration.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h b/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h index c741831e12d..ea4ad010190 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h +++ b/src/plugins/qmldesigner/libs/designercore/include/widgetregistration.h @@ -12,6 +12,9 @@ class WidgetRegistrationInterface public: virtual void registerWidgetInfo(WidgetInfo) = 0; virtual void deregisterWidgetInfo(WidgetInfo) = 0; + +protected: + ~WidgetRegistrationInterface() = default; }; } // namespace QmlDesigner From d44cbdd68996c5f5580dfaac9bb7ec2b3d314042 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Wed, 9 Apr 2025 11:12:34 +0300 Subject: [PATCH 75/82] QmlDesigner: Fix node order in QmlRewriter This patch fixes the case for prepending an item to NodeListProperty For the zero index corner case, If the order is available, we should prepend the node. Otherwise, it should be appended. This works for the case of NodeListProperty. If the node order has not been changed, or is not important, we should just append objects. This case works when we load and append nodes consecutively, and node orders are not changed in the transaction. nodeLocation is optional. If it has a value, it means that we need to consider the node location. Otherwise, we should only append. When we search for the items to insert an object after them, if we want to insert an object to the top (pos = -1), we should find the current first object, and return the last non-object item found before the first object. If there's no object, it will be automatically return the last non-object. Fixes: QDS-15226 Change-Id: I5c5c23a27a956baa15a7a4eecae2fa5d4f9bb650 Reviewed-by: Knud Dollereder --- .../filemanager/addobjectvisitor.cpp | 10 ++- .../filemanager/addobjectvisitor.h | 4 +- .../filemanager/qmlrefactoring.cpp | 4 +- .../designercore/filemanager/qmlrefactoring.h | 4 +- .../designercore/filemanager/qmlrewriter.cpp | 5 +- .../designercore/rewriter/rewriteaction.cpp | 89 ++++++++++--------- .../designercore/rewriter/rewriteaction.h | 80 +++++++---------- 7 files changed, 92 insertions(+), 104 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp index 728686ff098..873a77f8cff 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp @@ -10,7 +10,7 @@ using namespace QmlDesigner::Internal; AddObjectVisitor::AddObjectVisitor(QmlDesigner::TextModifier &modifier, quint32 parentLocation, - quint32 nodeLocation, + std::optional nodeLocation, const QString &content, Utils::span propertyOrder) : QMLRewriter(modifier) @@ -46,9 +46,11 @@ bool AddObjectVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) // FIXME: duplicate code in the QmlJS::Rewriter class, remove this void AddObjectVisitor::insertInto(QmlJS::AST::UiObjectInitializer *ast) { - QmlJS::AST::UiObjectMemberList *insertAfter = searchChildrenToInsertAfter(ast->members, - m_propertyOrder, - m_nodeLocation - 1); + QmlJS::AST::UiObjectMemberList *insertAfter; + if (m_nodeLocation.has_value()) + insertAfter = searchChildrenToInsertAfter(ast->members, m_propertyOrder, *m_nodeLocation - 1); + else + insertAfter = searchMemberToInsertAfter(ast->members, m_propertyOrder); int insertionPoint; int depth; diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h index d63dcc35be7..02b3dffc870 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h @@ -13,7 +13,7 @@ class AddObjectVisitor: public QMLRewriter public: AddObjectVisitor(QmlDesigner::TextModifier &modifier, quint32 parentLocation, - quint32 nodeLocation, + std::optional nodeLocation, const QString &content, Utils::span propertyOrder); @@ -26,7 +26,7 @@ private: private: quint32 m_parentLocation; - quint32 m_nodeLocation; + std::optional m_nodeLocation; QString m_content; Utils::span m_propertyOrder; }; diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp index 34c0aa331a5..cf80b3d0e01 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp @@ -77,7 +77,9 @@ bool QmlRefactoring::addToArrayMemberList(int parentLocation, return visit(qmlDocument->qmlProgram()); } -bool QmlRefactoring::addToObjectMemberList(int parentLocation, int nodeLocation, const QString &content) +bool QmlRefactoring::addToObjectMemberList(int parentLocation, + std::optional nodeLocation, + const QString &content) { if (parentLocation < 0) return false; diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h index 18460db592b..7d6bae12cc0 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h @@ -35,7 +35,9 @@ public: bool removeImport(const Import &import); bool addToArrayMemberList(int parentLocation, PropertyNameView propertyName, const QString &content); - bool addToObjectMemberList(int parentLocation, int nodeLocation, const QString &content); + bool addToObjectMemberList(int parentLocation, + std::optional nodeLocation, + const QString &content); bool addProperty(int parentLocation, PropertyNameView name, const QString &value, diff --git a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp index ae0fc1c56c2..43345537685 100644 --- a/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp +++ b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp @@ -288,9 +288,6 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( QmlJS::AST::UiObjectMemberList *members, Utils::span propertyOrder, int pos) { - if (pos < 0) - return searchMemberToInsertAfter(members, propertyOrder); - // An empty property name should be available in the propertyOrder List, which is the right place // to define the objects there. const int objectDefinitionInsertionPoint = indexOf(propertyOrder, ""); @@ -304,6 +301,8 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter( int idx = -1; if (QmlJS::AST::cast(member)) { + if (pos < 0) + break; lastObjectDef = iter; if (objectPos++ == pos) break; diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.cpp index 1035f8273a0..9b7f316d39e 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.cpp @@ -60,42 +60,47 @@ QStringView toString(QmlRefactoring::PropertyType type) } // namespace anonymous +std::optional PropertyRewriteAction::nodeLocation() const +{ + if (movedAfterCreation()) + return std::make_optional(m_property.toNodeListProperty().indexOf(m_containedModelNode)); + + return std::nullopt; +} + bool AddPropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) { - if (m_sheduledInHierarchy) { - const int parentLocation = positionStore.nodeOffset(m_property.parentModelNode()); + if (scheduledInHierarchy()) { + const int parentLocation = positionStore.nodeOffset(property().parentModelNode()); bool result = false; - if (m_propertyType != QmlRefactoring::ScriptBinding && m_property.isDefaultProperty()) { - const int nodeLocation = movedAfterCreation() - ? m_property.toNodeListProperty().indexOf(m_containedModelNode) - : -1; - result = refactoring.addToObjectMemberList(parentLocation, nodeLocation, m_valueText); + if (propertyType() != QmlRefactoring::ScriptBinding && property().isDefaultProperty()) { + result = refactoring.addToObjectMemberList(parentLocation, nodeLocation(), valueText()); if (!result) { qDebug() << "*** AddPropertyRewriteAction::execute failed in addToObjectMemberList(" - << parentLocation << ',' << nodeLocation << ',' << m_valueText << ") **" + << parentLocation << ',' << nodeLocation() << ',' << valueText() << ") **" << info(); } - } else if (m_property.isNodeListProperty() && m_property.toNodeListProperty().count() > 1) { - result = refactoring.addToArrayMemberList(parentLocation, m_property.name(), m_valueText); + } else if (property().isNodeListProperty() && property().toNodeListProperty().count() > 1) { + result = refactoring.addToArrayMemberList(parentLocation, property().name(), valueText()); if (!result) { qDebug() << "*** AddPropertyRewriteAction::execute failed in addToArrayMemberList(" - << parentLocation << ',' << m_property.name() << ',' << m_valueText + << parentLocation << ',' << property().name() << ',' << valueText() << ") **" << info(); } } else { result = refactoring.addProperty(parentLocation, - m_property.name(), - m_valueText, - m_propertyType, - m_property.dynamicTypeName()); + property().name(), + valueText(), + propertyType(), + property().dynamicTypeName()); if (!result) { qDebug() << "*** AddPropertyRewriteAction::execute failed in addProperty(" - << parentLocation << ',' << m_property.name() << ',' << m_valueText << "," - << toString(m_propertyType) << ") **" << info(); + << parentLocation << ',' << property().name() << ',' << valueText() << "," + << toString(propertyType()) << ") **" << info(); } } @@ -109,12 +114,12 @@ QString AddPropertyRewriteAction::info() const { return QStringView(u"AddPropertyRewriteAction for property \"%1\" (type: %2) of node \"%3\" " u"with value >>%4<< and contained object \"%5\"") - .arg(QString::fromUtf8(m_property.name()), - toString(m_propertyType), - (m_property.parentModelNode().isValid() ? m_property.parentModelNode().id() + .arg(QString::fromUtf8(property().name()), + toString(propertyType()), + (property().parentModelNode().isValid() ? property().parentModelNode().id() : QLatin1String("(invalid)")), - QString(m_valueText).replace(QLatin1Char('\n'), QLatin1String("\\n")), - (m_containedModelNode.isValid() ? m_containedModelNode.id() + QString(valueText()).replace(QLatin1Char('\n'), QLatin1String("\\n")), + (containedModelNode().isValid() ? containedModelNode().id() : QString(QStringLiteral("(none)")))); } @@ -166,46 +171,42 @@ QString ChangeIdRewriteAction::info() const bool ChangePropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) { - if (m_sheduledInHierarchy) { - const int parentLocation = positionStore.nodeOffset(m_property.parentModelNode()); + if (scheduledInHierarchy()) { + const int parentLocation = positionStore.nodeOffset(property().parentModelNode()); if (parentLocation < 0) { qWarning() << "*** ChangePropertyRewriteAction::execute ignored. Invalid node location"; return true; } bool result = false; - if (m_propertyType != QmlRefactoring::ScriptBinding && m_property.isDefaultProperty()) { - const int nodeLocation = movedAfterCreation() - ? m_property.toNodeListProperty().indexOf(m_containedModelNode) - : -1; - - result = refactoring.addToObjectMemberList(parentLocation, nodeLocation, m_valueText); + if (propertyType() != QmlRefactoring::ScriptBinding && property().isDefaultProperty()) { + result = refactoring.addToObjectMemberList(parentLocation, nodeLocation(), valueText()); if (!result) { qDebug() << "*** ChangePropertyRewriteAction::execute failed in addToObjectMemberList(" - << parentLocation << ',' << nodeLocation << ',' << m_valueText << ") **" + << parentLocation << ',' << nodeLocation() << ',' << valueText() << ") **" << info(); } - } else if (m_propertyType == QmlRefactoring::ArrayBinding) { - result = refactoring.addToArrayMemberList(parentLocation, m_property.name(), m_valueText); + } else if (propertyType() == QmlRefactoring::ArrayBinding) { + result = refactoring.addToArrayMemberList(parentLocation, property().name(), valueText()); if (!result) { qDebug() << "*** ChangePropertyRewriteAction::execute failed in addToArrayMemberList(" - << parentLocation << ',' << m_property.name() << ',' << m_valueText << ") **" + << parentLocation << ',' << property().name() << ',' << valueText() << ") **" << info(); } } else { result = refactoring.changeProperty(parentLocation, - m_property.name(), - m_valueText, - m_propertyType); + property().name(), + valueText(), + propertyType()); if (!result) { qDebug() << "*** ChangePropertyRewriteAction::execute failed in changeProperty(" - << parentLocation << ',' << m_property.name() << ',' << m_valueText << ',' - << toString(m_propertyType) << ") **" << info(); + << parentLocation << ',' << property().name() << ',' << valueText() << ',' + << toString(propertyType()) << ") **" << info(); } } @@ -219,12 +220,12 @@ QString ChangePropertyRewriteAction::info() const { return QStringView(u"ChangePropertyRewriteAction for property \"%1\" (type: %2) of node \"%3\" " u"with value >>%4<< and contained object \"%5\"") - .arg(QString::fromUtf8(m_property.name()), - toString(m_propertyType), - (m_property.parentModelNode().isValid() ? m_property.parentModelNode().id() + .arg(QString::fromUtf8(property().name()), + toString(propertyType()), + (property().parentModelNode().isValid() ? property().parentModelNode().id() : QLatin1String("(invalid)")), - QString(m_valueText).replace(QLatin1Char('\n'), QLatin1String("\\n")), - (m_containedModelNode.isValid() ? m_containedModelNode.id() + QString(valueText()).replace(QLatin1Char('\n'), QLatin1String("\\n")), + (containedModelNode().isValid() ? containedModelNode().id() : QString(QStringLiteral("(none)")))); } diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.h b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.h index a1f77f70d64..00fa8bc04c6 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.h +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.h @@ -48,43 +48,53 @@ public: RewriteAction &operator=(const RewriteAction&) = delete; }; -class AddPropertyRewriteAction: public RewriteAction +class PropertyRewriteAction : public RewriteAction { public: - AddPropertyRewriteAction(const AbstractProperty &property, const QString &valueText, QmlDesigner::QmlRefactoring::PropertyType propertyType, const ModelNode &containedModelNode/* = ModelNode()*/): - m_property(property), m_valueText(valueText), m_propertyType(propertyType), m_containedModelNode(containedModelNode), - m_sheduledInHierarchy(property.isValid() && property.parentModelNode().isInHierarchy()) + PropertyRewriteAction(const AbstractProperty &property, + const QString &valueText, + QmlDesigner::QmlRefactoring::PropertyType propertyType, + const ModelNode &containedModelNode /* = ModelNode()*/) + : m_property(property) + , m_valueText(valueText) + , m_propertyType(propertyType) + , m_containedModelNode(containedModelNode) + , m_scheduledInHierarchy(property.isValid() && property.parentModelNode().isInHierarchy()) {} - bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) override; - QString info() const override; + AbstractProperty property() const { return m_property; } - AddPropertyRewriteAction *asAddPropertyRewriteAction() override { return this; } + QString valueText() const { return m_valueText; } - AbstractProperty property() const - { return m_property; } + QmlDesigner::QmlRefactoring::PropertyType propertyType() const { return m_propertyType; } - QString valueText() const - { return m_valueText; } + ModelNode containedModelNode() const { return m_containedModelNode; } - QmlDesigner::QmlRefactoring::PropertyType propertyType() const - { return m_propertyType; } - - ModelNode containedModelNode() const - { return m_containedModelNode; } - - bool movedAfterCreation() const { return m_movedAfterCreation; } void setMovedAfterCreation(bool moved) { m_movedAfterCreation = moved; } +protected: + bool scheduledInHierarchy() const { return m_scheduledInHierarchy; } + bool movedAfterCreation() const { return m_movedAfterCreation; } + std::optional nodeLocation() const; + private: AbstractProperty m_property; QString m_valueText; QmlDesigner::QmlRefactoring::PropertyType m_propertyType; ModelNode m_containedModelNode; - bool m_sheduledInHierarchy; + bool m_scheduledInHierarchy; bool m_movedAfterCreation = false; }; +class AddPropertyRewriteAction : public PropertyRewriteAction +{ +public: + using PropertyRewriteAction::PropertyRewriteAction; + bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) override; + QString info() const override; + AddPropertyRewriteAction *asAddPropertyRewriteAction() override { return this; } +}; + class ChangeIdRewriteAction: public RewriteAction { public: @@ -106,41 +116,13 @@ private: QString m_newId; }; -class ChangePropertyRewriteAction: public RewriteAction +class ChangePropertyRewriteAction : public PropertyRewriteAction { public: - ChangePropertyRewriteAction(const AbstractProperty &property, const QString &valueText, QmlDesigner::QmlRefactoring::PropertyType propertyType, const ModelNode &containedModelNode/* = ModelNode()*/): - m_property(property), m_valueText(valueText), m_propertyType(propertyType), m_containedModelNode(containedModelNode), - m_sheduledInHierarchy(property.isValid() && property.parentModelNode().isInHierarchy()) - {} - + using PropertyRewriteAction::PropertyRewriteAction; bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) override; QString info() const override; - ChangePropertyRewriteAction *asChangePropertyRewriteAction() override { return this; } - - AbstractProperty property() const - { return m_property; } - - QString valueText() const - { return m_valueText; } - - QmlDesigner::QmlRefactoring::PropertyType propertyType() const - { return m_propertyType; } - - ModelNode containedModelNode() const - { return m_containedModelNode; } - - bool movedAfterCreation() const { return m_movedAfterCreation; } - void setMovedAfterCreation(bool moved) { m_movedAfterCreation = moved; } - -private: - AbstractProperty m_property; - QString m_valueText; - QmlDesigner::QmlRefactoring::PropertyType m_propertyType; - ModelNode m_containedModelNode; - bool m_sheduledInHierarchy; - bool m_movedAfterCreation; }; class ChangeTypeRewriteAction:public RewriteAction From 4c7e6c699264bc37100f43c00e08027e9f06518f Mon Sep 17 00:00:00 2001 From: Amr Essam Date: Mon, 31 Mar 2025 14:31:04 +0300 Subject: [PATCH 76/82] QmlDesigner: Add preset layout options for 3D View Task-number: QDS-14907 Change-Id: I0937a64dc1820727178372663e2913f2c2239f10 Reviewed-by: Mahmoud Badri --- .../commands/puppettocreatorcommand.h | 2 +- .../interfaces/nodeinstanceglobal.h | 3 +- .../components/edit3d/edit3dcanvas.cpp | 10 +- .../components/edit3d/edit3dview.cpp | 132 +++++--- .../components/edit3d/edit3dview.h | 28 +- .../components/edit3d/edit3dwidget.cpp | 47 ++- .../components/edit3d/edit3dwidget.h | 4 + .../instances/nodeinstanceview.cpp | 10 +- .../qmldesigner/qmldesignerconstants.h | 8 + .../mockfiles/qt6/EditCameraController.qml | 26 +- .../qmlpuppet/mockfiles/qt6/EditView3D.qml | 302 ++++++++++-------- .../qmlpuppet/mockfiles/qt6/OverlayView3D.qml | 4 +- .../qt5informationnodeinstanceserver.cpp | 15 +- .../qt5informationnodeinstanceserver.h | 2 +- 14 files changed, 364 insertions(+), 229 deletions(-) diff --git a/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h b/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h index a8f37a81e53..44d68f9ed29 100644 --- a/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h @@ -16,7 +16,7 @@ public: Edit3DToolState, Render3DView, ActiveSceneChanged, - ActiveSplitChanged, + ActiveViewportChanged, RenderModelNodePreviewImage, Import3DPreviewIcon, Import3DPreviewImage, diff --git a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h index a05d9681f64..8b25001f83e 100644 --- a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h +++ b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h @@ -51,10 +51,11 @@ enum class View3DActionType { ParticlesRestart, ParticlesSeek, SyncEnvBackground, + ViewportPreset, GetNodeAtPos, GetNodeAtMainScenePos, SetBakeLightsView3D, - SplitViewToggle, + ViewportViewToggle, MaterialOverride, ShowWireframe, FlyModeToggle, diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp index a0ac71a9399..3545c218a54 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp @@ -98,11 +98,11 @@ void Edit3DCanvas::setFlyMode(bool enabled, const QPoint &pos) m_flyModeStartCursorPos = pos; m_flyModeFirstUpdate = true; - // Hide cursor on the middle of the active split to make the wheel work during flight mode. - // We can't rely on current activeSplit value, as mouse press to enter flight mode can change the - // active split, so hide the cursor based on its current location. + // Hide cursor on the middle of the active viewport to make the wheel work during flight mode. + // We can't rely on current activeViewport value, as mouse press to enter flight mode can change the + // active viewport, so hide the cursor based on its current location. QPoint center = mapToGlobal(QPoint(width() / 2, height() / 2)); - if (m_parent->view()->isSplitView()) { + if (m_parent->view()->isMultiViewportView()) { if (pos.x() <= center.x()) { if (pos.y() <= center.y()) m_hiddenCursorPos = mapToGlobal(QPoint(width() / 4, height() / 4)); @@ -192,7 +192,7 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e) if (!m_flyModeFirstUpdate) { // We notify explicit camera rotation needs for QML Puppet rather than relying on mouse events, // as mouse isn't grabbed on QML Puppet side and can't handle fast movements that go out of - // edit camera mouse area. This also simplifies split view handling. + // edit camera mouse area. This also simplifies viewport view handling. QPointF diff = m_isQDSTrusted ? (m_hiddenCursorPos - globalPos) : (m_lastCursorPos - e->globalPosition().toPoint()); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 11edda9005e..37c9c66f542 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -73,7 +73,7 @@ Edit3DView::Edit3DView(ExternalDependenciesInterface &externalDependencies) connect(&m_compressionTimer, &QTimer::timeout, this, &Edit3DView::handleEntriesChanged); for (int i = 0; i < 4; ++i) - m_splitToolStates.append({0, false, i == 0}); + m_viewportToolStates.append({0, false, i == 0}); } void Edit3DView::createEdit3DWidget() @@ -120,15 +120,15 @@ void Edit3DView::renderImage3DChanged(const QImage &img) void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) { - const QString activeSplitKey = QStringLiteral("activeSplit"); - if (sceneState.contains(activeSplitKey)) { - setActiveSplit(sceneState[activeSplitKey].toInt()); - // If the sceneState contained just activeSplit key, then this is simply an active split + const QString activeViewportKey = QStringLiteral("activeViewport"); + if (sceneState.contains(activeViewportKey)) { + setActiveViewport(sceneState[activeViewportKey].toInt()); + // If the sceneState contained just activeViewport key, then this is simply an active Viewport // change rather than entire active scene change, and we don't need to process further. if (sceneState.size() == 1) return; } else { - setActiveSplit(0); + setActiveViewport(0); } const QString sceneKey = QStringLiteral("sceneInstanceId"); @@ -146,7 +146,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) const QString particleEmitterKey = QStringLiteral("showParticleEmitter"); const QString particlesPlayKey = QStringLiteral("particlePlay"); const QString syncEnvBgKey = QStringLiteral("syncEnvBackground"); - const QString splitViewKey = QStringLiteral("splitView"); + const QString activePresetKey = QStringLiteral("activePreset"); const QString matOverrideKey = QStringLiteral("matOverride"); const QString showWireframeKey = QStringLiteral("showWireframe"); @@ -177,10 +177,10 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) if (sceneState.contains(perspectiveKey)) { const QVariantList showList = sceneState[perspectiveKey].toList(); for (int i = 0; i < 4; ++i) - m_splitToolStates[i].isPerspective = i < showList.size() ? showList[i].toBool() : i == 0; + m_viewportToolStates[i].isPerspective = i < showList.size() ? showList[i].toBool() : i == 0; } else { for (int i = 0; i < 4; ++i) { - SplitToolState &state = m_splitToolStates[i]; + ViewportToolState &state = m_viewportToolStates[i]; state.isPerspective = i == 0; } } @@ -235,26 +235,21 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) else m_particlesPlayAction->action()->setChecked(true); - if (sceneState.contains(splitViewKey)) - m_splitViewAction->action()->setChecked(sceneState[splitViewKey].toBool()); - else - m_splitViewAction->action()->setChecked(false); - if (sceneState.contains(matOverrideKey)) { const QVariantList overrides = sceneState[matOverrideKey].toList(); for (int i = 0; i < 4; ++i) - m_splitToolStates[i].matOverride = i < overrides.size() ? overrides[i].toInt() : 0; + m_viewportToolStates[i].matOverride = i < overrides.size() ? overrides[i].toInt() : 0; } else { - for (SplitToolState &state : m_splitToolStates) + for (ViewportToolState &state : m_viewportToolStates) state.matOverride = 0; } if (sceneState.contains(showWireframeKey)) { const QVariantList showList = sceneState[showWireframeKey].toList(); for (int i = 0; i < 4; ++i) - m_splitToolStates[i].showWireframe = i < showList.size() ? showList[i].toBool() : false; + m_viewportToolStates[i].showWireframe = i < showList.size() ? showList[i].toBool() : false; } else { - for (SplitToolState &state : m_splitToolStates) + for (ViewportToolState &state : m_viewportToolStates) state.showWireframe = false; } @@ -274,10 +269,10 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) storeCurrentSceneEnvironment(); } -void Edit3DView::setActiveSplit(int split) +void Edit3DView::setActiveViewport(int viewport) { - m_activeSplit = split; - m_cameraModeAction->action()->setChecked(m_splitToolStates[m_activeSplit].isPerspective); + m_activeViewport = viewport; + m_cameraModeAction->action()->setChecked(m_viewportToolStates[m_activeViewport].isPerspective); } void Edit3DView::modelAttached(Model *model) @@ -709,6 +704,45 @@ void Edit3DView::createSyncEnvBackgroundAction() tooltip); } +void Edit3DView::createViewportPresetActions() +{ + auto createViewportPresetAction = [this](std::unique_ptr &targetAction, + const QByteArray &id, + const QString &label, + bool isChecked) { + auto operation = [this, &targetAction, label](const SelectionContext &) { + for (Edit3DAction *action : std::as_const(m_viewportPresetActions)) { + if (action->menuId() != targetAction->menuId()) + action->action()->setChecked(false); + } + emitView3DAction(View3DActionType::ViewportPreset, label); + }; + + targetAction = std::make_unique( + id, + View3DActionType::Empty, + label, + QKeySequence(), + true, + isChecked, + QIcon(), + this, + operation); + }; + + createViewportPresetAction(m_viewportPresetSingleAction, Constants::EDIT3D_PRESET_SINGLE, "Single", true); + createViewportPresetAction(m_viewportPresetQuadAction, Constants::EDIT3D_PRESET_QUAD, "Quad", false); + createViewportPresetAction(m_viewportPreset3Left1RightAction, Constants::EDIT3D_PRESET_3LEFT1RIGHT, "3Left1Right", false); + createViewportPresetAction(m_viewportPreset2HorizontalAction, Constants::EDIT3D_PRESET_2HORIZONTAL, "2Horizontal", false); + createViewportPresetAction(m_viewportPreset2VerticalAction, Constants::EDIT3D_PRESET_2VERTICAL, "2Vertical", false); + + m_viewportPresetActions << m_viewportPresetSingleAction.get(); + m_viewportPresetActions << m_viewportPresetQuadAction.get(); + m_viewportPresetActions << m_viewportPreset3Left1RightAction.get(); + m_viewportPresetActions << m_viewportPreset2HorizontalAction.get(); + m_viewportPresetActions << m_viewportPreset2VerticalAction.get(); +} + void Edit3DView::createSeekerSliderAction() { m_seekerAction = std::make_unique( @@ -930,27 +964,27 @@ void Edit3DView::storeCurrentSceneEnvironment() } } -const QList &Edit3DView::splitToolStates() const +const QList &Edit3DView::viewportToolStates() const { - return m_splitToolStates; + return m_viewportToolStates; } -void Edit3DView::setSplitToolState(int splitIndex, const SplitToolState &state) +void Edit3DView::setViewportToolState(int viewportIndex, const ViewportToolState &state) { - if (splitIndex >= m_splitToolStates.size()) + if (viewportIndex >= m_viewportToolStates.size()) return; - m_splitToolStates[splitIndex] = state; + m_viewportToolStates[viewportIndex] = state; } -int Edit3DView::activeSplit() const +int Edit3DView::activeViewport() const { - return m_activeSplit; + return m_activeViewport; } -bool Edit3DView::isSplitView() const +bool Edit3DView::isMultiViewportView() const { - return m_splitViewAction->action()->isChecked(); + return m_viewportPresetsMenuAction->action()->isChecked(); } void Edit3DView::createEdit3DActions() @@ -1022,12 +1056,12 @@ void Edit3DView::createEdit3DActions() SelectionContextOperation cameraModeTrigger = [this](const SelectionContext &) { QVariantList list; - for (int i = 0; i < m_splitToolStates.size(); ++i) { - Edit3DView::SplitToolState state = m_splitToolStates[i]; - if (i == m_activeSplit) { + for (int i = 0; i < m_viewportToolStates.size(); ++i) { + Edit3DView::ViewportToolState state = m_viewportToolStates[i]; + if (i == m_activeViewport) { bool isChecked = m_cameraModeAction->action()->isChecked(); state.isPerspective = isChecked; - setSplitToolState(i, state); + setViewportToolState(i, state); list.append(isChecked); } else { list.append(state.isPerspective); @@ -1315,14 +1349,24 @@ void Edit3DView::createEdit3DActions() this, snapConfigTrigger); - m_splitViewAction = std::make_unique(QmlDesigner::Constants::EDIT3D_SPLIT_VIEW, - View3DActionType::SplitViewToggle, - Tr::tr("Toggle Split View On/Off"), - QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Q), - true, + SelectionContextOperation viewportPresetsActionTrigger = [this](const SelectionContext &) { + if (!edit3DWidget()->viewportPresetsMenu()) + return; + + edit3DWidget()->showViewportPresetsMenu( + !edit3DWidget()->viewportPresetsMenu()->isVisible(), + resolveToolbarPopupPos(m_viewportPresetsMenuAction.get())); + }; + + m_viewportPresetsMenuAction = std::make_unique(QmlDesigner::Constants::EDIT3D_PRESETS, + View3DActionType::Empty, + Tr::tr("Show Viewport Modes"), + QKeySequence(), + false, false, toolbarIcon(DesignerIcons::SplitViewIcon), - this); + this, + viewportPresetsActionTrigger); SelectionContextOperation cameraSpeedConfigTrigger = [this](const SelectionContext &) { if (!m_cameraSpeedConfiguration) { @@ -1372,7 +1416,7 @@ void Edit3DView::createEdit3DActions() m_leftActions << nullptr; m_leftActions << m_visibilityTogglesAction.get(); m_leftActions << m_backgroundColorMenuAction.get(); - m_leftActions << m_splitViewAction.get(); + m_leftActions << m_viewportPresetsMenuAction.get(); m_rightActions << m_particleViewModeAction.get(); m_rightActions << m_particlesPlayAction.get(); @@ -1400,6 +1444,8 @@ void Edit3DView::createEdit3DActions() m_backgroundColorActions << m_selectGridColorAction.get(); m_backgroundColorActions << m_syncEnvBackgroundAction.get(); m_backgroundColorActions << m_resetColorAction.get(); + + createViewportPresetActions(); } QVector Edit3DView::leftActions() const @@ -1422,6 +1468,10 @@ QVector Edit3DView::backgroundColorActions() const return m_backgroundColorActions; } +QVector Edit3DView::viewportPresetActions() const +{ + return m_viewportPresetActions; +} Edit3DAction *Edit3DView::edit3DAction(View3DActionType type) const { diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 0cc421c8566..1c5d478357d 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -39,7 +39,7 @@ class QMLDESIGNERCOMPONENTS_EXPORT Edit3DView : public AbstractView Q_OBJECT public: - struct SplitToolState + struct ViewportToolState { int matOverride = 0; bool showWireframe = false; @@ -92,6 +92,7 @@ public: QVector rightActions() const; QVector visibilityToggleActions() const; QVector backgroundColorActions() const; + QVector viewportPresetActions() const; Edit3DAction *edit3DAction(View3DActionType type) const; Edit3DBakeLightsAction *bakeLightsAction() const; @@ -110,11 +111,11 @@ public: void setCameraSpeedAuxData(double speed, double multiplier); void getCameraSpeedAuxData(double &speed, double &multiplier); - const QList &splitToolStates() const; - void setSplitToolState(int splitIndex, const SplitToolState &state); + const QList &viewportToolStates() const; + void setViewportToolState(int viewportIndex, const ViewportToolState &state); - int activeSplit() const; - bool isSplitView() const; + int activeViewport() const; + bool isMultiViewportView() const; void setFlyMode(bool enabled); void emitView3DAction(View3DActionType type, const QVariant &value); @@ -147,12 +148,13 @@ private: void createGridColorSelectionAction(); void createResetColorAction(QAction *syncEnvBackgroundAction); void createSyncEnvBackgroundAction(); + void createViewportPresetActions(); void createSeekerSliderAction(); void syncCameraSpeedToNewView(); QmlObjectNode currentSceneEnv(); void storeCurrentSceneEnvironment(); - void setActiveSplit(int split); + void setActiveViewport(int viewportIndex); QPoint resolveToolbarPopupPos(Edit3DAction *action) const; @@ -164,6 +166,7 @@ private: QVector m_rightActions; QVector m_visibilityToggleActions; QVector m_backgroundColorActions; + QVector m_viewportPresetActions; QMap m_edit3DActions; std::unique_ptr m_selectionModeAction; @@ -191,7 +194,14 @@ private: std::unique_ptr m_selectBackgroundColorAction; std::unique_ptr m_selectGridColorAction; std::unique_ptr m_resetColorAction; - std::unique_ptr m_splitViewAction; + + // Viewport presets actions + std::unique_ptr m_viewportPresetSingleAction; + std::unique_ptr m_viewportPresetQuadAction; + std::unique_ptr m_viewportPreset3Left1RightAction; + std::unique_ptr m_viewportPreset2HorizontalAction; + std::unique_ptr m_viewportPreset2VerticalAction; + std::unique_ptr m_viewportPresetsMenuAction; // View3DActionType::Empty actions std::unique_ptr m_resetAction; @@ -216,9 +226,9 @@ private: bool m_isBakingLightsSupported = false; QPointer m_snapConfiguration; QPointer m_cameraSpeedConfiguration; - int m_activeSplit = 0; + int m_activeViewport = 0; - QList m_splitToolStates; + QList m_viewportToolStates; ModelNode m_contextMenuPendingNode; ModelNode m_pickView3dNode; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 12e7588c093..8f8071171b4 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -179,6 +179,10 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) handleActions(view->backgroundColorActions(), m_backgroundColorMenu, false); + m_viewportPresetsMenu = new QMenu(this); + m_viewportPresetsMenu->setToolTipsVisible(true); + handleActions(view->viewportPresetActions(), m_viewportPresetsMenu, false); + createContextMenu(); // Onboarding label contains instructions for new users how to get 3D content into the project @@ -568,11 +572,11 @@ void Edit3DWidget::onMatOverrideAction(QAction *action) return; QVariantList list; - for (int i = 0; i < m_view->splitToolStates().size(); ++i) { - Edit3DView::SplitToolState state = m_view->splitToolStates()[i]; - if (i == m_view->activeSplit()) { + for (int i = 0; i < m_view->viewportToolStates().size(); ++i) { + Edit3DView::ViewportToolState state = m_view->viewportToolStates()[i]; + if (i == m_view->activeViewport()) { state.matOverride = action->data().toInt(); - m_view->setSplitToolState(i, state); + m_view->setViewportToolState(i, state); list.append(action->data()); } else { list.append(state.matOverride); @@ -588,11 +592,11 @@ void Edit3DWidget::onWireframeAction() return; QVariantList list; - for (int i = 0; i < m_view->splitToolStates().size(); ++i) { - Edit3DView::SplitToolState state = m_view->splitToolStates()[i]; - if (i == m_view->activeSplit()) { + for (int i = 0; i < m_view->viewportToolStates().size(); ++i) { + Edit3DView::ViewportToolState state = m_view->viewportToolStates()[i]; + if (i == m_view->activeViewport()) { state.showWireframe = m_wireFrameAction->isChecked(); - m_view->setSplitToolState(i, state); + m_view->setViewportToolState(i, state); list.append(m_wireFrameAction->isChecked()); } else { list.append(state.showWireframe); @@ -610,11 +614,11 @@ void Edit3DWidget::onResetAllOverridesAction() QVariantList wList; QVariantList mList; - for (int i = 0; i < m_view->splitToolStates().size(); ++i) { - Edit3DView::SplitToolState state; + for (int i = 0; i < m_view->viewportToolStates().size(); ++i) { + Edit3DView::ViewportToolState state; state.showWireframe = false; state.matOverride = 0; - m_view->setSplitToolState(i, state); + m_view->setViewportToolState(i, state); wList.append(state.showWireframe); mList.append(state.matOverride); } @@ -675,6 +679,21 @@ void Edit3DWidget::showBackgroundColorMenu(bool show, const QPoint &pos) m_backgroundColorMenu->close(); } +QMenu *Edit3DWidget::viewportPresetsMenu() const +{ + return m_viewportPresetsMenu.data(); +} + +void Edit3DWidget::showViewportPresetsMenu(bool show, const QPoint &pos) +{ + if (m_viewportPresetsMenu.isNull()) + return; + if (show) + m_viewportPresetsMenu->popup(pos); + else + m_viewportPresetsMenu->close(); +} + void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode, const QVector3D &pos3d) { auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); @@ -711,11 +730,11 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode m_materialsAction->updateMenu(view()->selectedModelNodes()); if (m_view) { - int idx = m_view->activeSplit(); - m_wireFrameAction->setChecked(m_view->splitToolStates()[idx].showWireframe); + int idx = m_view->activeViewport(); + m_wireFrameAction->setChecked(m_view->viewportToolStates()[idx].showWireframe); for (QAction *a : std::as_const(m_matOverrideActions)) a->setChecked(false); - int type = m_view->splitToolStates()[idx].matOverride; + int type = m_view->viewportToolStates()[idx].matOverride; m_matOverrideActions[type]->setChecked(true); } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 9b286699977..bc5a1b20d60 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -58,6 +58,9 @@ public: QMenu *backgroundColorMenu() const; void showBackgroundColorMenu(bool show, const QPoint &pos); + QMenu *viewportPresetsMenu() const; + void showViewportPresetsMenu(bool show, const QPoint &pos); + void showContextMenu(const QPoint &pos, const ModelNode &modelNode, const QVector3D &pos3d); void updateCreateSubMenu(const QList &entriesList); @@ -91,6 +94,7 @@ private: Core::IContext *m_context = nullptr; QPointer m_visibilityTogglesMenu; QPointer m_backgroundColorMenu; + QPointer m_viewportPresetsMenu; QPointer m_contextMenu; QPointer m_bakeLightsAction; QPointer m_editComponentAction; diff --git a/src/plugins/qmldesigner/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/instances/nodeinstanceview.cpp index 6a16f65d83a..776541ec5ca 100644 --- a/src/plugins/qmldesigner/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/instances/nodeinstanceview.cpp @@ -1811,12 +1811,12 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand const auto sceneState = qvariant_cast(command.data()); if (isAttached()) model()->emitUpdateActiveScene3D(this, sceneState); - } else if (command.type() == PuppetToCreatorCommand::ActiveSplitChanged) { - // Active split change is a special case of active scene change - QVariantMap splitState; - splitState.insert("activeSplit", command.data()); + } else if (command.type() == PuppetToCreatorCommand::ActiveViewportChanged) { + // Active viewport change is a special case of active scene change + QVariantMap viewportState; + viewportState.insert("activeViewport", command.data()); if (isAttached()) - model()->emitUpdateActiveScene3D(this, splitState); + model()->emitUpdateActiveScene3D(this, viewportState); } else if (command.type() == PuppetToCreatorCommand::RenderModelNodePreviewImage) { ImageContainer container = qvariant_cast(command.data()); QImage image = container.image(); diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 7bde8178caa..8b1e89c4c78 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -44,6 +44,14 @@ inline constexpr char EDIT3D_EDIT_SHOW_CAMERA_FRUSTUM[] = "QmlDesigner.Editor3D.ToggleCameraFrustum"; inline constexpr char EDIT3D_EDIT_SHOW_PARTICLE_EMITTER[] = "QmlDesigner.Editor3D.ToggleParticleEmitter"; + +inline constexpr char EDIT3D_PRESETS[] = "QmlDesigner.Editor3D.Presets"; +inline constexpr char EDIT3D_PRESET_SINGLE[] = "QmlDesigner.Editor3D.Single"; +inline constexpr char EDIT3D_PRESET_QUAD[] = "QmlDesigner.Editor3D.Quad"; +inline constexpr char EDIT3D_PRESET_3LEFT1RIGHT[] = "QmlDesigner.Editor3D.3Left1Right"; +inline constexpr char EDIT3D_PRESET_2HORIZONTAL[] = "QmlDesigner.Editor3D.2Horizontal"; +inline constexpr char EDIT3D_PRESET_2VERTICAL[] = "QmlDesigner.Editor3D.2Vertical"; + inline constexpr char EDIT3D_RESET_VIEW[] = "QmlDesigner.Editor3D.ResetView"; inline constexpr char EDIT3D_PARTICLE_MODE[] = "QmlDesigner.Editor3D.ParticleViewModeToggle"; inline constexpr char EDIT3D_PARTICLES_PLAY[] = "QmlDesigner.Editor3D.ParticlesPlay"; diff --git a/src/tools/qmlpuppet/mockfiles/qt6/EditCameraController.qml b/src/tools/qmlpuppet/mockfiles/qt6/EditCameraController.qml index 27f1f717034..6ef65c9718c 100644 --- a/src/tools/qmlpuppet/mockfiles/qt6/EditCameraController.qml +++ b/src/tools/qmlpuppet/mockfiles/qt6/EditCameraController.qml @@ -8,9 +8,9 @@ Item { id: cameraCtrl property var viewRoot: null - property int splitId: -1 + property int viewportId: -1 property Camera camera: view3d ? view3d.camera : null - property View3D view3d: viewRoot.editViews[splitId] + property View3D view3d: viewRoot.editViews[viewportId] property string sceneId: viewRoot.sceneId property vector3d _lookAtPoint property vector3d _pressPoint @@ -55,11 +55,11 @@ Item { _lookAtPoint = Qt.vector3d(0, 0, 0); _zoomFactor = 1; - if (splitId === 1) { + if (viewportId === 1) { jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.PositiveZ)); - } else if (splitId === 2) { + } else if (viewportId === 2) { jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.NegativeY)); - } else if (splitId === 3) { + } else if (viewportId === 3) { jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.NegativeX)); } else { camera.position = _defaultCameraPosition; @@ -79,7 +79,7 @@ Item { cameraState[1] = _zoomFactor; cameraState[2] = camera.position; cameraState[3] = camera.rotation; - _generalHelper.storeToolState(sceneId, "editCamState" + splitId, cameraState, delay); + _generalHelper.storeToolState(sceneId, "editCamState" + viewportId, cameraState, delay); } function focusObject(targetNodes, rotation, updateZoom, closeUp) @@ -254,12 +254,12 @@ Item { } on_LookAtPointChanged: { - viewRoot.overlayViews[splitId].lookAtGizmo.position = _lookAtPoint; + viewRoot.overlayViews[viewportId].lookAtGizmo.position = _lookAtPoint; } Connections { target: _generalHelper - enabled: viewRoot.activeSplit === cameraCtrl.splitId + enabled: viewRoot.activeViewport === cameraCtrl.viewportId function onRequestCameraMove(camera, moveVec) { if (camera === cameraCtrl.camera) { @@ -272,7 +272,7 @@ Item { Image { anchors.centerIn: parent source: "qrc:///qtquickplugin/mockfiles/images/crosshair.png" - visible: cameraCtrl.showCrosshairs && viewRoot.activeSplit === cameraCtrl.splitId + visible: cameraCtrl.showCrosshairs && viewRoot.activeViewport === cameraCtrl.viewportId opacity: 0.7 } @@ -303,7 +303,7 @@ Item { onPressed: (mouse) => { if (cameraCtrl.flyMode) return; - viewRoot.activeSplit = cameraCtrl.splitId + viewRoot.activeViewport = cameraCtrl.viewportId if (cameraCtrl.camera && (mouse.modifiers & (Qt.AltModifier | Qt.ShiftModifier))) { cameraCtrl._dragging = true; cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation; @@ -328,9 +328,9 @@ Item { onCanceled: handleRelease() onWheel: (wheel) => { - if (cameraCtrl.flyMode && cameraCtrl.splitId !== viewRoot.activeSplit) + if (cameraCtrl.flyMode && cameraCtrl.viewportId !== viewRoot.activeViewport) return; - viewRoot.activeSplit = cameraCtrl.splitId; + viewRoot.activeViewport = cameraCtrl.viewportId; if (cameraCtrl.camera) { // Empirically determined divisor for nice zoom cameraCtrl.zoomRelative(wheel.angleDelta.y / -40); @@ -373,7 +373,7 @@ Item { targetNode: cameraCtrl.camera onAxisClicked: (axis) => { - viewRoot.activeSplit = cameraCtrl.splitId + viewRoot.activeViewport = cameraCtrl.viewportId cameraCtrl.jumpToRotation(quaternionForAxis(axis)); } } diff --git a/src/tools/qmlpuppet/mockfiles/qt6/EditView3D.qml b/src/tools/qmlpuppet/mockfiles/qt6/EditView3D.qml index f3a60c53020..2d4edbe033c 100644 --- a/src/tools/qmlpuppet/mockfiles/qt6/EditView3D.qml +++ b/src/tools/qmlpuppet/mockfiles/qt6/EditView3D.qml @@ -12,7 +12,7 @@ Item { visible: true property Node activeScene: null - property int activeSplit: 0 + property int activeViewport: 0 property var editViews: [null, null, null, null] property var usePerspective: [true, false, false, false] property var overlayViews: [overlayView0, overlayView1, overlayView2, overlayView3] @@ -21,8 +21,8 @@ Item { property var materialOverrides: [DebugSettings.None, DebugSettings.None, DebugSettings.None, DebugSettings.None] property var showWireframes: [false, false, false, false] - property var activeEditView: editViews[activeSplit] - property var activeOverlayView: overlayViews[activeSplit] + property var activeEditView: editViews[activeViewport] + property var activeOverlayView: overlayViews[activeViewport] property string sceneId property bool showEditLight: false @@ -37,12 +37,56 @@ Item { property color backgroundGradientColorStart: "#222222" property color backgroundGradientColorEnd: "#999999" property color gridColor: "#cccccc" + property color viewportBorderColor: "#aaaaaaaa" property bool syncEnvBackground: true - property bool splitView: false + property string activePreset: "Single" property bool flyMode: false property bool showCameraSpeed: false property string cameraViewMode + // The presets used to customize the display of the viewports + property var viewportPresets: { + "Single": { + numViewports: 1, + viewRects: [ + { x: 0.0, y: 0.0, width: 1.0, height: 1.0 } + ] + }, + "Quad": { + numViewports: 4, + viewRects: [ + { x: 0.0, y: 0.0, width: 0.5, height: 0.5 }, + { x: 0.5, y: 0.0, width: 0.5, height: 0.5 }, + { x: 0.0, y: 0.5, width: 0.5, height: 0.5 }, + { x: 0.5, y: 0.5, width: 0.5, height: 0.5 } + ] + }, + "3Left1Right": { + numViewports: 4, + viewRects: [ + { x: 0.0, y: 0.0, width: 0.25, height: 0.33 }, + { x: 0.0, y: 0.33, width: 0.25, height: 0.34 }, + { x: 0.0, y: 0.67, width: 0.25, height: 0.33 }, + { x: 0.25, y: 0.0, width: 0.75, height: 1.0 } + ] + }, + "2Horizontal": { + numViewports: 2, + viewRects: [ + { x: 0.0, y: 0.0, width: 1.0, height: 0.5 }, + { x: 0.0, y: 0.5, width: 1.0, height: 0.5 } + ] + }, + "2Vertical": { + numViewports: 2, + viewRects: [ + { x: 0.0, y: 0.0, width: 0.5, height: 1.0 }, + { x: 0.5, y: 0.0, width: 0.5, height: 1.0 } + ] + } + //TODO: reset of presets + }; + enum SelectionMode { Item, Group } enum TransformMode { Move, Rotate, Scale } @@ -64,7 +108,7 @@ Item { signal commitObjectProperty(var objects, var propNames) signal changeObjectProperty(var objects, var propNames) signal notifyActiveSceneChange() - signal notifyActiveSplitChange(int index) + signal notifyActiveViewportChange(int index) onUsePerspectiveChanged: _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective) onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight) @@ -81,14 +125,14 @@ Item { onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode); onMaterialOverridesChanged: _generalHelper.storeToolState(sceneId, "matOverride", materialOverrides); onShowWireframesChanged: _generalHelper.storeToolState(sceneId, "showWireframe", showWireframes); - onSplitViewChanged: { - _generalHelper.storeToolState(sceneId, "splitView", splitView); + onActivePresetChanged: { + _generalHelper.storeToolState(sceneId, "activePreset", activePreset); _generalHelper.requestOverlayUpdate(); } - onActiveSplitChanged: { - _generalHelper.storeToolState(sceneId, "activeSplit", activeSplit); - cameraControls[activeSplit].forceActiveFocus(); - notifyActiveSplitChange(activeSplit); + onActiveViewportChanged: { + _generalHelper.storeToolState(sceneId, "activeViewport", activeViewport); + cameraControls[activeViewport].forceActiveFocus(); + notifyActiveViewportChange(activeViewport); } onActiveSceneChanged: updateActiveScene() @@ -141,7 +185,7 @@ Item { selectionBoxCount = 0; editViewsChanged(); - cameraControls[activeSplit].forceActiveFocus(); + cameraControls[activeViewport].forceActiveFocus(); return true; } return false; @@ -234,7 +278,7 @@ Item { } else if (selectedNodes.length > 0 && selectionBoxCount > 0) { boxModels.push(activeEditView.selectionBoxes[0].model); } - cameraControls[activeSplit].focusObject( + cameraControls[activeViewport].focusObject( boxModels, activeEditView.camera.eulerRotation, true, false); } } @@ -242,7 +286,7 @@ Item { function alignCamerasToView(cameraNodes) { if (activeEditView) { - cameraControls[activeSplit].alignCameras(cameraNodes); + cameraControls[activeViewport].alignCameras(cameraNodes); var propertyNames = ["position", "eulerRotation"]; viewRoot.changeObjectProperty(cameraNodes, propertyNames); viewRoot.commitObjectProperty(cameraNodes, propertyNames); @@ -252,7 +296,7 @@ Item { function alignViewToCamera(cameraNodes) { if (activeEditView) - cameraControls[activeSplit].alignView(cameraNodes); + cameraControls[activeViewport].alignView(cameraNodes); } function updateBackgroundColors(colors) @@ -388,15 +432,16 @@ Item { viewRoot.showCameraSpeed = false; } - if ("splitView" in toolStates) - splitView = toolStates.splitView; + if ("activePreset" in toolStates) + activePreset = toolStates.activePreset; else if (resetToDefault) - splitView = false; + activePreset = "Quad"; + applyViewportPreset(activePreset) - if ("activeSplit" in toolStates) - activeSplit = toolStates.activeSplit; + if ("activeViewport" in toolStates) + activeViewport = toolStates.activeViewport; else if (resetToDefault) - activeSplit = 0; + activeViewport = 0; if ("showWireframe" in toolStates) showWireframes = toolStates.showWireframe; @@ -424,8 +469,8 @@ Item { _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode); _generalHelper.storeToolState(sceneId, "transformMode", transformMode); - _generalHelper.storeToolState(sceneId, "splitView", splitView) - _generalHelper.storeToolState(sceneId, "activeSplit", activeSplit) + _generalHelper.storeToolState(sceneId, "activePreset", activePreset) + _generalHelper.storeToolState(sceneId, "activeViewport", activeViewport) _generalHelper.storeToolState(sceneId, "showWireframe", showWireframes) _generalHelper.storeToolState(sceneId, "matOverride", materialOverrides) @@ -527,6 +572,7 @@ Item { selectionChanged(newSelection); } + //TODO: only update the active viewport views function addLightGizmo(scene, obj) { for (var i = 0; i < 4; ++i) @@ -617,64 +663,95 @@ Item { overlayViews[i].updateReflectionProbeGizmoScene(scene, obj); } - function resolveSplitPoint(x, y) + function resolveViewportPoint(x, y) { - if (!splitView || activeSplit === 0) + let rect = viewRects[activeViewport]; + // Check invisible or out or range, then fallback to original origin + if (!rect || !rect.visible) return Qt.point(x, y); - if (activeSplit === 1) - return Qt.point(x - viewContainer.width / 2, y); - else if (activeSplit === 2) - return Qt.point(x, y - viewContainer.height / 2); - else - return Qt.point(x - viewContainer.width / 2, y - viewContainer.height / 2); + // Transform topleft of the active viewport to be the origin + return Qt.point(x - rect.x, y - rect.y); } - function updateActiveSplit(x, y) + function updateActiveViewport(x, y) { - if (splitView) { - if (x <= viewContainer.width / 2) { - if (y <= viewContainer.height / 2) - activeSplit = 0; - else - activeSplit = 2; - } else { - if (y <= viewContainer.height / 2) - activeSplit = 1; - else - activeSplit = 3; + for (let i = 0; i < 4; ++i) { + let rect = viewRects[i]; + if (!rect.visible) + continue; + + if (x >= rect.x && x <= rect.x + rect.width + && y >= rect.y && y <= rect.y + rect.height) { + activeViewport = i; + return; } } + + // TODO: if click outside all visible viewRects, do nothing + // or reset to e.g. activeVireport = -1 or 0 } function gizmoAt(x, y) { - updateActiveSplit(x, y); - let splitPoint = resolveSplitPoint(x, y); + updateActiveViewport(x, y); + let viewportPoint = resolveViewportPoint(x, y); - return activeOverlayView.gizmoAt(splitPoint.x, splitPoint.y); + return activeOverlayView.gizmoAt(viewportPoint.x, viewportPoint.y); } function rotateEditCamera(angles) { - cameraControls[activeSplit].rotateCamera(angles); + cameraControls[activeViewport].rotateCamera(angles); } function moveEditCamera(amounts) { - cameraControls[activeSplit].moveCamera(amounts); + cameraControls[activeViewport].moveCamera(amounts); + } + + // Update viewports based on selected preset + function applyViewportPreset(presetName) + { + let preset = viewportPresets[presetName]; + if (!preset) + return; + + let count = preset.numViewports; + + for (let i = 0; i < 4; ++i) { + if (i < count) { + viewRects[i].visible = true; + viewRects[i].x = preset.viewRects[i].x * viewContainer.width; + viewRects[i].y = preset.viewRects[i].y * viewContainer.height; + viewRects[i].width = preset.viewRects[i].width * viewContainer.width; + viewRects[i].height = preset.viewRects[i].height * viewContainer.height; + } else { + viewRects[i].visible = false; + } + } + + //TODO: Do we need this here? + cameraView.updateSnapping(); } Component.onCompleted: { createEditViews(); selectObjects([]); + applyViewportPreset(activePreset) // Work-around the fact that the projection matrix for the camera is not calculated until // the first frame is rendered, so any initial calls to mapFrom3DScene() will fail. _generalHelper.requestOverlayUpdate(); } - onWidthChanged: _generalHelper.requestOverlayUpdate() - onHeightChanged: _generalHelper.requestOverlayUpdate() + onWidthChanged: { + applyViewportPreset(activePreset) + _generalHelper.requestOverlayUpdate() + } + onHeightChanged: { + applyViewportPreset(activePreset) + _generalHelper.requestOverlayUpdate() + } Connections { target: _generalHelper @@ -715,9 +792,9 @@ Item { } // Shared nodes of the overlay, set as importScene on all overlay views. - // Content here can be used as is on all splits. - // Nodes that utilize autoscaling or otherwise need to have different appearance on each split - // need to have separate copy on each split. + // Content here can be used as is on all viewports. + // Nodes that utilize autoscaling or otherwise need to have different appearance on each viewport + // need to have separate copy on each viewport. Node { id: overlayScene @@ -743,12 +820,9 @@ Item { Rectangle { id: viewRect0 - width: viewRoot.splitView ? parent.width / 2 : parent.width - height: viewRoot.splitView ? parent.height / 2 : parent.height - x: 0 - y: 0 - visible: viewRoot.splitView || viewRoot.activeSplit == 0 gradient: bgGradient + border.width: 1 + border.color: viewportBorderColor OverlayView3D { id: overlayView0 editView: viewRoot.editViews[0] @@ -765,18 +839,15 @@ Item { EditCameraController { id: cameraControl0 viewRoot: viewRoot - splitId: 0 + viewportId: 0 } } Rectangle { id: viewRect1 - width: viewRoot.splitView ? parent.width / 2 : parent.width - height: viewRoot.splitView ? parent.height / 2 : parent.height - x: viewRoot.splitView ? parent.width / 2 : 0 - y: 0 - visible: viewRoot.splitView || viewRoot.activeSplit == 1 gradient: bgGradient + border.width: 1 + border.color: viewportBorderColor OverlayView3D { id: overlayView1 editView: viewRoot.editViews[1] @@ -793,18 +864,15 @@ Item { EditCameraController { id: cameraControl1 viewRoot: viewRoot - splitId: 1 + viewportId: 1 } } Rectangle { id: viewRect2 - width: viewRoot.splitView ? parent.width / 2 : parent.width - height: viewRoot.splitView ? parent.height / 2 : parent.height - x: 0 - y: viewRoot.splitView ? parent.height / 2 : 0 - visible: viewRoot.splitView || viewRoot.activeSplit == 2 gradient: bgGradient + border.width: 1 + border.color: viewportBorderColor OverlayView3D { id: overlayView2 editView: viewRoot.editViews[2] @@ -821,18 +889,15 @@ Item { EditCameraController { id: cameraControl2 viewRoot: viewRoot - splitId: 2 + viewportId: 2 } } Rectangle { id: viewRect3 - width: viewRoot.splitView ? parent.width / 2 : parent.width - height: viewRoot.splitView ? parent.height / 2 : parent.height - x: viewRoot.splitView ? parent.width / 2 : 0 - y: viewRoot.splitView ? parent.height / 2 : 0 - visible: viewRoot.splitView || viewRoot.activeSplit == 3 gradient: bgGradient + border.width: 1 + border.color: viewportBorderColor OverlayView3D { id: overlayView3 editView: viewRoot.editViews[3] @@ -849,44 +914,21 @@ Item { EditCameraController { id: cameraControl3 viewRoot: viewRoot - splitId: 3 + viewportId: 3 } } + // Active viewport highlight Rectangle { - // Vertical border between splits - visible: viewRoot.splitView - x: parent.width / 2 - y: 0 - width: 1 - height: parent.height - border.width: 1 - border.color: "#aaaaaa" - } - - Rectangle { - // Horizontal border between splits - visible: viewRoot.splitView - x: 0 - y: parent.height / 2 - height: 1 - width: parent.width - border.width: 1 - border.color: "#aaaaaa" - } - - Rectangle { - // Active split highlight - visible: viewRoot.splitView - x: viewRects[viewRoot.activeSplit].x - y: viewRects[viewRoot.activeSplit].y - height: viewRects[viewRoot.activeSplit].height - + (viewRoot.activeSplit === 0 || viewRoot.activeSplit === 1 ? 1 : 0) - width: viewRects[viewRoot.activeSplit].width - + (viewRoot.activeSplit === 0 || viewRoot.activeSplit === 2 ? 1 : 0) + visible: activePreset !== "Single" && viewRects[viewRoot.activeViewport].visible + x: viewRects[viewRoot.activeViewport].x + y: viewRects[viewRoot.activeViewport].y + width: viewRects[viewRoot.activeViewport].width + height: viewRects[viewRoot.activeViewport].height border.width: 2 border.color: "#57B9FC" color: "transparent" + z: 1000 // Edge case to make sure selection rect drawn over everything } MouseArea { @@ -903,20 +945,20 @@ Item { if (viewRoot.flyMode) return; - viewRoot.updateActiveSplit(mouse.x, mouse.y); + viewRoot.updateActiveViewport(mouse.x, mouse.y); - let splitPoint = viewRoot.resolveSplitPoint(mouse.x, mouse.y); + let viewportPoint = viewRoot.resolveViewportPoint(mouse.x, mouse.y); if (viewRoot.activeEditView) { // First pick overlay to check for hits there var pickResult = _generalHelper.pickViewAt(activeOverlayView, - splitPoint.x, splitPoint.y); + viewportPoint.x, viewportPoint.y); var resolvedResult = _generalHelper.resolvePick(pickResult.objectHit); if (!resolvedResult) { // No hits from overlay view, pick the main scene pickResult = _generalHelper.pickViewAt(viewRoot.activeEditView, - splitPoint.x, splitPoint.y); + viewportPoint.x, viewportPoint.y); resolvedResult = _generalHelper.resolvePick(pickResult.objectHit); } @@ -940,17 +982,17 @@ Item { } onPositionChanged: (mouse) => { if (freeDraggerArea) { - let splitPoint = viewRoot.resolveSplitPoint(mouse.x, mouse.y); - let splitPress = viewRoot.resolveSplitPoint(pressPoint.x, pressPoint.y); - if (initialMoveBlock && Math.abs(splitPress.x - splitPoint.x) - + Math.abs(splitPress.y - splitPoint.y) > 10) { + let viewportPoint = viewRoot.resolveViewportPoint(mouse.x, mouse.y); + let viewportPress = viewRoot.resolveViewportPoint(pressPoint.x, pressPoint.y); + if (initialMoveBlock && Math.abs(viewportPress.x - viewportPoint.x) + + Math.abs(viewportPress.y - viewportPoint.y) > 10) { // Don't force press event at actual press, as that puts the gizmo // in free-dragging state, which is bad UX if drag is not actually done - freeDraggerArea.forcePressEvent(splitPress.x, splitPress.y); - freeDraggerArea.forceMoveEvent(splitPoint.x, splitPoint.y); + freeDraggerArea.forcePressEvent(viewportPress.x, viewportPress.y); + freeDraggerArea.forceMoveEvent(viewportPoint.x, viewportPoint.y); initialMoveBlock = false; } else { - freeDraggerArea.forceMoveEvent(splitPoint.x, splitPoint.y); + freeDraggerArea.forceMoveEvent(viewportPoint.x, viewportPoint.y); } } } @@ -959,11 +1001,11 @@ Item { { if (freeDraggerArea) { if (initialMoveBlock) { - let splitPress = viewRoot.resolveSplitPoint(pressPoint.x, pressPoint.y); - freeDraggerArea.forceReleaseEvent(splitPress.x, splitPress.y); + let viewportPress = viewRoot.resolveViewportPoint(pressPoint.x, pressPoint.y); + freeDraggerArea.forceReleaseEvent(viewportPress.x, viewportPress.y); } else { - let splitPoint = viewRoot.resolveSplitPoint(mouse.x, mouse.y); - freeDraggerArea.forceReleaseEvent(splitPoint.x, splitPoint.y); + let viewportPoint = viewRoot.resolveViewportPoint(mouse.x, mouse.y); + freeDraggerArea.forceReleaseEvent(viewportPoint.x, viewportPoint.y); } freeDraggerArea = null; } @@ -1107,19 +1149,17 @@ Item { viewPortSize: Qt.size(viewRoot.viewPortRect.width, viewRoot.viewPortRect.height) function updateSnapping() { - if (!viewRoot.splitView) - cameraView.snapLeft = true - else if (viewRoot.activeSplit === 2) - cameraView.snapLeft = false - else if (viewRoot.activeSplit === 3) - cameraView.snapLeft = true + const rect = viewRoot.viewRects[viewRoot.activeViewport]; + if (!rect || !rect.visible) + return; + + const centerX = rect.x + rect.width / 2; + cameraView.snapLeft = centerX < viewContainer.width / 2; } Connections { target: viewRoot - - onSplitViewChanged: cameraView.updateSnapping() - onActiveSplitChanged: cameraView.updateSnapping() + onActiveViewportChanged: cameraView.updateSnapping() } } } diff --git a/src/tools/qmlpuppet/mockfiles/qt6/OverlayView3D.qml b/src/tools/qmlpuppet/mockfiles/qt6/OverlayView3D.qml index 7d7f419e429..59dd33d6f3a 100644 --- a/src/tools/qmlpuppet/mockfiles/qt6/OverlayView3D.qml +++ b/src/tools/qmlpuppet/mockfiles/qt6/OverlayView3D.qml @@ -16,7 +16,7 @@ View3D { property var viewRoot: null property View3D editView: null - property bool isActive: viewRoot.overlayViews[viewRoot.activeSplit] === overlayView + property bool isActive: viewRoot.overlayViews[viewRoot.activeViewport] === overlayView property var lightIconGizmos: [] property var cameraGizmos: [] @@ -629,7 +629,7 @@ View3D { scale: lookAtAutoScale.getScale(Qt.vector3d(10, 10, 10)) visible: overlayView.viewRoot.showLookAt && overlayView.isActive - && !overlayView.viewRoot.cameraControls[viewRoot.activeSplit].showCrosshairs + && !overlayView.viewRoot.cameraControls[viewRoot.activeViewport].showCrosshairs } } } diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp index 2eb4d7f1cc7..99928dfe681 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.cpp @@ -956,9 +956,9 @@ void Qt5InformationNodeInstanceServer::handleActiveSceneChange() #endif } -void Qt5InformationNodeInstanceServer::handleActiveSplitChange(int index) +void Qt5InformationNodeInstanceServer::handleActiveViewportChange(int index) { - nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveSplitChanged, + nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveViewportChanged, index}); } @@ -1966,8 +1966,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView( this, SLOT(handleObjectPropertyChange(QVariant, QVariant))); QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveSceneChange()), this, SLOT(handleActiveSceneChange())); - QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveSplitChange(int)), - this, SLOT(handleActiveSplitChange(int))); + QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveViewportChange(int)), + this, SLOT(handleActiveViewportChange(int))); QObject::connect(&m_propertyChangeTimer, &QTimer::timeout, this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout); QObject::connect(&m_selectionChangeTimer, &QTimer::timeout, @@ -2599,6 +2599,9 @@ void Qt5InformationNodeInstanceServer::view3DAction([[maybe_unused]] const View3 case View3DActionType::SyncEnvBackground: updatedToolState.insert("syncEnvBackground", command.isEnabled()); break; + case View3DActionType::ViewportPreset: + updatedToolState.insert("activePreset", command.value()); + break; #ifdef QUICK3D_PARTICLES_MODULE case View3DActionType::ShowParticleEmitter: updatedToolState.insert("showParticleEmitter", command.isEnabled()); @@ -2637,8 +2640,8 @@ void Qt5InformationNodeInstanceServer::view3DAction([[maybe_unused]] const View3 getNodeAtMainScenePos(data[0].toPointF(), qint32(data[1].toInt())); return; } - case View3DActionType::SplitViewToggle: - updatedToolState.insert("splitView", command.isEnabled()); + case View3DActionType::ViewportViewToggle: + updatedToolState.insert("viewportView", command.isEnabled()); break; case View3DActionType::FlyModeToggle: updatedToolState.insert("flyMode", command.isEnabled()); diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h index 4bd3c157533..3f93ca5aebc 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h +++ b/src/tools/qmlpuppet/qmlpuppet/instances/qt5informationnodeinstanceserver.h @@ -66,7 +66,7 @@ private slots: void handleObjectPropertyCommit(const QVariant &objects, const QVariant &propNames); void handleObjectPropertyChange(const QVariant &objects, const QVariant &propNames); void handleActiveSceneChange(); - void handleActiveSplitChange(int index); + void handleActiveViewportChange(int index); void handleToolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState); void handleView3DSizeChange(); From f3eaf3877bf98470232e4c22e39a1eadc0d792db Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 21 Apr 2025 18:30:50 +0000 Subject: [PATCH 77/82] Revert "QmlDesigner: Add more ids to discouraged ids" This reverts commit 8dbc5475c6cb280ca593b108402d8ec1a17efaf6. Reason for revert: Blocking those ids breaks to many existing examples/projects. Change-Id: Ibbfedad63ab1535fcfa4f635c47e8da2ea30c2f0 Reviewed-by: Marco Bubke --- .../libs/designercore/designercoreutils/modelutils.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp index 7e3d703db9e..c22b9175c55 100644 --- a/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp @@ -116,8 +116,6 @@ constexpr auto qmlDiscouragedIds = toSortedArray(u"action", u"baseState", u"border", u"bottom", - u"button", - u"checkbox", u"clip", u"data", u"enabled", @@ -130,11 +128,9 @@ constexpr auto qmlDiscouragedIds = toSortedArray(u"action", u"layer", u"left", u"margin", - u"mouseArea", u"opacity", u"padding", u"parent", - u"rectangle", u"right", u"scale", u"shaderInfo", @@ -143,10 +139,7 @@ constexpr auto qmlDiscouragedIds = toSortedArray(u"action", u"spriteSequence", u"state", u"stateGroup", - u"switch", u"text", - u"textedit", - u"textinput", u"texture", u"time", u"top", From f2342f2563cf11bfddbcfbc7fdaac20363c33fc9 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 17 Apr 2025 11:39:37 +0200 Subject: [PATCH 78/82] UnitTests: Add PropertyMatcher Extend the matcher for Properties with arguments. It is only used if arguments are provided. The matcher argument must be always a matcher. struct Foo { int foo(int) const { return 1; } }; TEST(X, X) { Property("Foo::foo", &Foo::foo, Eq(10), 8); } Change-Id: If20d958dd65652f8268fc5e744220ed2ff26a0f5 Reviewed-by: Thomas Hartmann --- tests/unit/tests/matchers/property-matcher.h | 86 +++++++++++++++++++ .../tests/utils/google-using-declarations.h | 1 + 2 files changed, 87 insertions(+) create mode 100644 tests/unit/tests/matchers/property-matcher.h diff --git a/tests/unit/tests/matchers/property-matcher.h b/tests/unit/tests/matchers/property-matcher.h new file mode 100644 index 00000000000..561a94cb69e --- /dev/null +++ b/tests/unit/tests/matchers/property-matcher.h @@ -0,0 +1,86 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include + +#include +#include + +namespace internal { + +template +class PropertyMatcher +{ +public: + PropertyMatcher(Property property, const Matcher &matcher, Arguments... arguments) + : m_property(property) + , matcher_(matcher) + , m_whose_property() + , m_arguments{arguments...} + {} + + PropertyMatcher(const std::string &whose_property, + Property property, + const Matcher &matcher, + Arguments... arguments) + : m_property(property) + , matcher_(matcher) + , m_whose_property(whose_property) + , m_arguments{arguments...} + {} + + void DescribeTo(::std::ostream *os) const + { + *os << "is an object " << m_whose_property; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream *os) const + { + *os << "is an object " << m_whose_property; + matcher_.DescribeNegationTo(os); + } + + template + bool MatchAndExplain(const T &value, testing::MatchResultListener *listener) const + { + *listener << "which points to an object "; + + auto result = std::apply( + [&](auto &&...arguments) { return std::invoke(m_property, value, arguments...); }, + m_arguments); + return MatchPrintAndExplain(result, matcher_, listener); + } + +private: + Property m_property; + const Matcher matcher_; + const std::string m_whose_property; + const std::tuple m_arguments; +}; + +template +concept matcher = std::derived_from + || requires { typename PropertyMatcher::is_gtest_matcher; }; + +} // namespace internal + +template +inline auto Property(const std::string &propertyName, + PropertyType property, + const PropertyMatcher &matchingType, + Arguments... arguments) +// requires(sizeof...(Arguments) >= 1) +{ + using namespace std::string_literals; + + return testing::MakePolymorphicMatcher( + internal::PropertyMatcher( + "whose property `"s + propertyName + "` "s, + property, + matchingType, + std::forward(arguments)...)); +} diff --git a/tests/unit/tests/utils/google-using-declarations.h b/tests/unit/tests/utils/google-using-declarations.h index 8dd8e790b5c..ea781e59dbc 100644 --- a/tests/unit/tests/utils/google-using-declarations.h +++ b/tests/unit/tests/utils/google-using-declarations.h @@ -4,6 +4,7 @@ #pragma once #include +#include using testing::_; using testing::A; From e21a628c7df4ad39342b5185446f59d1791d4254 Mon Sep 17 00:00:00 2001 From: Burak Hancerli Date: Mon, 7 Apr 2025 12:45:44 +0200 Subject: [PATCH 79/82] QmlDesigner: Add trace points to modelnode Task-number: QDS-15148 Change-Id: Ied23cefa319dfff8936cf91815454cb2558f3405 Reviewed-by: Marco Bubke --- .../propertyeditor/propertyeditorview.cpp | 21 +- .../propertyeditor/qmlmodelnodeproxy.cpp | 2 +- .../scripteditor/propertytreemodel.cpp | 4 +- .../scripteditor/scripteditorbackend.cpp | 6 +- .../stateseditor/stateseditormodel.cpp | 4 +- .../transitioneditor/transitionform.cpp | 8 +- .../designercoreutils/functional.h | 5 + .../libs/designercore/include/modelnode.h | 252 ++-- .../libs/designercore/model/modelnode.cpp | 1036 ++++++++++++++--- tests/unit/tests/matchers/property-matcher.h | 16 +- .../designsystem/dsthemeqml-test.cpp | 6 +- .../listmodeleditor/listmodeleditor-test.cpp | 11 +- 12 files changed, 1047 insertions(+), 324 deletions(-) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index 6aef3705439..238ba83b4e2 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -8,12 +8,13 @@ #include "propertyeditorvalue.h" #include "propertyeditorwidget.h" +#include "qmldesignerplugin.h" #include #include #include +#include #include #include -#include "qmldesignerplugin.h" #include #include @@ -863,11 +864,16 @@ void PropertyEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) const ModelNodes &allRemovedNodes = removedNode.allSubModelNodesAndThisNode(); - if (Utils::contains(allRemovedNodes, model()->qtQuick3DTextureMetaInfo(), &ModelNode::metaInfo)) + using SL = ModelTracing::SourceLocation; + if (Utils::contains(allRemovedNodes, + model()->qtQuick3DTextureMetaInfo(), + bind_back(&ModelNode::metaInfo, SL{}))) m_textureAboutToBeRemoved = true; if (m_qmlBackEndForCurrentType) { - if (Utils::contains(allRemovedNodes, QLatin1String{Constants::MATERIAL_LIB_ID}, &ModelNode::id)) + if (Utils::contains(allRemovedNodes, + QLatin1String{Constants::MATERIAL_LIB_ID}, + bind_back(&ModelNode::id, SL{}))) m_qmlBackEndForCurrentType->contextObject()->setHasMaterialLibrary(false); } } @@ -1262,12 +1268,17 @@ void PropertyEditorView::nodeReparented(const ModelNode &node, if (node == activeNode()) m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(activeNode())); + using SL = const ModelTracing::SourceLocation; const ModelNodes &allNodes = node.allSubModelNodesAndThisNode(); - if (Utils::contains(allNodes, model()->qtQuick3DTextureMetaInfo(), &ModelNode::metaInfo)) + if (Utils::contains(allNodes, + model()->qtQuick3DTextureMetaInfo(), + bind_back(&ModelNode::metaInfo, SL{}))) m_qmlBackEndForCurrentType->refreshBackendModel(); if (m_qmlBackEndForCurrentType) { - if (Utils::contains(allNodes, QLatin1String{Constants::MATERIAL_LIB_ID}, &ModelNode::id)) + if (Utils::contains(allNodes, + QLatin1String{Constants::MATERIAL_LIB_ID}, + bind_back(&ModelNode::id, SL{}))) m_qmlBackEndForCurrentType->contextObject()->setHasMaterialLibrary(true); } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp index 07c7537c852..1f51e37ec7e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp @@ -120,7 +120,7 @@ QString QmlModelNodeProxy::simplifiedTypeName() const static QList toInternalIdList(const QList &nodes) { - return Utils::transform(nodes, &ModelNode::internalId); + return Utils::transform(nodes, [](const ModelNode &node) { return node.internalId(); }); } QList QmlModelNodeProxy::allChildren(int internalId) const diff --git a/src/plugins/qmldesigner/components/scripteditor/propertytreemodel.cpp b/src/plugins/qmldesigner/components/scripteditor/propertytreemodel.cpp index b1892c9b557..86c6cf33b5b 100644 --- a/src/plugins/qmldesigner/components/scripteditor/propertytreemodel.cpp +++ b/src/plugins/qmldesigner/components/scripteditor/propertytreemodel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -904,7 +905,8 @@ void PropertyTreeModelDelegate::setPropertyType(PropertyTreeModel::PropertyTypes void PropertyTreeModelDelegate::setup(const QString &id, const QString &name, bool *nameExists) { m_model.resetModel(); - QStringList idLists = Utils::transform(m_model.nodeList(), &ModelNode::id); + using SL = ModelTracing::SourceLocation; + QStringList idLists = Utils::transform(m_model.nodeList(), bind_back(&ModelNode::id, SL{})); if (!idLists.contains(id)) idLists.prepend(id); diff --git a/src/plugins/qmldesigner/components/scripteditor/scripteditorbackend.cpp b/src/plugins/qmldesigner/components/scripteditor/scripteditorbackend.cpp index 3bf324336b6..ae232fc8262 100644 --- a/src/plugins/qmldesigner/components/scripteditor/scripteditorbackend.cpp +++ b/src/plugins/qmldesigner/components/scripteditor/scripteditorbackend.cpp @@ -6,6 +6,7 @@ #include "scripteditorutils.h" #include +#include #include #include #include @@ -842,13 +843,14 @@ void StatementDelegate::setupChangeState() && !item.allStateNames().isEmpty(); }); - QStringList itemIds = Utils::transform(items, &ModelNode::id); + using SL = ModelTracing::SourceLocation; + QStringList itemIds = Utils::transform(items, bind_back(&ModelNode::id, SL{})); const auto groups = m_view->allModelNodesOfType(model->qtQuickStateGroupMetaInfo()); const auto rootId = m_view->rootModelNode().id(); itemIds.removeAll(rootId); - QStringList groupIds = Utils::transform(groups, &ModelNode::id); + QStringList groupIds = Utils::transform(groups, bind_back(&ModelNode::id, SL{})); Utils::sort(itemIds); Utils::sort(groupIds); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index df969197d9a..680082b5419 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -276,8 +277,9 @@ QStringList StatesEditorModel::stateGroups() const const auto groupMetaInfo = m_statesEditorView->model()->qtQuickStateGroupMetaInfo(); + using SL = ModelTracing::SourceLocation; auto stateGroups = Utils::transform(m_statesEditorView->allModelNodesOfType(groupMetaInfo), - &ModelNode::displayName); + bind_back(&ModelNode::displayName, SL{})); stateGroups.prepend(tr("Default")); return stateGroups; } diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp index 683cdd8cfe1..120cfee28e1 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp @@ -7,13 +7,14 @@ #include #include +#include #include +#include #include #include +#include #include #include -#include -#include #include @@ -220,8 +221,9 @@ void TransitionForm::setupStateGroups() const auto groupMetaInfo = view->model()->qtQuickStateGroupMetaInfo(); + using SL = ModelTracing::SourceLocation; auto stateGroups = Utils::transform(view->allModelNodesOfType(groupMetaInfo), - &ModelNode::displayName); + bind_back(&ModelNode::displayName, SL{})); stateGroups.prepend(tr("Default")); bool block = ui->stateGroupComboBox->blockSignals(true); diff --git a/src/plugins/qmldesigner/libs/designercore/designercoreutils/functional.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/functional.h index 66a0485c2f4..2c7d52738b1 100644 --- a/src/plugins/qmldesigner/libs/designercore/designercoreutils/functional.h +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/functional.h @@ -29,4 +29,9 @@ inline constexpr auto makeEqual = [](auto... projections) { }; }; +template +inline constexpr auto bind_back(Function &&function, Argument &&argument) +{ + return std::bind(function, std::placeholders::_1, std::forward(argument)); +} } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h index 3053fe10258..5e0661b79bf 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h @@ -3,17 +3,10 @@ #pragma once -#include "auxiliarydata.h" #include "abstractproperty.h" -#include "qmldesignercorelib_global.h" +#include "auxiliarydata.h" -#include -#include -#include -#include - -#include -#include +#include QT_BEGIN_NAMESPACE class QTextStream; @@ -75,6 +68,8 @@ class QMLDESIGNERCORE_EXPORT ModelNode friend NodeAbstractProperty; friend NodeProperty; + using SL = ModelTracing::SourceLocation; + public: enum NodeSourceType { NodeWithoutSource = 0, @@ -91,161 +86,172 @@ public: ModelNode &operator=(ModelNode &&) noexcept = default; ~ModelNode() = default; - TypeName type() const; - QString simplifiedTypeName() const; - QString displayName() const; - int minorVersion() const; - int majorVersion() const; + TypeName type(SL sl = {}) const; + QString simplifiedTypeName(SL sl = {}) const; + QString displayName(SL sl = {}) const; + int minorVersion(SL sl = {}) const; + int majorVersion(SL sl = {}) const; bool isValid() const; + explicit operator bool() const { return isValid(); } - bool isInHierarchy() const; + bool isInHierarchy(SL sl = {}) const; - NodeAbstractProperty parentProperty() const; - void setParentProperty(NodeAbstractProperty parent); - void changeType(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); - void setParentProperty(const ModelNode &newParentNode, const PropertyName &propertyName); - bool hasParentProperty() const; + NodeAbstractProperty parentProperty(SL sl = {}) const; + void setParentProperty(NodeAbstractProperty parent, SL sl = {}); + void changeType(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1, SL sl = {}); + void setParentProperty(const ModelNode &newParentNode, + const PropertyName &propertyName, + SL sl = {}); + bool hasParentProperty(SL sl = {}) const; - QList directSubModelNodes() const; - QList directSubModelNodesOfType(const NodeMetaInfo &type) const; - QList subModelNodesOfType(const NodeMetaInfo &type) const; + QList directSubModelNodes(SL sl = {}) const; + QList directSubModelNodesOfType(const NodeMetaInfo &type, SL sl = {}) const; + QList subModelNodesOfType(const NodeMetaInfo &type, SL sl = {}) const; - QList allSubModelNodes() const; - QList allSubModelNodesAndThisNode() const; - bool hasAnySubModelNodes() const; + QList allSubModelNodes(SL sl = {}) const; + QList allSubModelNodesAndThisNode(SL sl = {}) const; + bool hasAnySubModelNodes(SL sl = {}) const; //### - AbstractProperty property(PropertyNameView name) const; - VariantProperty variantProperty(PropertyNameView name) const; - BindingProperty bindingProperty(PropertyNameView name) const; - SignalHandlerProperty signalHandlerProperty(PropertyNameView name) const; - SignalDeclarationProperty signalDeclarationProperty(PropertyNameView name) const; - NodeListProperty nodeListProperty(PropertyNameView name) const; - NodeProperty nodeProperty(PropertyNameView name) const; - NodeAbstractProperty nodeAbstractProperty(PropertyNameView name) const; - NodeAbstractProperty defaultNodeAbstractProperty() const; - NodeListProperty defaultNodeListProperty() const; - NodeProperty defaultNodeProperty() const; + AbstractProperty property(PropertyNameView name, SL sl = {}) const; + VariantProperty variantProperty(PropertyNameView name, SL sl = {}) const; + BindingProperty bindingProperty(PropertyNameView name, SL sl = {}) const; + SignalHandlerProperty signalHandlerProperty(PropertyNameView name, SL sl = {}) const; + SignalDeclarationProperty signalDeclarationProperty(PropertyNameView name, SL sl = {}) const; + NodeListProperty nodeListProperty(PropertyNameView name, SL sl = {}) const; + NodeProperty nodeProperty(PropertyNameView name, SL sl = {}) const; + NodeAbstractProperty nodeAbstractProperty(PropertyNameView name, SL sl = {}) const; + NodeAbstractProperty defaultNodeAbstractProperty(SL sl = {}) const; + NodeListProperty defaultNodeListProperty(SL sl = {}) const; + NodeProperty defaultNodeProperty(SL sl = {}) const; - void removeProperty(PropertyNameView name) const; //### also implement in AbstractProperty - QList properties() const; - QList variantProperties() const; - QList nodeAbstractProperties() const; - QList nodeProperties() const; - QList nodeListProperties() const; - QList bindingProperties() const; - QList signalProperties() const; - QList dynamicProperties() const; - PropertyNameList propertyNames() const; + void removeProperty(PropertyNameView name, SL sl = {}) const; //### also implement in AbstractProperty + QList properties(SL sl = {}) const; + QList variantProperties(SL sl = {}) const; + QList nodeAbstractProperties(SL sl = {}) const; + QList nodeProperties(SL sl = {}) const; + QList nodeListProperties(SL sl = {}) const; + QList bindingProperties(SL sl = {}) const; + QList signalProperties(SL sl = {}) const; + QList dynamicProperties(SL sl = {}) const; + PropertyNameList propertyNames(SL sl = {}) const; - bool hasProperty(PropertyNameView name) const; - bool hasVariantProperty(PropertyNameView name) const; - bool hasBindingProperty(PropertyNameView name) const; - bool hasSignalHandlerProperty(PropertyNameView name) const; - bool hasNodeAbstractProperty(PropertyNameView name) const; - bool hasDefaultNodeAbstractProperty() const; - bool hasDefaultNodeListProperty() const; - bool hasDefaultNodeProperty() const; - bool hasNodeProperty(PropertyNameView name) const; - bool hasNodeListProperty(PropertyNameView name) const; - bool hasProperty(PropertyNameView name, PropertyType propertyType) const; + bool hasProperty(PropertyNameView name, SL sl = {}) const; + bool hasVariantProperty(PropertyNameView name, SL sl = {}) const; + bool hasBindingProperty(PropertyNameView name, SL sl = {}) const; + bool hasSignalHandlerProperty(PropertyNameView name, SL sl = {}) const; + bool hasNodeAbstractProperty(PropertyNameView name, SL sl = {}) const; + bool hasDefaultNodeAbstractProperty(SL sl = {}) const; + bool hasDefaultNodeListProperty(SL sl = {}) const; + bool hasDefaultNodeProperty(SL sl = {}) const; + bool hasNodeProperty(PropertyNameView name, SL sl = {}) const; + bool hasNodeListProperty(PropertyNameView name, SL sl = {}) const; + bool hasProperty(PropertyNameView name, PropertyType propertyType, SL sl = {}) const; - void setScriptFunctions(const QStringList &scriptFunctionList); - QStringList scriptFunctions() const; + void setScriptFunctions(const QStringList &scriptFunctionList, SL sl = {}); + QStringList scriptFunctions(SL sl = {}) const; //### - void destroy(); + void destroy(SL sl = {}); - QString id() const; - void ensureIdExists() const; - [[nodiscard]] QString validId() const; - void setIdWithRefactoring(const QString &id) const; - void setIdWithoutRefactoring(const QString &id) const; + QString id(SL sl = {}) const; + void ensureIdExists(SL sl = {}) const; + [[nodiscard]] QString validId(SL sl = {}) const; + void setIdWithRefactoring(const QString &id, SL sl = {}) const; + void setIdWithoutRefactoring(const QString &id, SL sl = {}) const; static bool isValidId(const QString &id); static QString getIdValidityErrorMessage(const QString &id); - bool hasId() const; + bool hasId(SL sl = {}) const; Model *model() const; AbstractView *view() const; - NodeMetaInfo metaInfo() const; - bool hasMetaInfo() const; + NodeMetaInfo metaInfo(SL sl = {}) const; + bool hasMetaInfo(SL sl = {}) const; - bool isSelected() const; - bool isRootNode() const; + bool isSelected(SL sl = {}) const; + bool isRootNode(SL sl = {}) const; - bool isAncestorOf(const ModelNode &node) const; - void selectNode(); - void deselectNode(); + bool isAncestorOf(const ModelNode &node, SL sl = {}) const; + void selectNode(SL sl = {}); + void deselectNode(SL sl = {}); static int variantTypeId(); - QVariant toVariant() const; + QVariant toVariant(SL sl = {}) const; - std::optional auxiliaryData(AuxiliaryDataKeyView key) const; - std::optional auxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const; - QVariant auxiliaryDataWithDefault(AuxiliaryDataType type, Utils::SmallStringView name) const; - QVariant auxiliaryDataWithDefault(AuxiliaryDataKeyView key) const; - QVariant auxiliaryDataWithDefault(AuxiliaryDataKeyDefaultValue key) const; - void setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data) const; - void setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data) const; - void setAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, const QVariant &data) const; + std::optional auxiliaryData(AuxiliaryDataKeyView key, SL sl = {}) const; + std::optional auxiliaryData(AuxiliaryDataType type, + Utils::SmallStringView name, + SL sl = {}) const; + QVariant auxiliaryDataWithDefault(AuxiliaryDataType type, + Utils::SmallStringView name, + SL sl = {}) const; + QVariant auxiliaryDataWithDefault(AuxiliaryDataKeyView key, SL sl = {}) const; + QVariant auxiliaryDataWithDefault(AuxiliaryDataKeyDefaultValue key, SL sl = {}) const; + void setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data, SL sl = {}) const; + void setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data, SL sl = {}) const; + void setAuxiliaryData(AuxiliaryDataType type, + Utils::SmallStringView name, + const QVariant &data, + SL sl = {}) const; void setAuxiliaryDataWithoutLock(AuxiliaryDataType type, Utils::SmallStringView name, - const QVariant &data) const; - void removeAuxiliaryData(AuxiliaryDataKeyView key) const; - void removeAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const; - bool hasAuxiliaryData(AuxiliaryDataKeyView key) const; - bool hasAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const; + const QVariant &data, + SL sl = {}) const; + void removeAuxiliaryData(AuxiliaryDataKeyView key, SL sl = {}) const; + void removeAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, SL sl = {}) const; + bool hasAuxiliaryData(AuxiliaryDataKeyView key, SL sl = {}) const; + bool hasAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, SL sl = {}) const; bool hasAuxiliaryData(AuxiliaryDataType type) const; - AuxiliaryDatasForType auxiliaryData(AuxiliaryDataType type) const; - AuxiliaryDatasView auxiliaryData() const; + AuxiliaryDatasForType auxiliaryData(AuxiliaryDataType type, SL sl = {}) const; + AuxiliaryDatasView auxiliaryData(SL sl = {}) const; - QString customId() const; - bool hasCustomId() const; - void setCustomId(const QString &str); - void removeCustomId(); + QString customId(SL sl = {}) const; + bool hasCustomId(SL sl = {}) const; + void setCustomId(const QString &str, SL sl = {}); + void removeCustomId(SL sl = {}); - QVector comments() const; - bool hasComments() const; - void setComments(const QVector &coms); - void addComment(const Comment &com); - bool updateComment(const Comment &com, int position); + QVector comments(SL sl = {}) const; + bool hasComments(SL sl = {}) const; + void setComments(const QVector &coms, SL sl = {}); + void addComment(const Comment &com, SL sl = {}); + bool updateComment(const Comment &com, int position, SL sl = {}); - Annotation annotation() const; - bool hasAnnotation() const; - void setAnnotation(const Annotation &annotation); - void removeAnnotation(); + Annotation annotation(SL sl = {}) const; + bool hasAnnotation(SL sl = {}) const; + void setAnnotation(const Annotation &annotation, SL sl = {}); + void removeAnnotation(SL sl = {}); - Annotation globalAnnotation() const; - bool hasGlobalAnnotation() const; - void setGlobalAnnotation(const Annotation &annotation); - void removeGlobalAnnotation(); + Annotation globalAnnotation(SL sl = {}) const; + bool hasGlobalAnnotation(SL sl = {}) const; + void setGlobalAnnotation(const Annotation &annotation, SL sl = {}); + void removeGlobalAnnotation(SL sl = {}); - GlobalAnnotationStatus globalStatus() const; - bool hasGlobalStatus() const; - void setGlobalStatus(const GlobalAnnotationStatus &status); - void removeGlobalStatus(); + GlobalAnnotationStatus globalStatus(SL sl = {}) const; + bool hasGlobalStatus(SL sl = {}) const; + void setGlobalStatus(const GlobalAnnotationStatus &status, SL sl = {}); + void removeGlobalStatus(SL sl = {}); - bool locked() const; - void setLocked(bool value); + bool locked(SL sl = {}) const; + void setLocked(bool value, SL sl = {}); - qint32 internalId() const; + qint32 internalId(SL sl = {}) const; - void setNodeSource(const QString&); - void setNodeSource(const QString &newNodeSource, NodeSourceType type); - QString nodeSource() const; + void setNodeSource(const QString &str, SL sl = {}); + void setNodeSource(const QString &newNodeSource, NodeSourceType type, SL sl = {}); + QString nodeSource(SL sl = {}) const; - QString convertTypeToImportAlias() const; + QString convertTypeToImportAlias(SL sl = {}) const; - NodeSourceType nodeSourceType() const; + NodeSourceType nodeSourceType(SL sl = {}) const; - bool isComponent() const; - QIcon typeIcon() const; - QString behaviorPropertyName() const; + bool isComponent(SL sl = {}) const; + QIcon typeIcon(SL sl = {}) const; + QString behaviorPropertyName(SL sl = {}) const; friend void swap(ModelNode &first, ModelNode &second) noexcept { @@ -273,7 +279,7 @@ private: // functions template QList properties(PropertyType... type) const; - bool hasLocked() const; + bool hasLocked(SL sl = {}) const; private: // variables Internal::InternalNodePointer m_internalNode; diff --git a/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp index ae8c2c6f33c..b7a968fae92 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp @@ -4,35 +4,25 @@ #include "modelnode.h" #include "annotation.h" -#include "bindingproperty.h" #include "designercoretr.h" #include "internalnode_p.h" #include "model_p.h" -#include "nodeabstractproperty.h" #include "nodelistproperty.h" #include "nodeproperty.h" #include "signalhandlerproperty.h" #include "variantproperty.h" #include -#include #include -#include #include #include -#include - -#include -#include -#include -#include - -#include namespace QmlDesigner { using namespace QmlDesigner::Internal; +auto category = ModelTracing::category; + /*! \class QmlDesigner::ModelNode \ingroup CoreModel @@ -73,23 +63,39 @@ ModelNode::ModelNode(const ModelNode &modelNode, AbstractView *view) /*! \brief returns the name of node which is a short cut to a property like objectName \return name of the node */ -QString ModelNode::id() const +QString ModelNode::id(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->id; } -void ModelNode::ensureIdExists() const +void ModelNode::ensureIdExists(SL sl) const { if (!hasId()) setIdWithoutRefactoring(model()->generateNewId(simplifiedTypeName())); + + NanotraceHR::Tracer tracer{"model node ensure id exists", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; } -QString ModelNode::validId() const +QString ModelNode::validId(SL sl) const { - ensureIdExists(); + NanotraceHR::Tracer tracer{"model node valid id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + ensureIdExists(sl); return id(); } @@ -126,32 +132,51 @@ QString ModelNode::getIdValidityErrorMessage(const QString &id) return DesignerCore::Tr::tr("ID includes invalid characters (%1).").arg(id); } -bool ModelNode::hasId() const +bool ModelNode::hasId(SL sl) const { if (!isValid()) return false; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return !m_internalNode->id.isEmpty(); } -void ModelNode::setIdWithRefactoring(const QString &id) const +void ModelNode::setIdWithRefactoring(const QString &id, SL sl) const { - if (isValid()) { - if (model()->rewriterView() && !id.isEmpty() - && !m_internalNode->id.isEmpty()) { // refactor the id if they are not empty - model()->rewriterView()->renameId(m_internalNode->id, id); - } else { - setIdWithoutRefactoring(id); - } + if (!isValid()) + return; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set id with refactoring", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + if (model()->rewriterView() && !id.isEmpty() + && !m_internalNode->id.isEmpty()) { // refactor the id if they are not empty + model()->rewriterView()->renameId(m_internalNode->id, id); + } else { + setIdWithoutRefactoring(id); } } -void ModelNode::setIdWithoutRefactoring(const QString &id) const +void ModelNode::setIdWithoutRefactoring(const QString &id, SL sl) const { Internal::WriteLocker locker(m_model.data()); if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set id without refactoring", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (!isValidId(id)) return; @@ -167,50 +192,77 @@ void ModelNode::setIdWithoutRefactoring(const QString &id) const /*! \brief the fully-qualified type name of the node is represented as string \return type of the node as a string */ -TypeName ModelNode::type() const +TypeName ModelNode::type(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->typeName; } /*! \brief minor number of the QML type \return minor number */ -int ModelNode::minorVersion() const +int ModelNode::minorVersion(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node minor version", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->minorVersion; } /*! \brief major number of the QML type \return major number */ -int ModelNode::majorVersion() const +int ModelNode::majorVersion(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node major version", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->majorVersion; } /*! \return the short-hand type name of the node. */ -QString ModelNode::simplifiedTypeName() const +QString ModelNode::simplifiedTypeName(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node simplified type name", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return QString::fromUtf8(type().split('.').constLast()); } -QString ModelNode::displayName() const +QString ModelNode::displayName(SL sl) const { - if (hasId()) - return id(); - return simplifiedTypeName(); + NanotraceHR::Tracer tracer{"model node display name", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + return hasId() ? id() : simplifiedTypeName(); } /*! \brief Returns whether the node is valid @@ -232,15 +284,22 @@ bool ModelNode::isValid() const Will return true also for the root node itself. */ -bool ModelNode::isInHierarchy() const +bool ModelNode::isInHierarchy(SL sl) const { if (!isValid()) return false; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node is in hierarchy", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (isRootNode()) return true; if (!hasParentProperty()) return false; - return parentProperty().parentModelNode().isInHierarchy(); + return parentProperty().parentModelNode().isInHierarchy(sl); } /*! @@ -252,11 +311,17 @@ bool ModelNode::isInHierarchy() const \return the property containing this ModelNode */ -NodeAbstractProperty ModelNode::parentProperty() const +NodeAbstractProperty ModelNode::parentProperty(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node parent property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (!m_internalNode->parentProperty()) return {}; @@ -284,11 +349,17 @@ parentNode4 == parentNode1; -> true */ -void ModelNode::setParentProperty(NodeAbstractProperty parent) +void ModelNode::setParentProperty(NodeAbstractProperty parent, SL sl) { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set parent property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (!parent.parentModelNode().isValid()) return; @@ -301,28 +372,45 @@ void ModelNode::setParentProperty(NodeAbstractProperty parent) parent.reparentHere(*this); } -void ModelNode::changeType(const TypeName &typeName, int majorVersion, int minorVersion) +void ModelNode::changeType(const TypeName &typeName, int majorVersion, int minorVersion, SL sl) { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node change type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + model()->d->changeNodeType(m_internalNode, typeName, majorVersion, minorVersion); } -void ModelNode::setParentProperty(const ModelNode &newParentNode, const PropertyName &propertyName) +void ModelNode::setParentProperty(const ModelNode &newParentNode, const PropertyName &propertyName, SL sl) { - setParentProperty(newParentNode.nodeAbstractProperty(propertyName)); + NanotraceHR::Tracer tracer{"model node set parent property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + setParentProperty(newParentNode.nodeAbstractProperty(propertyName), sl); } /*! \brief test if there is a parent for this node \return true is this node has a parent \see childNodes parentNode setParentNode hasChildNodes Model::undo */ -bool ModelNode::hasParentProperty() const +bool ModelNode::hasParentProperty(SL sl) const { if (!isValid()) return false; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has parent property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (!m_internalNode->parentProperty()) return false; @@ -339,27 +427,44 @@ bool ModelNode::hasParentProperty() const \return BindingProperty named name */ -BindingProperty ModelNode::bindingProperty(PropertyNameView name) const +BindingProperty ModelNode::bindingProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + NanotraceHR::Tracer tracer{"model node binding property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return BindingProperty(name, m_internalNode, model(), view()); } -SignalHandlerProperty ModelNode::signalHandlerProperty(PropertyNameView name) const +SignalHandlerProperty ModelNode::signalHandlerProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node signal handler property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return SignalHandlerProperty(name, m_internalNode, model(), view()); } -SignalDeclarationProperty ModelNode::signalDeclarationProperty(PropertyNameView name) const +SignalDeclarationProperty ModelNode::signalDeclarationProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node signal declaration property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return SignalDeclarationProperty(name, m_internalNode, model(), view()); } @@ -373,11 +478,17 @@ SignalDeclarationProperty ModelNode::signalDeclarationProperty(PropertyNameView \return NodeProperty named name */ -NodeProperty ModelNode::nodeProperty(PropertyNameView name) const +NodeProperty ModelNode::nodeProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return NodeProperty(name, m_internalNode, model(), view()); } @@ -391,34 +502,61 @@ NodeProperty ModelNode::nodeProperty(PropertyNameView name) const \return NodeListProperty named name */ -NodeListProperty ModelNode::nodeListProperty(PropertyNameView name) const +NodeListProperty ModelNode::nodeListProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node list property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return NodeListProperty(name, m_internalNode, model(), view()); } -NodeAbstractProperty ModelNode::nodeAbstractProperty(PropertyNameView name) const +NodeAbstractProperty ModelNode::nodeAbstractProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node abstract property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return NodeAbstractProperty(name, m_internalNode, model(), view()); } -NodeAbstractProperty ModelNode::defaultNodeAbstractProperty() const +NodeAbstractProperty ModelNode::defaultNodeAbstractProperty(SL sl) const { + NanotraceHR::Tracer tracer{"model node default node abstract property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return nodeAbstractProperty(metaInfo().defaultPropertyName()); } -NodeListProperty ModelNode::defaultNodeListProperty() const +NodeListProperty ModelNode::defaultNodeListProperty(SL sl) const { + NanotraceHR::Tracer tracer{"model node default node list property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return nodeListProperty(metaInfo().defaultPropertyName()); } -NodeProperty ModelNode::defaultNodeProperty() const +NodeProperty ModelNode::defaultNodeProperty(SL sl) const { + NanotraceHR::Tracer tracer{"model node default node property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return nodeProperty(metaInfo().defaultPropertyName()); } @@ -432,19 +570,30 @@ NodeProperty ModelNode::defaultNodeProperty() const \return VariantProperty named name */ -VariantProperty ModelNode::variantProperty(PropertyNameView name) const +VariantProperty ModelNode::variantProperty(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + NanotraceHR::Tracer tracer{"model node variant property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return VariantProperty(name, m_internalNode, model(), view()); } -AbstractProperty ModelNode::property(PropertyNameView name) const +AbstractProperty ModelNode::property(PropertyNameView name, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return AbstractProperty(name, m_internalNode, model(), view()); } @@ -463,11 +612,17 @@ It is searching only in the local Property. The list of properties */ -QList ModelNode::properties() const +QList ModelNode::properties(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node properties", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + QList propertyList; const QList propertyNames = m_internalNode->propertyNameList(); @@ -485,23 +640,47 @@ QList ModelNode::properties() const The list of all properties containing just an atomic value. */ -QList ModelNode::variantProperties() const +QList ModelNode::variantProperties(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node variant property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return properties(PropertyType::Variant); } -QList ModelNode::nodeAbstractProperties() const +QList ModelNode::nodeAbstractProperties(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node abstract property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return properties(PropertyType::Node, PropertyType::NodeList); } -QList ModelNode::nodeProperties() const +QList ModelNode::nodeProperties(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return properties(PropertyType::Node); } -QList ModelNode::nodeListProperties() const +QList ModelNode::nodeListProperties(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node list property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return properties(PropertyType::NodeList); } @@ -511,21 +690,39 @@ QList ModelNode::nodeListProperties() const The list of all properties containing an expression. */ -QList ModelNode::bindingProperties() const +QList ModelNode::bindingProperties(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node binding property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return properties(PropertyType::Binding); } -QList ModelNode::signalProperties() const +QList ModelNode::signalProperties(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node signal handler property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return properties(PropertyType::SignalHandler); } -QList ModelNode::dynamicProperties() const +QList ModelNode::dynamicProperties(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node dynamic property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + QList properties; for (const auto &propertyEntry : *m_internalNode.get()) { @@ -546,11 +743,17 @@ Does nothing if the node state does not set this property. \see addProperty property properties hasProperties */ -void ModelNode::removeProperty(PropertyNameView name) const +void ModelNode::removeProperty(PropertyNameView name, SL sl) const { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (!model()->d->propertyNameIsValid(name)) return; @@ -587,11 +790,17 @@ static void removeModelNodeFromSelection(const ModelNode &node) /*! \brief complete removes this ModelNode from the Model */ -void ModelNode::destroy() +void ModelNode::destroy(SL sl) { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node destroy", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (isRootNode()) return; @@ -626,23 +835,41 @@ The list contains every ModelNode that belongs to one of this ModelNodes properties. \return a list of all ModelNodes that are direct children */ -QList ModelNode::directSubModelNodes() const +QList ModelNode::directSubModelNodes(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node direct sub model nodes", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return toModelNodeList(m_internalNode->allDirectSubNodes(), model(), view()); } -QList ModelNode::directSubModelNodesOfType(const NodeMetaInfo &type) const +QList ModelNode::directSubModelNodesOfType(const NodeMetaInfo &type, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node direct sub model nodes of type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return Utils::filtered(directSubModelNodes(), [&](const ModelNode &node) { return node.metaInfo().isValid() && node.metaInfo().isBasedOn(type); }); } -QList ModelNode::subModelNodesOfType(const NodeMetaInfo &type) const +QList ModelNode::subModelNodesOfType(const NodeMetaInfo &type, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node sub model nodes of type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return Utils::filtered(allSubModelNodes(), [&](const ModelNode &node) { return node.metaInfo().isValid() && node.metaInfo().isBasedOn(type); }); @@ -655,16 +882,28 @@ All children in this list will be implicitly removed if this ModelNode is destro \return a list of all ModelNodes that are direct or indirect children */ -QList ModelNode::allSubModelNodes() const +QList ModelNode::allSubModelNodes(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node all sub model nodes", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return toModelNodeList(internalNode()->allSubNodes(), model(), view()); } -QList ModelNode::allSubModelNodesAndThisNode() const +QList ModelNode::allSubModelNodesAndThisNode(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node all sub model nodes and this node", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + QList modelNodeList; modelNodeList.append(*this); modelNodeList.append(allSubModelNodes()); @@ -678,17 +917,29 @@ QList ModelNode::allSubModelNodesAndThisNode() const \return if this ModelNode has any child ModelNodes */ -bool ModelNode::hasAnySubModelNodes() const +bool ModelNode::hasAnySubModelNodes(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has any sub model nodes", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return !nodeAbstractProperties().isEmpty(); } -NodeMetaInfo ModelNode::metaInfo() const +NodeMetaInfo ModelNode::metaInfo([[maybe_unused]] SL sl) const { if (!isValid()) return {}; #ifdef QDS_USE_PROJECTSTORAGE + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node meta info", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return NodeMetaInfo(m_internalNode->typeId, m_model->projectStorage()); #else return NodeMetaInfo(m_model->metaInfoProxyModel(), @@ -698,33 +949,51 @@ NodeMetaInfo ModelNode::metaInfo() const #endif } -bool ModelNode::hasMetaInfo() const +bool ModelNode::hasMetaInfo(SL sl) const { if (!isValid()) return false; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has meta info", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return model()->hasNodeMetaInfo(type(), majorVersion(), minorVersion()); } /*! \brief has a node the selection of the model \return true if the node his selection */ -bool ModelNode::isSelected() const +bool ModelNode::isSelected(SL sl) const { if (!isValid()) return false; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node is selected", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return model()->d->selectedNodes().contains(internalNode()); } /*! \briefis this node the root node of the model \return true if it is the root node */ -bool ModelNode::isRootNode() const +bool ModelNode::isRootNode(SL sl) const { if (!isValid()) return false; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node is root node", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_model->d->rootNode() == m_internalNode; } @@ -735,11 +1004,17 @@ The list of properties set in this state. \see addProperty property changePropertyValue removeProperty hasProperties */ -PropertyNameList ModelNode::propertyNames() const +PropertyNameList ModelNode::propertyNames(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node property names", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->propertyNameList(); } @@ -765,33 +1040,63 @@ QList ModelNode::properties(PropertyType... type) const return properties; } -/*! \brief test a if a property is set for this node -\return true if property a property ins this or a ancestor state exists +/*! \brief test if a property is set for this node +\return true if property a property in this or a ancestor state exists */ -bool ModelNode::hasProperty(PropertyNameView name) const +bool ModelNode::hasProperty(PropertyNameView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return isValid() && m_internalNode->property(name); } -bool ModelNode::hasVariantProperty(PropertyNameView name) const +bool ModelNode::hasVariantProperty(PropertyNameView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has variant property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasProperty(name, PropertyType::Variant); } -bool ModelNode::hasBindingProperty(PropertyNameView name) const +bool ModelNode::hasBindingProperty(PropertyNameView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has binding property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasProperty(name, PropertyType::Binding); } -bool ModelNode::hasSignalHandlerProperty(PropertyNameView name) const +bool ModelNode::hasSignalHandlerProperty(PropertyNameView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has signal handler property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasProperty(name, PropertyType::SignalHandler); } -bool ModelNode::hasNodeAbstractProperty(PropertyNameView name) const +bool ModelNode::hasNodeAbstractProperty(PropertyNameView name, SL sl) const { if (!isValid()) - return false; + return {}; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has node abstract property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; if (auto property = m_internalNode->property(name)) return property->isNodeAbstractProperty(); @@ -799,38 +1104,74 @@ bool ModelNode::hasNodeAbstractProperty(PropertyNameView name) const return false; } -bool ModelNode::hasDefaultNodeAbstractProperty() const +bool ModelNode::hasDefaultNodeAbstractProperty(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has default node abstract property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto defaultPropertyName = metaInfo().defaultPropertyName(); return hasNodeAbstractProperty(defaultPropertyName); } -bool ModelNode::hasDefaultNodeListProperty() const +bool ModelNode::hasDefaultNodeListProperty(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has default node list property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto defaultPropertyName = metaInfo().defaultPropertyName(); return hasNodeListProperty(defaultPropertyName); } -bool ModelNode::hasDefaultNodeProperty() const +bool ModelNode::hasDefaultNodeProperty(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has default node property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto defaultPropertyName = metaInfo().defaultPropertyName(); return hasNodeProperty(defaultPropertyName); } -bool ModelNode::hasNodeProperty(PropertyNameView name) const +bool ModelNode::hasNodeProperty(PropertyNameView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has node property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasProperty(name, PropertyType::Node); } -bool ModelNode::hasNodeListProperty(PropertyNameView name) const +bool ModelNode::hasNodeListProperty(PropertyNameView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has node list property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasProperty(name, PropertyType::NodeList); } -bool ModelNode::hasProperty(PropertyNameView name, PropertyType propertyType) const +bool ModelNode::hasProperty(PropertyNameView name, PropertyType propertyType, SL sl) const { if (!isValid()) - return false; + return {}; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has property", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; if (auto property = m_internalNode->property(name)) return property->type() == propertyType; @@ -852,8 +1193,14 @@ static bool recursiveAncestor(const ModelNode &possibleAncestor, const ModelNode return false; } -bool ModelNode::isAncestorOf(const ModelNode &node) const +bool ModelNode::isAncestorOf(const ModelNode &node, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node is ancestor of", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return recursiveAncestor(*this, node); } @@ -882,22 +1229,34 @@ QTextStream &operator<<(QTextStream &stream, const ModelNode &modelNode) return stream; } -void ModelNode::selectNode() +void ModelNode::selectNode(SL sl) { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node select node", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + QList selectedNodeList; selectedNodeList.append(*this); model()->setSelectedModelNodes(selectedNodeList); } -void ModelNode::deselectNode() +void ModelNode::deselectNode(SL sl) { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node deselect node", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto selectedNodes = model()->d->selectedNodes(); selectedNodes.removeAll(internalNode()); model()->d->setSelectedNodes(selectedNodes); @@ -908,34 +1267,74 @@ int ModelNode::variantTypeId() return qMetaTypeId(); } -QVariant ModelNode::toVariant() const +QVariant ModelNode::toVariant(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node to variant", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return QVariant::fromValue(*this); } -std::optional ModelNode::auxiliaryData(AuxiliaryDataKeyView key) const +std::optional ModelNode::auxiliaryData(AuxiliaryDataKeyView key, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->auxiliaryData(key); } -std::optional ModelNode::auxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const -{ - return auxiliaryData({type, name}); -} - -QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataType type, Utils::SmallStringView name) const -{ - return auxiliaryDataWithDefault({type, name}); -} - -QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataKeyView key) const +std::optional ModelNode::auxiliaryData(AuxiliaryDataType type, + Utils::SmallStringView name, + SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data with name", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + return auxiliaryData({type, name}); +} + +QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataType type, + Utils::SmallStringView name, + SL sl) const +{ + if (!isValid()) + return {}; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data with default 1", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + return auxiliaryDataWithDefault({type, name}); +} + +QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataKeyView key, SL sl) const +{ + if (!isValid()) + return {}; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data with default 2", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto data = m_internalNode->auxiliaryData(key); if (data) @@ -944,11 +1343,17 @@ QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataKeyView key) const return {}; } -QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataKeyDefaultValue key) const +QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataKeyDefaultValue key, SL sl) const { if (!isValid()) return toQVariant(key.defaultValue); + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data with default 3", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto data = m_internalNode->auxiliaryData(key); if (data) @@ -959,69 +1364,123 @@ QVariant ModelNode::auxiliaryDataWithDefault(AuxiliaryDataKeyDefaultValue key) c void ModelNode::setAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, - const QVariant &data) const + const QVariant &data, + SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set auxiliary data with type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + setAuxiliaryData({type, name}, data); } -void ModelNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data) const +void ModelNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data, SL sl) const { - if (isValid()) { - if (key.type == AuxiliaryDataType::Persistent) - ensureIdExists(); - Internal::WriteLocker locker(m_model.data()); - m_model->d->setAuxiliaryData(internalNode(), key, data); - } + if (!isValid()) + return; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set auxiliary data with key", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + if (key.type == AuxiliaryDataType::Persistent) + ensureIdExists(); + Internal::WriteLocker locker(m_model.data()); + m_model->d->setAuxiliaryData(internalNode(), key, data); } -void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data) const +void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data, SL sl) const { - if (isValid()) { - if (key.type == AuxiliaryDataType::Persistent) - ensureIdExists(); + if (!isValid()) + return; - m_model->d->setAuxiliaryData(internalNode(), key, data); - } + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set auxiliary data without lock with key", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + if (key.type == AuxiliaryDataType::Persistent) + ensureIdExists(); + + m_model->d->setAuxiliaryData(internalNode(), key, data); } void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataType type, Utils::SmallStringView name, - const QVariant &data) const + const QVariant &data, + SL sl) const { - if (isValid()) { - if (type == AuxiliaryDataType::Persistent) - ensureIdExists(); + if (!isValid()) + return; - m_model->d->setAuxiliaryData(internalNode(), {type, name}, data); - } + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set auxiliary data without lock with type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + if (type == AuxiliaryDataType::Persistent) + ensureIdExists(); + + m_model->d->setAuxiliaryData(internalNode(), {type, name}, data); } -void ModelNode::removeAuxiliaryData(AuxiliaryDataKeyView key) const +void ModelNode::removeAuxiliaryData(AuxiliaryDataKeyView key, SL sl) const { - if (isValid()) { - if (key.type == AuxiliaryDataType::Persistent) - ensureIdExists(); + if (!isValid()) + return; - Internal::WriteLocker locker(m_model.data()); - m_model->d->removeAuxiliaryData(internalNode(), key); - } + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove auxiliary data with key", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + if (key.type == AuxiliaryDataType::Persistent) + ensureIdExists(); + + Internal::WriteLocker locker(m_model.data()); + m_model->d->removeAuxiliaryData(internalNode(), key); } -void ModelNode::removeAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const +void ModelNode::removeAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove auxiliary data with type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + removeAuxiliaryData({type, name}); } -bool ModelNode::hasAuxiliaryData(AuxiliaryDataKeyView key) const +bool ModelNode::hasAuxiliaryData(AuxiliaryDataKeyView key, SL sl) const { if (!isValid()) return false; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has auxiliary data with key", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->hasAuxiliaryData(key); } -bool ModelNode::hasAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const +bool ModelNode::hasAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has auxiliary data with type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasAuxiliaryData({type, name}); } @@ -1030,78 +1489,150 @@ bool ModelNode::hasAuxiliaryData(AuxiliaryDataType type) const if (!isValid()) return false; + // using NanotraceHR::keyValue; + // NanotraceHR::Tracer tracer{"model node has auxiliary data with type", + // category(), + // keyValue("type id", m_internalNode->typeId), + // keyValue("caller location", sl)}; + return m_internalNode->hasAuxiliaryData(type); } -AuxiliaryDatasForType ModelNode::auxiliaryData(AuxiliaryDataType type) const +AuxiliaryDatasForType ModelNode::auxiliaryData(AuxiliaryDataType type, SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data with type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->auxiliaryData(type); } -AuxiliaryDatasView ModelNode::auxiliaryData() const +AuxiliaryDatasView ModelNode::auxiliaryData(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node auxiliary data with sl", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->auxiliaryData(); } -QString ModelNode::customId() const +QString ModelNode::customId(SL sl) const { auto data = auxiliaryData(customIdProperty); + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node custom id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (data) return data->toString(); return {}; } -bool ModelNode::hasCustomId() const +bool ModelNode::hasCustomId(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has custom id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasAuxiliaryData(customIdProperty); } -void ModelNode::setCustomId(const QString &str) +void ModelNode::setCustomId(const QString &str, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set custom id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + setAuxiliaryData(customIdProperty, QVariant::fromValue(str)); } -void ModelNode::removeCustomId() +void ModelNode::removeCustomId(SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove custom id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + removeAuxiliaryData(customIdProperty); } -QVector ModelNode::comments() const +QVector ModelNode::comments(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node comments", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return annotation().comments(); } -bool ModelNode::hasComments() const +bool ModelNode::hasComments(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has comments", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return annotation().hasComments(); } -void ModelNode::setComments(const QVector &coms) +void ModelNode::setComments(const QVector &coms, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set comments", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + Annotation anno = annotation(); anno.setComments(coms); setAnnotation(anno); } -void ModelNode::addComment(const Comment &com) +void ModelNode::addComment(const Comment &com, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node add comment", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + Annotation anno = annotation(); anno.addComment(com); setAnnotation(anno); } -bool ModelNode::updateComment(const Comment &com, int position) +bool ModelNode::updateComment(const Comment &com, int position, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node update comment", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + bool result = false; if (hasAnnotation()) { Annotation anno = annotation(); @@ -1115,8 +1646,14 @@ bool ModelNode::updateComment(const Comment &com, int position) return result; } -Annotation ModelNode::annotation() const +Annotation ModelNode::annotation(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto data = auxiliaryData(annotationProperty); if (data) @@ -1125,23 +1662,47 @@ Annotation ModelNode::annotation() const return {}; } -bool ModelNode::hasAnnotation() const +bool ModelNode::hasAnnotation(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return hasAuxiliaryData(annotationProperty); } -void ModelNode::setAnnotation(const Annotation &annotation) +void ModelNode::setAnnotation(const Annotation &annotation, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + setAuxiliaryData(annotationProperty, QVariant::fromValue(annotation.toQString())); } -void ModelNode::removeAnnotation() +void ModelNode::removeAnnotation(SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + removeAuxiliaryData(annotationProperty); } -Annotation ModelNode::globalAnnotation() const +Annotation ModelNode::globalAnnotation(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node global annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + Annotation result; ModelNode root = m_model->rootModelNode(); @@ -1153,24 +1714,47 @@ Annotation ModelNode::globalAnnotation() const return {}; } -bool ModelNode::hasGlobalAnnotation() const +bool ModelNode::hasGlobalAnnotation(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has global annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_model->rootModelNode().hasAuxiliaryData(globalAnnotationProperty); } -void ModelNode::setGlobalAnnotation(const Annotation &annotation) +void ModelNode::setGlobalAnnotation(const Annotation &annotation, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set global annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; m_model->rootModelNode().setAuxiliaryData(globalAnnotationProperty, QVariant::fromValue(annotation.toQString())); } -void ModelNode::removeGlobalAnnotation() +void ModelNode::removeGlobalAnnotation(SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove global annotation", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + m_model->rootModelNode().removeAuxiliaryData(globalAnnotationProperty); } -GlobalAnnotationStatus ModelNode::globalStatus() const +GlobalAnnotationStatus ModelNode::globalStatus(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node global status", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + GlobalAnnotationStatus result; ModelNode root = m_model->rootModelNode(); @@ -1182,26 +1766,50 @@ GlobalAnnotationStatus ModelNode::globalStatus() const return result; } -bool ModelNode::hasGlobalStatus() const +bool ModelNode::hasGlobalStatus(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has global status", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_model->rootModelNode().hasAuxiliaryData(globalAnnotationStatus); } -void ModelNode::setGlobalStatus(const GlobalAnnotationStatus &status) +void ModelNode::setGlobalStatus(const GlobalAnnotationStatus &status, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set global status", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + m_model->rootModelNode().setAuxiliaryData(globalAnnotationStatus, QVariant::fromValue(status.toQString())); } -void ModelNode::removeGlobalStatus() +void ModelNode::removeGlobalStatus(SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node remove global status", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (hasGlobalStatus()) { m_model->rootModelNode().removeAuxiliaryData(globalAnnotationStatus); } } -bool ModelNode::locked() const +bool ModelNode::locked(SL sl) const { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node locked", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + auto data = auxiliaryData(lockedProperty); if (data) @@ -1210,13 +1818,25 @@ bool ModelNode::locked() const return false; } -bool ModelNode::hasLocked() const +bool ModelNode::hasLocked(SL sl) const { - return hasAuxiliaryData(lockedProperty); + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node has locked", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + + return hasAuxiliaryData(lockedProperty, sl); } -void ModelNode::setLocked(bool value) +void ModelNode::setLocked(bool value, SL sl) { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set locked", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (value) { setAuxiliaryData(lockedProperty, true); // Remove newly locked node and all its descendants from potential selection @@ -1230,50 +1850,80 @@ void ModelNode::setLocked(bool value) } } -void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList) +void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList, SL sl) { if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set script functions", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + model()->d->setScriptFunctions(m_internalNode, scriptFunctionList); } -QStringList ModelNode::scriptFunctions() const +QStringList ModelNode::scriptFunctions(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node script functions", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->scriptFunctions; } -qint32 ModelNode::internalId() const +qint32 ModelNode::internalId(SL sl) const { if (!m_internalNode) return -1; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node internal id", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->internalId; } -void ModelNode::setNodeSource(const QString &newNodeSource) +void ModelNode::setNodeSource(const QString &newNodeSource, SL sl) { Internal::WriteLocker locker(m_model.data()); if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set node source", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (m_internalNode->nodeSource == newNodeSource) return; m_model.data()->d->setNodeSource(m_internalNode, newNodeSource); } -void ModelNode::setNodeSource(const QString &newNodeSource, NodeSourceType type) +void ModelNode::setNodeSource(const QString &newNodeSource, NodeSourceType type, SL sl) { Internal::WriteLocker locker(m_model.data()); if (!isValid()) return; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node set node source with type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (m_internalNode->nodeSourceType == type && m_internalNode->nodeSource == newNodeSource) return; @@ -1281,37 +1931,61 @@ void ModelNode::setNodeSource(const QString &newNodeSource, NodeSourceType type) m_model.data()->d->setNodeSource(m_internalNode, newNodeSource); } -QString ModelNode::nodeSource() const +QString ModelNode::nodeSource(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node source", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->nodeSource; } -QString ModelNode::convertTypeToImportAlias() const +QString ModelNode::convertTypeToImportAlias(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node convert type to import alias", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (model()->rewriterView()) return model()->rewriterView()->convertTypeToImportAlias(QString::fromLatin1(type())); return QString::fromLatin1(type()); } -ModelNode::NodeSourceType ModelNode::nodeSourceType() const +ModelNode::NodeSourceType ModelNode::nodeSourceType(SL sl) const { if (!isValid()) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node node source type", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return static_cast(m_internalNode->nodeSourceType); } -bool ModelNode::isComponent() const +bool ModelNode::isComponent(SL sl) const { if (!isValid()) - return false; + return {}; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node is component", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; if (!metaInfo().isValid()) return false; @@ -1364,12 +2038,18 @@ bool ModelNode::isComponent() const return false; } -QIcon ModelNode::typeIcon() const +QIcon ModelNode::typeIcon([[maybe_unused]] SL sl) const { #ifdef QDS_USE_PROJECTSTORAGE if (!isValid()) return QIcon(QStringLiteral(":/ItemLibrary/images/item-invalid-icon.png")); + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node type icon", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + if (auto iconPath = metaInfo().iconPath(); iconPath.size()) return QIcon(iconPath.toQString()); else @@ -1391,11 +2071,17 @@ QIcon ModelNode::typeIcon() const #endif } -QString ModelNode::behaviorPropertyName() const +QString ModelNode::behaviorPropertyName(SL sl) const { if (!m_internalNode) return {}; + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"model node behavior property name", + category(), + keyValue("type id", m_internalNode->typeId), + keyValue("caller location", sl)}; + return m_internalNode->behaviorPropertyName; } diff --git a/tests/unit/tests/matchers/property-matcher.h b/tests/unit/tests/matchers/property-matcher.h index 561a94cb69e..33922872bc7 100644 --- a/tests/unit/tests/matchers/property-matcher.h +++ b/tests/unit/tests/matchers/property-matcher.h @@ -17,7 +17,7 @@ class PropertyMatcher public: PropertyMatcher(Property property, const Matcher &matcher, Arguments... arguments) : m_property(property) - , matcher_(matcher) + , m_matcher(matcher) , m_whose_property() , m_arguments{arguments...} {} @@ -27,7 +27,7 @@ public: const Matcher &matcher, Arguments... arguments) : m_property(property) - , matcher_(matcher) + , m_matcher(matcher) , m_whose_property(whose_property) , m_arguments{arguments...} {} @@ -35,13 +35,13 @@ public: void DescribeTo(::std::ostream *os) const { *os << "is an object " << m_whose_property; - matcher_.DescribeTo(os); + m_matcher.DescribeTo(os); } void DescribeNegationTo(::std::ostream *os) const { *os << "is an object " << m_whose_property; - matcher_.DescribeNegationTo(os); + m_matcher.DescribeNegationTo(os); } template @@ -52,14 +52,14 @@ public: auto result = std::apply( [&](auto &&...arguments) { return std::invoke(m_property, value, arguments...); }, m_arguments); - return MatchPrintAndExplain(result, matcher_, listener); + return m_matcher.MatchAndExplain(result, listener->stream()); } private: Property m_property; - const Matcher matcher_; - const std::string m_whose_property; - const std::tuple m_arguments; + Matcher m_matcher; + std::string m_whose_property; + std::tuple m_arguments; }; template diff --git a/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp b/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp index 91205aeba18..48fb66eb97d 100644 --- a/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp +++ b/tests/unit/tests/unittests/designsystem/dsthemeqml-test.cpp @@ -24,6 +24,8 @@ using QmlDesigner::Import; using QmlDesigner::ModelNode; using QmlDesigner::ThemeProperty; +constexpr QmlDesigner::ModelTracing::SourceLocation sl; + namespace { std::string formatedPropStr(std::string tag, const QByteArray &name, const QVariant &value) { @@ -136,7 +138,7 @@ TEST_P(DesignSystemQmlTest, group_aliase_properties_are_generated) // assert ASSERT_THAT(rootNode, - AllOf(Property("ModelNode::type", &ModelNode::type, Eq("QtObject")), + AllOf(Property("ModelNode::type", &ModelNode::type, Eq("QtObject"), sl), HasBindingProperty(groupName, binding), HasBindingProperty("currentTheme", darkThemeName), HasNodeProperty(darkThemeName, "QtObject"))); @@ -154,7 +156,7 @@ TEST_P(DesignSystemQmlTest, empty_groups_generate_no_group_aliase_properties) // assert ASSERT_THAT(rootNode, - AllOf(Property("ModelNode::type", &ModelNode::type, Eq("QtObject")), + AllOf(Property("ModelNode::type", &ModelNode::type, Eq("QtObject"), sl), Not(HasBindingProperty(groupName, binding)), Not(HasBindingProperty("currentTheme", darkThemeName)), Not(HasNodeProperty(darkThemeName, "QtObject")))); diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index 9fd89d5e78d..5b704599bb1 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -27,6 +27,8 @@ using QmlDesigner::PropertyDeclarationId; using QmlDesigner::TypeId; namespace Info = QmlDesigner::Storage::Info; +constexpr QmlDesigner::ModelTracing::SourceLocation sl; + MATCHER_P2(HasItem, name, value, @@ -388,10 +390,13 @@ TEST_F(ListModelEditor, add_row_creates_new_model_node_and_reparents) { model.setListModel(listModelNode); - EXPECT_CALL(mockView, nodeCreated(Property("ModelNode::type", &ModelNode::type, Eq("ListElement")))); EXPECT_CALL(mockView, - nodeReparented(Property("ModelNode::type", &ModelNode::type, Eq("ListElement")), - Property("AbstractProperty::parentModelNode", &AbstractProperty::parentModelNode, Eq(listModelNode)), + nodeCreated(Property("ModelNode::type", &ModelNode::type, Eq("ListElement"), sl))); + EXPECT_CALL(mockView, + nodeReparented(Property("ModelNode::type", &ModelNode::type, Eq("ListElement"), sl), + Property("AbstractProperty::parentModelNode", + &AbstractProperty::parentModelNode, + Eq(listModelNode)), _, _)); From 534b507907b05ec40df572943ebe27fd0a62a625 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Thu, 13 Mar 2025 12:35:09 +0000 Subject: [PATCH 80/82] QmlDesigner: Fix feedback popup behavior in Linux Fixes: QDS-14841 Change-Id: Ibbc4983a046684c0c72c577a1b8500c2f8e901a1 Reviewed-by: Ali Kianian --- src/plugins/qmldesigner/qmldesignerplugin.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 55be25b7c2a..8d665dd5788 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -848,6 +848,12 @@ void QmlDesignerPlugin::launchFeedbackPopupInternal(const QString &identifier) const QString qmlPath = Core::ICore::resourcePath("qmldesigner/feedback/FeedbackPopup.qml").toUrlishString(); m_feedbackWidget->setSource(QUrl::fromLocalFile(qmlPath)); + if (Utils::HostOsInfo::isLinuxHost()) { + QPoint pos = Core::ICore::dialogParent()->pos(); + int x = (Core::ICore::dialogParent()->width() - m_feedbackWidget->width()) / 2; + int y = (Core::ICore::dialogParent()->height() - m_feedbackWidget->height()) / 2; + m_feedbackWidget->move(pos.x() + x, pos.y() + y); + } if (!m_feedbackWidget->errors().isEmpty()) { qDebug() << qmlPath; qDebug() << m_feedbackWidget->errors().first().toString(); From 8b33f3e1fde9dc782e1ff039ff13d440a5392560 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Fri, 4 Apr 2025 13:08:06 +0300 Subject: [PATCH 81/82] Doc: Add ALT-texts to images Task-number: QDS-14285 Change-Id: Idbe8e2acffe7eb19e6e41e99f572fdbda0f7cbf0 Reviewed-by: Johanna Vanhatapio Reviewed-by: Alessandro Portale --- .../best practices/best-practices-glow.qdoc | 34 +++++++++---------- .../best-practices-shader-code.qdoc | 2 +- .../components/qtquick-components-custom.qdoc | 6 ++-- .../src/components/qtquick-controls.qdoc | 22 ++++++------ .../src/components/qtquick-images.qdoc | 4 +-- .../src/components/qtquick-shapes.qdoc | 2 +- ...-accessing-output-issues-and-warnings.qdoc | 6 ++-- .../developers/studio-jump-to-the-code.qdoc | 8 ++--- doc/qtdesignstudio/src/effects-concept.qdoc | 2 +- ...signstudio-creating-projects-for-mcus.qdoc | 2 +- ...udio-developing-applications-for-mcus.qdoc | 2 +- .../qt-design-viewer-navigation.qdoc | 16 ++++----- .../src/qtbridge/qtbridge-figma-overview.qdoc | 2 +- .../src/qtbridge/qtbridge-figma-using.qdoc | 2 +- .../src/qtbridge/qtbridge-ps-overview.qdoc | 2 +- .../src/qtbridge/qtbridge-ps-setup.qdoc | 2 +- .../src/qtbridge/qtbridge-ps-using.qdoc | 16 ++++----- .../qtbridge/qtbridge-sketch-overview.qdoc | 2 +- .../src/qtbridge/qtbridge-sketch-using.qdoc | 6 ++-- .../src/qtbridge/qtbridge-xd-overview.qdoc | 2 +- .../src/qtbridge/qtbridge-xd-setup.qdoc | 2 +- .../src/qtbridge/qtbridge-xd-using.qdoc | 6 ++-- ...tdesignstudio-exporting-and-importing.qdoc | 2 +- .../qtdesignstudio-qt-runtime-version.qdocinc | 2 +- ...signstudio-using-effect-maker-effects.qdoc | 6 ++-- .../qtdesignstudio-3d-camera.qdoc | 2 +- .../qtdesignstudio-3d-editor.qdoc | 2 +- .../qtdesignstudio-3d-importing.qdoc | 2 +- .../qtdesignstudio-3d-lights.qdoc | 14 ++++---- .../qtdesignstudio-3d-loader-3d.qdoc | 10 +++--- .../qtdesignstudio-3d-particles.qdoc | 10 +++--- .../qtdesignstudio-3d-repeater-3d.qdoc | 12 +++---- .../qtdesignstudio-logic-helpers.qdoc | 4 +-- .../qtdesignstudio-keyboard-shortcuts.qdoc | 2 +- .../qtquick-connection-editor-bindings.qdoc | 8 ++--- .../qtquick-connection-editor-properties.qdoc | 8 ++--- .../qtquick-connection-editor-signals.qdoc | 8 ++--- .../src/views/qtquick-navigator.qdoc | 2 +- .../src/views/qtquick-properties-view.qdoc | 10 +++--- .../src/views/qtquick-properties.qdoc | 4 +-- .../src/views/qtquick-states.qdoc | 4 +-- .../src/views/qtquick-timeline.qdoc | 14 ++++---- .../src/views/studio-content-library.qdoc | 4 +-- .../src/views/studio-qtinsight.qdoc | 2 +- .../src/views/studio-translations.qdoc | 4 +-- 45 files changed, 142 insertions(+), 142 deletions(-) diff --git a/doc/qtdesignstudio/src/best practices/best-practices-glow.qdoc b/doc/qtdesignstudio/src/best practices/best-practices-glow.qdoc index 29847e73004..6caa58c1311 100644 --- a/doc/qtdesignstudio/src/best practices/best-practices-glow.qdoc +++ b/doc/qtdesignstudio/src/best practices/best-practices-glow.qdoc @@ -14,7 +14,7 @@ using image-based lighting) or add ambient light. Using the glow effect is one way to make your scene more realistic. - \image glow-example.webp + \image {glow-example.webp} {An example showing the difference between using a glow effect and not using a glow effect.} \section1 Creating a project with ExtendedSceneEnvironment @@ -29,7 +29,7 @@ \uicontrol {ExtendedSceneEnvironment} component from \uicontrol Components to the \uicontrol 2D or \uicontrol Navigator view. - \image ext-scene-env-navigator.webp + \image {ext-scene-env-navigator.webp} {The ExtendedSceneEnvironment in the Navigator view.} \section1 Enabling the Glow effect @@ -37,7 +37,7 @@ then, in the \uicontrol Properties view, select \uicontrol Enabled in the \uicontrol Glow section. - \image glow-properties.webp + \image {glow-properties.webp} {The Glow effect properties in the Properties view.} \note When setting up or experimenting with the glow effect, use the \l {Blend Modes}{Replace} blend mode to see the effect more clearly. @@ -52,7 +52,7 @@ properties is to change them directly in the \uicontrol Properties view in \QDS and see the changes live in the \uicontrol 2D view. - \image glow-example-project.webp + \image {glow-example-project.webp} {The Flashlight Example project running.} \section1 Basic properties @@ -96,13 +96,13 @@ \li Example \row \li Bloom disabled - \li \image bleed-scale-no.webp + \li \image {bleed-scale-no.webp} {A close-up of a light in the scene with Bloom disabled.} \row \li 8 - \li \image bleed-scale-8.webp + \li \image {bleed-scale-8.webp} {A close-up of a light in the scene with HDR Scale set to 8.} \row \li 1 - \li \image bleed-scale-1.webp + \li \image {bleed-scale-1.webp} {A close-up of a light in the scene with HDR Scale set to 1.} \endtable \section1 Blur Levels @@ -122,13 +122,13 @@ \li Example \row \li 1, 2, 3 - \li \image glow_low_blur_levels.webp + \li \image {glow_low_blur_levels.webp} {A close-up of a light in the scene with Blur level set to 1, 2, 3.} \row \li 5, 6, 7 - \li \image glow_high_blur_levels.webp + \li \image {glow_high_blur_levels.webp} {A close-up of a light in the scene with Blur level set to 5, 6, 7.} \row \li 1, 2, 3, 4, 5, 6, 7 - \li \image glow_all_blur_levels.webp + \li \image {glow_all_blur_levels.webp} {A close-up of a light in the scene with Blur level set to 1, 2, 3, 4, 5, 6, 7.} \endtable \section2 Blend modes @@ -143,21 +143,21 @@ \row \li Additive \li Often recommended for outdoor scenes with a visible sky or sun. - \li \image glow-additive-blend.webp + \li \image {glow-additive-blend.webp} {A close-up of a light in the scene with Blend mode set to Additive.} \row \li Screen \li Similar to \uicontrol {Additive}, but the result is less bright. - \li \image glow-screen-blend.webp + \li \image {glow-screen-blend.webp} {A close-up of a light in the scene with Blend mode set to Additive.} \row \li SoftLight \li Often recommended for in-door environments. - \li \image glow-softlight-blend.webp + \li \image {glow-softlight-blend.webp} {A close-up of a light in the scene with Blend mode set to SoftLight.} \row \li Replace \li Does not perform any blending, but displays only the contribution the glow effect would blend with the actual content. In practice, this is useful for experimenting and troubleshooting when setting up the glow effect. - \li \image glow-replace-blend.webp + \li \image {glow-replace-blend.webp} {A close-up of a light in the scene with Blend mode set to Replace.} \endtable \section1 Improvement properties @@ -187,13 +187,13 @@ \li Example \row \li No effect - \li \image glow-no-enhancment.webp + \li \image {glow-no-enhancment.webp} {A close-up of a light in the scene with no effect.} \row \li High Quality - \li \image glow-high-quality.webp + \li \image {glow-high-quality.webp} {A close-up of a light in the scene with the High Quality effect.} \row \li Bicubic Upsampling - \li \image glow-bicubic.webp + \li \image {glow-bicubic.webp} {A close-up of a light in the scene with the Bicubic Upsampling effect.} \endtable diff --git a/doc/qtdesignstudio/src/best practices/best-practices-shader-code.qdoc b/doc/qtdesignstudio/src/best practices/best-practices-shader-code.qdoc index 7ddd066e961..0e1148ca7b9 100644 --- a/doc/qtdesignstudio/src/best practices/best-practices-shader-code.qdoc +++ b/doc/qtdesignstudio/src/best practices/best-practices-shader-code.qdoc @@ -146,7 +146,7 @@ You can control these settings either from the \uicontrol Properties view or from code. - \image timeRunning_property.webp + \image {timeRunning_property.webp} {The Running setting turned on in the Properties view.} \code NorthernLights { diff --git a/doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc b/doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc index 1c8d5ef8dd6..f22dbdf0cf0 100644 --- a/doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc @@ -13,7 +13,7 @@ new components that you can create instances of. You can then use the instances of the new components in other components. - \image qtquick-components-custom.png "Custom components in My Components" + \image {qtquick-components-custom.png} {Custom components in My Components.} Custom components are stored in \uicontrol Components > \uicontrol {My Components}. You can create instances of custom components @@ -86,7 +86,7 @@ in \uicontrol Navigator or the \uicontrol {2D} view, and select \uicontrol {Create Component} in the context menu. - \image qtcreator-move-component-into-separate-file.png + \image {qtcreator-move-component-into-separate-file.png} {The Move Component into Separate File dialog.} Give the new component a name, and select whether properties are set for the new component or for the original one. @@ -117,7 +117,7 @@ \uicontrol Navigator or \uicontrol {2D} view and select \uicontrol {Merge File with Template} in the context menu. - \image qmldesigner-merge-with-template.png "Merge with Template dialog" + \image {qmldesigner-merge-with-template.png} {The Merge with Template dialog.} In the \uicontrol Template field, select the file to use as a template. */ diff --git a/doc/qtdesignstudio/src/components/qtquick-controls.qdoc b/doc/qtdesignstudio/src/components/qtquick-controls.qdoc index aa650ae7d65..227e86cee5b 100644 --- a/doc/qtdesignstudio/src/components/qtquick-controls.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-controls.qdoc @@ -13,7 +13,7 @@ available in \uicontrol Components > \uicontrol {Qt Quick Controls} > \uicontrol Controls. - \image qtquick-designer-qtquickcontrols-types.png "Qt Quick Controls components" + \image {qtquick-designer-qtquickcontrols-types.png} {The Qt Quick Controls components in the Components view.} The following types of controls are available for user interaction: @@ -36,7 +36,7 @@ You can set control properties in the \l Properties view. - \image qtquick-designer-control-properties.png "Control section in Properties" + \image {qtquick-designer-control-properties.png} {The Control section in the Properties view.} The \uicontrol Enable check box indicates whether the control is enabled. @@ -64,7 +64,7 @@ most suitable for a use case and discuss the values you can set for button properties in the \uicontrol Properties view. - \image qtquick-designer-button-types.png "Button controls in the 2D view" + \image {qtquick-designer-button-types.png} {Different types of button controls in the 2D view.} Recommendations for buttons that contain text: @@ -387,20 +387,20 @@ \target progress-bar-control \section2 Progress Bar - \image qtquickcontrols2-progressbar.gif "Progress bar" + \image {qtquickcontrols2-progressbar.gif} {An animation of a Progress Bar running.} \uicontrol {Progress Bar} indicates the progress of an operation. You can specify the initial value in the \uicontrol Value field, but it should be updated regularly. Specify the range in the \uicontrol From and \uicontrol To fields, which can both contain any value. - \image qtquick-designer-progressbar-properties.png "Progress Bar properties" + \image {qtquick-designer-progressbar-properties.png} {The Progress Bar section in the Properties view.} Select the \uicontrol Indeterminate check box when unable to determine the size of the item being downloaded, or if the download progress might get interrupted due to a network failure. - \image qtquickcontrols2-progressbar-indeterminate.gif + \image {qtquickcontrols2-progressbar-indeterminate.gif} {A runnning Progress Bar with the Indeterminate property turned on.} The indeterminate mode is similar to a \l {Busy Indicator} in that both can be used to indicate background activity. Due to their visual differences, @@ -561,7 +561,7 @@ \section2 Tumbler - \image qtquickcontrols2-tumbler-wrap.gif + \image {qtquickcontrols2-tumbler-wrap.gif} {An animation of a Tumbler with multiple wheels spinning.} \uicontrol Tumbler allows users to select an option from a spinnable \e wheel of items. It is useful when there are too many options to use, for @@ -573,7 +573,7 @@ field. Select the index of the current option in the \uicontrol {Current index} field. - \image qtquick-designer-tumbler-properties.png "Tumbler properties" + \image {qtquick-designer-tumbler-properties.png} {The Tumbler section in the Properties view.} To enable wrapping, select the \uicontrol Wrap check box. @@ -600,18 +600,18 @@ If the total width of the buttons exceeds the available width of the tab bar, it automatically becomes \l{Flickable}{flickable}. - \image qtquickcontrols2-tabbar-flickable.png + \image {qtquickcontrols2-tabbar-flickable.png} {A Tab Bar exceeding the available width.} \section1 Tool Bar - \image qtquickcontrols2-toolbar.png + \image {qtquickcontrols2-toolbar.png} {A Tool Bar} \uicontrol {Tool Bar} contains application-wide and context-sensitive actions and controls, such as navigation buttons and search fields. A toolbar is commonly used as a header or footer of an \l ApplicationWindow. Select the toolbar position in the \uicontrol Position field. - \image qtquick-designer-toolbar-properties.png "Tool Bar properties" + \image {qtquick-designer-toolbar-properties.png} {The Tool Bar section in the Properties View.} \uicontrol {Tool Button} is nearly identical to \l Button, but it has a graphical appearance that makes it more suitable for insertion into a diff --git a/doc/qtdesignstudio/src/components/qtquick-images.qdoc b/doc/qtdesignstudio/src/components/qtquick-images.qdoc index 6528388f1ae..151ef30bfed 100644 --- a/doc/qtdesignstudio/src/components/qtquick-images.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-images.qdoc @@ -204,12 +204,12 @@ the ISO icon in the \l Navigator or \l {2D} view, and then select \uicontrol {Choose Icon} in the context menu. - \image studio-iso-icon.png + \image {studio-iso-icon.png} {An Iso Icon selected in the 2D view.} You can use the \l{Picking colors}{color picker} in \l Properties to set the value of \uicontrol {Icon color}. - \image iso-icon-browser.png + \image {iso-icon-browser.png} {The Iso Icon browser window.} \section1 Summary of the image components diff --git a/doc/qtdesignstudio/src/components/qtquick-shapes.qdoc b/doc/qtdesignstudio/src/components/qtquick-shapes.qdoc index 310615b0df9..ac386724832 100644 --- a/doc/qtdesignstudio/src/components/qtquick-shapes.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-shapes.qdoc @@ -199,7 +199,7 @@ fields in the \uicontrol Opacity section are used to hide and show either the front or back side of the item at a time. - \image studio-flipable.png + \image {studio-flipable.png} {A Flipable in the 2D, Navigator, and Properties view.} The \uicontrol {Flip angle} property is used to animate the angle of the component to produce the flipping effect. The value of the diff --git a/doc/qtdesignstudio/src/developers/studio-accessing-output-issues-and-warnings.qdoc b/doc/qtdesignstudio/src/developers/studio-accessing-output-issues-and-warnings.qdoc index 7bcb6588abb..7f26ce04664 100644 --- a/doc/qtdesignstudio/src/developers/studio-accessing-output-issues-and-warnings.qdoc +++ b/doc/qtdesignstudio/src/developers/studio-accessing-output-issues-and-warnings.qdoc @@ -8,7 +8,7 @@ \title Accessing output, issue, and warning messages - \image studio-output-view.webp Qt Design Studio Output view + \image {studio-output-view.webp} {The Qt Design Studio Output view.} \QDS projects generate output information that represent the executed processes. It also shows you the issues that stop a project from @@ -41,10 +41,10 @@ \li Message example \row \li Issue notification - \li \image studio-issue-message.webp + \li \image {studio-issue-message.webp} {Example issue notification in the Output view.} \row \li Warning notification - \li \image studio-warning-message.webp + \li \image {studio-warning-message.webp} {Example warning notification in the Output view.} \endtable diff --git a/doc/qtdesignstudio/src/developers/studio-jump-to-the-code.qdoc b/doc/qtdesignstudio/src/developers/studio-jump-to-the-code.qdoc index 7284eee1a1c..d5518ffeed5 100644 --- a/doc/qtdesignstudio/src/developers/studio-jump-to-the-code.qdoc +++ b/doc/qtdesignstudio/src/developers/studio-jump-to-the-code.qdoc @@ -26,7 +26,7 @@ \li Select \uicontrol {Jump to the Code}. \endlist - \image jump-to-the-code-from-navigator-view.webp + \image {jump-to-the-code-from-navigator-view.webp} {Selecting Jump to the Code from the context menu in the Navigator view.} \section1 Jump to the Code from the 2D view @@ -35,7 +35,7 @@ \li Select \uicontrol {Jump to the Code}. \endlist - \image jump-to-the-code-from-2D-view.webp + \image {jump-to-the-code-from-2D-view.webp} {Selecting Jump to the Code from the context menu in the 2D view.} \note Alternatively, you can select the component in the \uicontrol {Navigator} view or in the \uicontrol {2D} view and select \key {F4}. That takes you to the code @@ -50,7 +50,7 @@ \li Select \uicontrol {Jump to the Code}. \endlist - \image jump-to-the-code-from-state-view.webp + \image {jump-to-the-code-from-state-view.webp} {Selecting Jump to the Code from the context menu in the States view.} \section1 Jump to the Code from the Connections view @@ -60,6 +60,6 @@ to jump to the code segment related to the connection. \endlist - \image jump-to-the-code-from-connections-view.webp + \image {jump-to-the-code-from-connections-view.webp} {Selecting Jump to the Code from the context menu in the Connections view.} */ diff --git a/doc/qtdesignstudio/src/effects-concept.qdoc b/doc/qtdesignstudio/src/effects-concept.qdoc index a79198edf25..849b5484d32 100644 --- a/doc/qtdesignstudio/src/effects-concept.qdoc +++ b/doc/qtdesignstudio/src/effects-concept.qdoc @@ -19,7 +19,7 @@ designed for both experienced developers and beginners, simplifying the process of developing visual effects without requiring extensive knowledge of shader coding. -\image northern-lights-effect.webp +\image {northern-lights-effect.webp} {A northern lights effect in Effect Composer.} Key features of the \QDS Effect Composer: diff --git a/doc/qtdesignstudio/src/mcus/qtdesignstudio-creating-projects-for-mcus.qdoc b/doc/qtdesignstudio/src/mcus/qtdesignstudio-creating-projects-for-mcus.qdoc index ea8912f12dd..247a456f27b 100644 --- a/doc/qtdesignstudio/src/mcus/qtdesignstudio-creating-projects-for-mcus.qdoc +++ b/doc/qtdesignstudio/src/mcus/qtdesignstudio-creating-projects-for-mcus.qdoc @@ -12,7 +12,7 @@ project. When you create a project with the wizard, all the necessary files are created, you can adjust the project settings, and save custom presets. - \image studio-preset-for-mcus.png + \image studio-preset-for-mcus.png {The Qt for MCU preset on the Qt Design Studio Welcome page.} Using the \uicontrol {\QMCU} preset creates an application that uses a subset of the default components that you can deploy, run, and debug on MCU boards. diff --git a/doc/qtdesignstudio/src/mcus/qtdesignstudio-developing-applications-for-mcus.qdoc b/doc/qtdesignstudio/src/mcus/qtdesignstudio-developing-applications-for-mcus.qdoc index 00f8b6f9ae2..9d8291f34af 100644 --- a/doc/qtdesignstudio/src/mcus/qtdesignstudio-developing-applications-for-mcus.qdoc +++ b/doc/qtdesignstudio/src/mcus/qtdesignstudio-developing-applications-for-mcus.qdoc @@ -18,7 +18,7 @@ mode to modify UI files (.ui.qml). For more information, see \l {Implementing applications}. - \image qds-mcu-target-deployment.png + \image {qds-mcu-target-deployment.png} {The workflow of using Qt Design Studio and Qt for MCUs to create an application for an MCU target device.} With Qt Creator, you can test, preview, and fine-tune your designs directly on the desktop or on an actual MCU target device. As a developer you can use diff --git a/doc/qtdesignstudio/src/overviews/qt-design-viewer-navigation.qdoc b/doc/qtdesignstudio/src/overviews/qt-design-viewer-navigation.qdoc index 61a4c378e4a..2f945b58dae 100644 --- a/doc/qtdesignstudio/src/overviews/qt-design-viewer-navigation.qdoc +++ b/doc/qtdesignstudio/src/overviews/qt-design-viewer-navigation.qdoc @@ -68,7 +68,7 @@ \endlist - \image web-navigation-components.png + \image {web-navigation-components.png} {The structure of the web application in the Navigator view.} \section1 Creating the pages @@ -88,7 +88,7 @@ \li Set \uicontrol {Root Item} to \e Rectangle. \endlist - \image web-navigation-new-file.png + \image {web-navigation-new-file.png} {The New File dialog.} When you have created the new page, select \e rectangle in \uicontrol Navigator, and in the \uicontrol Properties view: @@ -114,7 +114,7 @@ \li Top, 100 \li Left, 50 \endlist - \image web-navigation-page-margins.png + \image {web-navigation-page-margins.png} {The Anchor and Margin properties for the web application header.} \endlist Now, with the first page done, create two more pages in the same way. For these @@ -124,13 +124,13 @@ You can change the file that you are working on from the drop-down menu in the toolbar. Now, select \e Screen01.ui.qml from this menu to go back to your main page. -\image web-navigation-change-file.png +\image {web-navigation-change-file.png} {Changing the file in top toolbar.} You can see the pages you created under \uicontrol {My Components} in the \uicontrol Components view. To edit a component, right-click it in \uicontrol Components and select \uicontrol {Edit Component} -\image web-navigation-page-components.png +\image {web-navigation-page-components.png} {The web app pages in the Components view.} \section1 Organizing the pages @@ -139,7 +139,7 @@ To organize the pages vertically: \list 1 \li From \uicontrol Components, drag each of the pages to \e columnLayout in \uicontrol Navigator. - \image web-navigation-components-2.png + \image {web-navigation-components-2.png} {} \li Select \e columnLayout in Navigator and in \uicontrol Properties: \list \li Next to \uicontrol Size > \uicontrol W and \uicontrol Size > @@ -189,7 +189,7 @@ main rectangle so that it adapts to the window size: \imageactioniconbinding next to \uicontrol Width and select \uicontrol {Set Binding}. \li Enter \c {Window.width} - \image web-navigation-size-binding.png + \image {web-navigation-size-binding.png} {Window.width set in Binding Editor.} \li Repeat step 2 and 3 for \uicontrol Height and set the value to \c {Window.height}. \endlist @@ -226,7 +226,7 @@ vertically to the correct place: \li Select \imageactioniconbinding next to \uicontrol Width and select \uicontrol {Set Binding}. \li Enter \c {parent.width}. - \image web-navigation-size-binding-2.png + \image {web-navigation-size-binding-2.png} {parent.width set in Binding Editor.} \li In \uicontrol Navigator: \list 1 \li Select \e Button and on the \uicontrol Button tab in \uicontrol Properties, diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-overview.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-overview.qdoc index f93808d2619..b0dcc5f8e37 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-overview.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-overview.qdoc @@ -13,7 +13,7 @@ You can use \QBF to export designs from Figma to a \e {.qtbridge} archive that you can \l{Importing 2D Assets}{import} to projects in \QDS. - \image studio-figma-export.png + \image {studio-figma-export.png} {Qt Bridge for Figma open in Figma.} The following topics describe setting up and using \QBF: diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc index edcdeed411a..b58151a5e0e 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc @@ -226,7 +226,7 @@ \section2 Settings - \image qt-figma-bridge-settings.png + \image {qt-figma-bridge-settings.png} {The Qt Bridge for Figma settings window in Figma.} You can export assets in the selected format (JPG, PNG, or SVG). diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-overview.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-overview.qdoc index 80c41467290..fe198b067f3 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-overview.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-overview.qdoc @@ -13,7 +13,7 @@ You can use \QBPS to export designs from Adobe Photoshop to \e {.metadata} format that you can \l{Importing 2D Assets}{import} to projects in \QDS. - \image studio-ps-export.png + \image {studio-ps-export.png} {Qt Bridge for Photoshop open in Adobe Photoshop.} The following topics describe setting up and using \QBPS: diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc index 489dbabeeff..0e7a4443f85 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc @@ -81,7 +81,7 @@ enter a password in the \uicontrol Password field. \li To test that the connection is working properly, start \QBPS and select the settings icon in the top right corner. - \image qt-bridge-settings.png + \image {qt-bridge-settings.png} {The Qt Bridge for Photoshop settings window in Adobe Photoshop.} \li In the \uicontrol Password field, enter the password you entered in Adobe Photoshop and select \uicontrol {Connect}. \li In the \uicontrol {Export Path} group, select the folder button diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc index f6d78347464..7c68cea1377 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc @@ -133,7 +133,7 @@ \l{Property Aliases}{property aliases} to fetch the values from other properties. - \image qt-bridge.png + \image {qt-bridge.png} {The Qt Bridge for Photoshop default home screen.} \section2 Specifying settings for exporting assets @@ -238,7 +238,7 @@ In the \uicontrol {ID Suffix} field, specify an ID suffix that will be appended to all auto generated IDs. - \image qt-bridge-qml-id-settings.png + \image {qt-bridge-qml-id-settings.png} {The ID Prefix field highlighted in the settings.} \section1 Cloning documents @@ -246,7 +246,7 @@ allows the user to filter out certain kind of layers and groups. In the \QBPS \uicontrol Settings dialog, select \uicontrol {Clone} to start cloning the document. - \image qt-bridge-clone.png + \image {qt-bridge-clone.png} {The Clone button highlighted in the Clone document settings.} \section2 Clone options The following exclusion options can be selected to exclude certain kind of layers and @@ -273,7 +273,7 @@ \note The sanitization is done in memory and the document must be saved to keep the sanitized state. - \image qt-bridge-sanitize.png + \image {qt-bridge-sanitize.png} {The Sanitize button highlighted in the settings.} \section1 Extending \QBPS You can change the default behavior of \QBPS with the help of a JSX script. One can write @@ -297,11 +297,11 @@ PSD layer instance. \endlist - \note Please refer to \l {https://www.adobe.com/devnet/photoshop/scripting.html} + \note See the \l {https://www.adobe.com/devnet/photoshop/scripting.html} {Adobe Photoshop CC Javascript} scripting guide to understand the object model and \e Document and \e Layer instances. - \image qt-bridge-override.png + \image {qt-bridge-override.png} {The Script Path field highlighted in the settings.} In the \QBPS \uicontrol Settings dialog, select \uicontrol {Override JSX Script} to set the override JSX script. @@ -317,14 +317,14 @@ Select the \uicontrol Import button to launch the \uicontrol Import panel. Alternatively, \QB import can be launched from \uicontrol Window > \uicontrol Extensions. - \image qt-bridge-import.png + \image {qt-bridge-import.png} {The Qt Bridge import dialog.} Create a new PSD document and launch the \uicontrol Import dialog. Open the metadata file to import and select \uicontrol Import. \note The import process removes all the existing layers in the selected PSD document. - \image qt-bridge-import-warning.png + \image {qt-bridge-import-warning.png} {An import warning in the Qt Bridge import dialog.} The following guidelines are followed to generate the Photoshop document: \list diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-overview.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-overview.qdoc index 12156d6733b..118bc1f5042 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-overview.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-overview.qdoc @@ -13,7 +13,7 @@ You can use \QBSK to export designs from Sketch to \e {.metadata} format that you can \l{Importing 2D Assets}{import} to projects in \QDS. - \image studio-sketch-export.png + \image {studio-sketch-export.png} {Qt Bridge for Sketch open in Sketch.} The following topics describe setting up and using \QBSK: diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-using.qdoc index d052bf3138c..69e815f8f64 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-using.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-using.qdoc @@ -160,7 +160,7 @@ component in \QDS. Or you could export a button as a Qt Quick Controls \l Button component. - \image qt-sketch-bridge.png + \image {qt-sketch-bridge.png} {Qt Bridge for Sketch open with default settings.} \section2 Specifying settings for exporting assets @@ -253,7 +253,7 @@ You can export assets into JPG, PNG, or SVG format. To specify export path and asset format, select \uicontrol Settings. - \image qt-sketch-bridge-settings.png + \image {qt-sketch-bridge-settings.png} {Qt Bridge for Sketch export settings with export path and asset format specified.} \QBSK exports assets to a .qtbridge archive named after your Sketch file. By default, the directory is located inside the parent directory @@ -303,5 +303,5 @@ To export a library, select \uicontrol Export. \QBSK asks you whether you want to export the complete library or to unlink the symbols. - \image qt-sketch-bridge-library.png + \image {qt-sketch-bridge-library.png} {Qt Bridge for Sketch Export Library dialog.} */ diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-overview.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-overview.qdoc index 13442251676..edf28dca206 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-overview.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-overview.qdoc @@ -16,7 +16,7 @@ You can use \QBXD to export designs from Adobe XD to \e {.qtbridge} format that you can \l{Importing 2D Assets}{import} to projects in \QDS. - \image qt-bridge-xd.png + \image {qt-bridge-xd.png} {The Qt Bridge for Adobe XD open in Adobe XD.} The following topics describe setting up and using \QBXD: diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-setup.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-setup.qdoc index a20bfddd969..e9087911f3b 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-setup.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-setup.qdoc @@ -29,7 +29,7 @@ \note Since the plugin is not distributed through Adobe's marketplace, during the installation Adobe XD might warn about the third-party developer. - \image qt-bridge-xd-warn.png + \image {qt-bridge-xd-warn.png} {The Install Qt Bridge plugin warning dialog.} You can launch the plugin from \uicontrol Plugins > \uicontrol {\QB}. */ diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc index 0bc76b1eca5..647beea35b0 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc @@ -68,7 +68,7 @@ exported. The \uicontrol {Home} panel displays and allows layer annotation for export. - \image qt-bridge-xd-home.png + \image {qt-bridge-xd-home.png} {The Qt Bridge for Adobe XD home panel.} \list 1 \li In the \uicontrol ID field, enter a unique and descriptive name. @@ -180,8 +180,8 @@ \list 1 \li Select \uicontrol Settings. - \image qt-bridge-xd-menu.png - \image qt-bridge-xd-settings.png + \image {qt-bridge-xd-menu.png} {Settings selected in the file menu.} + \image {qt-bridge-xd-settings.png} {The Qt Bridge for Adobe XD Settings panel.} \li You can now edit the following settings: \list diff --git a/doc/qtdesignstudio/src/qtdesignstudio-exporting-and-importing.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-exporting-and-importing.qdoc index bc5ccdc12ab..55d4708fc72 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-exporting-and-importing.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-exporting-and-importing.qdoc @@ -19,7 +19,7 @@ The following image describes the workflow in a basic way using \QBPS and \QDS: - \image studio-workflow.png + \image {studio-workflow.png} {The complete designer-developer workflow from design tool to a finished application.} The workflow consists of the following steps: diff --git a/doc/qtdesignstudio/src/qtdesignstudio-qt-runtime-version.qdocinc b/doc/qtdesignstudio/src/qtdesignstudio-qt-runtime-version.qdocinc index fb74f9180db..c92a1545bd4 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-qt-runtime-version.qdocinc +++ b/doc/qtdesignstudio/src/qtdesignstudio-qt-runtime-version.qdocinc @@ -5,6 +5,6 @@ \QDS runs projects using a specific version of Qt. In \QDS, find the Qt runtime version in the bottom toolbar. - \image studio-qt-development-kit.webp + \image {studio-qt-development-kit.webp} {The kit selector dropdown menu in the bottom toolbar.} //! [qt-runtime-version] */ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-using-effect-maker-effects.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-using-effect-maker-effects.qdoc index 42588f7d2b4..0a97a5e4dc4 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-using-effect-maker-effects.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-using-effect-maker-effects.qdoc @@ -23,11 +23,11 @@ \li Right-click in the \uicontrol Assets view and select \uicontrol {New Effect}. \QDS creates an effect file and opens it in \QQEM. - \image qt-quick-effect-maker.webp + \image {qt-quick-effect-maker.webp} {The Qt Effect Maker default view.} \li Edit the effect. \li In \QQEM, go to \uicontrol File > \uicontrol Save. \li With the default settings, select \uicontrol OK. - \image effect-maker-export.png + \image {effect-maker-export.png} {Qt Effect Maker export effect dialog.} \endlist Now, you can close \QQEM and return to \QDS and apply the @@ -39,6 +39,6 @@ from the \uicontrol Assets view to the component in the \uicontrol 2D or \uicontrol Navigator view. - \image apply-effect-maker-effect.webp + \image {apply-effect-maker-effect.webp} {Qt Design Studio with a Qt Effect Maker effect applied.} */ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc index f40b0633e04..bd598bc4399 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc @@ -137,7 +137,7 @@ \li In \uicontrol Navigator, select the camera. \li In \uicontrol Properties > \uicontrol {Look-at-Node}, select the object that the camera should look at. - \image camera-look-at-node.webp + \image {camera-look-at-node.webp} {Selecting the Look-at-Node object in the Camera sections in the Properties view.} \endlist When you set a camera to look at an object, the camera automatically rotates to diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc index 9b365110a77..b26d9c962c4 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -186,7 +186,7 @@ In the 3D view, you can show a small window displaying the camera view. - \image 3d-view-camera-view.webp + \image {3d-view-camera-view.webp} {The Camera view in the 3D view.} To toggle this view, select \imagevisibilityon diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc index cafa97421a5..b98be425d0b 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc @@ -23,7 +23,7 @@ For more information about exporting 3D graphics, see \l{Exporting 3D assets}. - \image studio-import-3d.webp + \image {studio-import-3d.webp} {The Asset Import dialog.} \section1 Importing a 3D asset diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc index 8b4f76e90f1..56191e5b602 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc @@ -249,7 +249,7 @@ \li Select \uicontrol Bake. \endlist - \image bake-lights-dialog.png + \image {bake-lights-dialog.png} {The Lights Baking Setup dialog.} \section2 Manually baking lightmaps for a 3D model @@ -261,7 +261,7 @@ \list 1 \li From \uicontrol Components, drag a \uicontrol {Baked Lightmap} component to the 3D model in the \uicontrol Navigator view. - \image baked-lightmaps-navigator.png + \image {baked-lightmaps-navigator.png} {The Baked Lightmap component in the Navigator view.} \li In the \uicontrol Navigator view, select \e bakedLightmap, and in the \uicontrol Properties view: \list @@ -289,15 +289,15 @@ \list 1 \li In the \uicontrol Navigator view, right-click the subcomponent and select \uicontrol {Edit Component}. - \image baked-lightmaps-edit-component.png + \image {baked-lightmaps-edit-component.png} {Selecting Edit Component from the context menu in the Navigator view.} \li In the \uicontrol Navigator view, select the root component. \li In the \uicontrol Properties view, select \imageplus in the \uicontrol {Local Custom Properties} section. \li Add a new property, set \uicontrol Type to alias. - \image baked-lightmaps-add-property.png + \image {baked-lightmaps-add-property.png} {The Add New Property dialog.} \li For the property, set the value to the ID of the 3D model that you want to bake lightmaps for. - \image baked-lightmaps-property-value.png + \image {baked-lightmaps-property-value.png} {The custom property set to sphere in the Local Custom Tab in the Properties view.} \li In the \uicontrol Navigator view, select the 3D model and in the \uicontrol Properties view: \list @@ -306,10 +306,10 @@ \endlist \li Save your changes (\key {Ctrl+S}) and return to the main project file. To do this, select the bread crumb in the top toolbar. - \image baked-lightmaps-exit-component.png + \image {baked-lightmaps-exit-component.png} {Selecting the main project file bread crumb in the top toolbar.} \li From the \uicontrol Components view, drag a \uicontrol {Baked Lightmap} component to the subcomponent in the \uicontrol Navigator view. - \image baked-lightmaps-navigator-blm.png + \image {baked-lightmaps-navigator-blm.png} {The Baked Lightmap component in the Navigator view.} \li In the \uicontrol Navigator view, select the subcomponent and go to the \uicontrol Code view. \li In the \uicontrol Code view, you need to set the properties for the model inside the sub diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc index f9034f4a227..7d33d87540e 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc @@ -67,10 +67,10 @@ \li From \uicontrol {Components}, drag a \uicontrol Loader3D component to \e scene in the \uicontrol Navigator or \uicontrol{3D} view. \li In \uicontrol {Navigator}, select \e{loader3D}. - \image loader3d-navigator.png + \image {loader3d-navigator.png} {The loader3D component in the Navigator view.} \li In \uicontrol {Properties}, select \uicontrol{Source} and select a QML file. - \image loader3d-select-source.png + \image {loader3d-select-source.png} {Setting the Loader3D Source setting in the Properties view.} \endlist \section1 Setting Loader3D to load a Component3D component @@ -85,12 +85,12 @@ \li In \uicontrol {Navigator}, select the filter icon and clear \uicontrol {Show Only Visible Components}. This makes the \uicontrol Component3D component visible in \uicontrol Navigator. - \image navigator-show-all-loader.png + \image {navigator-show-all-loader.png} {Toggling component visibility in the Navigator view.} \li In \uicontrol {Navigator}, select \e{loader3D}. \li In \uicontrol {Properties}, select \uicontrol{Source Component} and select \e {component3D}. - \image loader3d-select-source-component.png + \image {loader3d-select-source-component.png} {Selecting Source Component in the Properties view.} \endlist \section1 Setting the Visibility of loading components @@ -101,7 +101,7 @@ \list 1 \li In \uicontrol Properties > \uicontrol Loader3D, select the \uicontrol Asynchronous check box. - \image loader3d-visibility.png + \image {loader3d-visibility.png} {The Asynchronous setting turned on in the Properties view.} \li In \uicontrol {Visibility}, select \imageactionicon to open the actions menu, and then select \uicontrol {Set Binding}. diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-particles.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-particles.qdoc index 14cc442158e..6834b5005b2 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-particles.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-particles.qdoc @@ -311,7 +311,7 @@ \uicontrol Navigator. You can also drag it to the \uicontrol{3D} view. \endlist - \image studio-3d-particles-sprite-template.png + \image {studio-3d-particles-sprite-template.png} {The particle system template components in the Component view.} \section1 Performance considerations @@ -536,7 +536,7 @@ Specify properties for line particles in \uicontrol Properties > \uicontrol {Line Particle}. - \image studio-3d-properties-line-particle.png + \image {studio-3d-properties-line-particle.png} {The Line Particle properties in the Properties view.} \uicontrol {Segments} defines the number of segments in each line. @@ -845,7 +845,7 @@ Specify properties for emit bursts in \uicontrol Properties > \uicontrol {Dynamic Burst}. - \image studio-3d-properties-particle-dynamic-burst.png + \image {studio-3d-properties-particle-dynamic-burst.png} {The Dynamic Burst properties in the Properties view.} \uicontrol {Trigger Mode} defines when the burst is triggered: @@ -1022,7 +1022,7 @@ Specify settings for \uicontrol Repeller component instances in \uicontrol Properties > \uicontrol {Particle Repeller}. - \image studio-3d-properties-particle-repeller.png + \image {studio-3d-properties-particle-repeller.png} {The Repeller properties in the Properties view.} \uicontrol {Outer Radius} defines the outer radius of the repeller. The particle is not affected until it enters this radius and the repel @@ -1038,7 +1038,7 @@ \uicontrol {Scale Affector} scales particles based on their lifetime and other parameters. - \image studio-3d-properties-particle-scale-affector.png + \image {studio-3d-properties-particle-scale-affector.png} {The Particle Scale Affector properties in the Properties view.} \uicontrol {Minimum Size} defines the minimum size that the affector can scale particles to. diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-repeater-3d.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-repeater-3d.qdoc index ec3ed257926..87632a6e703 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-repeater-3d.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-repeater-3d.qdoc @@ -74,7 +74,7 @@ \e scene in \uicontrol Navigator. \li Select \e repeater3D in \uicontrol Navigator and in \uicontrol Properties, set \uicontrol Model to 4. - \image repeater3d-model-property.png + \image {repeater3d-model-property.png} {The Repeater Model property set to 4 in the Properties view.} \endlist Now, you have set up the \uicontrol Repeater3D component to use a numeric model that draws four instances of the same item. Next, you need to add the @@ -90,11 +90,11 @@ \li Select \uicontrol {Set binding} to open \uicontrol {Binding Editor}. \li In the binding editor, enter \c{index * 150}. This sets the X location to increase by 150 for each of the cube instances. - \image repeater3d-index-binding.png + \image {repeater3d-index-binding.png} {index * 150 set in Bindings Editor.} \li Select \uicontrol OK and go to the \uicontrol{3D} view to see the result. \endlist - \image repeater3d-numeric-model.webp + \image {repeater3d-numeric-model.webp} {Four cubes rendered with the Repeater component in the 3D view.} \section1 Adding a Repeater3D component with a List Model @@ -172,7 +172,7 @@ \list 1 \li From \uicontrol Components, drag a \uicontrol Sphere to \e _3DRepeater in \uicontrol Navigator. - \image repeater3d-listmodel-navigator.png + \image {repeater3d-listmodel-navigator.png} {The Sphere component in the Navigator view.} \li Select \e sphere in \uicontrol Navigator and in the \uicontrol Properties view, select \imageactionicon next to \uicontrol Scale > \uicontrol X. @@ -180,7 +180,7 @@ \li In the binding editor, enter \c{radius}. This sets the X scale to the radius value defined in the list model for each of the sphere instances. - \image repeater3d-radius-binding.png + \image {repeater3d-radius-binding.png} {radius set in Binding Editor.} \li Select \uicontrol OK. \li Repeat steps 2 to 5 for \uicontrol Scale > \uicontrol Y and \uicontrol Scale > \uicontrol Z. @@ -196,7 +196,7 @@ \li Select \uicontrol {Set binding} to open \uicontrol {Binding Editor}. \li In the binding editor, enter \c{index * 1000}. This sets the X location to increase by 1000 for each of the sphere instances. - \image repeater3d-location-binding.png + \image {repeater3d-location-binding.png} {index * 1000 set in Binding Editor.} \li Select \uicontrol OK and go to the \uicontrol{3D} view to see the result. You need to zoom out to see all the spheres. \endlist diff --git a/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc b/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc index e0b24f21772..077b953a67f 100644 --- a/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc +++ b/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc @@ -246,7 +246,7 @@ is under or over the going value. We then use \uicontrol {And Operator} components to determine whether the value is below minimum or above maximum. - \image studio-logic-helper-combining-example.gif + \image {studio-logic-helper-combining-example.gif} {An animated example of an app combining several logic helpers.} We use one \uicontrol {String Mapper} component to map the slider value to a \uicontrol Text component that displays the price, as @@ -295,7 +295,7 @@ and sell hints. For this purpose, we create the states and set \c when conditions for them. - \image studio-logic-helper-combining-example.png + \image {studio-logic-helper-combining-example.png} {The different stats of the app in the States view.} First, we create a \e tooLow state and set a \c when condition to apply it when the value of the \uicontrol {Below min} field of diff --git a/doc/qtdesignstudio/src/reference/qtdesignstudio-keyboard-shortcuts.qdoc b/doc/qtdesignstudio/src/reference/qtdesignstudio-keyboard-shortcuts.qdoc index 3d1b1d00821..646876a3bfa 100644 --- a/doc/qtdesignstudio/src/reference/qtdesignstudio-keyboard-shortcuts.qdoc +++ b/doc/qtdesignstudio/src/reference/qtdesignstudio-keyboard-shortcuts.qdoc @@ -14,7 +14,7 @@ To view all \QDS functions in and their keyboard shortcuts, select \preferences > \uicontrol Environment > \uicontrol Keyboard. - \image qtcreator-keyboard-shortcuts.png + \image {qtcreator-keyboard-shortcuts.png} {Keyboard shortcut settings.} The shortcuts that are displayed in red color are associated with several functions. \QDS executes the function that is available in the current diff --git a/doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc index cc7f1e2cdb5..e91adb949fd 100644 --- a/doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc @@ -25,7 +25,7 @@ You can create bindings between components in \uicontrol Bindings. - \image qmldesigner-bindings.webp + \image {qmldesigner-bindings.webp} {The Bindings tab in the Connections view.} \section1 Creating bindings between component properties @@ -35,7 +35,7 @@ \li Place two components in the \uicontrol {2D} view. - \image qmldesigner-components-before-binding.webp + \image {qmldesigner-components-before-binding.webp} {Two components next to each other in the 2D view.} \li Name the first component as \e {viewBox}. \li Name the second component as \e {connectBox}. @@ -46,7 +46,7 @@ (\uicontrol Add) button to add a binding to the currently selected component. - \image qmldesigner-updated-bindings-editor.webp + \image qmldesigner-updated-bindings-editor.webp {The Add Binding dialog.} \li From the pop-up \uicontrol {Bindings editor}, in the \uicontrol From section, select \e {viewBox} as the parent component, then select its \uicontrol {border.color} @@ -58,7 +58,7 @@ instantly getting applied to the \uicontrol {color} of the \e {connectBox} component. - \image qmldesigner-components-after-binding.webp + \image qmldesigner-components-after-binding.webp {Two components next to each other in the 2D view with the property binding applied.} \endlist diff --git a/doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc index fd5e13e23f6..8cf4e901f8f 100644 --- a/doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc @@ -40,9 +40,9 @@ \li Select the \imageplus (\uicontrol Add) button to add a custom property for the currently selected component. - \image add-local-custom-property.png + \image {add-local-custom-property.png} {Selecting the Add button in the Properties view.} \li Set the \uicontrol Name and \uicontrol Type for the property. - \image add-new-property-dialog.png + \image {add-new-property-dialog.png} {Selecting the Type for the property in the Add New Property dialog.} \endlist \section1 Binding a property value @@ -69,14 +69,14 @@ \uicontrol {2D} view or in the \uicontrol {Navigator} view. \li Select \uicontrol {Properties} from the \uicontrol {Connections} view. - \image add-updated-local-custom-property.webp + \image {add-updated-local-custom-property.webp} {The Properties tab in the Connections view.} \li Select the \imageplus (\uicontrol Add) button to add a Custom property. \li From the pop-up \uicontrol {Custom property editor}, select the \uicontrol {Type} of the property you want to include. - \image add-updated-local-custom-property-editor.webp + \image {add-updated-local-custom-property-editor.webp} {The Custom Property Editor dialog.} \li Next, set the \uicontrol{Name} of the property. \li Set a value to the Custom property in the \uicontrol {Value} field. diff --git a/doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc index 683a01e2921..f231a9fcf74 100644 --- a/doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc @@ -45,7 +45,7 @@ put \b {logical conditions} on this \uicontrol Actions to control them according to your needs. - \image qmldesigner-connections-advanced.webp + \image {qmldesigner-connections-advanced.webp} {The Connections tab in the Connections view.} Initiate a new connection for a component: @@ -57,7 +57,7 @@ (\uicontrol Add) button to add a connection. \endlist - \image qmldesigner-connections-editor.webp + \image {qmldesigner-connections-editor.webp} {The Add Connection dialog.} Connect component \uicontrol Signal to \uicontrol Action: @@ -108,7 +108,7 @@ \li Follow the steps described above in Connect component \uicontrol Signal to \uicontrol Action. For a list of \uicontrol Actions and their properties, see \l {Action Properties}. - \image qmldesigner-connections-ConditionalAction-Autometic.webp + \image {qmldesigner-connections-ConditionalAction-Autometic.webp} {The Add Connection dialog with a JavaScript expression.} \li Open the \uicontrol {Manual Code Edit} window from the \uicontrol {Connections} view and write JavaScript expressions with components and logical expressions manually. @@ -118,7 +118,7 @@ level \e {if-else} expression. For nested level \e {if-else} expressions, use the \uicontrol {Manual Code Edit}. - \image qmldesigner-connections-ConditionalAction-Manual.webp + \image {qmldesigner-connections-ConditionalAction-Manual.webp} {A JavaScript code snippet in the Manual Code Edit dialog.} \endlist \section2 Action properties diff --git a/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc b/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc index 8238dc1b467..d5b90450eec 100644 --- a/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc @@ -162,7 +162,7 @@ (\uicontrol Export) button in \uicontrol Navigator to export a component as a property alias with a valid alias reference. - \image qmldesigner-export-item.png + \image {qmldesigner-export-item.png} {Selecting the Export button in the Navigator view.} You can then use the property alias in other components to \l{Working with connections}{create connections} to this component. diff --git a/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc index 84faad338d9..24d1d7a80b3 100644 --- a/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc @@ -44,7 +44,7 @@ \li A property that has been added inside a component. \endtable - \image custom-properties.png + \image {custom-properties.png} {Local Custom Properties and Exposed Custom Properties settings in the Settings view.} \section1 Viewing changes in properties @@ -81,21 +81,21 @@ \table \row - \li \image qmldesigner-boolean-true.png + \li \image {qmldesigner-boolean-true.png} {The Visibility property selected but not highlighted.} \li TRUE \li The component is visible by default. The visibility might be overridden by the visibility set in the base state. \row - \li \image qmldesigner-boolean-true-blue.png + \li \image {qmldesigner-boolean-true-blue.png} {The Visibility property selected and highlighted.} \li TRUE (highlighted) \li The component is explicitly set to visible. \row - \li \image qmldesigner-boolean-false.png + \li \image {qmldesigner-boolean-false.png} {The Visibility property not selected and not highlighted.} \li FALSE \li The component is hidden by default. The visibility might be overridden by the visibility set in the base state. \row - \li \image qmldesigner-boolean-false-blue.png + \li \image {qmldesigner-boolean-false-blue.png} {The Visibility property not selected but highlighted.} \li FALSE (hightlighted) \li The component is explicitly set to hidden. \endtable diff --git a/doc/qtdesignstudio/src/views/qtquick-properties.qdoc b/doc/qtdesignstudio/src/views/qtquick-properties.qdoc index f4ff275ec14..c31ca5d33f3 100644 --- a/doc/qtdesignstudio/src/views/qtquick-properties.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-properties.qdoc @@ -208,7 +208,7 @@ or \uicontrol Vertical in the \uicontrol {Gradient Controls} section of the color picker. - \image qtquick-designer-gradient-stops.gif + \image {qtquick-designer-gradient-stops.gif} {An Animation showing how to add and remove gradient stops.} Calculating gradients can be computationally expensive compared to the use of solid color fills or images. Consider using gradients only for @@ -462,5 +462,5 @@ you can also right-click components to open the inline editors from the context menu. - \image qmldesigner-inline-editing.png + \image qmldesigner-inline-editing.png {Selecting Edit Color from the context menu in the 2D view.} */ diff --git a/doc/qtdesignstudio/src/views/qtquick-states.qdoc b/doc/qtdesignstudio/src/views/qtquick-states.qdoc index a3daed09935..b87789f790a 100644 --- a/doc/qtdesignstudio/src/views/qtquick-states.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-states.qdoc @@ -183,10 +183,10 @@ Here, extended states are not used: - \image no-extended-state.webp + \image {no-extended-state.webp} {Three states in the States view with no extended state.} Here, \e State2 is extended from \e State1: - \image extended-state.webp + \image {extended-state.webp} {Three states in the States view with State2 extended from State1.} */ diff --git a/doc/qtdesignstudio/src/views/qtquick-timeline.qdoc b/doc/qtdesignstudio/src/views/qtquick-timeline.qdoc index 715a822fc51..82843990428 100644 --- a/doc/qtdesignstudio/src/views/qtquick-timeline.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-timeline.qdoc @@ -37,7 +37,7 @@ of the timeline. Negative values are allowed. \li In the \uicontrol {End frame} field, set the last frame of the timeline. - \image timeline-settings-dialog.png + \image {timeline-settings-dialog.png} {The Timeline Settings dialog.} \endlist \li On the \uicontrol {Animation Settings} tab: \list @@ -87,13 +87,13 @@ . This creates another timeline. \li In the table below the \uicontrol {Animation Settings} tab, set the Timeline for the state where you want to use it. - \image timeline-settings-dialog-second.png + \image {timeline-settings-dialog-second.png} {Two timelines in the Timeline Settings dialog.} \endlist To set the keyframe values for the timeline you created, first select the state in \uicontrol {States} and the timeline is available in \uicontrol{Timelines}. - \image timeline-states.webp + \image {timeline-states.webp} {The Timeline and States views.} \section2 Setting keyframe values @@ -114,11 +114,11 @@ \li In the \l Properties view, select \imageactionicon (\uicontrol Actions) > \uicontrol {Insert Keyframe} for the property that you want to animate. - \image timeline-insert-keyframe.png + \image {timeline-insert-keyframe.png} {Selecting Insert Keyframe from the Action drop-down menu in the Properties view.} \li In the \l Timeline view, select the \uicontrol {Per Property Recording} button to start recording property changes. - \image timeline-per-property-recording.webp + \image {timeline-per-property-recording.webp} {Selecting the Per Property Recording button in the Timeline view.} \li Ensure that the playhead is in frame 0 and enter the value of the property in the field next to the property name on the timeline. Select \key Enter to save the value. @@ -155,7 +155,7 @@ next to the \uicontrol {Animation Settings} tab to delete the animation. If you have several animations, delete all. \li In \uicontrol {Expression binding}, enter \c {slider.value}. - \image timeline-settings-property-binding.png + \image {timeline-settings-property-binding.png} {Expression binding set to slider.value in the Timeline Settings dialog.} \endlist \section2 Binding animations to states @@ -172,7 +172,7 @@ the timeline with the animation you want to bind to the state. \li Double-click the value in the \uicontrol Animation field and select the animation you want to bind to the state. - \image timeline-bind-animation-state.png + \image {timeline-bind-animation-state.png} {Selecting an Animation in the Timeline Settings dialog window to bind it to a state.} \endlist \endlist To bind a state to a certain keyframe in an animation without running the diff --git a/doc/qtdesignstudio/src/views/studio-content-library.qdoc b/doc/qtdesignstudio/src/views/studio-content-library.qdoc index 2bbb3d6e691..9d71b3d0677 100644 --- a/doc/qtdesignstudio/src/views/studio-content-library.qdoc +++ b/doc/qtdesignstudio/src/views/studio-content-library.qdoc @@ -26,7 +26,7 @@ Assets added to \uicontrol {User Assets} are always available in \uicontrol {Content Library} regardless of what project you are working on. - \image content-library.webp + \image {content-library.webp} {The Materials tab in the Content Library view.} \section1 Adding a material to your project @@ -86,7 +86,7 @@ \section1 User Assets - \image user-assets.webp + \image {user-assets.webp} {The User Assets tab in the Content Library view.} Add assets to \uicontrol {User Assets} to access them in any project. diff --git a/doc/qtdesignstudio/src/views/studio-qtinsight.qdoc b/doc/qtdesignstudio/src/views/studio-qtinsight.qdoc index ef77d6e3641..65dbbf3f8d2 100644 --- a/doc/qtdesignstudio/src/views/studio-qtinsight.qdoc +++ b/doc/qtdesignstudio/src/views/studio-qtinsight.qdoc @@ -21,7 +21,7 @@ \l{https://www.qt.io/product/insight/onboarding-instructions}{Getting Started with Qt Insight} documentation. - \image qt-insight-view.png + \image {qt-insight-view.png} {The Qt Insight view.} In \QDS, you can do the following with Qt Insight: \list diff --git a/doc/qtdesignstudio/src/views/studio-translations.qdoc b/doc/qtdesignstudio/src/views/studio-translations.qdoc index f4f9310478d..c31faaa56a0 100644 --- a/doc/qtdesignstudio/src/views/studio-translations.qdoc +++ b/doc/qtdesignstudio/src/views/studio-translations.qdoc @@ -106,13 +106,13 @@ \li \uicontrol{Exceeds boundaries} highlights translations where the text is too long to fit in the text object. \endlist - \image translation-tester.png + \image {translation-tester.png} {The Translation Tester dialog with all highlights selected.} \li Select \uicontrol{Run Tests}. \endlist When the test has completed, you can see the test result highlights in the \uicontrol {2D} view. - \image qml-translation-test-result.png + \image {qml-translation-test-result.png} {The Test Results dialog.} If the test finds an error, it is highlighted for all languages. For example, if a translation is missing for Swedish, it is also highlighted From 4dedce4b541bc7543e15736806679cce98563ba7 Mon Sep 17 00:00:00 2001 From: Pranta Dastider Date: Wed, 23 Apr 2025 11:59:28 +0200 Subject: [PATCH 82/82] QmlDesigner: Fix linking the MCU Treadmill example This patch fixes a link the MCU Treadmill example. Fixes: QDS-15235 Change-Id: I0d70b2bad7af0577808d20f9edcd778d1a2f10d3 Reviewed-by: Mats Honkamaa --- doc/qtdesignstudio/examples/doc/treadmilMcu.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/qtdesignstudio/examples/doc/treadmilMcu.qdoc b/doc/qtdesignstudio/examples/doc/treadmilMcu.qdoc index ddb138ede1e..419ad37b0e2 100644 --- a/doc/qtdesignstudio/examples/doc/treadmilMcu.qdoc +++ b/doc/qtdesignstudio/examples/doc/treadmilMcu.qdoc @@ -22,7 +22,7 @@ \section1 Getting the MCU Treadmill design to Figma \list 1 - \li Get the optimized MCU Treadmill for Figma design from \l {https://git.qt.io/public-demos/qtdesign-studio/-/blob/treadmill-revision-revision/examples/TreadmillMcuDemo/figmadesign/McuDemo.fig} {here}. + \li Get the optimized MCU Treadmill for Figma design from \l {https://git.qt.io/public-demos/qtdesign-studio/-/blob/master/examples/TreadmillMcuDemo/figmadesign/McuDemo.fig} {here}. \li Go to \l {https://www.figma.com/}{Figma} and log in. \li Open the downloaded MCU Treadmill design in Figma. \endlist