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:
Brecht Van Lommel 2019-07-03 20:36:49 +02:00
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
3 changed files with 57 additions and 43 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -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;