Added better grouping for text markers with a separate group field (instead of using flags). The lower two bytes of the group are used for python scripts while the upper two (or more) are reserved for internal grouping. Plenty either way.

This commit is contained in:
2008-08-24 13:30:35 +00:00
parent d6a9f7f485
commit bf0803c0c2
6 changed files with 61 additions and 77 deletions

View File

@@ -101,11 +101,11 @@ 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);
short txt_clear_marker_region (struct Text *text, struct TextLine *line, int start, int end, int flags);
short 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);
void txt_add_marker (struct Text *text, struct TextLine *line, int start, int end, char clr[4], int group, int flags);
short txt_clear_marker_region (struct Text *text, struct TextLine *line, int start, int end, int group, int flags);
short txt_clear_markers (struct Text *text, int group, int flags);
struct TextMarker *txt_find_marker (struct Text *text, struct TextLine *line, int curs, int group, int flags);
struct TextMarker *txt_find_marker_region (struct Text *text, struct TextLine *line, int start, int end, int group, int flags);
struct TextMarker *txt_prev_marker (struct Text *text, struct TextMarker *marker);
struct TextMarker *txt_next_marker (struct Text *text, struct TextMarker *marker);
struct TextMarker *txt_prev_marker_color (struct Text *text, struct TextMarker *marker);

View File

