[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15721] branches/soc-2008-quorn/source/ blender: Improvements to text find (and replace):

Ian Thompson quornian at googlemail.com
Wed Jul 23 21:35:13 CEST 2008


Revision: 15721
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15721
Author:   quorn
Date:     2008-07-23 21:35:13 +0200 (Wed, 23 Jul 2008)

Log Message:
-----------
Improvements to text find (and replace):
 - Added GUI panel
 - Selected text is copied to "find" field
 - Option to search "all texts"
 - Option to replace text
 - Alt+F finds, Ctrl+Alt+F finds again (without UI)
 - Alt+H replaces (UI), Ctrl+Alt+H replaces again (and undo works)
 - Fixed: Find didn't push undos so cursor position was wrong

Modified Paths:
--------------
    branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h
    branches/soc-2008-quorn/source/blender/blenkernel/intern/text.c
    branches/soc-2008-quorn/source/blender/src/drawtext.c
    branches/soc-2008-quorn/source/blender/src/header_text.c

Modified: branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h
===================================================================
--- branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h	2008-07-23 18:50:00 UTC (rev 15720)
+++ branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h	2008-07-23 19:35:13 UTC (rev 15721)
@@ -52,7 +52,7 @@
 char*	txt_to_buf			(struct Text *text);
 void	txt_clean_text		(struct Text *text);
 void	txt_order_cursors	(struct Text *text);
-int		txt_find_string		(struct Text *text, char *findstr);
+int		txt_find_string		(struct Text *text, char *findstr, int wrap);
 int		txt_has_sel			(struct Text *text);
 int		txt_get_span		(struct TextLine *from, struct TextLine *to);
 void	txt_move_up			(struct Text *text, short sel);
@@ -87,7 +87,7 @@
 void	txt_backspace_word	(struct Text *text);
 int		txt_add_char		(struct Text *text, char add);
 int		txt_replace_char	(struct Text *text, char add);
-void	txt_find_panel		(struct SpaceText *st, int again);
+void	txt_find_panel		(struct SpaceText *st, int again, int flags);
 void	run_python_script	(struct SpaceText *st);
 int	jumptoline_interactive	(struct SpaceText *st);
 void	txt_export_to_object	(struct Text *text);
@@ -141,6 +141,11 @@
 #define UNDO_COMMENT		034
 #define UNDO_UNCOMMENT		035
 
+/* Find and replace flags */
+#define TXT_FIND_REPLACE 0x01
+#define TXT_FIND_ALLTEXTS 0x02
+#define TXT_FIND_WRAP 0x04
+
 #ifdef __cplusplus
 }
 #endif

Modified: branches/soc-2008-quorn/source/blender/blenkernel/intern/text.c
===================================================================
--- branches/soc-2008-quorn/source/blender/blenkernel/intern/text.c	2008-07-23 18:50:00 UTC (rev 15720)
+++ branches/soc-2008-quorn/source/blender/blenkernel/intern/text.c	2008-07-23 19:35:13 UTC (rev 15721)
@@ -1080,22 +1080,31 @@
 	return buf;
 }
 
-int txt_find_string(Text *text, char *findstr)
+int txt_find_string(Text *text, char *findstr, int wrap)
 {
 	TextLine *tl, *startl;
 	char *s= NULL;
+	int oldcl, oldsl, oldcc, oldsc;
 
 	if (!text || !text->curl || !text->sell) return 0;
 	
 	txt_order_cursors(text);
 
+	oldcl= txt_get_span(text->lines.first, text->curl);
+	oldsl= txt_get_span(text->lines.first, text->sell);
 	tl= startl= text->sell;
+	oldcc= text->curc;
+	oldsc= text->selc;
 	
 	s= strstr(&tl->line[text->selc], findstr);
 	while (!s) {
 		tl= tl->next;
-		if (!tl)
-			tl= text->lines.first;
+		if (!tl) {
+			if (wrap)
+				tl= text->lines.first;
+			else
+				break;
+		}
 
 		s= strstr(tl->line, findstr);
 		if (tl==startl)
@@ -1103,10 +1112,10 @@
 	}
 	
 	if (s) {
-		text->curl= text->sell= tl;
-		text->curc= (int) (s-tl->line);
-		text->selc= text->curc + strlen(findstr);
-		
+		int newl= txt_get_span(text->lines.first, tl);
+		int newc= (int)(s-tl->line);
+		txt_move_to(text, newl, newc, 0);
+		txt_move_to(text, newl, newc + strlen(findstr), 1);
 		return 1;				
 	} else
 		return 0;

Modified: branches/soc-2008-quorn/source/blender/src/drawtext.c
===================================================================
--- branches/soc-2008-quorn/source/blender/src/drawtext.c	2008-07-23 18:50:00 UTC (rev 15720)
+++ branches/soc-2008-quorn/source/blender/src/drawtext.c	2008-07-23 19:35:13 UTC (rev 15721)
@@ -115,7 +115,10 @@
 static void get_suggest_prefix(Text *text);
 static void confirm_suggestion(Text *text, int skipleft);
 
+static int last_txt_find_flags= 0;
 static void *last_txt_find_string= NULL;
+static void *last_txt_repl_string= NULL;
+
 static double last_check_time= 0;
 
 static BMF_Font *spacetext_get_font(SpaceText *st) {
@@ -178,6 +181,7 @@
 	txt_free_cut_buffer();
 	
 	if (last_txt_find_string) MEM_freeN(last_txt_find_string);
+	if (last_txt_repl_string) MEM_freeN(last_txt_repl_string);
 	if (temp_char_buf) MEM_freeN(temp_char_buf);
 	if (temp_char_accum) MEM_freeN(temp_char_accum);	
 }
@@ -1650,41 +1654,168 @@
 	}
 }
 
