Blender V4.3
asset_ops.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
9#include "AS_asset_library.hh"
11
12#include "BKE_bpath.hh"
13#include "BKE_context.hh"
14#include "BKE_lib_id.hh"
15#include "BKE_main.hh"
16#include "BKE_preferences.h"
17#include "BKE_report.hh"
18
19#include "BLI_fnmatch.h"
20#include "BLI_path_utils.hh"
21#include "BLI_set.hh"
22
23#include "ED_asset.hh"
24#include "ED_screen.hh"
25/* XXX needs access to the file list, should all be done via the asset system in future. */
26#include "ED_fileselect.hh"
27
28#include "BLT_translation.hh"
29
30#include "RNA_access.hh"
31#include "RNA_define.hh"
32#include "RNA_prototypes.hh"
33
34#include "WM_api.hh"
35
36#include "DNA_space_types.h"
37
38namespace blender::ed::asset {
39/* -------------------------------------------------------------------- */
40
42{
44 PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
45 if (idptr.data) {
46 ids.append(idptr);
47 }
48 return ids;
49}
50
57{
59
60 /* "selected_ids" context member. */
61 CTX_data_selected_ids(C, &ids);
62 if (!ids.is_empty()) {
63 return ids;
64 }
65
66 /* "id" context member. */
68}
69
74struct IDVecStats {
75 bool has_asset = false;
76 bool has_supported_type = false;
77 bool is_single = false;
78};
79
85{
86 IDVecStats stats;
87
88 stats.is_single = id_pointers.size() == 1;
89
90 for (const PointerRNA &ptr : id_pointers) {
92
93 ID *id = static_cast<ID *>(ptr.data);
94 if (id_type_is_supported(id)) {
95 stats.has_supported_type = true;
96 }
97 if (ID_IS_ASSET(id)) {
98 stats.has_asset = true;
99 }
100 }
101
102 return stats;
103}
104
105static const char *asset_operation_unsupported_type_msg(const bool is_single)
106{
107 const char *msg_single =
108 "Data-block does not support asset operations - must be "
110 const char *msg_multiple =
111 "No data-block selected that supports asset operations - select at least "
113 return is_single ? msg_single : msg_multiple;
114}
115
116/* -------------------------------------------------------------------- */
117
119 public:
120 void operator()(const bContext &C, Span<PointerRNA> ids);
121
122 void reportResults(ReportList &reports) const;
123 bool wasSuccessful() const;
124
125 private:
126 struct Stats {
127 int tot_created = 0;
128 int tot_already_asset = 0;
129 ID *last_id = nullptr;
130 };
131
132 Stats stats;
133};
134
136{
137 for (const PointerRNA &ptr : ids) {
139
140 ID *id = static_cast<ID *>(ptr.data);
141 if (id->asset_data) {
142 stats.tot_already_asset++;
143 continue;
144 }
145
146 if (mark_id(id)) {
147 generate_preview(&C, id);
148
149 stats.last_id = id;
150 stats.tot_created++;
151 }
152 }
153}
154
156{
157 return stats.tot_created > 0;
158}
159
161{
162 /* User feedback on failure. */
163 if (!wasSuccessful()) {
164 if (stats.tot_already_asset > 0) {
165 BKE_report(&reports,
166 RPT_ERROR,
167 "Selected data-blocks are already assets (or do not support use as assets)");
168 }
169 else {
170 BKE_report(&reports,
171 RPT_ERROR,
172 "No data-blocks to create assets for found (or do not support use as assets)");
173 }
174 }
175 /* User feedback on success. */
176 else if (stats.tot_created == 1) {
177 /* If only one data-block: Give more useful message by printing asset name. */
178 BKE_reportf(&reports, RPT_INFO, "Data-block '%s' is now an asset", stats.last_id->name + 2);
179 }
180 else {
181 BKE_reportf(&reports, RPT_INFO, "%i data-blocks are now assets", stats.tot_created);
182 }
183}
184
185static int asset_mark_exec(const bContext *C, const wmOperator *op, const Span<PointerRNA> ids)
186{
187 AssetMarkHelper mark_helper;
188 mark_helper(*C, ids);
189 mark_helper.reportResults(*op->reports);
190
191 if (!mark_helper.wasSuccessful()) {
192 return OPERATOR_CANCELLED;
193 }
194
197
198 return OPERATOR_FINISHED;
199}
200
201static bool asset_mark_poll(bContext *C, const Span<PointerRNA> ids)
202{
204
205 if (!ctx_stats.has_supported_type) {
207 return false;
208 }
209
210 return true;
211}
212
214{
215 ot->name = "Mark as Asset";
216 ot->description =
217 "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of "
218 "customizable metadata (like previews, descriptions and tags)";
219 ot->idname = "ASSET_OT_mark";
220
221 ot->exec = [](bContext *C, wmOperator *op) -> int {
223 };
224 ot->poll = [](bContext *C) -> bool {
226 };
227
229}
230
235{
236 ot->name = "Mark as Single Asset";
237 ot->description =
238 "Enable easier reuse of a data-block through the Asset Browser, with the help of "
239 "customizable metadata (like previews, descriptions and tags)";
240 ot->idname = "ASSET_OT_mark_single";
241
242 ot->exec = [](bContext *C, wmOperator *op) -> int {
244 };
245 ot->poll = [](bContext *C) -> bool {
247 };
248
250}
251
252/* -------------------------------------------------------------------- */
253
255 const bool set_fake_user_;
256
257 public:
258 AssetClearHelper(const bool set_fake_user) : set_fake_user_(set_fake_user) {}
259
261
262 void reportResults(const bContext *C, ReportList &reports) const;
263 bool wasSuccessful() const;
264
265 private:
266 struct Stats {
267 int tot_cleared = 0;
268 ID *last_id = nullptr;
269 };
270
271 Stats stats;
272};
273
275{
276 for (const PointerRNA &ptr : ids) {
278
279 ID *id = static_cast<ID *>(ptr.data);
280 if (!id->asset_data) {
281 continue;
282 }
283
284 if (!clear_id(id)) {
285 continue;
286 }
287
288 if (set_fake_user_) {
290 }
291
292 stats.tot_cleared++;
293 stats.last_id = id;
294 }
295}
296
298{
299 if (!wasSuccessful()) {
300 /* Dedicated error message for when there is an active asset detected, but it's not an ID local
301 * to this file. Helps users better understanding what's going on. */
302 if (AssetRepresentationHandle *active_asset = CTX_wm_asset(C); !active_asset->is_local_id()) {
303 BKE_report(&reports,
304 RPT_ERROR,
305 "No asset data-blocks from the current file selected (assets must be stored in "
306 "the current file to be able to edit or clear them)");
307 }
308 else {
309 BKE_report(&reports, RPT_ERROR, "No asset data-blocks selected/focused");
310 }
311 }
312 else if (stats.tot_cleared == 1) {
313 /* If only one data-block: Give more useful message by printing asset name. */
315 &reports, RPT_INFO, "Data-block '%s' is not an asset anymore", stats.last_id->name + 2);
316 }
317 else {
318 BKE_reportf(&reports, RPT_INFO, "%i data-blocks are not assets anymore", stats.tot_cleared);
319 }
320}
321
323{
324 return stats.tot_cleared > 0;
325}
326
327static int asset_clear_exec(const bContext *C, const wmOperator *op, const Span<PointerRNA> ids)
328{
329 const bool set_fake_user = RNA_boolean_get(op->ptr, "set_fake_user");
330 AssetClearHelper clear_helper(set_fake_user);
331 clear_helper(ids);
332 clear_helper.reportResults(C, *op->reports);
333
334 if (!clear_helper.wasSuccessful()) {
335 return OPERATOR_CANCELLED;
336 }
337
340
341 return OPERATOR_FINISHED;
342}
343
345{
347
348 if (!ctx_stats.has_asset) {
349 const char *msg_single = N_("Data-block is not marked as asset");
350 const char *msg_multiple = N_("No data-block selected that is marked as asset");
351 CTX_wm_operator_poll_msg_set(C, ctx_stats.is_single ? msg_single : msg_multiple);
352 return false;
353 }
354 if (!ctx_stats.has_supported_type) {
356 return false;
357 }
358
359 return true;
360}
361
362static std::string asset_clear_get_description(bContext * /*C*/,
363 wmOperatorType * /*ot*/,
365{
366 const bool set_fake_user = RNA_boolean_get(ptr, "set_fake_user");
367 if (!set_fake_user) {
368 return "";
369 }
370 return TIP_(
371 "Delete all asset metadata, turning the selected asset data-blocks back into normal "
372 "data-blocks, and set Fake User to ensure the data-blocks will still be saved");
373}
374
379{
380 ot->name = "Clear Asset";
381 ot->description =
382 "Delete all asset metadata and turn the selected asset data-blocks back into normal "
383 "data-blocks";
385 ot->idname = "ASSET_OT_clear";
386
387 ot->exec = [](bContext *C, wmOperator *op) -> int {
389 };
390 ot->poll = [](bContext *C) -> bool {
392 };
393
395
397 "set_fake_user",
398 false,
399 "Set Fake User",
400 "Ensure the data-block is saved, even when it is no longer marked as asset");
401}
402
404{
405 ot->name = "Clear Single Asset";
406 ot->description =
407 "Delete all asset metadata and turn the asset data-block back into a normal data-block";
409 ot->idname = "ASSET_OT_clear_single";
410
411 ot->exec = [](bContext *C, wmOperator *op) -> int {
413 };
414 ot->poll = [](bContext *C) -> bool {
416 };
417
419
421 "set_fake_user",
422 false,
423 "Set Fake User",
424 "Ensure the data-block is saved, even when it is no longer marked as asset");
425}
426
427/* -------------------------------------------------------------------- */
428
430{
432 return true;
433 }
434
435 /* While not inside an Asset Browser, check if there's a asset list stored for the active asset
436 * library (stored in the workspace, obtained via context). */
438 if (!library) {
439 return false;
440 }
441
443}
444
446{
447 /* Execution mode #1: Inside the Asset Browser. */
449 SpaceFile *sfile = CTX_wm_space_file(C);
452 }
453 else {
454 /* Execution mode #2: Outside the Asset Browser, use the asset list. */
456 list::clear(library, C);
457 }
458
459 return OPERATOR_FINISHED;
460}
461
468{
469 /* identifiers */
470 ot->name = "Refresh Asset Library";
471 ot->description = "Reread assets and asset catalogs from the asset library on disk";
472 ot->idname = "ASSET_OT_library_refresh";
473
474 /* api callbacks */
477}
478
479/* -------------------------------------------------------------------- */
480
482{
483 const SpaceFile *sfile = CTX_wm_space_file(C);
484 if (!sfile) {
485 return false;
486 }
488 if (!asset_library) {
489 return false;
490 }
491 if (catalogs_read_only(*asset_library)) {
492 CTX_wm_operator_poll_msg_set(C, "Asset catalogs cannot be edited in this asset library");
493 return false;
494 }
495 return true;
496}
497
499{
500 SpaceFile *sfile = CTX_wm_space_file(C);
502 char *parent_path = RNA_string_get_alloc(op->ptr, "parent_path", nullptr, 0, nullptr);
503
505 asset_library, DATA_("Catalog"), parent_path);
506
507 if (sfile) {
509 }
510
511 MEM_freeN(parent_path);
512
515
516 return OPERATOR_FINISHED;
517}
518
520{
521 /* identifiers */
522 ot->name = "New Asset Catalog";
523 ot->description = "Create a new catalog to put assets in";
524 ot->idname = "ASSET_OT_catalog_new";
525
526 /* api callbacks */
529
531 "parent_path",
532 nullptr,
533 0,
534 "Parent Path",
535 "Optional path defining the location to put the new catalog under");
536}
537
539{
540 SpaceFile *sfile = CTX_wm_space_file(C);
542 char *catalog_id_str = RNA_string_get_alloc(op->ptr, "catalog_id", nullptr, 0, nullptr);
543 asset_system::CatalogID catalog_id;
544 if (!BLI_uuid_parse_string(&catalog_id, catalog_id_str)) {
545 return OPERATOR_CANCELLED;
546 }
547
548 catalog_remove(asset_library, catalog_id);
549
550 MEM_freeN(catalog_id_str);
551
554
555 return OPERATOR_FINISHED;
556}
557
559{
560 /* identifiers */
561 ot->name = "Delete Asset Catalog";
562 ot->description =
563 "Remove an asset catalog from the asset library (contained assets will not be affected and "
564 "show up as unassigned)";
565 ot->idname = "ASSET_OT_catalog_delete";
566
567 /* api callbacks */
570
571 RNA_def_string(ot->srna, "catalog_id", nullptr, 0, "Catalog ID", "ID of the catalog to delete");
572}
573
575{
576 const SpaceFile *sfile = CTX_wm_space_file(C);
577 if (!sfile || ED_fileselect_is_file_browser(sfile)) {
578 return nullptr;
579 }
580
582 if (asset_lib) {
583 return &asset_lib->catalog_service();
584 }
585
586 return nullptr;
587}
588
590{
592 if (!catalog_service) {
593 return OPERATOR_CANCELLED;
594 }
595
596 catalog_service->undo();
598 return OPERATOR_FINISHED;
599}
600
602{
603 const asset_system::AssetCatalogService *catalog_service = get_catalog_service(C);
604 return catalog_service && catalog_service->is_undo_possbile();
605}
606
608{
609 /* identifiers */
610 ot->name = "Undo Catalog Edits";
611 ot->description = "Undo the last edit to the asset catalogs";
612 ot->idname = "ASSET_OT_catalog_undo";
613
614 /* api callbacks */
617}
618
620{
622 if (!catalog_service) {
623 return OPERATOR_CANCELLED;
624 }
625
626 catalog_service->redo();
628 return OPERATOR_FINISHED;
629}
630
632{
633 const asset_system::AssetCatalogService *catalog_service = get_catalog_service(C);
634 return catalog_service && catalog_service->is_redo_possbile();
635}
636
638{
639 /* identifiers */
640 ot->name = "Redo Catalog Edits";
641 ot->description = "Redo the last undone edit to the asset catalogs";
642 ot->idname = "ASSET_OT_catalog_redo";
643
644 /* api callbacks */
647}
648
650{
652 if (!catalog_service) {
653 return OPERATOR_CANCELLED;
654 }
655
656 catalog_service->undo_push();
657 return OPERATOR_FINISHED;
658}
659
661{
662 return get_catalog_service(C) != nullptr;
663}
664
666{
667 /* identifiers */
668 ot->name = "Store undo snapshot for asset catalog edits";
669 ot->description = "Store the current state of the asset catalogs in the undo buffer";
670 ot->idname = "ASSET_OT_catalog_undo_push";
671
672 /* api callbacks */
675
676 /* Generally artists don't need to find & use this operator, it's meant for scripts only. */
678}
679
680/* -------------------------------------------------------------------- */
681
683{
685 return false;
686 }
687
688 const Main *bmain = CTX_data_main(C);
689 if (!bmain->filepath[0]) {
690 CTX_wm_operator_poll_msg_set(C, "Cannot save asset catalogs before the Blender file is saved");
691 return false;
692 }
693
695 CTX_wm_operator_poll_msg_set(C, "No changes to be saved");
696 return false;
697 }
698
699 return true;
700}
701
703{
704 const SpaceFile *sfile = CTX_wm_space_file(C);
706
708
711
712 return OPERATOR_FINISHED;
713}
714
716{
717 /* identifiers */
718 ot->name = "Save Asset Catalogs";
719 ot->description =
720 "Make any edits to any catalogs permanent by writing the current set up to the asset "
721 "library";
722 ot->idname = "ASSET_OT_catalogs_save";
723
724 /* api callbacks */
727}
728
729/* -------------------------------------------------------------------- */
730
731static bool could_be_asset_bundle(const Main *bmain);
733static bool is_contained_in_selected_asset_library(wmOperator *op, const char *filepath);
734static bool set_filepath_for_asset_lib(const Main *bmain, wmOperator *op);
735static bool has_external_files(Main *bmain, ReportList *reports);
736
738{
739 /* This operator only works when the asset browser is set to Current File. */
740 const SpaceFile *sfile = CTX_wm_space_file(C);
741 if (sfile == nullptr) {
742 return false;
743 }
745 return false;
746 }
747
748 const Main *bmain = CTX_data_main(C);
749 if (!could_be_asset_bundle(bmain)) {
750 return false;
751 }
752
753 /* Check whether this file is already located inside any asset library. */
755 &U, bmain->filepath);
756 if (asset_lib) {
757 return false;
758 }
759
760 return true;
761}
762
763static int asset_bundle_install_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
764{
765 Main *bmain = CTX_data_main(C);
766 if (has_external_files(bmain, op->reports)) {
767 return OPERATOR_CANCELLED;
768 }
769
771
772 /* Make the "Save As" dialog box default to "${ASSET_LIB_ROOT}/${CURRENT_FILE}.blend". */
773 if (!set_filepath_for_asset_lib(bmain, op)) {
774 return OPERATOR_CANCELLED;
775 }
776
778}
779
781{
782 Main *bmain = CTX_data_main(C);
783 if (has_external_files(bmain, op->reports)) {
784 return OPERATOR_CANCELLED;
785 }
786
787 /* Check file path, copied from #wm_file_write(). */
788 char filepath[FILE_MAX];
789 RNA_string_get(op->ptr, "filepath", filepath);
790 const size_t len = strlen(filepath);
791
792 if (len == 0) {
793 BKE_report(op->reports, RPT_ERROR, "Path is empty, cannot save");
794 return OPERATOR_CANCELLED;
795 }
796
797 if (len >= FILE_MAX) {
798 BKE_report(op->reports, RPT_ERROR, "Path too long, cannot save");
799 return OPERATOR_CANCELLED;
800 }
801
802 /* Check that the destination is actually contained in the selected asset library. */
803 if (!is_contained_in_selected_asset_library(op, filepath)) {
804 BKE_reportf(op->reports, RPT_ERROR, "Selected path is outside of the selected asset library");
805 return OPERATOR_CANCELLED;
806 }
807
808 WM_cursor_wait(true);
810 /* Store undo step, such that on a failed save the 'prepare_to_merge_on_write' call can be
811 * un-done. */
812 cat_service->undo_push();
813 cat_service->prepare_to_merge_on_write();
814
815 const int operator_result = WM_operator_name_call(
816 C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, op->ptr, nullptr);
817 WM_cursor_wait(false);
818
819 if (operator_result != OPERATOR_FINISHED) {
820 cat_service->undo();
821 return operator_result;
822 }
823
825 BLI_assert_msg(lib, "If the asset library is not known, how did we get here?");
827 RPT_INFO,
828 R"(Saved "%s" to asset library "%s")",
830 lib->name);
831 return OPERATOR_FINISHED;
832}
833
835 PointerRNA * /*ptr*/,
836 PropertyRNA * /*prop*/,
837 bool *r_free)
838{
840 if (!items) {
841 *r_free = false;
842 return nullptr;
843 }
844
845 *r_free = true;
846 return items;
847}
848
850{
851 /* identifiers */
852 ot->name = "Copy to Asset Library";
853 ot->description =
854 "Copy the current .blend file into an Asset Library. Only works on standalone .blend files "
855 "(i.e. when no other files are referenced)";
856 ot->idname = "ASSET_OT_bundle_install";
857
858 /* api callbacks */
862
863 ot->prop = RNA_def_property(ot->srna, "asset_library_reference", PROP_ENUM, PROP_NONE);
866
870 FILE_SAVE,
874}
875
876/* Cheap check to see if this is an "asset bundle" just by checking main file name.
877 * A proper check will be done in the exec function, to ensure that no external files will be
878 * referenced. */
879static bool could_be_asset_bundle(const Main *bmain)
880{
881 return fnmatch("*_bundle.blend", bmain->filepath, FNM_CASEFOLD) == 0;
882}
883
885{
886 const int enum_value = RNA_enum_get(op->ptr, "asset_library_reference");
889 &U, lib_ref.custom_library_index);
890 return lib;
891}
892
893static bool is_contained_in_selected_asset_library(wmOperator *op, const char *filepath)
894{
896 if (!lib) {
897 return false;
898 }
899 return BLI_path_contains(lib->dirpath, filepath);
900}
901
906static bool set_filepath_for_asset_lib(const Main *bmain, wmOperator *op)
907{
908 /* Find the directory path of the selected asset library. */
910 if (lib == nullptr) {
911 return false;
912 }
913
914 /* Concatenate the filename of the current blend file. */
915 const char *blend_filename = BLI_path_basename(bmain->filepath);
916 if (blend_filename == nullptr || blend_filename[0] == '\0') {
917 return false;
918 }
919
920 char file_path[FILE_MAX];
921 BLI_path_join(file_path, sizeof(file_path), lib->dirpath, blend_filename);
922 RNA_string_set(op->ptr, "filepath", file_path);
923
924 return true;
925}
926
931
933 char * /*path_dst*/,
934 size_t /*path_dst_maxncpy*/,
935 const char *path_src)
936{
937 FileCheckCallbackInfo *callback_info = static_cast<FileCheckCallbackInfo *>(
938 bpath_data->user_data);
939 callback_info->external_files.add(std::string(path_src));
940 return false;
941}
942
950static bool has_external_files(Main *bmain, ReportList *reports)
951{
952 FileCheckCallbackInfo callback_info = {reports, Set<std::string>()};
953
955 BKE_BPATH_FOREACH_PATH_SKIP_PACKED /* Packed files are fine. */
956 | BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE /* Only report multi-files once, it's enough. */
957 | BKE_BPATH_TRAVERSE_SKIP_WEAK_REFERENCES); /* Only care about actually used files. */
958
959 BPathForeachPathData bpath_data = {
960 /*bmain*/ bmain,
961 /*callback_function*/ &external_file_check_callback,
962 /*flag*/ flag,
963 /*user_data*/ &callback_info,
964 /*absolute_base_path*/ nullptr,
965 };
966 BKE_bpath_foreach_path_main(&bpath_data);
967
968 if (callback_info.external_files.is_empty()) {
969 /* No external dependencies. */
970 return false;
971 }
972
973 if (callback_info.external_files.size() == 1) {
974 /* Only one external dependency, report it directly. */
975 BKE_reportf(callback_info.reports,
976 RPT_ERROR,
977 "Unable to copy bundle due to external dependency: \"%s\"",
978 callback_info.external_files.begin()->c_str());
979 return true;
980 }
981
982 /* Multiple external dependencies, report the aggregate and put details on console. */
984 callback_info.reports,
985 RPT_ERROR,
986 "Unable to copy bundle due to %zu external dependencies; more details on the console",
987 size_t(callback_info.external_files.size()));
988 printf("Unable to copy bundle due to %zu external dependencies:\n",
989 size_t(callback_info.external_files.size()));
990 for (const std::string &path : callback_info.external_files) {
991 printf(" \"%s\"\n", path.c_str());
992 }
993 return true;
994}
995
996/* -------------------------------------------------------------------- */
997
1015
1016} // namespace blender::ed::asset
bool AS_asset_library_has_any_unsaved_catalogs()
Main runtime representation of an asset.
eBPathForeachFlag
Definition BKE_bpath.hh:26
@ BKE_BPATH_TRAVERSE_SKIP_WEAK_REFERENCES
Definition BKE_bpath.hh:45
@ BKE_BPATH_FOREACH_PATH_SKIP_PACKED
Definition BKE_bpath.hh:37
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
Definition BKE_bpath.hh:55
void BKE_bpath_foreach_path_main(BPathForeachPathData *bpath_data)
Definition bpath.cc:114
SpaceFile * CTX_wm_space_file(const bContext *C)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
wmWindow * CTX_wm_window(const bContext *C)
const AssetLibraryReference * CTX_wm_asset_library_ref(const bContext *C)
class blender::asset_system::AssetRepresentation * CTX_wm_asset(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
bool CTX_data_selected_ids(const bContext *C, blender::Vector< PointerRNA > *list)
void id_fake_user_set(ID *id)
Definition lib_id.cc:389
struct bUserAssetLibrary * BKE_preferences_asset_library_find_index(const struct UserDef *userdef, int index) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
struct bUserAssetLibrary * BKE_preferences_asset_library_containing_path(const struct UserDef *userdef, const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define FILE_MAX
bool BLI_path_contains(const char *container_path, const char *containee_path) ATTR_NONNULL(1
#define BLI_path_join(...)
bool BLI_uuid_parse_string(bUUID *uuid, const char *buffer) ATTR_NONNULL()
Definition uuid.cc:112
#define TIP_(msgid)
#define DATA_(msgid)
#define ID_IS_ASSET(_id)
Definition DNA_ID.h:690
@ FILE_SORT_DEFAULT
@ FILE_BLENDER
@ FILE_TYPE_BLENDER
@ FILE_TYPE_FOLDER
@ FILE_DEFAULTDISPLAY
struct AssetRepresentationHandle AssetRepresentationHandle
@ OPERATOR_RUNNING_MODAL
#define ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING
void ED_fileselect_activate_asset_catalog(const SpaceFile *sfile, bUUID catalog_id)
Definition filesel.cc:500
bool ED_fileselect_is_file_browser(const SpaceFile *sfile)
Definition filesel.cc:462
bool ED_fileselect_is_local_asset_library(const SpaceFile *sfile)
Definition filesel.cc:408
blender::asset_system::AssetLibrary * ED_fileselect_active_asset_library_get(const SpaceFile *sfile)
Definition filesel.cc:472
void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile)
Definition filesel.cc:1289
bool ED_operator_asset_browsing_active(bContext *C)
@ PROP_ENUM
Definition RNA_types.hh:69
@ PROP_HIDDEN
Definition RNA_types.hh:239
@ PROP_NONE
Definition RNA_types.hh:136
#define C
Definition RandGen.cpp:29
@ WM_FILESEL_FILEPATH
Definition WM_api.hh:936
@ FILE_SAVE
Definition WM_api.hh:946
@ OPTYPE_INTERNAL
Definition WM_types.hh:182
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_ID
Definition WM_types.hh:362
#define ND_SPACE_ASSET_PARAMS
Definition WM_types.hh:491
#define NA_ADDED
Definition WM_types.hh:552
#define NA_EDITED
Definition WM_types.hh:550
#define NC_ASSET
Definition WM_types.hh:371
#define NA_REMOVED
Definition WM_types.hh:553
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:225
#define ND_ASSET_CATALOGS
Definition WM_types.hh:520
#define NC_SPACE
Definition WM_types.hh:359
#define ND_SPACE_FILE_LIST
Definition WM_types.hh:490
unsigned int U
Definition btGjkEpa3.h:78
Iterator begin() const
Definition BLI_set.hh:461
int64_t size() const
Definition BLI_set.hh:564
bool add(const Key &key)
Definition BLI_set.hh:248
bool is_empty() const
Definition BLI_set.hh:572
constexpr int64_t size() const
Definition BLI_span.hh:253
void append(const T &value)
bool is_empty() const
AssetCatalogService & catalog_service() const
void reportResults(const bContext *C, ReportList &reports) const
Definition asset_ops.cc:297
void operator()(Span< PointerRNA > ids)
Definition asset_ops.cc:274
AssetClearHelper(const bool set_fake_user)
Definition asset_ops.cc:258
void operator()(const bContext &C, Span< PointerRNA > ids)
Definition asset_ops.cc:135
void reportResults(ReportList &reports) const
Definition asset_ops.cc:160
#define printf
int len
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void clear(const AssetLibraryReference *library_reference, const bContext *C)
bool storage_has_list_for_library(const AssetLibraryReference *library_reference)
static bool asset_catalogs_save_poll(bContext *C)
Definition asset_ops.cc:682
static bool could_be_asset_bundle(const Main *bmain)
Definition asset_ops.cc:879
void catalog_remove(asset_system::AssetLibrary *library, const asset_system::CatalogID &catalog_id)
bool catalogs_read_only(const asset_system::AssetLibrary &library)
static bool asset_catalog_undo_push_poll(bContext *C)
Definition asset_ops.cc:660
static bool external_file_check_callback(BPathForeachPathData *bpath_data, char *, size_t, const char *path_src)
Definition asset_ops.cc:932
static int asset_catalogs_save_exec(bContext *C, wmOperator *)
Definition asset_ops.cc:702
static void ASSET_OT_clear(wmOperatorType *ot)
Definition asset_ops.cc:378
void catalogs_save_from_main_path(asset_system::AssetLibrary *library, const Main *bmain)
static void ASSET_OT_catalog_redo(wmOperatorType *ot)
Definition asset_ops.cc:637
static int asset_catalog_undo_push_exec(bContext *C, wmOperator *)
Definition asset_ops.cc:649
AssetLibraryReference library_reference_from_enum_value(int value)
static std::string asset_clear_get_description(bContext *, wmOperatorType *, PointerRNA *ptr)
Definition asset_ops.cc:362
static void ASSET_OT_catalog_new(wmOperatorType *ot)
Definition asset_ops.cc:519
static bool asset_catalog_redo_poll(bContext *C)
Definition asset_ops.cc:631
static void ASSET_OT_clear_single(wmOperatorType *ot)
Definition asset_ops.cc:403
static void ASSET_OT_catalog_delete(wmOperatorType *ot)
Definition asset_ops.cc:558
static IDVecStats asset_operation_get_id_vec_stats_from_ids(const Span< PointerRNA > id_pointers)
Definition asset_ops.cc:84
asset_system::AssetCatalog * catalog_add(asset_system::AssetLibrary *library, StringRefNull name, StringRef parent_path=nullptr)
static int asset_mark_exec(const bContext *C, const wmOperator *op, const Span< PointerRNA > ids)
Definition asset_ops.cc:185
static void ASSET_OT_mark_single(wmOperatorType *ot)
Definition asset_ops.cc:234
static bool is_contained_in_selected_asset_library(wmOperator *op, const char *filepath)
Definition asset_ops.cc:893
static Vector< PointerRNA > asset_operation_get_ids_from_context(const bContext *C)
Definition asset_ops.cc:56
static int asset_catalog_undo_exec(bContext *C, wmOperator *)
Definition asset_ops.cc:589
static Vector< PointerRNA > get_single_id_vec_from_context(const bContext *C)
Definition asset_ops.cc:41
static bool asset_clear_poll(bContext *C, const Span< PointerRNA > ids)
Definition asset_ops.cc:344
static bool asset_bundle_install_poll(bContext *C)
Definition asset_ops.cc:737
void operatortypes_asset()
Definition asset_ops.cc:998
static int asset_catalog_new_exec(bContext *C, wmOperator *op)
Definition asset_ops.cc:498
static void ASSET_OT_catalog_undo_push(wmOperatorType *ot)
Definition asset_ops.cc:665
const EnumPropertyItem * library_reference_to_rna_enum_itemf(bool include_generated)
static bool set_filepath_for_asset_lib(const Main *bmain, wmOperator *op)
Definition asset_ops.cc:906
static int asset_clear_exec(const bContext *C, const wmOperator *op, const Span< PointerRNA > ids)
Definition asset_ops.cc:327
void generate_preview(const bContext *C, ID *id)
static void ASSET_OT_bundle_install(wmOperatorType *ot)
Definition asset_ops.cc:849
static const char * asset_operation_unsupported_type_msg(const bool is_single)
Definition asset_ops.cc:105
static bool asset_catalog_undo_poll(bContext *C)
Definition asset_ops.cc:601
static bool asset_mark_poll(bContext *C, const Span< PointerRNA > ids)
Definition asset_ops.cc:201
static void ASSET_OT_mark(wmOperatorType *ot)
Definition asset_ops.cc:213
static int asset_library_refresh_exec(bContext *C, wmOperator *)
Definition asset_ops.cc:445
static int asset_catalog_delete_exec(bContext *C, wmOperator *op)
Definition asset_ops.cc:538
static void ASSET_OT_catalog_undo(wmOperatorType *ot)
Definition asset_ops.cc:607
static int asset_catalog_redo_exec(bContext *C, wmOperator *)
Definition asset_ops.cc:619
static int asset_bundle_install_exec(bContext *C, wmOperator *op)
Definition asset_ops.cc:780
static bool asset_library_refresh_poll(bContext *C)
Definition asset_ops.cc:429
static asset_system::AssetCatalogService * get_catalog_service(bContext *C)
Definition asset_ops.cc:574
static int asset_bundle_install_invoke(bContext *C, wmOperator *op, const wmEvent *)
Definition asset_ops.cc:763
static const bUserAssetLibrary * selected_asset_library(wmOperator *op)
Definition asset_ops.cc:884
static void ASSET_OT_library_refresh(wmOperatorType *ot)
Definition asset_ops.cc:467
bool id_type_is_supported(const ID *id)
Definition asset_type.cc:26
static void ASSET_OT_catalogs_save(wmOperatorType *ot)
Definition asset_ops.cc:715
static bool has_external_files(Main *bmain, ReportList *reports)
Definition asset_ops.cc:950
static const EnumPropertyItem * rna_asset_library_reference_itemf(bContext *, PointerRNA *, PropertyRNA *, bool *r_free)
Definition asset_ops.cc:834
static bool asset_catalog_operator_poll(bContext *C)
Definition asset_ops.cc:481
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
bool RNA_struct_is_ID(const StructRNA *type)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
char filepath[1024]
Definition BKE_main.hh:136
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
Universally Unique Identifier according to RFC4122.
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
std::string(* get_description)(bContext *C, wmOperatorType *ot, PointerRNA *ptr)
Definition WM_types.hh:1074
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
PropertyRNA * prop
Definition WM_types.hh:1092
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct PointerRNA * ptr
#define N_(msgid)
static DynamicLibrary lib
void WM_cursor_wait(bool val)
void WM_event_add_fileselect(bContext *C, wmOperator *op)
void WM_event_add_notifier_ex(wmWindowManager *wm, const wmWindow *win, uint type, void *reference)
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
int WM_operator_name_call(bContext *C, const char *opstring, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
uint8_t flag
Definition wm_window.cc:138