[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26395] trunk/blender/source/blender: Fix #20327: uv smart project options can't be tweaked.

Brecht Van Lommel brecht at blender.org
Fri Jan 29 14:06:50 CET 2010


Revision: 26395
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26395
Author:   blendix
Date:     2010-01-29 14:06:50 +0100 (Fri, 29 Jan 2010)

Log Message:
-----------
Fix #20327: uv smart project options can't be tweaked.

Python operators calling C operators would get too many undo pushes,
causing redo of the python operator not to work. Now the depth of
operator callbacks is counted to detected nested calls, and in that
case skip the undo/register here, and only do a single undo/register
for the mother operator.

Modified Paths:
--------------
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2010-01-29 11:26:17 UTC (rev 26394)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2010-01-29 13:06:50 UTC (rev 26395)
@@ -4540,6 +4540,7 @@
 	
 	wm->windrawable= NULL;
 	wm->initialized= 0;
+	wm->op_undo_depth= 0;
 }
 
 static void lib_link_windowmanager(FileData *fd, Main *main)

Modified: trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h	2010-01-29 11:26:17 UTC (rev 26394)
+++ trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h	2010-01-29 13:06:50 UTC (rev 26395)
@@ -109,7 +109,7 @@
 	
 	int initialized;		/* set on file read */
 	short file_saved;		/* indicator whether data was saved */
-	short pad;
+	short op_undo_depth;	/* operator stack depth to avoid nested undo pushes */
 	
 	ListBase operators;		/* operator registry */
 	

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2010-01-29 11:26:17 UTC (rev 26394)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2010-01-29 13:06:50 UTC (rev 26395)
@@ -303,9 +303,37 @@
 	return 1;
 }
 
+static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
+{
+	wmWindowManager *wm= CTX_wm_manager(C);
+
+	op->customdata= NULL;
+
+	/* we don't want to do undo pushes for operators that are being
+	   called from operators that already do an undo push. usually
+	   this will happen for python operators that call C operators */
+	if(wm->op_undo_depth == 0)
+		if(op->type->flag & OPTYPE_UNDO)
+			ED_undo_push_op(C, op);
+	
+	if(repeat==0) {
+		if(G.f & G_DEBUG) {
+			char *buf = WM_operator_pystring(C, op->type, op->ptr, 1);
+			BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
+			MEM_freeN(buf);
+		}
+
+		if((wm->op_undo_depth == 0) && (op->type->flag & OPTYPE_REGISTER))
+			wm_operator_register(C, op);
+		else
+			WM_operator_free(op);
+	}
+}
+
 /* if repeat is true, it doesn't register again, nor does it free */
 static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
 {
+	wmWindowManager *wm= CTX_wm_manager(C);
 	int retval= OPERATOR_CANCELLED;
 	
 	if(op==NULL || op->type==NULL)
@@ -314,32 +342,22 @@
 	if(0==WM_operator_poll(C, op->type))
 		return retval;
 	
-	if(op->type->exec)
+	if(op->type->exec) {
+		if(op->type->flag & OPTYPE_UNDO)
+			wm->op_undo_depth++;
+
 		retval= op->type->exec(C, op);
+
+		if(op->type->flag & OPTYPE_UNDO)
+			wm->op_undo_depth--;
+	}
 	
 	if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED))
 		if(op->reports->list.first)
 			uiPupMenuReports(C, op->reports);
 	
-	if(retval & OPERATOR_FINISHED) {
-		op->customdata= NULL;
-
-		if(op->type->flag & OPTYPE_UNDO)
-			ED_undo_push_op(C, op);
-		
-		if(repeat==0) {
-			if(G.f & G_DEBUG) {
-				char *buf = WM_operator_pystring(C, op->type, op->ptr, 1);
-				BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
-				MEM_freeN(buf);
-			}
-
-			if((op->type->flag & OPTYPE_REGISTER))
-				wm_operator_register(C, op);
-			else
-				WM_operator_free(op);
-		}
-	}
+	if(retval & OPERATOR_FINISHED)
+		wm_operator_finished(C, op, repeat);
 	else if(repeat==0)
 		WM_operator_free(op);
 	
@@ -472,10 +490,24 @@
 		
 		if(op->type->invoke && event) {
 			wm_region_mouse_co(C, event);
+
+			if(op->type->flag & OPTYPE_UNDO)
+				wm->op_undo_depth++;
+
 			retval= op->type->invoke(C, op, event);
+
+			if(op->type->flag & OPTYPE_UNDO)
+				wm->op_undo_depth--;
 		}
-		else if(op->type->exec)
+		else if(op->type->exec) {
+			if(op->type->flag & OPTYPE_UNDO)
+				wm->op_undo_depth++;
+
 			retval= op->type->exec(C, op);
+
+			if(op->type->flag & OPTYPE_UNDO)
+				wm->op_undo_depth--;
+		}
 		else
 			printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */
 
