Fix T65899, T66314, T61808: various issues appending workspaces
This fixes crashes, wrong names and inability to append workspaces in edit mode. We now bypass the append operator so we can easily return a datablock pointer and work in any mode.
This commit is contained in:
parent
466cc3fbe4
commit
0a3e73a91f
Notes:
blender-bot
2023-02-14 06:05:22 +01:00
Referenced by issue #66314, Issues with the add Workspace /+\ menu Referenced by issue #65899, Crash on add workspace via /+\ tab Referenced by issue #61808, Workspace appending is greyed out in Edit Mode
|
@ -331,30 +331,6 @@ static void WORKSPACE_OT_delete(wmOperatorType *ot)
|
|||
ot->exec = workspace_delete_exec;
|
||||
}
|
||||
|
||||
static bool workspace_append_activate_poll(bContext *C)
|
||||
{
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
|
||||
return WM_operator_poll(C, ot);
|
||||
}
|
||||
|
||||
static int workspace_append(bContext *C, const char *directory, const char *idname)
|
||||
{
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
|
||||
PointerRNA opptr;
|
||||
int retval;
|
||||
|
||||
WM_operator_properties_create_ptr(&opptr, ot);
|
||||
RNA_string_set(&opptr, "directory", directory);
|
||||
RNA_string_set(&opptr, "filename", idname);
|
||||
RNA_boolean_set(&opptr, "autoselect", false);
|
||||
|
||||
retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr);
|
||||
|
||||
WM_operator_properties_free(&opptr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int workspace_append_activate_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
@ -367,23 +343,20 @@ static int workspace_append_activate_exec(bContext *C, wmOperator *op)
|
|||
RNA_string_get(op->ptr, "idname", idname);
|
||||
RNA_string_get(op->ptr, "filepath", filepath);
|
||||
|
||||
if (workspace_append(C, filepath, idname) != OPERATOR_CANCELLED) {
|
||||
WorkSpace *appended_workspace = BLI_findstring(
|
||||
&bmain->workspaces, idname, offsetof(ID, name) + 2);
|
||||
BLI_assert(appended_workspace != NULL);
|
||||
WorkSpace *appended_workspace = (WorkSpace *)WM_file_append_datablock(
|
||||
C, filepath, ID_WS, idname);
|
||||
|
||||
if (appended_workspace) {
|
||||
/* Set defaults. */
|
||||
BLO_update_defaults_workspace(appended_workspace, NULL);
|
||||
if (appended_workspace) {
|
||||
/* Set defaults. */
|
||||
BLO_update_defaults_workspace(appended_workspace, NULL);
|
||||
|
||||
/* Reorder to last position. */
|
||||
BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
|
||||
/* Reorder to last position. */
|
||||
BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
|
||||
|
||||
/* Changing workspace changes context. Do delayed! */
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
|
||||
/* Changing workspace changes context. Do delayed! */
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
|
@ -398,7 +371,6 @@ static void WORKSPACE_OT_append_activate(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = workspace_append_activate_exec;
|
||||
ot->poll = workspace_append_activate_poll;
|
||||
|
||||
RNA_def_string(ot->srna,
|
||||
"idname",
|
||||
|
@ -449,20 +421,17 @@ static void workspace_append_button(uiLayout *layout,
|
|||
{
|
||||
const ID *id = (ID *)workspace;
|
||||
PointerRNA opptr;
|
||||
char lib_path[FILE_MAX_LIBEXTRA];
|
||||
const char *filepath = from_main->name;
|
||||
|
||||
if (strlen(filepath) == 0) {
|
||||
filepath = BLO_EMBEDDED_STARTUP_BLEND;
|
||||
}
|
||||
|
||||
BLI_path_join(lib_path, sizeof(lib_path), filepath, BKE_idcode_to_name(GS(id->name)), NULL);
|
||||
|
||||
BLI_assert(STREQ(ot_append->idname, "WORKSPACE_OT_append_activate"));
|
||||
uiItemFullO_ptr(
|
||||
layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_string_set(&opptr, "idname", id->name + 2);
|
||||
RNA_string_set(&opptr, "filepath", lib_path);
|
||||
RNA_string_set(&opptr, "filepath", filepath);
|
||||
}
|
||||
|
||||
static void workspace_add_menu(bContext *C, uiLayout *layout, void *template_v)
|
||||
|
|
|
@ -42,6 +42,7 @@ extern "C" {
|
|||
struct ARegion;
|
||||
struct GHashIterator;
|
||||
struct GPUViewport;
|
||||
struct ID;
|
||||
struct IDProperty;
|
||||
struct ImBuf;
|
||||
struct ImageFormatData;
|
||||
|
@ -178,6 +179,10 @@ void WM_autosave_init(struct wmWindowManager *wm);
|
|||
void WM_recover_last_session(struct bContext *C, struct ReportList *reports);
|
||||
void WM_file_tag_modified(void);
|
||||
|
||||
struct ID *WM_file_append_datablock(struct bContext *C,
|
||||
const char *filepath,
|
||||
const short id_code,
|
||||
const char *id_name);
|
||||
void WM_lib_reload(struct Library *lib, struct bContext *C, struct ReportList *reports);
|
||||
|
||||
/* mouse cursors */
|
||||
|
|
|
@ -618,10 +618,50 @@ void WM_OT_append(wmOperatorType *ot)
|
|||
"Localize all appended data, including those indirectly linked from other libraries");
|
||||
}
|
||||
|
||||
/** \name Reload/relocate libraries.
|
||||
/** \name Append single datablock and return it.
|
||||
*
|
||||
* Used for appending workspace from startup files.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
ID *WM_file_append_datablock(bContext *C,
|
||||
const char *filepath,
|
||||
const short id_code,
|
||||
const char *id_name)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
/* Tag everything so we can make local only the new datablock. */
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
|
||||
|
||||
/* Define working data, with just the one item we want to append. */
|
||||
WMLinkAppendData *lapp_data = wm_link_append_data_new(0);
|
||||
|
||||
wm_link_append_data_library_add(lapp_data, filepath);
|
||||
WMLinkAppendDataItem *item = wm_link_append_data_item_add(lapp_data, id_name, id_code, NULL);
|
||||
BLI_BITMAP_ENABLE(item->libraries, 0);
|
||||
|
||||
/* Link datablock. */
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
wm_link_do(lapp_data, NULL, bmain, scene, view_layer, v3d);
|
||||
|
||||
/* Get linked datablock and free working data. */
|
||||
ID *id = item->new_id;
|
||||
wm_link_append_data_free(lapp_data);
|
||||
|
||||
/* Make datablock local. */
|
||||
BKE_library_make_local(bmain, NULL, NULL, true, false);
|
||||
|
||||
/* Clear pre existing tag. */
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
Library *lib;
|
||||
|
|
Loading…
Reference in New Issue