diff --git a/source/blender/editors/space_topbar/space_topbar.cc b/source/blender/editors/space_topbar/space_topbar.cc index 8b83b2488b5..c0eb0b72595 100644 --- a/source/blender/editors/space_topbar/space_topbar.cc +++ b/source/blender/editors/space_topbar/space_topbar.cc @@ -237,6 +237,10 @@ static void undo_history_draw_menu(const bContext *C, Menu *menu) /* Reverse the order so the most recent state is first in the menu. */ int i = undo_step_count_all - 1; + + /* Is this step an undo or a redo? */ + bool is_undo = false; + for (UndoStep *us = static_cast(wm->undo_stack->steps.last); us; us = us->prev, i--) { if (us->skip) { @@ -246,14 +250,23 @@ static void undo_history_draw_menu(const bContext *C, Menu *menu) column = uiLayoutColumn(split, false); } const bool is_active = (us == wm->undo_stack->step_active); - uiLayout *row = uiLayoutRow(column, false); - uiLayoutSetEnabled(row, !is_active); - uiItemIntO(row, + if (is_active) { + if (undo_step_count > 0) { + /* Horizontal line to indicate current position. */ + uiItemS_ex(column, 0.2f); + } + /* Items from now on are undo, before this were redo. */ + is_undo = true; + } + + const int undo_step = MAX2(is_undo ? i - 1 : i, 0); + + uiItemIntO(column, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, us->name), - is_active ? ICON_LAYER_ACTIVE : ICON_NONE, + ICON_NONE, "ED_OT_undo_history", "item", - i); + undo_step); undo_step_count += 1; } } diff --git a/source/blender/editors/undo/ed_undo.cc b/source/blender/editors/undo/ed_undo.cc index ad5e57c815b..ec9a2bc7244 100644 --- a/source/blender/editors/undo/ed_undo.cc +++ b/source/blender/editors/undo/ed_undo.cc @@ -590,6 +590,18 @@ static bool ed_undo_poll(bContext *C) return (undo_stack->step_active != nullptr) && (undo_stack->step_active->prev != nullptr); } +static std::string ed_undo_get_name(wmOperatorType *ot, PointerRNA * /*ptr*/) +{ + UndoStack *undo_stack = ED_undo_stack_get(); + if ((undo_stack && undo_stack->step_active != NULL) && (undo_stack->step_active->prev != NULL)) { + return CTX_IFACE_(ot->translation_context, "Undo") + std::string(" ") + + std::string(CTX_IFACE_(ot->translation_context, undo_stack->step_active->name)); + } + else { + return ""; + } +} + void ED_OT_undo(wmOperatorType *ot) { /* identifiers */ @@ -600,6 +612,7 @@ void ED_OT_undo(wmOperatorType *ot) /* api callbacks */ ot->exec = ed_undo_exec; ot->poll = ed_undo_poll; + ot->get_name = ed_undo_get_name; } void ED_OT_undo_push(wmOperatorType *ot) @@ -633,6 +646,18 @@ static bool ed_redo_poll(bContext *C) return (undo_stack->step_active != nullptr) && (undo_stack->step_active->next != nullptr); } +static std::string ed_redo_get_name(wmOperatorType *ot, PointerRNA * /*ptr*/) +{ + UndoStack *undo_stack = ED_undo_stack_get(); + if ((undo_stack && undo_stack->step_active != NULL) && (undo_stack->step_active->next != NULL)) { + return CTX_IFACE_(ot->translation_context, "Redo") + std::string(" ") + + std::string(CTX_IFACE_(ot->translation_context, undo_stack->step_active->next->name)); + } + else { + return ""; + } +} + void ED_OT_redo(wmOperatorType *ot) { /* identifiers */ @@ -643,6 +668,7 @@ void ED_OT_redo(wmOperatorType *ot) /* api callbacks */ ot->exec = ed_redo_exec; ot->poll = ed_redo_poll; + ot->get_name = ed_redo_get_name; } void ED_OT_undo_redo(wmOperatorType *ot) diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index 5fd86f3a02b..7bf2986538d 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -761,6 +761,10 @@ bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna) PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier) { + if (!ptr) { + return nullptr; + } + if (identifier[0] == '[' && identifier[1] == '"') { /* id prop lookup, not so common */ PropertyRNA *r_prop = nullptr; @@ -5377,6 +5381,10 @@ void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values) int RNA_enum_get(PointerRNA *ptr, const char *name) { + if (!ptr) { + return 0; + } + PropertyRNA *prop = RNA_struct_find_property(ptr, name); if (prop) { diff --git a/source/blender/windowmanager/intern/wm_operator_type.cc b/source/blender/windowmanager/intern/wm_operator_type.cc index b6e9356dc58..f41e0a7e346 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.cc +++ b/source/blender/windowmanager/intern/wm_operator_type.cc @@ -577,7 +577,7 @@ static void wm_operatortype_free_macro(wmOperatorType *ot) std::string WM_operatortype_name(wmOperatorType *ot, PointerRNA *properties) { std::string name; - if (ot->get_name && properties) { + if (ot->get_name) { name = ot->get_name(ot, properties); }