[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15960] branches/soc-2008-quorn/source/ blender: Text Markers: multiple, coloured selections within a Text object with group relationships.

Ian Thompson quornian at googlemail.com
Tue Aug 5 01:01:49 CEST 2008


Revision: 15960
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15960
Author:   quorn
Date:     2008-08-05 01:01:47 +0200 (Tue, 05 Aug 2008)

Log Message:
-----------
Text Markers: multiple, coloured selections within a Text object with group relationships. They allow portions of text to be edited as one and enable quick jumping between and editing of different areas.

Flags control the behaviour and grouping of markers. At present, Ctrl+M places a marker with TMARK_EDITALL set for testing purposes.

I have also split the text area event handler into separate methods for marker handling and the existing text tools. This makes the events system much easier to follow as it was getting a little hairy.

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/blenloader/intern/readfile.c
    branches/soc-2008-quorn/source/blender/blenloader/intern/writefile.c
    branches/soc-2008-quorn/source/blender/makesdna/DNA_text_types.h
    branches/soc-2008-quorn/source/blender/src/drawtext.c

Modified: branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h
===================================================================
--- branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h	2008-08-04 22:49:05 UTC (rev 15959)
+++ branches/soc-2008-quorn/source/blender/blenkernel/BKE_text.h	2008-08-04 23:01:47 UTC (rev 15960)
@@ -100,6 +100,15 @@
 void	convert_tabs		(struct SpaceText *st, int tab);
 void	txt_copy_clipboard	(struct Text *text);
 void	txt_paste_clipboard	(struct Text *text);
+
+void	txt_add_marker						(struct Text *text, struct TextLine *line, int start, int end, char clr[4], int flags);
+void	txt_clear_marker_region				(struct Text *text, struct TextLine *line, int start, int end, int flags);
+void	txt_clear_markers					(struct Text *text, int flags);
+struct TextMarker	*txt_find_marker		(struct Text *text, struct TextLine *line, int curs, int flags);
+struct TextMarker	*txt_find_marker_region	(struct Text *text, struct TextLine *line, int start, int end, int flags);
+struct TextMarker	*txt_prev_marker		(struct Text *text, struct TextMarker *marker);
+struct TextMarker	*txt_next_marker		(struct Text *text, struct TextMarker *marker);
+
 /* Undo opcodes */
 
 /* Simple main cursor movement */
@@ -146,6 +155,10 @@
 #define TXT_FIND_ALLTEXTS 0x02
 #define TXT_FIND_WRAP 0x04
 
+/* Marker flags */
+#define TMARK_TEMP		0x01	/* Remove on non-editing events, don't save */
+#define TMARK_EDITALL	0x02	/* Edit all markers of the same group as one */
+
 #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-08-04 22:49:05 UTC (rev 15959)
+++ branches/soc-2008-quorn/source/blender/blenkernel/intern/text.c	2008-08-04 23:01:47 UTC (rev 15960)
@@ -148,6 +148,7 @@
 	}
 	
 	BLI_freelistN(&text->lines);
+	BLI_freelistN(&text->markers);
 
 	if(text->name) MEM_freeN(text->name);
 	MEM_freeN(text->undo_buf);
@@ -172,6 +173,7 @@
 	ta->flags= TXT_ISDIRTY | TXT_ISTMP | TXT_ISMEM;
 
 	ta->lines.first= ta->lines.last= NULL;
+	ta->markers.first= ta->markers.last= NULL;
 
 	tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
 	tmp->line= (char*) MEM_mallocN(1, "textline_string");
@@ -334,6 +336,7 @@
 	ta->id.us= 1;
 
 	ta->lines.first= ta->lines.last= NULL;
+	ta->markers.first= ta->markers.last= NULL;
 	ta->curl= ta->sell= NULL;
 
 /* 	ta->flags= TXT_ISTMP | TXT_ISEXT; */
@@ -421,6 +424,7 @@
 	tan->flags = ta->flags | TXT_ISDIRTY | TXT_ISTMP;
 	
 	tan->lines.first= tan->lines.last= NULL;
+	tan->markers.first= tan->markers.last= NULL;
 	tan->curl= tan->sell= NULL;
 	
 	tan->nlines= ta->nlines;
