Add 'reload' function to libraries' RNA API.

This commit is contained in:
Bastien Montagne 2016-07-19 17:49:01 +02:00
parent 6921bb7a4a
commit 5f4a3785c6
4 changed files with 78 additions and 46 deletions

View File

@ -1024,6 +1024,7 @@ static void rna_def_ID(BlenderRNA *brna)
static void rna_def_library(BlenderRNA *brna)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "Library", "ID");
@ -1042,6 +1043,10 @@ static void rna_def_library(BlenderRNA *brna)
prop = RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
RNA_def_property_ui_text(prop, "Packed File", "");
func = RNA_def_function(srna, "reload", "WM_lib_reload");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Reload this library and all its linked datablocks");
}
void RNA_def_ID(BlenderRNA *brna)
{

View File

@ -114,6 +114,8 @@ void WM_autosave_init(struct wmWindowManager *wm);
void WM_recover_last_session(struct bContext *C, struct ReportList *reports);
void WM_file_tag_modified(const struct bContext *C);
void WM_lib_reload(struct Library *lib, struct bContext *C, struct ReportList *reports);
/* mouse cursors */
void WM_cursor_set(struct wmWindow *win, int curs);
void WM_cursor_modal_set(struct wmWindow *win, int curs);

View File

@ -551,8 +551,9 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN
return OPERATOR_CANCELLED;
}
/* Note that IDs listed in lapp_data items *must* have been removed from bmain by caller. */
static void lib_relocate_do(Main *bmain, WMLinkAppendData *lapp_data, ReportList *reports, const bool do_reload)
static void lib_relocate_do(
Main *bmain, Scene *scene,
Library *library, WMLinkAppendData *lapp_data, ReportList *reports, const bool do_reload)
{
ListBase *lbarray[MAX_LIBARRAY];
int lba_idx;
@ -560,6 +561,34 @@ static void lib_relocate_do(Main *bmain, WMLinkAppendData *lapp_data, ReportList
LinkNode *itemlink;
int item_idx;
/* Remove all IDs to be reloaded from Main. */
lba_idx = set_listbasepointers(bmain, lbarray);
while (lba_idx--) {
ID *id = lbarray[lba_idx]->first;
const short idcode = id ? GS(id->name) : 0;
if (!id || !BKE_idcode_is_linkable(idcode)) {
/* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */
continue;
}
for (; id; id = id->next) {
if (id->lib == library) {
WMLinkAppendDataItem *item;
/* We remove it from current Main, and add it to items to link... */
/* Note that non-linkable IDs (like e.g. shapekeys) are also explicitely linked here... */
BLI_remlink(lbarray[lba_idx], id);
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries);
#ifdef PRINT_DEBUG
printf("\tdatablock to seek for: %s\n", id->name);
#endif
}
}
}
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
/* We do not want any instanciation here! */
@ -698,6 +727,43 @@ static void lib_relocate_do(Main *bmain, WMLinkAppendData *lapp_data, ReportList
}
}
}
BKE_main_lib_objects_recalc_all(bmain);
IMB_colormanagement_check_file_config(bmain);
/* important we unset, otherwise these object wont
* link into other scenes from this blend file */
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
/* recreate dependency graph to include new objects */
DAG_scene_relations_rebuild(bmain, scene);
/* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
GPU_materials_free();
}
void WM_lib_reload(Library *lib, bContext *C, ReportList *reports)
{
if (!BLO_has_bfile_extension(lib->filepath)) {
BKE_reportf(reports, RPT_ERROR, "'%s' is not a valid library filepath", lib->filepath);
return;
}
if (!BLI_exists(lib->filepath)) {
BKE_reportf(reports, RPT_ERROR,
"Trying to reload library '%s' from invalid path '%s'", lib->id.name, lib->filepath);
return;
}
WMLinkAppendData *lapp_data = wm_link_append_data_new(0);
wm_link_append_data_library_add(lapp_data, lib->filepath);
lib_relocate_do(CTX_data_main(C), CTX_data_scene(C), lib, lapp_data, reports, true);
wm_link_append_data_free(lapp_data);
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
@ -714,9 +780,6 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
PropertyRNA *prop;
WMLinkAppendData *lapp_data;
ListBase *lbarray[MAX_LIBARRAY];
int lba_idx;
char path[FILE_MAX], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX];
short flag = 0;
@ -803,50 +866,10 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
}
}
lba_idx = set_listbasepointers(bmain, lbarray);
while (lba_idx--) {
ID *id = lbarray[lba_idx]->first;
const short idcode = id ? GS(id->name) : 0;
if (!id || !BKE_idcode_is_linkable(idcode)) {
/* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */
continue;
}
for (; id; id = id->next) {
if (id->lib == lib) {
WMLinkAppendDataItem *item;
/* We remove it from current Main, and add it to items to link... */
/* Note that non-linkable IDs (like e.g. shapekeys) are also explicitely linked here... */
BLI_remlink(lbarray[lba_idx], id);
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries);
#ifdef PRINT_DEBUG
printf("\tdatablock to seek for: %s\n", id->name);
#endif
}
}
}
lib_relocate_do(bmain, lapp_data, op->reports, do_reload);
lib_relocate_do(bmain, scene, lib, lapp_data, op->reports, do_reload);
wm_link_append_data_free(lapp_data);
BKE_main_lib_objects_recalc_all(bmain);
IMB_colormanagement_check_file_config(bmain);
/* important we unset, otherwise these object wont
* link into other scenes from this blend file */
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
/* recreate dependency graph to include new objects */
DAG_scene_relations_rebuild(bmain, scene);
/* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
GPU_materials_free();
/* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */
BLI_strncpy(G.lib, root, FILE_MAX);

View File

@ -308,6 +308,8 @@ void WM_operator_handlers_clear(wmWindowManager *wm, struct wmOperatorType *ot)
void WM_autosave_init(wmWindowManager *wm) RET_NONE
void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner) RET_NONE
void WM_lib_reload(struct Library *lib, struct bContext *C, struct ReportList *reports) RET_NONE
char *WM_clipboard_text_get(bool selection, int *r_len) RET_NULL
char *WM_clipboard_text_get_firstline(bool selection, int *r_len) RET_NULL
void WM_clipboard_text_set(const char *buf, bool selection) RET_NONE