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
diff options
context:
space:
mode:
-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;