diff options
author | Ian Thompson <quornian@googlemail.com> | 2008-07-23 23:35:13 +0400 |
---|---|---|
committer | Ian Thompson <quornian@googlemail.com> | 2008-07-23 23:35:13 +0400 |
commit | 3b70337f7f247f8f394992c57c835b65fee25c03 (patch) | |
tree | fbcb5c5fb47619dc98fa402a95907e2fada9ae79 /source/blender | |
parent | 16ebff308e5813117a49c4bd5a45617103a66d93 (diff) |
Improvements to text find (and replace):
- Added GUI panel
- Selected text is copied to "find" field
- Option to search "all texts"
- Option to replace text
- Alt+F finds, Ctrl+Alt+F finds again (without UI)
- Alt+H replaces (UI), Ctrl+Alt+H replaces again (and undo works)
- Fixed: Find didn't push undos so cursor position was wrong
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_text.h | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/text.c | 23 | ||||
-rw-r--r-- | source/blender/src/drawtext.c | 213 | ||||
-rw-r--r-- | source/blender/src/header_text.c | 16 |
4 files changed, 211 insertions, 50 deletions
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index 10223589859..abdf32c8ea5 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -52,7 +52,7 @@ void txt_free_cut_buffer (void); char* txt_to_buf (struct Text *text); void txt_clean_text (struct Text *text); void txt_order_cursors (struct Text *text); -int txt_find_string (struct Text *text, char *findstr); +int txt_find_string (struct Text *text, char *findstr, int wrap); int txt_has_sel (struct Text *text); int txt_get_span (struct TextLine *from, struct TextLine *to); void txt_move_up (struct Text *text, short sel); @@ -87,7 +87,7 @@ void txt_backspace_char (struct Text *text); void txt_backspace_word (struct Text *text); int txt_add_char (struct Text *text, char add); int txt_replace_char (struct Text *text, char add); -void txt_find_panel (struct SpaceText *st, int again); +void txt_find_panel (struct SpaceText *st, int again, int flags); void run_python_script (struct SpaceText *st); int jumptoline_interactive (struct SpaceText *st); void txt_export_to_object (struct Text *text); @@ -141,6 +141,11 @@ void txt_paste_clipboard (struct Text *text); #define UNDO_COMMENT 034 #define UNDO_UNCOMMENT 035 +/* Find and replace flags */ +#define TXT_FIND_REPLACE 0x01 +#define TXT_FIND_ALLTEXTS 0x02 +#define TXT_FIND_WRAP 0x04 + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 5c1ec1b4008..4291150f443 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -1080,22 +1080,31 @@ char *txt_to_buf (Text *text) return buf; } -int txt_find_string(Text *text, char *findstr) +int txt_find_string(Text *text, char *findstr, int wrap) { TextLine *tl, *startl; char *s= NULL; + int oldcl, oldsl, oldcc, oldsc; if (!text || !text->curl || !text->sell) return 0; txt_order_cursors(text); + oldcl= txt_get_span(text->lines.first, text->curl); + oldsl= txt_get_span(text->lines.first, text->sell); tl= startl= text->sell; + oldcc= text->curc; + oldsc= text->selc; s= strstr(&tl->line[text->selc], findstr); while (!s) { tl= tl->next; - if (!tl) - tl= text->lines.first; + if (!tl) { + if (wrap) + tl= text->lines.first; + else + break; + } s= strstr(tl->line, findstr); if (tl==startl) @@ -1103,10 +1112,10 @@ int txt_find_string(Text *text, char *findstr) } if (s) { - text->curl= text->sell= tl; - text->curc= (int) (s-tl->line); - text->selc= text->curc + strlen(findstr); - + int newl= txt_get_span(text->lines.first, tl); + int newc= (int)(s-tl->line); + txt_move_to(text, newl, newc, 0); + txt_move_to(text, newl, newc + strlen(findstr), 1); return 1; } else return 0; diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c index ce8128de790..5dfadf5b7f7 100644 --- a/source/blender/src/drawtext.c +++ b/source/blender/src/drawtext.c @@ -115,7 +115,10 @@ static int check_whitespace(char ch); static void get_suggest_prefix(Text *text); static void confirm_suggestion(Text *text, int skipleft); +static int last_txt_find_flags= 0; static void *last_txt_find_string= NULL; +static void *last_txt_repl_string= NULL; + static double last_check_time= 0; static BMF_Font *spacetext_get_font(SpaceText *st) { @@ -178,6 +181,7 @@ void free_txt_data(void) { txt_free_cut_buffer(); if (last_txt_find_string) MEM_freeN(last_txt_find_string); + if (last_txt_repl_string) MEM_freeN(last_txt_repl_string); if (temp_char_buf) MEM_freeN(temp_char_buf); if (temp_char_accum) MEM_freeN(temp_char_accum); } @@ -1650,41 +1654,168 @@ void txt_copy_clipboard(Text *text) { } } -/* - * again==0 show find panel or find - * again==1 find text again */ -void txt_find_panel(SpaceText *st, int again) +static short find_and_replace_popup(char *findvar, char *replvar, int *flags, short min, short max) { - Text *text=st->text; - char *findstr= last_txt_find_string; - - if (again==0) { - findstr= txt_sel_to_buf(text); - } else if (again==1) { - char buf[256]; + uiBlock *block; + ListBase listb={0, 0}; + short x1,y1; + short ret=0; + char *editfindvar=NULL, *editreplvar=NULL; /* dont edit the original text, incase we cancel the popup */ + + if(min>max) min= max; - if (findstr && strlen(findstr)<(sizeof(buf)-1)) - strcpy(buf, findstr); - else - buf[0]= 0; - - if (sbutton(buf, 0, sizeof(buf)-1, "Find: ") && buf[0]) - findstr= BLI_strdup(buf); - else - findstr= NULL; - } + block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK); + + x1= curarea->winrct.xmax - 240; + y1= curarea->winrct.ymin; + + editfindvar = MEM_callocN(max+1, "findvar"); + editreplvar = MEM_callocN(max+1, "replvar"); + BLI_strncpy(editfindvar, findvar, max); + BLI_strncpy(editreplvar, replvar, max); + + uiDefButC(block, TEX, 0, "Find: ", x1+5,y1+85,225,20, editfindvar,(float)min,(float)max, 0, 0, ""); + uiDefButC(block, TEX, 0, "Replace: ", x1+5,y1+60,225,20, editreplvar,(float)min,(float)max, 0, 0, ""); + uiDefButBitI(block, TOG, TXT_FIND_REPLACE, 0, "Replace", x1+5,y1+35,55,20, flags, 0, 0, 0, 0, "Replace previous item found"); + uiDefButBitI(block, TOG, TXT_FIND_ALLTEXTS, 0, "All Texts", x1+60,y1+35,55,20, flags, 0, 0, 0, 0, "Search all texts"); + uiDefButBitI(block, TOG, TXT_FIND_WRAP, 0, "Wrap", x1+115,y1+35,55,20, flags, 0, 0, 0, 0, "Wrap search around current text"); + uiDefBut(block, BUT, 3, "Replace/Find", x1+125,y1+10,105,20, NULL, 0, 0, 0, 0, ""); - if (findstr!=last_txt_find_string) { - if (last_txt_find_string) - MEM_freeN(last_txt_find_string); - last_txt_find_string= findstr; + uiBoundsBlock(block, 5); + + ret= uiDoBlocks(&listb, 0, 0); + + if(ret==UI_RETURN_OK) { + BLI_strncpy(findvar, editfindvar, max); + BLI_strncpy(replvar, editreplvar, max); + MEM_freeN(editfindvar); + MEM_freeN(editreplvar); + return 1; } + MEM_freeN(editfindvar); + MEM_freeN(editreplvar); + return 0; + +} + +/* + * again==0 always show find panel + * again==1 find text again (no panel) If first find, panel shown anyway + * flags: + * TXT_FIND_REPLACE replace last found occurrence before searching again + * TXT_FIND_ALLTEXTS search through all texts (off wraps current text) + */ +void txt_find_panel(SpaceText *st, int again, int flags) +{ + Text *text, *start; + char *tmp= NULL; + char buf[256], repbuf[256]; + int searched, skip, noswitch; + + text= start= st->text; + if (!text) return; + if (again) { + if (!last_txt_find_string) again= 0; /* Can't search again */ + if (!last_txt_repl_string && (flags & TXT_FIND_REPLACE)) again= 0; + } + + if (!again) { + /* Populate tmp with selected text, or the last searched string */ + if (txt_has_sel(text)) + tmp= txt_sel_to_buf(text); + else if (last_txt_find_string) + tmp= BLI_strdup(last_txt_find_string); + + if (tmp && strlen(tmp) < sizeof(buf)-1)strcpy(buf, tmp); + else buf[0]= 0; + if (tmp) { MEM_freeN(tmp); tmp= NULL; } + + if (last_txt_repl_string) strcpy(repbuf, last_txt_repl_string); + else repbuf[0]= 0; + + searched= skip= noswitch= 0; + while (skip || find_and_replace_popup(buf, repbuf, &flags, 0, sizeof(buf)-1) && buf[0]) { + skip= 0; + + /* Allow us to detect when to go to the next text */ + if (flags & TXT_FIND_ALLTEXTS) + flags &= ~TXT_FIND_WRAP; + + /* Replace selection first */ + if ((flags & TXT_FIND_REPLACE) && txt_has_sel(text)) { + tmp= txt_sel_to_buf(text); + if (strcmp(buf, tmp)==0) { /* Searching for same thing? */ + txt_insert_buf(text, repbuf); + if (st->showsyntax) get_format_string(st); + } + MEM_freeN(tmp); + tmp= NULL; + } + + /* Now find the next occurrence */ + searched= 1; + if (txt_find_string(text, buf, flags&TXT_FIND_WRAP)) { + pop_space_text(st); + } else if ((flags & TXT_FIND_ALLTEXTS) && !noswitch) { + if (text->id.next) text= st->text= text->id.next; + else text= st->text= G.main->text.first; - if (findstr) { - if (txt_find_string(text, findstr)) - pop_space_text(st); - else - error("Not found: %s", findstr); + /* Finish at end of this text if we've been round once */ + if (text==start) + noswitch= 1; + + txt_move_toline(text, 0, 0); + pop_space_text(st); + skip= 1; /* Skip panel so we immediately search the next text */ + } else { + okee("Text not found: %s", buf); + break; + } + + /* Redraw */ + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + + /* Store last search details */ + if (searched) { + last_txt_find_flags= flags; + if (last_txt_find_string) + MEM_freeN(last_txt_find_string); + last_txt_find_string= BLI_strdup(buf); + if (last_txt_repl_string) + MEM_freeN(last_txt_repl_string); + last_txt_repl_string= BLI_strdup(repbuf); + } + } else { + if (strlen(last_txt_find_string) < sizeof(buf)-1) { + + /* Replace current */ + if ((flags & TXT_FIND_REPLACE) && last_txt_repl_string && txt_has_sel(text)) { + tmp= txt_sel_to_buf(text); + if (strcmp(last_txt_find_string, tmp)==0) + txt_insert_buf(text, last_txt_repl_string); + MEM_freeN(tmp); + tmp= NULL; + } + + /* Find next */ + if (flags & TXT_FIND_ALLTEXTS) + flags &= ~TXT_FIND_WRAP; + if (txt_find_string(text, last_txt_find_string, flags & TXT_FIND_WRAP)) { + pop_space_text(st); + } else if (flags & flags&TXT_FIND_ALLTEXTS) { + if (text->id.next) + text= st->text= text->id.next; + else + text= st->text= G.main->text.first; + txt_move_toline(text, 0, 0); + pop_space_text(st); + } else { + okee("Text not found: %s", last_txt_find_string); + } + } } } @@ -2051,13 +2182,21 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } } else if (G.qual == LR_ALTKEY) { - if (txt_has_sel(text)) { - txt_find_panel(st,0); - do_draw= 1; - } + txt_find_panel(st, 0, last_txt_find_flags & ~TXT_FIND_REPLACE); + do_draw= 1; + } + else if (G.qual == (LR_ALTKEY|LR_CTRLKEY)) { + txt_find_panel(st, 1, last_txt_find_flags & ~TXT_FIND_REPLACE); + do_draw= 1; + } + break; /* BREAK F */ + case HKEY: + if (G.qual == LR_ALTKEY) { + txt_find_panel(st, 0, last_txt_find_flags | TXT_FIND_REPLACE); + do_draw= 1; } - else if (G.qual == (LR_ALTKEY|LR_CTRLKEY)) { /* always search button */ - txt_find_panel(st,1); + else if (G.qual == (LR_ALTKEY|LR_CTRLKEY)) { + txt_find_panel(st, 1, last_txt_find_flags | TXT_FIND_REPLACE); do_draw= 1; } break; /* BREAK F */ @@ -2140,7 +2279,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } break; /* BREAK S */ case UKEY: - //txt_print_undo(text); //debug buffer in console + txt_print_undo(text); //debug buffer in console if (G.qual == (LR_ALTKEY|LR_SHIFTKEY)) { txt_do_redo(text); do_draw= 1; diff --git a/source/blender/src/header_text.c b/source/blender/src/header_text.c index e371bd56160..49f14784927 100644 --- a/source/blender/src/header_text.c +++ b/source/blender/src/header_text.c @@ -404,10 +404,16 @@ static void do_text_editmenu(void *arg, int event) jumptoline_interactive(st); break; case 8: - txt_find_panel(st,1); + txt_find_panel(st, 0, TXT_FIND_WRAP); break; case 9: - txt_find_panel(st,0); + txt_find_panel(st, 1, TXT_FIND_WRAP); + break; + case 10: + txt_find_panel(st, 0, TXT_FIND_WRAP | TXT_FIND_REPLACE); + break; + case 11: + txt_find_panel(st, 1, TXT_FIND_WRAP | TXT_FIND_REPLACE); break; default: break; @@ -707,8 +713,10 @@ static uiBlock *text_editmenu(void *arg_unused) uiDefIconTextBlockBut(block, text_editmenu_selectmenu, NULL, ICON_RIGHTARROW_THIN, "Select|Alt Shift S ", 0, yco-=20, 120, 19, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump...|Alt J", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find...|Alt Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Again|Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find...|Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Again|Alt Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Replace...|Alt H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Replace Again|Alt Ctrl H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBlockBut(block, text_editmenu_to3dmenu, NULL, ICON_RIGHTARROW_THIN, "Text to 3d Object", 0, yco-=20, 120, 19, ""); |