NLA SoC: Start of 'Meta' Strips
[blender.git] / source / blender / blenkernel / intern / text.c
index 35422353b0de4279b91cc8094f44b5e5103e7010..8e3d59bbc5869985a5ac92170d3fd27562640bfc 100644 (file)
 #include "DNA_scene_types.h"
 #include "DNA_text_types.h"
 
-#include "BKE_bad_level_calls.h"
 #include "BKE_utildefines.h"
 #include "BKE_text.h"
 #include "BKE_library.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 
+#ifndef DISABLE_PYTHON
 #include "BPY_extern.h"
+#endif
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -64,9 +65,6 @@ A text should relate to a file as follows -
 (Text *)->flags has the following bits
        TXT_ISDIRTY - should always be set if the file in mem. differs from
                                        the file on disk, or if there is no file on disk.
-       TXT_ISTMP - should always be set if the (Text *)->name file has not
-                                       been written before, and attempts to save should result
-                                       in "Save over?"
        TXT_ISMEM - should always be set if the Text has not been mapped to
                                        a file, in which case (Text *)->name may be NULL or garbage.                    
        TXT_ISEXT - should always be set if the Text is not to be written into
@@ -129,7 +127,6 @@ static void txt_delete_line(Text *text, TextLine *line);
 
 /***/
 
-static char *txt_cut_buffer= NULL;
 static unsigned char undoing;
 
 /* allow to switch off undoing externally */
@@ -158,7 +155,9 @@ void free_text(Text *text)
 
        if(text->name) MEM_freeN(text->name);
        MEM_freeN(text->undo_buf);
+#ifndef DISABLE_PYTHON
        if (text->compiled) BPY_free_compiled_text(text);
+#endif
 }
 
 Text *add_empty_text(char *name) 
@@ -176,7 +175,7 @@ Text *add_empty_text(char *name)
        ta->undo_buf= MEM_mallocN(ta->undo_len, "undo buf");
                
        ta->nlines=1;
-       ta->flags= TXT_ISDIRTY | TXT_ISTMP | TXT_ISMEM;
+       ta->flags= TXT_ISDIRTY | TXT_ISMEM;
 
        ta->lines.first= ta->lines.last= NULL;
        ta->markers.first= ta->markers.last= NULL;
@@ -254,8 +253,6 @@ int reopen_text(Text *text)
        text->undo_len= TXT_INIT_UNDO;
        text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
        
-       text->flags= TXT_ISTMP; 
-       
        fseek(fp, 0L, SEEK_END);
        len= ftell(fp);
        fseek(fp, 0L, SEEK_SET);        
@@ -319,7 +316,7 @@ int reopen_text(Text *text)
        return 1;
 }
 