@@ -948,7 +952,9 @@
 static void txt_delete_sel (Text *text)
 {
 	TextLine *tmpl;
+	TextMarker *mrk;
 	char *buf;
+	int move, lineno;
 	
 	if (!text) return;
 	if (!text->curl) return;
@@ -966,6 +972,23 @@
 
 	buf= MEM_mallocN(text->curc+(text->sell->len - text->selc)+1, "textline_string");
 	
+	if (text->curl != text->sell) {
+		txt_clear_marker_region(text, text->curl, text->curc, text->curl->len, 0);
+		move= txt_get_span(text->curl, text->sell);
+	} else
+		move= 0;
+
+	mrk= txt_find_marker_region(text, text->sell, text->selc-1, text->sell->len, 0);
+	if (mrk) {
+		lineno= mrk->lineno;
+		do {
+			mrk->lineno -= move;
+			if (mrk->start > text->curc) mrk->start -= text->selc - text->curc;
+			mrk->end -= text->selc - text->curc;
+			mrk= mrk->next;
+		} while (mrk && mrk->lineno==lineno);
+	}
+
 	strncpy(buf, text->curl->line, text->curc);
 	strcpy(buf+text->curc, text->sell->line + text->selc);
 	buf[text->curc+(text->sell->len - text->selc)]=0;
@@ -2050,13 +2073,30 @@
 void txt_split_curline (Text *text) 
 {
 	TextLine *ins;
+	TextMarker *mrk;
 	char *left, *right;
+	int lineno= -1;
 	
 	if (!text) return;
 	if (!text->curl) return;
 
-	txt_delete_sel(text);	
+	txt_delete_sel(text);
 
+	/* Move markers */
+
+	lineno= txt_get_span(text->lines.first, text->curl);
+	mrk= text->markers.first;
+	while (mrk) {
+		if (mrk->lineno==lineno && mrk->start>text->curc) {
+			mrk->lineno++;
+			mrk->start -= text->curc;
+			mrk->end -= text->curc;
+		} else if (mrk->lineno > lineno) {
+			mrk->lineno++;
+		}
+		mrk= mrk->next;
+	}
+
 	/* Make the two half strings */
 
 	left= MEM_mallocN(text->curc+1, "textline_string");
@@ -2094,9 +2134,23 @@
 
 static void txt_delete_line (Text *text, TextLine *line) 
 {
+	TextMarker *mrk=NULL, *nxt;
+	int lineno= -1;
+
 	if (!text) return;
 	if (!text->curl) return;
 
+	lineno= txt_get_span(text->lines.first, line);
+	mrk= text->markers.first;
+	while (mrk) {
+		nxt= mrk->next;
+		if (mrk->lineno==lineno)
+			BLI_freelinkN(&text->markers, mrk);
+		else if (mrk->lineno > lineno)
+			mrk->lineno--;
+		mrk= nxt;
+	}
+
 	BLI_remlink (&text->lines, line);
 	
 	if (line->line) MEM_freeN(line->line);
@@ -2111,10 +2165,25 @@
 static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
 {
 	char *tmp;
+	TextMarker *mrk= NULL;
+	int lineno=-1;
 	
 	if (!text) return;
 	
 	if(!linea || !lineb) return;
+
+	mrk= txt_find_marker_region(text, lineb, 0, lineb->len, 0);
+	if (mrk) {
+		lineno= mrk->lineno;
+		do {
+			mrk->lineno--;
+			mrk->start += linea->len;
+			mrk->end += linea->len;
+			mrk= mrk->next;
+		} while (mrk && mrk->lineno==lineno);
+	}
+	if (lineno==-1) lineno= txt_get_span(text->lines.first, lineb);
+	if (!mrk) mrk= text->markers.first;
 	
 	tmp= MEM_mallocN(linea->len+lineb->len+1, "textline_string");
 	
@@ -2123,7 +2192,7 @@
 
 	make_new_line(linea, tmp);
 	
-	txt_delete_line(text, lineb); 
+	txt_delete_line(text, lineb);
 	
 	txt_make_dirty(text);
 	txt_clean_text(text);
@@ -2137,8 +2206,8 @@
 	if (!text->curl) return;
 
 	if (txt_has_sel(text)) { /* deleting a selection */
-	  txt_delete_sel(text);
-	  return;
+		txt_delete_sel(text);
+		return;
 	}
 	else if (text->curc== text->curl->len) { /* Appending two lines */
 		if (text->curl->next) {
@@ -2147,6 +2216,25 @@
 		}
 	} else { /* Just deleting a char */
 		int i= text->curc;
+
+		TextMarker *mrk= txt_find_marker_region(text, text->curl, i-1, text->curl->len, 0);
+		if (mrk) {
+			int lineno= mrk->lineno;
+			if (mrk->end==i) {
+				if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
+					txt_clear_markers(text, mrk->flags);
+				} else {
+					TextMarker *nxt= mrk->next;
+					BLI_freelinkN(&text->markers, mrk);
+				}
+				return;
+			}
+			do {
+				if (mrk->start>i) mrk->start--;
+				mrk->end--;
+				mrk= mrk->next;
+			} while (mrk && mrk->lineno==lineno);
+		}
 		
 		c= text->curl->line[i];
 		while(i< text->curl->len) {
@@ -2178,8 +2266,8 @@
 	if (!text->curl) return;
 	
 	if (txt_has_sel(text)) { /* deleting a selection */
-	  txt_delete_sel(text);
-	  return;
+		txt_delete_sel(text);
+		return;
 	}
 	else if (text->curc==0) { /* Appending two lines */
 		if (!text->curl->prev) return;
@@ -2189,19 +2277,38 @@
 		
 		txt_combine_lines(text, text->curl, text->curl->next);
 		txt_pop_sel(text);
-	} 
+	}
 	else { /* Just backspacing a char */
-	  int i= text->curc-1;
+		int i= text->curc-1;
+
+		TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0);
+		if (mrk) {
+			int lineno= mrk->lineno;
+			if (mrk->start==i+1) {
+				if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
+					txt_clear_markers(text, mrk->flags);
+				} else {
+					TextMarker *nxt= mrk->next;
+					BLI_freelinkN(&text->markers, mrk);
+				}
+				return;
+			}
+			do {
+				if (mrk->start>i) mrk->start--;
+				mrk->end--;
+				mrk= mrk->next;
+			} while (mrk && mrk->lineno==lineno);
+		}
 		
-	  c= text->curl->line[i];
-	  while(i< text->curl->len) {
-	    text->curl->line[i]= text->curl->line[i+1];
-	    i++;
-	  }
-	  text->curl->len--;
-	  text->curc--;
-		
-	  txt_pop_sel(text);
+		c= text->curl->line[i];
+		while(i< text->curl->len) {
+			text->curl->line[i]= text->curl->line[i+1];
+			i++;
+		}
+		text->curl->len--;
+		text->curc--;
+
+		txt_pop_sel(text);
 	}
 
 	txt_make_dirty(text);
@@ -2218,8 +2325,9 @@
 
 int txt_add_char (Text *text, char add) 
 {
-	int len;
+	int len, lineno;
 	char *tmp;
+	TextMarker *mrk;
 	
 	if (!text) return 0;
 	if (!text->curl) return 0;
@@ -2231,6 +2339,16 @@
 	
 	txt_delete_sel(text);
 	
+	mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0);
+	if (mrk) {
+		lineno= mrk->lineno;
+		do {
+			if (mrk->start>text->curc) mrk->start++;
+			mrk->end++;
+			mrk= mrk->next;
+		} while (mrk && mrk->lineno==lineno);
+	}
+	
 	tmp= MEM_mallocN(text->curl->len+2, "textline_string");
 	
 	if(text->curc) memcpy(tmp, text->curl->line, text->curc);
@@ -2535,3 +2653,124 @@
 	return i;
 }
 
+/*********************************/
+/* Text marker utility functions */
+/*********************************/
+
+/* Creates and adds a marker to the list maintaining sorted order */
+void txt_add_marker(Text *text, TextLine *line, int start, int end, char clr[4], int flags) {
+	TextMarker *tmp, *marker;
+
+	marker= MEM_mallocN(sizeof(TextMarker), "text_marker");
+	
+	marker->lineno= txt_get_span(text->lines.first, line);
+	marker->start= MIN2(start, end);
+	marker->end= MAX2(start, end);
+	marker->flags= flags;
+
+	marker->clr[0]= clr[0];
+	marker->clr[1]= clr[1];
+	marker->clr[2]= clr[2];
+	marker->clr[3]= clr[3];
+
+	for (tmp=text->markers.last; tmp; tmp=tmp->prev)
+		if (tmp->lineno < marker->lineno || (tmp->lineno==marker->lineno && tmp->start < marker->start))
+			break;
+
+	if (tmp) BLI_insertlinkafter(&text->markers, tmp, marker);
+	else BLI_addhead(&text->markers, marker);
+}
+
+/* Returns the first matching marker on the specified line between two points
+   If flags is zero, all markers will be searched */
+TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int flags) {
+	TextMarker *marker, *next;
+	int lineno= txt_get_span(text->lines.first, line);
+	
+	for (marker=text->markers.first; marker; marker=next) {
+		next= marker->next;
+
+		if (flags && marker->flags != flags) continue;
+		else if (marker->lineno < lineno) continue;
+		else if (marker->lineno > lineno) break;
+
+		if ((marker->start==marker->end && start<=marker->start && marker->start<=end) ||
+				(marker->start<end && marker->end>start))
+			return marker;
+	}
+	return NULL;
+}
+
+/* Clears all matching markers on the specified line between two points
+   If flags is zero, all markers will be cleared */
+void txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int flags) {
+	TextMarker *marker, *next;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list