bugfix [#25230] Quick extrude Ctrl-LMB : wrong behaviour of 'RotateSource' option.
Problem is is with operator redo which click-extrude exposed. Check if redo operator can run, otherwise lock the UI and add a label that the operator doesn't support redo. This is clunky but IMHO better then failing silently and leaving the user confused. - Merged redo functions into ED_undo_operator_repeat(), code was duplicated in a few places. - added WM_operator_repeat_check to check if WM_operator_repeat() can run, avoids an undo call when redo work. Unrelated changes - GHOST_SystemWin32.cpp set to utf8 encoding. - cmake_consistency_check.py now checks source files are utf8.
This commit is contained in:
parent
ff6e631c86
commit
acd7b81c2d
@ -192,3 +192,16 @@ for hf in sorted(source_list(base, is_c_header)):
|
||||
if not is_ignore(hf):
|
||||
if hf not in global_h:
|
||||
print("missing_h: ", hf)
|
||||
|
||||
# test encoding
|
||||
import traceback
|
||||
for files in (global_c, global_h):
|
||||
for f in sorted(files):
|
||||
i = 1
|
||||
try:
|
||||
for l in open(f, "r", encoding="utf8"):
|
||||
i += 1
|
||||
except:
|
||||
print("Non utf8: %s:%d" % (f, i))
|
||||
if i > 1:
|
||||
traceback.print_exc()
|
||||
|
@ -855,7 +855,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
* specifies a character code generated by a dead key. A dead key is a key that
|
||||
* generates a character, such as the umlaut (double-dot), that is combined with
|
||||
* another character to form a composite character. For example, the umlaut-O
|
||||
* character (Ù) is generated by typing the dead key for the umlaut character, and
|
||||
* character (Ù) is generated by typing the dead key for the umlaut character, and
|
||||
* then typing the O key.
|
||||
*/
|
||||
case WM_SYSDEADCHAR:
|
||||
|
@ -51,6 +51,11 @@ void ED_undo_redo (struct bContext *C);
|
||||
void ED_OT_undo (struct wmOperatorType *ot);
|
||||
void ED_OT_redo (struct wmOperatorType *ot);
|
||||
|
||||
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op);
|
||||
/* convenience since UI callbacks use this mostly*/
|
||||
void ED_undo_operator_repeat_cb(struct bContext *C, void *arg_op, void *arg_unused);
|
||||
void ED_undo_operator_repeat_cb_evt(struct bContext *C, void *arg_op, int arg_unused);
|
||||
|
||||
/* undo_editmode.c */
|
||||
void undo_editmode_push(struct bContext *C, const char *name,
|
||||
void * (*getdata)(struct bContext *C),
|
||||
@ -66,7 +71,6 @@ void undo_editmode_menu (struct bContext *C);
|
||||
void undo_editmode_clear (void);
|
||||
void undo_editmode_step (struct bContext *C, int step);
|
||||
|
||||
|
||||
/* ************** XXX OLD CRUFT WARNING ************* */
|
||||
|
||||
void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert);
|
||||
|
@ -1392,26 +1392,6 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
/* op->invoke */
|
||||
static void redo_cb(bContext *C, void *arg_op, void *arg2)
|
||||
{
|
||||
wmOperator *lastop= arg_op;
|
||||
|
||||
if(lastop) {
|
||||
int retval;
|
||||
|
||||
if (G.f & G_DEBUG)
|
||||
printf("operator redo %s\n", lastop->type->name);
|
||||
ED_undo_pop(C);
|
||||
retval= WM_operator_repeat(C, lastop);
|
||||
if((retval & OPERATOR_FINISHED)==0) {
|
||||
if (G.f & G_DEBUG)
|
||||
printf("operator redo failed %s\n", lastop->type->name);
|
||||
ED_undo_redo(C);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
@ -1429,7 +1409,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
if(op==NULL)
|
||||
return;
|
||||
|
||||
uiBlockSetFunc(block, redo_cb, op, NULL);
|
||||
uiBlockSetFunc(block, ED_undo_operator_repeat_cb, op, NULL);
|
||||
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
|
@ -63,38 +63,6 @@
|
||||
|
||||
/* ******************* view3d space & buttons ************** */
|
||||
|
||||
|
||||
/* op->exec */
|
||||
/* XXX DUPLICATE CODE */
|
||||
static void redo_cb(bContext *C, void *arg_op, void *UNUSED(arg2))
|
||||
{
|
||||
wmOperator *lastop= arg_op;
|
||||
|
||||
if(lastop) {
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
ARegion *ar1= BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
|
||||
int retval;
|
||||
|
||||
if(ar1)
|
||||
CTX_wm_region_set(C, ar1);
|
||||
|
||||
if (G.f & G_DEBUG)
|
||||
printf("operator redo %s\n", lastop->type->name);
|
||||
|
||||
ED_undo_pop_op(C, lastop);
|
||||
retval= WM_operator_repeat(C, lastop);
|
||||
|
||||
if((retval & OPERATOR_FINISHED)==0) {
|
||||
if (G.f & G_DEBUG)
|
||||
printf("operator redo failed %s\n", lastop->type->name);
|
||||
ED_undo_redo(C);
|
||||
}
|
||||
|
||||
/* set region back */
|
||||
CTX_wm_region_set(C, ar);
|
||||
}
|
||||
}
|
||||
|
||||
static wmOperator *view3d_last_operator(const bContext *C)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
@ -118,6 +86,13 @@ static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOper
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
/* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
|
||||
* just fails silently */
|
||||
if(!WM_operator_repeat_check(C, op)) {
|
||||
uiBlockSetButLock(uiLayoutGetBlock(pa->layout), TRUE, "Operator cannot redo");
|
||||
uiItemL(pa->layout, "* Redo Unsupported *", 0); // XXX, could give some nicer feedback or not show redo panel at all?
|
||||
}
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
if(op->type->ui) {
|
||||
op->layout= pa->layout;
|
||||
@ -161,7 +136,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
|
||||
block= uiLayoutGetBlock(pa->layout);
|
||||
|
||||
uiBlockSetFunc(block, redo_cb, op, NULL);
|
||||
uiBlockSetFunc(block, ED_undo_operator_repeat_cb, op, NULL);
|
||||
|
||||
view3d_panel_operator_redo_operator(C, pa, op);
|
||||
}
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
@ -261,3 +263,53 @@ void ED_OT_redo(wmOperatorType *ot)
|
||||
}
|
||||
|
||||
|
||||
/* ui callbacks should call this rather then calling WM_operator_repeat() themselves */
|
||||
int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
|
||||
{
|
||||
int ret= 0;
|
||||
|
||||
if(op) {
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
ARegion *ar1= BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
|
||||
|
||||
if(ar1)
|
||||
CTX_wm_region_set(C, ar1);
|
||||
|
||||
if(WM_operator_repeat_check(C, op) && WM_operator_poll(C, op->type)) {
|
||||
int retval;
|
||||
|
||||
if (G.f & G_DEBUG)
|
||||
printf("redo_cb: operator redo %s\n", op->type->name);
|
||||
ED_undo_pop_op(C, op);
|
||||
retval= WM_operator_repeat(C, op);
|
||||
if((retval & OPERATOR_FINISHED)==0) {
|
||||
if (G.f & G_DEBUG)
|
||||
printf("redo_cb: operator redo failed: %s, return %d\n", op->type->name, retval);
|
||||
ED_undo_redo(C);
|
||||
}
|
||||
else {
|
||||
ret= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* set region back */
|
||||
CTX_wm_region_set(C, ar);
|
||||
}
|
||||
else {
|
||||
if (G.f & G_DEBUG) {
|
||||
printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void *UNUSED(arg_unused))
|
||||
{
|
||||
ED_undo_operator_repeat(C, (wmOperator *)arg_op);
|
||||
}
|
||||
|
||||
void ED_undo_operator_repeat_cb_evt(bContext *C, void *arg_op, int UNUSED(arg_event))
|
||||
{
|
||||
ED_undo_operator_repeat(C, (wmOperator *)arg_op);
|
||||
}
|
||||
|
@ -221,6 +221,7 @@ int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot);
|
||||
int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context);
|
||||
int WM_operator_call (struct bContext *C, struct wmOperator *op);
|
||||
int WM_operator_repeat (struct bContext *C, struct wmOperator *op);
|
||||
int WM_operator_repeat_check(const struct bContext *C, struct wmOperator *op);
|
||||
int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
|
||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports);
|
||||
|
||||
|
@ -514,6 +514,14 @@ int WM_operator_repeat(bContext *C, wmOperator *op)
|
||||
{
|
||||
return wm_operator_exec(C, op, 1);
|
||||
}
|
||||
/* TRUE if WM_operator_repeat can run
|
||||
* simple check for now but may become more involved.
|
||||
* To be sure the operator can run call WM_operator_poll(C, op->type) also, since this call
|
||||
* checks if WM_operator_repeat() can run at all, not that it WILL run at any time. */
|
||||
int WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op)
|
||||
{
|
||||
return op->type->exec != NULL;
|
||||
}
|
||||
|
||||
static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, PointerRNA *properties, ReportList *reports)
|
||||
{
|
||||
|
@ -869,17 +869,6 @@ int WM_operator_winactive(bContext *C)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* op->exec */
|
||||
static void redo_cb(bContext *C, void *arg_op, int UNUSED(event))
|
||||
{
|
||||
wmOperator *lastop= arg_op;
|
||||
|
||||
if(lastop) {
|
||||
ED_undo_pop_op(C, lastop);
|
||||
WM_operator_repeat(C, lastop);
|
||||
}
|
||||
}
|
||||
|
||||
static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
@ -896,10 +885,10 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
||||
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
|
||||
/* if register is not enabled, the operator gets freed on OPERATOR_FINISHED
|
||||
* ui_apply_but_funcs_after calls redo_cb and crashes */
|
||||
* ui_apply_but_funcs_after calls ED_undo_operator_repeate_cb and crashes */
|
||||
assert(op->type->flag & OPTYPE_REGISTER);
|
||||
|
||||
uiBlockSetHandleFunc(block, redo_cb, arg_op);
|
||||
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op);
|
||||
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
@ -910,6 +899,13 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
||||
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, 20, style);
|
||||
uiItemL(layout, op->type->name, 0);
|
||||
|
||||
/* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
|
||||
* just fails silently */
|
||||
if(!WM_operator_repeat_check(C, op)) {
|
||||
uiBlockSetButLock(uiLayoutGetBlock(layout), TRUE, "Operator cannot redo");
|
||||
uiItemL(layout, "* Redo Unsupported *", 0); // XXX, could give some nicer feedback or not show redo panel at all?
|
||||
}
|
||||
|
||||
if(op->type->ui) {
|
||||
op->layout= layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
|
Loading…
Reference in New Issue
Block a user