@@ -987,16 +987,16 @@ 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);
txt_clear_marker_region(text, text->curl, text->curc, text->curl->len, 0, 0);
move= txt_get_span(text->curl, text->sell);
} else {
mrk= txt_find_marker_region(text, text->curl, text->curc, text->selc, 0);
mrk= txt_find_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
if (mrk && (mrk->start > text->curc || mrk->end < text->selc))
txt_clear_marker_region(text, text->curl, text->curc, text->selc, 0);
txt_clear_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
move= 0;
}
mrk= txt_find_marker_region(text, text->sell, text->selc-1, text->sell->len, 0);
mrk= txt_find_marker_region(text, text->sell, text->selc-1, text->sell->len, 0, 0);
if (mrk) {
lineno= mrk->lineno;
do {
@@ -2190,7 +2190,7 @@ static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
if(!linea || !lineb) return;
mrk= txt_find_marker_region(text, lineb, 0, lineb->len, 0);
mrk= txt_find_marker_region(text, lineb, 0, lineb->len, 0, 0);
if (mrk) {
lineno= mrk->lineno;
do {
@@ -2236,12 +2236,12 @@ 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);
TextMarker *mrk= txt_find_marker_region(text, text->curl, i-1, text->curl->len, 0, 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);
txt_clear_markers(text, mrk->group, TMARK_TEMP);
} else {
TextMarker *nxt= mrk->next;
BLI_freelinkN(&text->markers, mrk);
@@ -2301,12 +2301,12 @@ void txt_backspace_char (Text *text)
else { /* Just backspacing a char */
int i= text->curc-1;
TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0);
TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0, 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);
txt_clear_markers(text, mrk->group, TMARK_TEMP);
} else {
TextMarker *nxt= mrk->next;
BLI_freelinkN(&text->markers, mrk);
@@ -2359,7 +2359,7 @@ 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);
mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0);
if (mrk) {
lineno= mrk->lineno;
do {
@@ -2401,7 +2401,7 @@ int txt_replace_char (Text *text, char add)
if (text->curc==text->curl->len || txt_has_sel(text) || add=='\n') {
TextMarker *mrk;
int i= txt_add_char(text, add);
mrk= txt_find_marker(text, text->curl, text->curc, 0);
mrk= txt_find_marker(text, text->curl, text->curc, 0, 0);
if (mrk && mrk->end==text->curc) mrk->end--;
return i;
}
@@ -2689,7 +2689,7 @@ static int color_match(TextMarker *a, TextMarker *b) {
}
/* 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) {
void txt_add_marker(Text *text, TextLine *line, int start, int end, char clr[4], int group, int flags) {
TextMarker *tmp, *marker;
marker= MEM_mallocN(sizeof(TextMarker), "text_marker");
@@ -2697,6 +2697,7 @@ void txt_add_marker(Text *text, TextLine *line, int start, int end, char clr[4],
marker->lineno= txt_get_span(text->lines.first, line);
marker->start= MIN2(start, end);
marker->end= MAX2(start, end);
marker->group= group;
marker->flags= flags;
marker->clr[0]= clr[0];
@@ -2712,17 +2713,18 @@ void txt_add_marker(Text *text, TextLine *line, int start, int end, char clr[4],
else BLI_addhead(&text->markers, marker);
}
/* Returns the first matching marker on the specified line between two points,
with at least the specified flags set. If flags is zero, all markers will be
searched */
TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int flags) {
/* Returns the first matching marker on the specified line between two points.
If the group or flags fields are non-zero the returned flag must be in the
specified group and have at least the specified flags set. */
TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, 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 ((marker->flags & flags) != flags) continue;
if (group && marker->group != group) continue;
else if ((marker->flags & flags) != flags) continue;
else if (marker->lineno < lineno) continue;
else if (marker->lineno > lineno) break;
@@ -2733,9 +2735,10 @@ TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int en
return NULL;
}
/* Clears all markers on the specified line between two points with at least
the specified flags set. If flags is zero, all markers will be cleared */
short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int flags) {
/* Clears all markers on the specified line between two points. If the group or
flags fields are non-zero the returned flag must be in the specified group
and have at least the specified flags set. */
short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) {
TextMarker *marker, *next;
int lineno= txt_get_span(text->lines.first, line);
short cleared= 0;
@@ -2743,7 +2746,8 @@ short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, in
for (marker=text->markers.first; marker; marker=next) {
next= marker->next;
if ((marker->flags & flags) != flags) continue;
if (group && marker->group != group) continue;
else if ((marker->flags & flags) != flags) continue;
else if (marker->lineno < lineno) continue;
else if (marker->lineno > lineno) break;
@@ -2756,16 +2760,18 @@ short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, in
return cleared;
}
/* Clears all markers with at least the specified flags set (useful for
clearing temporary markers) */
short txt_clear_markers(Text *text, int flags) {
/* Clears all markers in the specified group (if given) with at least the
specified flags set. Useful for clearing temporary markers (group=0,
flags=TMARK_TEMP) */
short txt_clear_markers(Text *text, int group, int flags) {
TextMarker *marker, *next;
short cleared= 0;
for (marker=text->markers.first; marker; marker=next) {
next= marker->next;
if ((marker->flags & flags) == flags) {
if ((!group || marker->group==group) &&
(marker->flags & flags) == flags) {
BLI_freelinkN(&text->markers, marker);
cleared= 1;
}
@@ -2774,13 +2780,14 @@ short txt_clear_markers(Text *text, int flags) {
}
/* Finds the marker at the specified line and cursor position with at least the
specified flags set. If flags is zero, all markers will be searched */
TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int flags) {
specified flags set in the given group (if non-zero). */
TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags) {
TextMarker *marker;
int lineno= txt_get_span(text->lines.first, line);
for (marker=text->markers.first; marker; marker=marker->next) {
if ((marker->flags & flags) != flags) continue;
if (group && marker->group != group) continue;
else if ((marker->flags & flags) != flags) continue;
else if (marker->lineno < lineno) continue;
else if (marker->lineno > lineno) break;
@@ -2790,53 +2797,27 @@ TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int flags) {
return NULL;
}
/* Finds the previous marker with matching flags. If no other marker is found,
the same one will be returned */
/* Finds the previous marker in the same group. If no other is found, the same
marker 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)
if (tmp->group == marker->group)
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 */
/* Finds the next marker in the same group. If no other is found, the same
marker 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 */
}
/* Finds the previous marker with matching colour. If no other marker is found,
the same one will be returned */
TextMarker *txt_prev_marker_color(Text *text, TextMarker *marker) {
TextMarker *tmp= marker;
while (tmp) {
if (tmp->prev) tmp= tmp->prev;
else tmp= text->markers.last;
if (color_match(tmp, marker))
return tmp;
}
return NULL; /* Only if marker==NULL */
}
/* Finds the next marker with matching colour. If no other marker is found, the
same one will be returned */
TextMarker *txt_next_marker_color(Text *text, TextMarker *marker) {
TextMarker *tmp= marker;
while (tmp) {
if (tmp->next) tmp= tmp->next;
else tmp= text->markers.first;
if (color_match(tmp, marker))
if (tmp->group == marker->group)
return tmp;
}
return NULL; /* Only if marker==NULL */

View File

@@ -44,7 +44,8 @@ typedef struct TextLine {
typedef struct TextMarker {
struct TextMarker *next, *prev;
int lineno, start, end, flags;
int lineno, start, end, pad1;
int group, flags;
char clr[4], pad[4];
} TextMarker;

View File

@@ -708,7 +708,9 @@ static PyObject *Text_markSelection( BPy_Text * self, PyObject * args )
clr[2] = (char) (b&0xFF);
clr[3] = 255;
txt_add_marker(text, text->curl, text->curc, text->selc, clr, ((group+2)<<16)|flags);
group &= 0xFFFF;
txt_add_marker(text, text->curl, text->curc, text->selc, clr, group, flags);
Py_RETURN_NONE;
}

View File

@@ -124,8 +124,8 @@ 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 */
#define TMARK_GRP_CUSTOM 0x00010000 /* Lower 2 bytes used for Python groups */
#define TMARK_GRP_FINDALL 0x00020000
/* forward declarations */
@@ -1507,7 +1507,7 @@ void find_and_replace(SpaceText *st, short mode) {
do {
if (first)
txt_clear_markers(text, TMARK_GRP_FINDALL);
txt_clear_markers(text, TMARK_GRP_FINDALL, 0);
first= 0;
/* Replace current */
@@ -1520,11 +1520,11 @@ void find_and_replace(SpaceText *st, short mode) {
} else if (mode==2) {
char clr[4];
BIF_GetThemeColor4ubv(TH_SHADE2, clr);
if (txt_find_marker(text, text->curl, text->selc, TMARK_GRP_FINDALL)) {
if (txt_find_marker(text, text->curl, text->selc, TMARK_GRP_FINDALL, 0)) {
if (tmp) MEM_freeN(tmp), tmp=NULL;
break;
}
txt_add_marker(text, text->curl, text->curc, text->selc, clr, TMARK_GRP_FINDALL | TMARK_EDITALL);
txt_add_marker(text, text->curl, text->curc, text->selc, clr, TMARK_GRP_FINDALL, TMARK_EDITALL);
}
}
MEM_freeN(tmp);
@@ -2477,7 +2477,7 @@ static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short va
text= st->text;
if (!text || text->id.lib || text->curl != text->sell) return 0;
marker= txt_find_marker(text, text->sell, text->selc, 0);
marker= txt_find_marker(text, text->sell, text->selc, 0, 0);
if (marker && (marker->start > text->curc || marker->end < text->curc))
marker= NULL;
@@ -2503,8 +2503,8 @@ static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short va
swallow= 1;
}
} else if (evnt==ESCKEY) {
if (txt_clear_markers(text, TMARK_TEMP)) swallow= 1;
else if (txt_clear_markers(text, 0)) swallow= 1;
if (txt_clear_markers(text, 0, TMARK_TEMP)) swallow= 1;
else if (txt_clear_markers(text, 0, 0)) swallow= 1;
else return 0;
evnt= ascii= val= 0;
draw= 1;
@@ -2608,7 +2608,7 @@ static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short va
case RETKEY:
case ESCKEY:
if (marker->flags & (TMARK_EDITALL | TMARK_TEMP))
txt_clear_markers(text, marker->flags);
txt_clear_markers(text, marker->group, 0);
else
BLI_freelinkN(&text->markers, marker);
swallow= 1;

View File

@@ -513,7 +513,7 @@ static void do_text_editmenu_markermenu(void *arg, int event)
switch(event) {
case 1:
txt_clear_markers(text, 0);
txt_clear_markers(text, 0, 0);
break;
case 2:
lineno= txt_get_span(text->lines.first, text->curl);