bugfix [#25230] Quick extrude Ctrl-LMB : wrong behaviour of 'RotateSource' option.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 15 Dec 2010 04:06:19 +0000 (04:06 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 15 Dec 2010 04:06:19 +0000 (04:06 +0000)
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.

build_files/cmake/cmake_consistency_check.py
intern/ghost/intern/GHOST_SystemWin32.cpp
source/blender/editors/include/ED_util.h
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/editors/util/undo.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_operators.c

index 302ea8561d1c5257e9f77599cbdccdb2fe9452af..7c47c1d8bfd38eb2005ec0c2118583201e7823cf 100644 (file)
@@ -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()
index 09b53544e31f3246505432e03bd99ce44d9bf9e3..371a8bf865ba3d4977e615bc1017610278a151a6 100644 (file)
@@ -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:
index 8d654e4eaa5158ac580329d3cd2322c2ed83eb28..2936d63511c99322abf698ccaa49b331f33a959b 100644 (file)
@@ -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);
index 1c400ee1ff8bb34005c5949949238b95c2a9436e..0352996484ac7b0b7f9fe71e16bb7aaf86516367 100644 (file)
@@ -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};
index 1064611b84f3a204a4c7b26b737f11d8412a4271..a20397aa720a795733fd573d015e230484bb1ea4 100644 (file)
 
 /* ******************* 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);
 }
index f0e8184b99190e37055695aedf6ebaf0e69ac453..0165cf5a03dfc1dcc5400b27e8a3399076db3a1d 100644 (file)
@@ -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);
+}
index 3a47e29f553b18ab94ffe7870c63e50c43434c38..9c3e19ef4b704bdceb4a91603e55002f2362afca 100644 (file)
@@ -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);
 
index 579bac52306a3e5cedb67558ea32fa7e057172a5..08b50ef9d3f40b241ef5764fd031bca604011e6b 100644 (file)
@@ -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)
 {
index 9f18f23bdd660dc9398d93321eb19df1122fd799..d7c84392a12d5da14391bb06b226db7d51056a9d 100644 (file)
@@ -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);