-Text *add_text(char *file) 
+Text *add_text(char *file, const char *relpath
 {
        FILE *fp;
        int i, llen, len, res;
@@ -331,8 +328,8 @@ Text *add_text(char *file)
        struct stat st;
 
        BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE);
-       if (G.scene) /* can be NULL (bg mode) */
-               BLI_convertstringcode(str, G.sce);
+       if (relpath) /* can be NULL (bg mode) */
+               BLI_convertstringcode(str, relpath);
        BLI_split_dirfile_basic(str, NULL, sfile);
        
        fp= fopen(str, "r");
@@ -344,9 +341,6 @@ Text *add_text(char *file)
        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; */
-       ta->flags= TXT_ISTMP;
        
        fseek(fp, 0L, SEEK_END);
        len= ftell(fp);
@@ -427,7 +421,7 @@ Text *copy_text(Text *ta)
        tan->name= MEM_mallocN(strlen(ta->name)+1, "text_name");
        strcpy(tan->name, ta->name);
        
-       tan->flags = ta->flags | TXT_ISDIRTY | TXT_ISTMP;
+       tan->flags = ta->flags | TXT_ISDIRTY;
        
        tan->lines.first= tan->lines.last= NULL;
        tan->markers.first= tan->markers.last= NULL;
@@ -571,19 +565,22 @@ int txt_get_span (TextLine *from, TextLine *to)
 static void txt_make_dirty (Text *text)
 {
        text->flags |= TXT_ISDIRTY;
+#ifndef DISABLE_PYTHON
        if (text->compiled) BPY_free_compiled_text(text);
+#endif
 }
 
 /* 0:whitespace, 1:punct, 2:alphanumeric */
 static short txt_char_type (char ch)
 {
-       if (ch <= ' ') return 0;
-       if (ch <= '/') return 1;
-       if (ch <= '9') return 2;
-       if (ch <= '@') return 1;
-       if (ch <= 'Z') return 2;
-       if (ch <= '`') return 1;
-       if (ch <= 'z') return 2;
+       if (ch <= ' ') return 0; /* 32 */
+       if (ch <= '/') return 1; /* 47 */
+       if (ch <= '9') return 2; /* 57 */
+       if (ch <= '@') return 1; /* 64 */
+       if (ch <= 'Z') return 2; /* 90 */
+       if (ch == '_') return 2; /* 95, dont delimit '_' */
+       if (ch <= '`') return 1; /* 96 */
+       if (ch <= 'z') return 2; /* 122 */
        return 1;
 }
 
@@ -987,16 +984,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 {
@@ -1050,11 +1047,6 @@ void txt_sel_line (Text *text)
 /* Cut and paste functions */
 /***************************/
 
-void txt_print_cutbuffer (void) 
-{
-       printf ("Cut buffer\n--\n%s\n--\n", txt_cut_buffer);    
-}
-
 char *txt_to_buf (Text *text)
 {
        int length;
@@ -1159,15 +1151,6 @@ int txt_find_string(Text *text, char *findstr, int wrap)
                return 0;
 }
 
-void txt_cut_sel (Text *text)
-{
-       if (!G.background) /* Python uses txt_cut_sel, which it should not, working around for now  */
-               txt_copy_clipboard(text);
-       
-       txt_delete_sel(text);
-       txt_make_dirty(text);
-}
-
 char *txt_sel_to_buf (Text *text)
 {
        char *buf;
@@ -1245,85 +1228,6 @@ char *txt_sel_to_buf (Text *text)
        return buf;
 }
 
-void txt_copy_sel (Text *text)
-{
-       int length=0;
-       TextLine *tmp, *linef, *linel;
-       int charf, charl;
-       
-       if (!text) return;
-       if (!text->curl) return;
-       if (!text->sell) return;
-
-       if (!txt_has_sel(text)) return;
-       
-       if (txt_cut_buffer) MEM_freeN(txt_cut_buffer);
-       txt_cut_buffer= NULL;
-       
-       if (text->curl==text->sell) {
-               linef= linel= text->curl;
-               
-               if (text->curc < text->selc) {
-                       charf= text->curc;
-                       charl= text->selc;
-               } else{
-                       charf= text->selc;
-                       charl= text->curc;
-               }
-       } else if (txt_get_span(text->curl, text->sell)<0) {
-               linef= text->sell;
-               linel= text->curl;
-
-               charf= text->selc;              
-               charl= text->curc;
-       } else {
-               linef= text->curl;
-               linel= text->sell;
-               
-               charf= text->curc;
-               charl= text->selc;
-       }
-
-       if (linef == linel) {
-               length= charl-charf;
-
-               txt_cut_buffer= MEM_mallocN(length+1, "cut buffera");
-               
-               BLI_strncpy(txt_cut_buffer, linef->line + charf, length+1);
-       } else {
-               length+= linef->len - charf;
-               length+= charl;
-               length++; /* For the '\n' */
-               
-               tmp= linef->next;
-               while (tmp && tmp!= linel) {
-                       length+= tmp->len+1;
-                       tmp= tmp->next;
-               }
-               
-               txt_cut_buffer= MEM_mallocN(length+1, "cut bufferb");
-               
-               strncpy(txt_cut_buffer, linef->line+ charf, linef->len-charf);
-               length= linef->len-charf;
-               
-               txt_cut_buffer[length++]='\n';
-               
-               tmp= linef->next;
-               while (tmp && tmp!=linel) {
-                       strncpy(txt_cut_buffer+length, tmp->line, tmp->len);
-                       length+= tmp->len;
-                       
-                       txt_cut_buffer[length++]='\n';                  
-                       
-                       tmp= tmp->next;
-               }
-               strncpy(txt_cut_buffer+length, linel->line, charl);
-               length+= charl;
-               
-               txt_cut_buffer[length]=0;
-       }
-}
-
 void txt_insert_buf(Text *text, char *in_buffer)
 {
        int i=0, l=0, j, u, len;
@@ -1374,38 +1278,32 @@ void txt_insert_buf(Text *text, char *in_buffer)
        undoing= u;
 }
 
-void txt_free_cut_buffer(void) 
-{
-       if (txt_cut_buffer) MEM_freeN(txt_cut_buffer);
-}
-
-void txt_paste(Text *text)
-{
-       txt_insert_buf(text, txt_cut_buffer);
-}
-
 /******************/
 /* Undo functions */
 /******************/
 
-#define MAX_UNDO_TEST(x) \
-       while (text->undo_pos+x >= text->undo_len) { \
-               if(text->undo_len*2 > TXT_MAX_UNDO) { \
-                       error("Undo limit reached, buffer cleared\n"); \
-                       MEM_freeN(text->undo_buf); \
-                       text->undo_len= TXT_INIT_UNDO; \
-                       text->undo_buf= MEM_mallocN(text->undo_len, "undo buf"); \
-                       text->undo_pos=-1; \
-                       return; \
-               } else { \
-                       void *tmp= text->undo_buf; \
-                       text->undo_buf= MEM_callocN(text->undo_len*2, "undo buf"); \
-                       memcpy(text->undo_buf, tmp, text->undo_len); \
-                       text->undo_len*=2; \
-                       MEM_freeN(tmp); \
-               } \
+static int max_undo_test(Text *text, int x)
+{
+       while (text->undo_pos+x >= text->undo_len) {
+               if(text->undo_len*2 > TXT_MAX_UNDO) {
+                       /* XXX error("Undo limit reached, buffer cleared\n"); */
+                       MEM_freeN(text->undo_buf);
+                       text->undo_len= TXT_INIT_UNDO;
+                       text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
+                       text->undo_pos=-1;
+                       return 0;
+               } else {
+                       void *tmp= text->undo_buf;
+                       text->undo_buf= MEM_callocN(text->undo_len*2, "undo buf");
+                       memcpy(text->undo_buf, tmp, text->undo_len);
+                       text->undo_len*=2;
+                       MEM_freeN(tmp);
+               }
        }
 
+       return 1;
+}
+
 static void dump_buffer(Text *text) 
 {
        int i= 0;
@@ -1551,7 +1449,8 @@ void txt_print_undo(Text *text)
 
 static void txt_undo_add_op(Text *text, int op)
 {
-       MAX_UNDO_TEST(2);
+       if(!max_undo_test(text, 2))
+               return;
        
        text->undo_pos++;
        text->undo_buf[text->undo_pos]= op;
@@ -1564,7 +1463,8 @@ static void txt_undo_add_block(Text *text, int op, char *buf)
        
        length= strlen(buf);
        
-       MAX_UNDO_TEST(length+11);
+       if(!max_undo_test(text, length+11))
+               return;
 
        text->undo_pos++;
        text->undo_buf[text->undo_pos]= op;
@@ -1598,7 +1498,8 @@ static void txt_undo_add_block(Text *text, int op, char *buf)
 
 void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc)
 {
-       MAX_UNDO_TEST(15);
+       if(!max_undo_test(text, 15))
+               return;
 
        if (froml==tol && fromc==toc) return;
 
@@ -1641,7 +1542,8 @@ void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fr
 
 static void txt_undo_add_charop(Text *text, int op, char c)
 {
-       MAX_UNDO_TEST(4);
+       if(!max_undo_test(text, 4))
+               return;
 
        text->undo_pos++;
        text->undo_buf[text->undo_pos]= op;
@@ -1862,7 +1764,7 @@ void txt_do_undo(Text *text)
                        text->undo_pos--;
                        break;
                default:
-                       error("Undo buffer error - resetting");
+                       //XXX error("Undo buffer error - resetting");
                        text->undo_pos= -1;
                        
                        break;
@@ -2075,7 +1977,7 @@ void txt_do_redo(Text *text)
                        }
                        break;
                default:
-                       error("Undo buffer error - resetting");
+                       //XXX error("Undo buffer error - resetting");
                        text->undo_pos= -1;
 
                        break;
@@ -2190,7 +2092,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,14 +2138,13 @@ 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);
                                }
                                return;
@@ -2301,14 +2202,13 @@ 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);
                                }
                                return;
@@ -2359,7 +2259,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 {
@@ -2390,6 +2290,12 @@ int txt_add_char (Text *text, char add)
        return 1;
 }
 
+void txt_delete_selected(Text *text)
+{
+       txt_delete_sel(text);
+       txt_make_dirty(text);
+}
+
 int txt_replace_char (Text *text, char add)
 {
        char del;
@@ -2401,7 +2307,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;
        }
@@ -2681,15 +2587,8 @@ int setcurr_tab (Text *text)
 /* Text marker utility functions */
 /*********************************/
 
-static int color_match(TextMarker *a, TextMarker *b) {
-       return (a->clr[0]==b->clr[0] &&
-                       a->clr[1]==b->clr[1] &&
-                       a->clr[2]==b->clr[2] &&
-                       a->clr[3]==b->clr[3]);
-}
-
 /* 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 color[4], int group, int flags) {
        TextMarker *tmp, *marker;
 
        marker= MEM_mallocN(sizeof(TextMarker), "text_marker");
@@ -2697,12 +2596,13 @@ 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];
-       marker->clr[1]= clr[1];
-       marker->clr[2]= clr[2];
-       marker->clr[3]= clr[3];
+       marker->color[0]= color[0];
+       marker->color[1]= color[1];
+       marker->color[2]= color[2];
+       marker->color[3]= color[3];
 
        for (tmp=text->markers.last; tmp; tmp=tmp->prev)
                if (tmp->lineno < marker->lineno || (tmp->lineno==marker->lineno && tmp->start < marker->start))
@@ -2712,17 +2612,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 +2634,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 +2645,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 +2659,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 +2679,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 +2696,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 */