+static short find_and_replace_popup(char *findvar, char *replvar, int *flags, short min, short max)
+{
+	uiBlock *block;
+	ListBase listb={0, 0};
+	short x1,y1;
+	short ret=0;
+	char *editfindvar=NULL, *editreplvar=NULL; /* dont edit the original text, incase we cancel the popup */
+	
+	if(min>max) min= max;
+
+	block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
+	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
+
+	x1= curarea->winrct.xmax - 240;
+	y1= curarea->winrct.ymin;
+	
+	editfindvar = MEM_callocN(max+1, "findvar");
+	editreplvar = MEM_callocN(max+1, "replvar");
+	BLI_strncpy(editfindvar, findvar, max);
+	BLI_strncpy(editreplvar, replvar, max);
+	
+	uiDefButC(block, TEX, 0, "Find: ", x1+5,y1+85,225,20, editfindvar,(float)min,(float)max, 0, 0, "");
+	uiDefButC(block, TEX, 0, "Replace: ", x1+5,y1+60,225,20, editreplvar,(float)min,(float)max, 0, 0, "");
+	uiDefButBitI(block, TOG, TXT_FIND_REPLACE, 0, "Replace", x1+5,y1+35,55,20, flags, 0, 0, 0, 0, "Replace previous item found");
+	uiDefButBitI(block, TOG, TXT_FIND_ALLTEXTS, 0, "All Texts", x1+60,y1+35,55,20, flags, 0, 0, 0, 0, "Search all texts");
+	uiDefButBitI(block, TOG, TXT_FIND_WRAP, 0, "Wrap", x1+115,y1+35,55,20, flags, 0, 0, 0, 0, "Wrap search around current text");
+	uiDefBut(block, BUT, 3, "Replace/Find", x1+125,y1+10,105,20, NULL, 0, 0, 0, 0, "");
+
+	uiBoundsBlock(block, 5);
+	
+	ret= uiDoBlocks(&listb, 0, 0);
+
+	if(ret==UI_RETURN_OK) {
+		BLI_strncpy(findvar, editfindvar, max);
+		BLI_strncpy(replvar, editreplvar, max);
+		MEM_freeN(editfindvar);
+		MEM_freeN(editreplvar);
+		return 1;
+	}
+	MEM_freeN(editfindvar);
+	MEM_freeN(editreplvar);
+	return 0;
+	
+}
+
 /*
- * again==0 show find panel or find
- * again==1 find text again */
-void txt_find_panel(SpaceText *st, int again)
+ * again==0 always show find panel
+ * again==1 find text again (no panel) If first find, panel shown anyway
+ * flags:
+ *   TXT_FIND_REPLACE  replace last found occurrence before searching again
+ *   TXT_FIND_ALLTEXTS search through all texts (off wraps current text)
+ */
+void txt_find_panel(SpaceText *st, int again, int flags)
 {
-	Text *text=st->text;
-	char *findstr= last_txt_find_string;
-			
-	if (again==0) {
-		findstr= txt_sel_to_buf(text);
-	} else if (again==1) {
-		char buf[256];
+	Text *text, *start;
+	char *tmp= NULL;
+	char buf[256], repbuf[256];
+	int searched, skip, noswitch;
 
-	if (findstr && strlen(findstr)<(sizeof(buf)-1))
-		strcpy(buf, findstr);
-	else
-		buf[0]= 0;
-		
-	if (sbutton(buf, 0, sizeof(buf)-1, "Find: ") && buf[0])
-		findstr= BLI_strdup(buf);
-	else
-		findstr= NULL;
+	text= start= st->text;
+	if (!text) return;
+	if (again) {
+		if (!last_txt_find_string) again= 0; /* Can't search again */
+		if (!last_txt_repl_string && (flags & TXT_FIND_REPLACE)) again= 0;
 	}
 
-	if (findstr!=last_txt_find_string) {
-		if (last_txt_find_string)
-			MEM_freeN(last_txt_find_string);
-		last_txt_find_string= findstr;
-	}
+	if (!again) {
+		/* Populate tmp with selected text, or the last searched string */
+		if (txt_has_sel(text))
+			tmp= txt_sel_to_buf(text);
+		else if (last_txt_find_string)
+			tmp= BLI_strdup(last_txt_find_string);
+
+		if (tmp && strlen(tmp) < sizeof(buf)-1)strcpy(buf, tmp);
+		else buf[0]= 0;
+		if (tmp) { MEM_freeN(tmp); tmp= NULL; }
+
+		if (last_txt_repl_string) strcpy(repbuf, last_txt_repl_string);
+		else repbuf[0]= 0;
+
+		searched= skip= noswitch= 0;
+		while (skip || find_and_replace_popup(buf, repbuf, &flags, 0, sizeof(buf)-1) && buf[0]) {
+			skip= 0;
+
+			/* Allow us to detect when to go to the next text */
+			if (flags & TXT_FIND_ALLTEXTS)
+				flags &= ~TXT_FIND_WRAP;
+
+			/* Replace selection first */
+			if ((flags & TXT_FIND_REPLACE) && txt_has_sel(text)) {
+				tmp= txt_sel_to_buf(text);
+				if (strcmp(buf, tmp)==0) { /* Searching for same thing? */
+					txt_insert_buf(text, repbuf);
+					if (st->showsyntax) get_format_string(st);
+				}
+				MEM_freeN(tmp);
+				tmp= NULL;
+			}
+
+			/* Now find the next occurrence */
+			searched= 1;
+			if (txt_find_string(text, buf, flags&TXT_FIND_WRAP)) {
+				pop_space_text(st);
+			} else if ((flags & TXT_FIND_ALLTEXTS) && !noswitch) {
+				if (text->id.next) text= st->text= text->id.next;
+				else text= st->text= G.main->text.first;
 				
-	if (findstr) {
-		if (txt_find_string(text, findstr))
-			pop_space_text(st);
-		else
-			error("Not found: %s", findstr);
+				/* Finish at end of this text if we've been round once */
+				if (text==start)
+					noswitch= 1;
+				
+				txt_move_toline(text, 0, 0);
+				pop_space_text(st);
+				skip= 1; /* Skip panel so we immediately search the next text */
+			} else {
+				okee("Text not found: %s", buf);
+				break;
+			}
+			
+			/* Redraw */
+			scrarea_do_windraw(curarea);
+			screen_swapbuffers();
+		}
+
+		/* Store last search details */
+		if (searched) {
+			last_txt_find_flags= flags;
+			if (last_txt_find_string)
+				MEM_freeN(last_txt_find_string);
+			last_txt_find_string= BLI_strdup(buf);
+			if (last_txt_repl_string)
+				MEM_freeN(last_txt_repl_string);
+			last_txt_repl_string= BLI_strdup(repbuf);
+		}
+	} else {
+		if (strlen(last_txt_find_string) < sizeof(buf)-1) {
+
+			/* Replace current */
+			if ((flags & TXT_FIND_REPLACE) && last_txt_repl_string && txt_has_sel(text)) {
+				tmp= txt_sel_to_buf(text);
+				if (strcmp(last_txt_find_string, tmp)==0)
+					txt_insert_buf(text, last_txt_repl_string);
+				MEM_freeN(tmp);
+				tmp= NULL;
+			}
+
+			/* Find next */
+			if (flags & TXT_FIND_ALLTEXTS)
+				flags &= ~TXT_FIND_WRAP;
+			if (txt_find_string(text, last_txt_find_string, flags & TXT_FIND_WRAP)) {
+				pop_space_text(st);
+			} else if (flags & flags&TXT_FIND_ALLTEXTS) {
+				if (text->id.next)
+					text= st->text= text->id.next;
+				else
+					text= st->text= G.main->text.first;
+				txt_move_toline(text, 0, 0);
+				pop_space_text(st);
+			} else {
+				okee("Text not found: %s", last_txt_find_string);
+			}
+		}
 	}
 }
 
@@ -2051,16 +2182,24 @@
 				}
 			}
 			else if (G.qual == LR_ALTKEY) {
-				if (txt_has_sel(text)) {
-					txt_find_panel(st,0);
-					do_draw= 1;
-				}
+				txt_find_panel(st, 0, last_txt_find_flags & ~TXT_FIND_REPLACE);
+				do_draw= 1;
 			}
-			else if (G.qual == (LR_ALTKEY|LR_CTRLKEY)) {	/* always search button */
-				txt_find_panel(st,1);
+			else if (G.qual == (LR_ALTKEY|LR_CTRLKEY)) {
+				txt_find_panel(st, 1, last_txt_find_flags & ~TXT_FIND_REPLACE);
 				do_draw= 1;
 			}
 			break; /* BREAK F */
+		case HKEY:
+			if (G.qual == LR_ALTKEY) {
+				txt_find_panel(st, 0, last_txt_find_flags | TXT_FIND_REPLACE);
+				do_draw= 1;
+			}

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list