Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorIan Thompson <quornian@googlemail.com>2008-08-05 03:01:47 +0400
committerIan Thompson <quornian@googlemail.com>2008-08-05 03:01:47 +0400
commit53e535dfcf9637e3aa3327dd3bf2793a67756868 (patch)
treeedc307efe53008580feeffab327056779b8ab6b0 /source
parented5002458b810974277b7a6bd5d9c3c29d052d53 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_text.h13
-rw-r--r--source/blender/blenkernel/intern/text.c275
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/writefile.c10
-rw-r--r--source/blender/makesdna/DNA_text_types.h8
-rw-r--r--source/blender/src/drawtext.c546
6 files changed, 668 insertions, 185 deletions
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index abdf32c8ea5..de54b6413ae 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -100,6 +100,15 @@ int setcurr_tab (struct Text *text);
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 @@ void txt_paste_clipboard (struct Text *text);
#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
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 67beb4e4397..611eed3999e 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -148,6 +148,7 @@ void free_text(Text *text)
}
BLI_freelistN(&text->lines);
+ BLI_freelistN(&text->markers);
if(text->name) MEM_freeN(text->name);
MEM_freeN(text->undo_buf);
@@ -172,6 +173,7 @@ Text *add_empty_text(char *name)
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 @@ Text *add_text(char *file)
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 @@ Text *copy_text(Text *ta)
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 @@ int txt_has_sel(Text *text)
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 @@ static void txt_delete_sel (Text *text)
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,12 +2073,29 @@ void txt_do_redo(Text *text)
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 */
@@ -2094,9 +2134,23 @@ void txt_split_curline (Text *text)
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_delete_line (Text *text, TextLine *line)
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 @@ static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
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 @@ void txt_delete_char (Text *text)
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 @@ void txt_delete_char (Text *text)
}
} 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 @@ void txt_backspace_char (Text *text)
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 @@ void txt_backspace_char (Text *text)
txt_combine_lines(text, text->curl, text->curl->next);
txt_pop_sel(text);
- }
+ }
else { /* Just backspacing a char */
- int i= text->curc-1;
-
- 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--;
+ 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);
+ }
- 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 @@ void txt_backspace_word (Text *text)
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 @@ int txt_add_char (Text *text, char add)
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 @@ int setcurr_tab (Text *text)
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;
+ 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))
+ BLI_freelinkN(&text->markers, marker);
+ }
+}
+
+/* Clears all markers with matching flags (useful for clearing temporary markers) */
+void txt_clear_markers(Text *text, int flags) {
+ TextMarker *marker, *next;
+
+ for (marker=text->markers.first; marker; marker=next) {
+ next= marker->next;
+
+ if (marker->flags == flags)
+ BLI_freelinkN(&text->markers, marker);
+ }
+}
+
+/* Finds the marker at the specified line and cursor position with matching flags.
+ If flags is zero, all markers will be searched */
+TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int flags) {
+ TextMarker *marker;
+ int lineno= txt_get_span(text->lines.first, line);
+
+ for (marker=text->markers.first; marker; marker=marker->next) {
+ if (flags && marker->flags != flags) continue;
+ else if (marker->lineno < lineno) continue;
+ else if (marker->lineno > lineno) break;
+
+ if (marker->start <= curs && curs <= marker->end)
+ return marker;
+ }
+ return NULL;
+}
+
+/* Finds the previous marker with matching flags. If no other marker is found, the
+ same one will be returned */
+TextMarker *txt_prev_marker(Text *text, TextMarker *marker) {
+ TextMarker *tmp= marker;
+ while (tmp) {
+ if (tmp->prev) tmp= tmp->prev;
+ else tmp= text->markers.last;
+ if (tmp->flags == marker->flags)
+ return tmp;
+ }
+ return NULL; /* Only if marker==NULL */
+}
+
+/* Finds the next marker with matching flags. If no other marker is found, the
+ same one will be returned */
+TextMarker *txt_next_marker(Text *text, TextMarker *marker) {
+ TextMarker *tmp= marker;
+ while (tmp) {
+ if (tmp->next) tmp= tmp->next;
+ else tmp= text->markers.first;
+ if (tmp->flags == marker->flags)
+ return tmp;
+ }
+ return NULL; /* Only if marker==NULL */
+} \ No newline at end of file
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ad19cde3c9b..29fd314236b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2273,6 +2273,7 @@ static void direct_link_text(FileData *fd, Text *text)
*/
link_list(fd, &text->lines);
+ link_list(fd, &text->markers);
text->curl= newdataadr(fd, text->curl);
text->sell= newdataadr(fd, text->sell);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 3a70438dd13..3af7d3f7c25 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1845,6 +1845,7 @@ static void write_texts(WriteData *wd, ListBase *idbase)
{
Text *text;
TextLine *tmp;
+ TextMarker *mrk;
text= idbase->first;
while(text) {
@@ -1868,7 +1869,16 @@ static void write_texts(WriteData *wd, ListBase *idbase)
writedata(wd, DATA, tmp->len+1, tmp->line);
tmp= tmp->next;
}
+
+ /* write markers */
+ mrk= text->markers.first;
+ while (mrk) {
+ writestruct(wd, DATA, "TextMarker", 1, mrk);
+ mrk= mrk->next;
+ }
}
+
+
text= text->id.next;
}
diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h
index bec4e0062f9..41ea0b23323 100644
--- a/source/blender/makesdna/DNA_text_types.h
+++ b/source/blender/makesdna/DNA_text_types.h
@@ -42,6 +42,12 @@ typedef struct TextLine {
int len, blen;
} TextLine;
+typedef struct TextMarker {
+ struct TextMarker *next, *prev;
+ int lineno, start, end, flags;
+ char clr[4], pad[4];
+} TextMarker;
+
typedef struct Text {
ID id;
@@ -52,12 +58,12 @@ typedef struct Text {
ListBase lines;
TextLine *curl, *sell;
int curc, selc;
+ ListBase markers;
char *undo_buf;
int undo_pos, undo_len;
void *compiled;
-
double mtime;
} Text;
diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c
index 335062cb055..a05133f47bd 100644
--- a/source/blender/src/drawtext.c
+++ b/source/blender/src/drawtext.c
@@ -123,6 +123,9 @@ def wrap(line, view_width, wrap_chars):
#define TOOL_SUGG_LIST 0x01
#define TOOL_DOCUMENT 0x02
+#define TMARK_GRP_CUSTOM 0x00010000 /* Lower 2 bytes used for flags */
+#define TMARK_GRP_FINDALL 0x00020000 /* Upper 2 bytes used for group */
+
/* forward declarations */
void drawtextspace(ScrArea *sa, void *spacedata);
@@ -141,7 +144,6 @@ static int check_whitespace(char ch);
static int get_wrap_width(SpaceText *st);
static int get_wrap_points(SpaceText *st, char *line);
-
static void get_suggest_prefix(Text *text);
static void confirm_suggestion(Text *text, int skipleft);
@@ -777,6 +779,77 @@ static int get_char_pos(SpaceText *st, char *line, int cur) {
return a;
}
+static void draw_markers(SpaceText *st) {
+ Text *text= st->text;
+ TextMarker *marker, *next;
+ TextLine *top, *bottom, *line;
+ int offl, offc, i, cy, x1, x2, y1, y2, x, y;
+
+ for (i=st->top, top= text->lines.first; top->next && i>0; i--) top= top->next;
+ for (i=st->viewlines-1, bottom=top; bottom->next && i>0; i--) bottom= bottom->next;
+
+ for (marker= text->markers.first; marker; marker= next) {
+ next= marker->next;
+ for (cy= 0, line= top; line; cy++, line= line->next) {
+ if (cy+st->top==marker->lineno) {
+ /* Remove broken markers */
+ if (marker->end>line->len || marker->start>marker->end) {
+ BLI_freelinkN(&text->markers, marker);
+ break;
+ }
+
+ wrap_offset(st, line, marker->start, &offl, &offc);
+ x1= get_char_pos(st, line->line, marker->start) - st->left + offc;
+ y1= cy + offl;
+ wrap_offset(st, line, marker->end, &offl, &offc);
+ x2= get_char_pos(st, line->line, marker->end) - st->left + offc;
+ y2= cy + offl;
+
+ glColor3ub(marker->clr[0], marker->clr[1], marker->clr[2]);
+ x= st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
+ y= curarea->winy-3;
+
+ if (y1==y2) {
+ y -= y1*st->lheight;
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(x+x2*spacetext_get_fontwidth(st), y);
+ glVertex2i(x+x1*spacetext_get_fontwidth(st)-1, y);
+ glVertex2i(x+x1*spacetext_get_fontwidth(st)-1, y-st->lheight);
+ glVertex2i(x+x2*spacetext_get_fontwidth(st), y-st->lheight);
+ glEnd();
+ } else {
+ y -= y1*st->lheight;
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(curarea->winx, y);
+ glVertex2i(x+x1*spacetext_get_fontwidth(st)-1, y);
+ glVertex2i(x+x1*spacetext_get_fontwidth(st)-1, y-st->lheight);
+ glVertex2i(curarea->winx, y-st->lheight);
+ glEnd();
+ y-=st->lheight;
+ for (i=y1+1; i<y2; i++) {
+ glBegin(GL_LINES);
+ glVertex2i(x, y);
+ glVertex2i(curarea->winx, y);
+ glVertex2i(x, y-st->lheight);
+ glVertex2i(curarea->winx, y-st->lheight);
+ glEnd();
+ y-=st->lheight;
+ }
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x+x2*spacetext_get_fontwidth(st), y);
+ glVertex2i(x+x2*spacetext_get_fontwidth(st), y-st->lheight);
+ glVertex2i(x, y-st->lheight);
+ glEnd();
+ }
+
+ break;
+ }
+ if (line==bottom) break;
+ }
+ }
+}
+
static void draw_cursor(SpaceText *st) {
Text *text= st->text;
int vcurl, vcurc, vsell, vselc, hidden=0;
@@ -1410,6 +1483,7 @@ void drawtextspace(ScrArea *sa, void *spacedata)
}
draw_brackets(st);
+ draw_markers(st);
draw_textscroll(st);
draw_documentation(st);
@@ -2032,6 +2106,277 @@ static void confirm_suggestion(Text *text, int skipleft) {
texttool_text_clear();
}
+static short do_texttools(SpaceText *st, char ascii, unsigned short evnt, short val) {
+ int draw=0, swallow=0, tools=0, tools_cancel=0, tools_update=0, scroll=1;
+ if (!texttool_text_is_active(st->text)) return 0;
+ if (!st->text || st->text->id.lib) return 0;
+
+ if (st->showsyntax && texttool_text_is_active(st->text)) {
+ if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST;
+ if (texttool_docs_get()) tools |= TOOL_DOCUMENT;
+ }
+
+ if (ascii) {
+ if (tools & TOOL_SUGG_LIST) {
+ if ((ascii != '_' && ascii != '*' && ispunct(ascii)) || check_whitespace(ascii)) {
+ confirm_suggestion(st->text, 0);
+ if (st->showsyntax) txt_format_line(st, st->text->curl, 1);
+ } else if ((st->overwrite && txt_replace_char(st->text, ascii)) || txt_add_char(st->text, ascii)) {
+ tools_update |= TOOL_SUGG_LIST;
+ swallow= 1;
+ draw= 1;
+ }
+ }
+ tools_cancel |= TOOL_DOCUMENT;
+
+ } else if (val) {
+ switch (evnt) {
+ case LEFTMOUSE:
+ if (do_suggest_select(st)) swallow= 1;
+ else tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
+ draw= 1;
+ break;
+ case MIDDLEMOUSE:
+ if (do_suggest_select(st)) {
+ confirm_suggestion(st->text, 0);
+ if (st->showsyntax) txt_format_line(st, st->text->curl, 1);
+ swallow= 1;
+ } else
+ tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
+ draw= 1;
+ break;
+ case ESCKEY:
+ swallow= 1;
+ if (tools & TOOL_SUGG_LIST)
+ tools_cancel |= TOOL_SUGG_LIST;
+ else if (tools & TOOL_DOCUMENT)
+ tools_cancel |= TOOL_DOCUMENT;
+ else
+ swallow= 0;
+ break;
+ case RETKEY:
+ if (tools & TOOL_SUGG_LIST) {
+ confirm_suggestion(st->text, 0);
+ if (st->showsyntax) txt_format_line(st, st->text->curl, 1);
+ swallow= 1;
+ draw= 1;
+ }
+ tools_cancel |= TOOL_DOCUMENT;
+ break;
+ case BACKSPACEKEY:
+ if (tools & TOOL_SUGG_LIST) {
+ if (G.qual) tools_cancel |= TOOL_SUGG_LIST;
+ else {
+ /* Work out which char we are about to delete */
+ if (st->text->curl && st->text->curc > 0) {
+ char ch= st->text->curl->line[st->text->curc-1];
+ if ((ch=='_' || !ispunct(ch)) && !check_whitespace(ch))
+ tools_update |= TOOL_SUGG_LIST;
+ else
+ tools_cancel |= TOOL_SUGG_LIST;
+ }
+ }
+ }
+ tools_cancel |= TOOL_DOCUMENT;
+ break;
+ case PAGEDOWNKEY:
+ scroll= SUGG_LIST_SIZE-1;
+ case WHEELDOWNMOUSE:
+ case DOWNARROWKEY:
+ if (tools & TOOL_DOCUMENT) {
+ doc_scroll++;
+ swallow= 1;
+ draw= 1;
+ break;
+ } else if (tools & TOOL_SUGG_LIST) {
+ SuggItem *sel = texttool_suggest_selected();
+ if (!sel) {
+ texttool_suggest_select(texttool_suggest_first());
+ } else while (sel && sel!=texttool_suggest_last() && sel->next && scroll--) {
+ texttool_suggest_select(sel->next);
+ sel= sel->next;
+ }
+ swallow= 1;
+ draw= 1;
+ break;
+ }
+ case PAGEUPKEY:
+ scroll= SUGG_LIST_SIZE-1;
+ case WHEELUPMOUSE:
+ case UPARROWKEY:
+ if (tools & TOOL_DOCUMENT) {
+ if (doc_scroll>0) doc_scroll--;
+ swallow= 1;
+ draw= 1;
+ break;
+ } else if (tools & TOOL_SUGG_LIST) {
+ SuggItem *sel = texttool_suggest_selected();
+ while (sel && sel!=texttool_suggest_first() && sel->prev && scroll--) {
+ texttool_suggest_select(sel->prev);
+ sel= sel->prev;
+ }
+ swallow= 1;
+ draw= 1;
+ break;
+ }
+ default:
+ if (G.qual!=0 && G.qual!=LR_SHIFTKEY)
+ tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
+ }
+ }
+
+ if (tools & TOOL_SUGG_LIST) {
+ if (tools_update & TOOL_SUGG_LIST) {
+ get_suggest_prefix(st->text);
+ } else if (tools_cancel & TOOL_SUGG_LIST) {
+ texttool_suggest_clear();
+ }
+ draw= 1;
+ }
+ if (tools & TOOL_DOCUMENT) {
+ if (tools_cancel & TOOL_DOCUMENT) {
+ texttool_docs_clear();
+ doc_scroll= 0;
+ }
+ draw= 1;
+ }
+
+ if (draw) {
+ ScrArea *sa;
+
+ for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+ SpaceText *st= sa->spacedata.first;
+
+ if (st && st->spacetype==SPACE_TEXT) {
+ scrarea_queue_redraw(sa);
+ }
+ }
+ }
+
+ return swallow;
+}
+
+static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short val) {
+ Text *text;
+ TextMarker *marker, *mrk, *nxt;
+ int c, s, draw=0, swallow=0;
+
+ text= st->text;
+ if (!text || text->curl != text->sell) return 0;
+
+ marker= txt_find_marker(text, text->curl, text->curc, 0);
+ if (!marker || text->id.lib) return 0;
+
+ if (ascii) {
+ if (marker->flags & TMARK_EDITALL) {
+ c= text->curc-marker->start;
+ s= text->selc-marker->start;
+ if (s<0 || s>marker->end-marker->start) return 0;
+
+ mrk= txt_next_marker(text, marker);
+ while (mrk) {
+ txt_move_to(text, mrk->lineno, mrk->start+c, 0);
+ if (s!=c) txt_move_to(text, mrk->lineno, mrk->start+s, 1);
+ if (st->overwrite) {
+ if (txt_replace_char(text, ascii))
+ if (st->showsyntax) txt_format_line(st, text->curl, 1);
+ } else {
+ if (txt_add_char(text, ascii)) {
+ if (st->showsyntax) txt_format_line(st, text->curl, 1);
+ }
+ }
+
+ if (mrk==marker) break;
+ mrk=txt_next_marker(text, mrk);
+ }
+ swallow= 1;
+ draw= 1;
+ }
+ } else if (val) {
+ switch(evnt) {
+ case BACKSPACEKEY:
+ if (marker->flags & TMARK_EDITALL) {
+ c= text->curc-marker->start;
+ s= text->selc-marker->start;
+ if (s<0 || s>marker->end-marker->start) return 0;
+
+ mrk= txt_next_marker(text, marker);
+ while (mrk) {
+ nxt= txt_next_marker(text, mrk); /* mrk may become invalid */
+ txt_move_to(text, mrk->lineno, mrk->start+c, 0);
+ if (s!=c) txt_move_to(text, mrk->lineno, mrk->start+s, 1);
+ txt_backspace_char(text);
+ if (st->showsyntax) txt_format_line(st, text->curl, 1);
+ if (mrk==marker) break;
+ mrk= nxt;
+ }
+ swallow= 1;
+ draw= 1;
+ }
+ break;
+ case DELKEY:
+ if (marker->flags & TMARK_EDITALL) {
+ c= text->curc-marker->start;
+ s= text->selc-marker->start;
+ if (s<0 || s>marker->end-marker->start) return 0;
+
+ mrk= txt_next_marker(text, marker);
+ while (mrk) {
+ nxt= txt_next_marker(text, mrk); /* mrk may become invalid */
+ txt_move_to(text, mrk->lineno, mrk->start+c, 0);
+ if (s!=c) txt_move_to(text, mrk->lineno, mrk->start+s, 1);
+ txt_delete_char(text);
+ if (st->showsyntax) txt_format_line(st, text->curl, 1);
+ if (mrk==marker) break;
+ mrk= nxt;
+ }
+ swallow= 1;
+ draw= 1;
+ }
+ break;
+ case TABKEY:
+ marker= (G.qual & LR_SHIFTKEY) ? txt_prev_marker(text, marker) : txt_next_marker(text, marker);
+ txt_move_to(text, marker->lineno, marker->start, 0);
+ txt_move_to(text, marker->lineno, marker->end, 1);
+ pop_space_text(st);
+ swallow= 1;
+ draw= 1;
+ break;
+
+ /* Events that should clear markers */
+ case RETKEY:
+ case ESCKEY:
+ if (marker->flags & (TMARK_EDITALL | TMARK_TEMP))
+ txt_clear_markers(text, marker->flags);
+ else
+ BLI_freelinkN(&text->markers, marker);
+ swallow= 1;
+ draw= 1;
+ break;
+ case RIGHTMOUSE: /* Marker context menu? */
+ case LEFTMOUSE:
+ break;
+
+ default:
+ if (G.qual!=0 && G.qual!=LR_SHIFTKEY)
+ swallow= 1; /* Swallow all other shortcut events */
+ }
+ }
+
+ if (draw) {
+ ScrArea *sa;
+
+ for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+ SpaceText *st= sa->spacedata.first;
+
+ if (st && st->spacetype==SPACE_TEXT) {
+ scrarea_queue_redraw(sa);
+ }
+ }
+ }
+ return swallow;
+}
+
void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
unsigned short event= evt->event;
@@ -2040,7 +2385,6 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
SpaceText *st= curarea->spacedata.first;
Text *text;
int do_draw=0, p;
- int tools=0, tools_cancel=0, tools_update=0; /* Bitmasks for operations */
if (st==NULL || st->spacetype != SPACE_TEXT) return;
@@ -2104,10 +2448,8 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
return;
}
- if (st->showsyntax && texttool_text_is_active(text)) {
- if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST;
- if (texttool_docs_get()) tools |= TOOL_DOCUMENT;
- }
+ if (st->showsyntax && do_texttools(st, ascii, event, val)) return;
+ if (do_markers(st, ascii, event, val)) return;
if (event==LEFTMOUSE) {
if (val) {
@@ -2118,9 +2460,6 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (mval[0]>2 && mval[0]<20 && mval[1]>2 && mval[1]<curarea->winy-2) {
do_textscroll(st, 2);
- tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
- } else if (do_suggest_select(st)) {
- do_draw= 1;
} else {
do_selection(st, G.qual&LR_SHIFTKEY);
if (txt_has_sel(text)) {
@@ -2129,24 +2468,16 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
MEM_freeN(buffer);
}
do_draw= 1;
- tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
}
}
} else if (event==MIDDLEMOUSE) {
if (val) {
- if (do_suggest_select(st)) {
- confirm_suggestion(text, 0);
+ if (U.uiflag & USER_MMB_PASTE) {
+ do_selection(st, G.qual&LR_SHIFTKEY);
+ get_selection_buffer(text);
do_draw= 1;
} else {
- if (U.uiflag & USER_MMB_PASTE) {
- do_selection(st, G.qual&LR_SHIFTKEY);
- get_selection_buffer(text);
- do_draw= 1;
- tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
- } else {
- do_textscroll(st, 1);
- tools_cancel |= TOOL_SUGG_LIST;
- }
+ do_textscroll(st, 1);
}
}
} else if (event==RIGHTMOUSE) {
@@ -2180,33 +2511,16 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
default:
break;
}
- tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
}
} else if (ascii) {
if (text && text->id.lib) {
error_libdata();
-
} else if ((st->overwrite && txt_replace_char(text, ascii)) || txt_add_char(text, ascii)) {
if (st->showsyntax) txt_format_line(st, text->curl, 1);
pop_space_text(st);
do_draw= 1;
- if (tools & TOOL_SUGG_LIST) {
- if ((ascii != '_' && ascii != '*' && ispunct(ascii)) || check_whitespace(ascii)) {
- confirm_suggestion(text, 1);
- if (st->showsyntax) txt_format_line(st, text->curl, 1);
- } else {
- tools_update |= TOOL_SUGG_LIST;
- }
- }
- tools_cancel |= TOOL_DOCUMENT;
}
} else if (val) {
-
- /* Cases that require tools not to be cancelled must explicitly say so.
- * The default case does this to prevent window/mousemove events
- * from cancelling. */
- tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
-
switch (event) {
case AKEY:
if (G.qual & LR_ALTKEY) {
@@ -2334,6 +2648,16 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (G.qual == LR_ALTKEY) {
txt_export_to_object(text);
do_draw= 1;
+ } else if ((G.qual & LR_CTRLKEY) && text->sell==text->curl) {
+ int a= text->curc < text->selc ? text->curc : text->selc;
+ int b= text->curc < text->selc ? text->selc : text->curc;
+
+ /* Don't allow overlapping markers */
+ txt_clear_marker_region(text, text->curl, a, b, TMARK_GRP_CUSTOM);
+ if (!(G.qual & LR_ALTKEY)) {
+ txt_add_marker(text, text->curl, a, b, "\xFF\xC0\xFF\xFF", TMARK_GRP_CUSTOM | TMARK_EDITALL);
+ do_draw= 1;
+ }
}
break; /* BREAK M */
case NKEY:
@@ -2477,31 +2801,26 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
do_draw= 1;
}
break;
- case ESCKEY:
- /* To allow ESC to close one tool at a time we remove all others from the cancel list */
- if (tools & TOOL_DOCUMENT) {
- tools_cancel &= ~TOOL_SUGG_LIST;
- }
- break;
case TABKEY:
if (text && text->id.lib) {
error_libdata();
break;
- }
- if (G.qual & LR_SHIFTKEY) {
- if (txt_has_sel(text)) {
- txt_order_cursors(text);
- unindent(text);
- if (st->showsyntax) txt_format_text(st);
- }
} else {
- if ( txt_has_sel(text)) {
- txt_order_cursors(text);
- indent(text);
- if (st->showsyntax) txt_format_text(st);
+ if (G.qual & LR_SHIFTKEY) {
+ if (txt_has_sel(text)) {
+ txt_order_cursors(text);
+ unindent(text);
+ if (st->showsyntax) txt_format_text(st);
+ }
} else {
- txt_add_char(text, '\t');
- if (st->showsyntax) txt_format_line(st, text->curl, 1);
+ if ( txt_has_sel(text)) {
+ txt_order_cursors(text);
+ indent(text);
+ if (st->showsyntax) txt_format_text(st);
+ } else {
+ txt_add_char(text, '\t');
+ if (st->showsyntax) txt_format_line(st, text->curl, 1);
+ }
}
}
pop_space_text(st);
@@ -2513,11 +2832,6 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
error_libdata();
break;
}
- if (tools & TOOL_SUGG_LIST) {
- confirm_suggestion(text, 0);
- if (st->showsyntax) txt_format_line(st, text->curl, 1);
- break;
- }
//double check tabs before splitting the line
st->currtab_set = setcurr_tab(text);
txt_split_curline(text);
@@ -2545,15 +2859,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
if (G.qual & (LR_ALTKEY | LR_CTRLKEY)) {
txt_backspace_word(text);
- tools_cancel |= TOOL_SUGG_LIST;
} else {
- /* Work out which char we are about to delete */
- if (text && text->curl && text->curc > 0) {
- char ch= text->curl->line[text->curc-1];
- if (!ispunct(ch) && !check_whitespace(ch)) {
- tools_update |= TOOL_SUGG_LIST;
- }
- }
txt_backspace_char(text);
}
set_tabs(text);
@@ -2579,23 +2885,8 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case INSERTKEY:
st->overwrite= !st->overwrite;
do_draw= 1;
- tools_cancel = 0;
break;
case DOWNARROWKEY:
- if (tools & TOOL_DOCUMENT) {
- doc_scroll++;
- tools_cancel &= ~(TOOL_SUGG_LIST | TOOL_DOCUMENT);
- break;
- } else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- if (!sel) {
- texttool_suggest_select(texttool_suggest_first());
- } else if (sel!=texttool_suggest_last() && sel->next) {
- texttool_suggest_select(sel->next);
- }
- tools_cancel &= ~TOOL_SUGG_LIST;
- break;
- }
txt_move_down(text, G.qual & LR_SHIFTKEY);
set_tabs(text);
do_draw= 1;
@@ -2624,48 +2915,17 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
pop_space_text(st);
break;
case UPARROWKEY:
- if (tools & TOOL_DOCUMENT) {
- if (doc_scroll) doc_scroll--;
- tools_cancel &= ~(TOOL_SUGG_LIST | TOOL_DOCUMENT);
- break;
- } else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- if (sel && sel!=texttool_suggest_first() && sel->prev)
- texttool_suggest_select(sel->prev);
- tools_cancel &= ~TOOL_SUGG_LIST;
- break;
- }
txt_move_up(text, G.qual & LR_SHIFTKEY);
set_tabs(text);
do_draw= 1;
pop_space_text(st);
break;
case PAGEDOWNKEY:
- if (tools & TOOL_SUGG_LIST) {
- int i;
- SuggItem *sel = texttool_suggest_selected();
- if (!sel)
- sel = texttool_suggest_first();
- for (i=0; i<SUGG_LIST_SIZE-1 && sel && sel!=texttool_suggest_last() && sel->next; i++, sel=sel->next)
- texttool_suggest_select(sel->next);
- tools_cancel &= ~TOOL_SUGG_LIST;
- break;
- } else {
- screen_skip(st, st->viewlines);
- }
+ screen_skip(st, st->viewlines);
do_draw= 1;
break;
case PAGEUPKEY:
- if (tools & TOOL_SUGG_LIST) {
- int i;
- SuggItem *sel = texttool_suggest_selected();
- for (i=0; i<SUGG_LIST_SIZE-1 && sel && sel!=texttool_suggest_first() && sel->prev; i++, sel=sel->prev)
- texttool_suggest_select(sel->prev);
- tools_cancel &= ~TOOL_SUGG_LIST;
- break;
- } else {
- screen_skip(st, -st->viewlines);
- }
+ screen_skip(st, -st->viewlines);
do_draw= 1;
break;
case HOMEKEY:
@@ -2679,43 +2939,13 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
pop_space_text(st);
break;
case WHEELUPMOUSE:
- if (tools & TOOL_DOCUMENT) {
- if (doc_scroll) doc_scroll--;
- tools_cancel &= ~(TOOL_SUGG_LIST | TOOL_DOCUMENT);
- break;
- } else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- if (sel && sel!=texttool_suggest_first() && sel->prev)
- texttool_suggest_select(sel->prev);
- tools_cancel &= ~TOOL_SUGG_LIST;
- } else {
- screen_skip(st, -U.wheellinescroll);
- tools_cancel &= ~TOOL_DOCUMENT;
- }
+ screen_skip(st, -U.wheellinescroll);
do_draw= 1;
break;
case WHEELDOWNMOUSE:
- if (tools & TOOL_DOCUMENT) {
- doc_scroll++;
- tools_cancel &= ~(TOOL_SUGG_LIST | TOOL_DOCUMENT);
- break;
- } else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- if (!sel) {
- texttool_suggest_select(texttool_suggest_first());
- } else if (sel && sel!=texttool_suggest_last() && sel->next) {
- texttool_suggest_select(sel->next);
- }
- tools_cancel &= ~TOOL_SUGG_LIST;
- } else {
- screen_skip(st, U.wheellinescroll);
- tools_cancel &= ~TOOL_DOCUMENT;
- }
+ screen_skip(st, U.wheellinescroll);
do_draw= 1;
break;
- default:
- /* We don't want all sorts of events closing the suggestions box */
- tools_cancel &= ~TOOL_SUGG_LIST & ~TOOL_DOCUMENT;
}
}
@@ -2779,22 +3009,6 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
- if (tools & TOOL_SUGG_LIST) {
- if (tools_update & TOOL_SUGG_LIST) {
- get_suggest_prefix(text);
- } else if (tools_cancel & TOOL_SUGG_LIST) {
- texttool_suggest_clear();
- }
- do_draw= 1;
- }
- if (tools & TOOL_DOCUMENT) {
- if (tools_cancel & TOOL_DOCUMENT) {
- texttool_docs_clear();
- doc_scroll= 0;
- }
- do_draw= 1;
- }
-
if (do_draw) {
ScrArea *sa;