Blender V5.0
editors/asset/intern/asset_catalog.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "AS_asset_library.hh"
10
11#include "AS_asset_catalog.hh"
12
13#include "BKE_main.hh"
14
15#include "BLI_string_utils.hh"
16
17#include "RNA_access.hh"
18
19#include "ED_asset_catalog.hh"
20
21#include "WM_api.hh"
22
23namespace blender::ed::asset {
24
25using namespace blender::asset_system;
26
27bool catalogs_read_only(const AssetLibrary &library)
28{
29 const asset_system::AssetCatalogService &catalog_service = library.catalog_service();
30 return catalog_service.is_read_only();
31}
32
33static std::string catalog_name_ensure_unique(AssetCatalogService &catalog_service,
35 StringRef parent_path)
36{
37 char unique_name[MAX_NAME] = "";
39 [&](const StringRef check_name) {
40 AssetCatalogPath fullpath = AssetCatalogPath(parent_path) / check_name;
41 return catalog_service.find_catalog_by_path(fullpath);
42 },
43 name.c_str(),
44 '.',
46 sizeof(unique_name));
47
48 return unique_name;
49}
50
53 StringRef parent_path)
54{
55 asset_system::AssetCatalogService &catalog_service = library->catalog_service();
56 if (catalog_service.is_read_only()) {
57 return nullptr;
58 }
59
60 std::string unique_name = catalog_name_ensure_unique(catalog_service, name, parent_path);
61 AssetCatalogPath fullpath = AssetCatalogPath(parent_path) / unique_name;
62
63 catalog_service.undo_push();
64 asset_system::AssetCatalog *new_catalog = catalog_service.create_catalog(fullpath);
65 if (!new_catalog) {
66 return nullptr;
67 }
68 catalog_service.tag_has_unsaved_changes(new_catalog);
69
71 return new_catalog;
72}
73
74void catalog_remove(AssetLibrary *library, const CatalogID &catalog_id)
75{
76 asset_system::AssetCatalogService &catalog_service = library->catalog_service();
77 if (catalog_service.is_read_only()) {
78 return;
79 }
80
81 catalog_service.undo_push();
82 catalog_service.tag_has_unsaved_changes(nullptr);
83 catalog_service.prune_catalogs_by_id(catalog_id);
85}
86
88 const CatalogID catalog_id,
89 const StringRefNull new_name)
90{
91 asset_system::AssetCatalogService &catalog_service = library->catalog_service();
92 if (catalog_service.is_read_only()) {
93 return;
94 }
95
96 AssetCatalog *catalog = catalog_service.find_catalog(catalog_id);
97
98 const AssetCatalogPath new_path = catalog->path.parent() / StringRef(new_name);
99 const AssetCatalogPath clean_new_path = new_path.cleanup();
100
101 if (new_path == catalog->path || clean_new_path == catalog->path) {
102 /* Nothing changed, so don't bother renaming for nothing. */
103 return;
104 }
105
106 catalog_service.undo_push();
107 catalog_service.tag_has_unsaved_changes(catalog);
108 catalog_service.update_catalog_path(catalog_id, clean_new_path);
110}
111
113 const CatalogID src_catalog_id,
114 const std::optional<CatalogID> dst_parent_catalog_id)
115{
116 asset_system::AssetCatalogService &catalog_service = library->catalog_service();
117 if (catalog_service.is_read_only()) {
118 return;
119 }
120
121 AssetCatalog *src_catalog = catalog_service.find_catalog(src_catalog_id);
122 if (!src_catalog) {
124 return;
125 }
126 AssetCatalog *dst_catalog = dst_parent_catalog_id ?
127 catalog_service.find_catalog(*dst_parent_catalog_id) :
128 nullptr;
129 if (!dst_catalog && dst_parent_catalog_id) {
131 return;
132 }
133
135 catalog_service, src_catalog->path.name(), dst_catalog ? dst_catalog->path.c_str() : "");
136 /* If a destination catalog was given, construct the path using that. Otherwise, the path is just
137 * the name of the catalog to be moved, which means it ends up at the root level. */
138 const AssetCatalogPath new_path = dst_catalog ? (dst_catalog->path / unique_name) :
140 const AssetCatalogPath clean_new_path = new_path.cleanup();
141
142 if (new_path == src_catalog->path || clean_new_path == src_catalog->path) {
143 /* Nothing changed, so don't bother renaming for nothing. */
144 return;
145 }
146
147 catalog_service.undo_push();
148 catalog_service.tag_has_unsaved_changes(src_catalog);
149 catalog_service.update_catalog_path(src_catalog_id, clean_new_path);
151}
152
154{
155 asset_system::AssetCatalogService &catalog_service = library->catalog_service();
156 if (catalog_service.is_read_only()) {
157 return;
158 }
159
160 /* Since writing to disk also means loading any on-disk changes, it may be a good idea to store
161 * an undo step. */
162 catalog_service.undo_push();
163 catalog_service.write_to_disk(bmain->filepath);
164}
165
167{
168 asset_system::AssetCatalogService &catalog_service = library.catalog_service();
169 if (catalog_service.is_read_only()) {
170 return;
171 }
172
173 char asset_full_path_buffer[1024 + MAX_ID_NAME /*FILE_MAX_LIBEXTRA*/];
174 char *file_path = nullptr;
176 &reference, asset_full_path_buffer, &file_path, nullptr, nullptr);
177 if (!file_path) {
179 return;
180 }
181
182 /* Since writing to disk also means loading any on-disk changes, it may be a good idea to store
183 * an undo step. */
184 catalog_service.undo_push();
185 catalog_service.write_to_disk(file_path);
186}
187
192
197
198} // namespace blender::ed::asset
void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference, char r_path_buffer[1282], char **r_dir, char **r_group, char **r_name)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
#define MAX_ID_NAME
Definition DNA_ID.h:373
#define MAX_NAME
Definition DNA_defs.h:50
#define ND_SPACE_ASSET_PARAMS
Definition WM_types.hh:525
#define NC_SPACE
Definition WM_types.hh:392
AssetCatalog * find_catalog_by_path(const AssetCatalogPath &path) const
AssetCatalog * find_catalog(CatalogID catalog_id) const
bool write_to_disk(const CatalogFilePath &blend_file_path)
AssetCatalog * create_catalog(const AssetCatalogPath &catalog_path)
void update_catalog_path(CatalogID catalog_id, const AssetCatalogPath &new_catalog_path)
void tag_has_unsaved_changes(AssetCatalog *edited_catalog=nullptr)
AssetCatalogService & catalog_service() const
void catalog_remove(asset_system::AssetLibrary *library, const asset_system::CatalogID &catalog_id)
bool catalogs_read_only(const asset_system::AssetLibrary &library)
void catalogs_save_from_main_path(asset_system::AssetLibrary *library, const Main *bmain)
static std::string catalog_name_ensure_unique(AssetCatalogService &catalog_service, StringRefNull name, StringRef parent_path)
asset_system::AssetCatalog * catalog_add(asset_system::AssetLibrary *library, StringRefNull name, StringRef parent_path=nullptr)
void catalog_move(asset_system::AssetLibrary *library, asset_system::CatalogID src_catalog_id, std::optional< asset_system::CatalogID > dst_parent_catalog_id=std::nullopt)
void catalogs_save_from_asset_reference(asset_system::AssetLibrary &library, const AssetWeakReference &reference)
void catalogs_set_save_catalogs_when_file_is_saved(bool should_save)
void catalog_rename(asset_system::AssetLibrary *library, asset_system::CatalogID catalog_id, StringRefNull new_name)
static void unique_name(bNode *node)
const char * name
char filepath[1024]
Definition BKE_main.hh:179
void WM_main_add_notifier(uint type, void *reference)