@@ -493,21 +525,7 @@
 		if(retval & OPERATOR_HANDLED)
 			; /* do nothing, wm_operator_exec() has been called somewhere */
 		else if(retval & OPERATOR_FINISHED) {
-			op->customdata= NULL;
-
-			if(ot->flag & OPTYPE_UNDO)
-				ED_undo_push_op(C, op);
-			
-			if(G.f & G_DEBUG) {
-				char *buf = WM_operator_pystring(C, op->type, op->ptr, 1);
-				BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
-				MEM_freeN(buf);
-			}
-			
-			if((ot->flag & OPTYPE_REGISTER))
-				wm_operator_register(C, op);
-			else
-				WM_operator_free(op);
+			wm_operator_finished(C, op, 0);
 		}
 		else if(retval & OPERATOR_RUNNING_MODAL) {
 			/* grab cursor during blocking modal ops (X11)
@@ -657,8 +675,15 @@
 	wmWindowManager *wm=	CTX_wm_manager(C);
 	op= wm_operator_create(wm, ot, properties, reports);
 
-	if (op->type->exec)
+	if (op->type->exec) {
+		if(op->type->flag & OPTYPE_UNDO)
+			wm->op_undo_depth++;
+
 		retval= op->type->exec(C, op);
+
+		if(op->type->flag & OPTYPE_UNDO)
+			wm->op_undo_depth--;
+	}
 	else
 		printf("error \"%s\" operator has no exec function, python cannot call it\n", op->type->name);
 #endif
@@ -721,6 +746,7 @@
 void WM_event_remove_handlers(bContext *C, ListBase *handlers)
 {
 	wmEventHandler *handler;
+	wmWindowManager *wm= CTX_wm_manager(C);
 	
 	/* C is zero on freeing database, modal handlers then already were freed */
 	while((handler=handlers->first)) {
@@ -733,8 +759,14 @@
 				
 				wm_handler_op_context(C, handler);
 
+				if(handler->op->type->flag & OPTYPE_UNDO)
+					wm->op_undo_depth++;
+
 				handler->op->type->cancel(C, handler->op);
 
+				if(handler->op->type->flag & OPTYPE_UNDO)
+					wm->op_undo_depth--;
+
 				CTX_wm_area_set(C, area);
 				CTX_wm_region_set(C, region);
 			}
@@ -926,6 +958,7 @@
 
 		if(ot->modal) {
 			/* we set context to where modal handler came from */
+			wmWindowManager *wm= CTX_wm_manager(C);
 			ScrArea *area= CTX_wm_area(C);
 			ARegion *region= CTX_wm_region(C);
 			
@@ -933,8 +966,14 @@
 			wm_region_mouse_co(C, event);
 			wm_event_modalkeymap(C, op, event);
 			
+			if(ot->flag & OPTYPE_UNDO)
+				wm->op_undo_depth++;
+
 			retval= ot->modal(C, op, event);
 
+			if(ot->flag & OPTYPE_UNDO)
+				wm->op_undo_depth--;
+
 			/* putting back screen context, reval can pass trough after modal failures! */
 			if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
 				CTX_wm_area_set(C, area);
@@ -956,21 +995,7 @@
 			}			
 
 			if(retval & OPERATOR_FINISHED) {
-				op->customdata= NULL;
-
-				if(ot->flag & OPTYPE_UNDO)
-					ED_undo_push_op(C, op);
-				
-				if(G.f & G_DEBUG) {
-					char *buf = WM_operator_pystring(C, op->type, op->ptr, 1);
-					BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
-					MEM_freeN(buf);
-				}
-				
-				if((ot->flag & OPTYPE_REGISTER))
-					wm_operator_register(C, op);
-				else
-					WM_operator_free(op);
+				wm_operator_finished(C, op, 0);
 				handler->op= NULL;
 			}
 			else if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
@@ -1053,6 +1078,7 @@
 /* fileselect handlers are only in the window queue, so it's save to switch screens or area types */
 static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event)
 {
+	wmWindowManager *wm= CTX_wm_manager(C);
 	SpaceFile *sfile;
 	int action= WM_HANDLER_CONTINUE;
 	
@@ -1119,8 +1145,16 @@
 						uiPupMenuSaveOver(C, handler->op, (path)? path: "");
 					}
 					else {
-						int retval= handler->op->type->exec(C, handler->op);
+						int retval;
 						
+						if(handler->op->type->flag & OPTYPE_UNDO)
+							wm->op_undo_depth++;
+
+						retval= handler->op->type->exec(C, handler->op);
+
+						if(handler->op->type->flag & OPTYPE_UNDO)
+							wm->op_undo_depth--;
+						
 						if (retval & OPERATOR_FINISHED)
 							if(G.f & G_DEBUG)
 								wm_operator_print(handler->op);
@@ -1144,9 +1178,16 @@
 					}
 				}
 				else {
-					if(handler->op->type->cancel)
+					if(handler->op->type->cancel) {
+						if(handler->op->type->flag & OPTYPE_UNDO)
+							wm->op_undo_depth++;
+
 						handler->op->type->cancel(C, handler->op);
 
+						if(handler->op->type->flag & OPTYPE_UNDO)
+							wm->op_undo_depth--;
+					}
+
 					WM_operator_free(handler->op);
 				}
 





More information about the Bf-blender-cvs mailing list