diff options
Diffstat (limited to 'source/blender/editors/space_text/text_ops.c')
-rw-r--r-- | source/blender/editors/space_text/text_ops.c | 626 |
1 files changed, 454 insertions, 172 deletions
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index ed70f31f970..8d4f3f87f66 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -66,7 +66,7 @@ /************************ poll ***************************/ -static int text_new_poll(bContext *C) +static int text_new_poll(bContext *UNUSED(C)) { return 1; } @@ -125,7 +125,7 @@ static int text_region_edit_poll(bContext *C) /********************** updates *********************/ -void text_update_line_edited(Text *text, TextLine *line) +void text_update_line_edited(TextLine *line) { if(!line) return; @@ -142,12 +142,12 @@ void text_update_edited(Text *text) TextLine *line; for(line=text->lines.first; line; line=line->next) - text_update_line_edited(text, line); + text_update_line_edited(line); } /******************* new operator *********************/ -static int new_exec(bContext *C, wmOperator *op) +static int new_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceText *st= CTX_wm_space_text(C); Text *text; @@ -173,6 +173,7 @@ static int new_exec(bContext *C, wmOperator *op) st->top= 0; } + text_drawcache_tag_update(st, 1); WM_event_add_notifier(C, NC_TEXT|NA_ADDED, text); return OPERATOR_FINISHED; @@ -203,7 +204,7 @@ static void open_init(bContext *C, wmOperator *op) uiIDContextProperty(C, &pprop->ptr, &pprop->prop); } -static int open_cancel(bContext *C, wmOperator *op) +static int open_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); return OPERATOR_CANCELLED; @@ -220,7 +221,7 @@ static int open_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", str); - text= add_text(str, G.sce); + text= add_text(str, G.main->name); if(!text) { if(op->customdata) MEM_freeN(op->customdata); @@ -254,6 +255,7 @@ static int open_exec(bContext *C, wmOperator *op) text->name = NULL; } + text_drawcache_tag_update(st, 1); WM_event_add_notifier(C, NC_TEXT|NA_ADDED, text); MEM_freeN(op->customdata); @@ -261,10 +263,10 @@ static int open_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { Text *text= CTX_data_edit_text(C); - char *path= (text && text->name)? text->name: G.sce; + char *path= (text && text->name)? text->name: G.main->name; if(RNA_property_is_set(op->ptr, "filepath")) return open_exec(C, op); @@ -315,6 +317,7 @@ static int reload_exec(bContext *C, wmOperator *op) text_update_edited(text); text_update_cursor_moved(C); + text_drawcache_tag_update(CTX_wm_space_text(C), 1); WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); return OPERATOR_FINISHED; @@ -335,7 +338,7 @@ void TEXT_OT_reload(wmOperatorType *ot) /******************* delete operator *********************/ -static int unlink_exec(bContext *C, wmOperator *op) +static int unlink_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain= CTX_data_main(C); SpaceText *st= CTX_wm_space_text(C); @@ -357,6 +360,8 @@ static int unlink_exec(bContext *C, wmOperator *op) unlink_text(bmain, text); free_libblock(&bmain->text, text); + + text_drawcache_tag_update(st, 1); WM_event_add_notifier(C, NC_TEXT|NA_REMOVED, NULL); return OPERATOR_FINISHED; @@ -380,7 +385,7 @@ void TEXT_OT_unlink(wmOperatorType *ot) /******************* make internal operator *********************/ -static int make_internal_exec(bContext *C, wmOperator *op) +static int make_internal_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); @@ -433,7 +438,7 @@ static void txt_write_file(Text *text, ReportList *reports) char file[FILE_MAXDIR+FILE_MAXFILE]; BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); - BLI_path_abs(file, G.sce); + BLI_path_abs(file, G.main->name); fp= fopen(file, "w"); if(fp==NULL) { @@ -506,7 +511,7 @@ static int save_as_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { Text *text= CTX_data_edit_text(C); char *str; @@ -519,7 +524,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event) else if(text->flags & TXT_ISMEM) str= text->id.name+2; else - str= G.sce; + str= G.main->name; RNA_string_set(op->ptr, "filepath", str); WM_event_add_fileselect(C, op); @@ -588,7 +593,7 @@ void TEXT_OT_run_script(wmOperatorType *ot) /******************* refresh pyconstraints operator *********************/ -static int refresh_pyconstraints_exec(bContext *C, wmOperator *op) +static int refresh_pyconstraints_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) { #ifndef DISABLE_PYTHON #if 0 @@ -738,6 +743,8 @@ static int paste_exec(bContext *C, wmOperator *op) if(!buf) return OPERATOR_CANCELLED; + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + txt_insert_buf(text, buf); text_update_edited(text); @@ -782,7 +789,7 @@ static void txt_copy_clipboard(Text *text) } } -static int copy_exec(bContext *C, wmOperator *op) +static int copy_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); @@ -809,6 +816,8 @@ static int cut_exec(bContext *C, wmOperator *op) { Text *text= CTX_data_edit_text(C); + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + txt_copy_clipboard(text); txt_delete_selected(text); @@ -836,10 +845,12 @@ void TEXT_OT_cut(wmOperatorType *ot) /******************* indent operator *********************/ -static int indent_exec(bContext *C, wmOperator *op) +static int indent_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + if(txt_has_sel(text)) { txt_order_cursors(text); indent(text); @@ -869,11 +880,13 @@ void TEXT_OT_indent(wmOperatorType *ot) /******************* unindent operator *********************/ -static int unindent_exec(bContext *C, wmOperator *op) +static int unindent_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); if(txt_has_sel(text)) { + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + txt_order_cursors(text); unindent(text); @@ -902,13 +915,15 @@ void TEXT_OT_unindent(wmOperatorType *ot) /******************* line break operator *********************/ -static int line_break_exec(bContext *C, wmOperator *op) +static int line_break_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceText *st= CTX_wm_space_text(C); Text *text= CTX_data_edit_text(C); int a, curts; int space = (text->flags & TXT_TABSTOSPACES) ? st->tabnumber : 1; + text_drawcache_tag_update(st, 0); + // double check tabs/spaces before splitting the line curts= setcurr_tab_spaces(text, space); txt_split_curline(text); @@ -923,8 +938,8 @@ static int line_break_exec(bContext *C, wmOperator *op) if(text->curl) { if(text->curl->prev) - text_update_line_edited(text, text->curl->prev); - text_update_line_edited(text, text->curl); + text_update_line_edited(text->curl->prev); + text_update_line_edited(text->curl); } text_update_cursor_moved(C); @@ -947,11 +962,13 @@ void TEXT_OT_line_break(wmOperatorType *ot) /******************* comment operator *********************/ -static int comment_exec(bContext *C, wmOperator *op) +static int comment_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); if(txt_has_sel(text)) { + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + txt_order_cursors(text); comment(text); text_update_edited(text); @@ -978,11 +995,13 @@ void TEXT_OT_comment(wmOperatorType *ot) /******************* uncomment operator *********************/ -static int uncomment_exec(bContext *C, wmOperator *op) +static int uncomment_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); if(txt_has_sel(text)) { + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + txt_order_cursors(text); uncomment(text); text_update_edited(text); @@ -1130,6 +1149,7 @@ static int convert_whitespace_exec(bContext *C, wmOperator *op) text_update_edited(text); text_update_cursor_moved(C); + text_drawcache_tag_update(st, 1); WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); return OPERATOR_FINISHED; @@ -1152,7 +1172,7 @@ void TEXT_OT_convert_whitespace(wmOperatorType *ot) /******************* select all operator *********************/ -static int select_all_exec(bContext *C, wmOperator *op) +static int select_all_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); @@ -1178,7 +1198,7 @@ void TEXT_OT_select_all(wmOperatorType *ot) /******************* select line operator *********************/ -static int select_line_exec(bContext *C, wmOperator *op) +static int select_line_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); @@ -1204,7 +1224,7 @@ void TEXT_OT_select_line(wmOperatorType *ot) /******************* previous marker operator *********************/ -static int previous_marker_exec(bContext *C, wmOperator *op) +static int previous_marker_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); TextMarker *mrk; @@ -1240,7 +1260,7 @@ void TEXT_OT_previous_marker(wmOperatorType *ot) /******************* next marker operator *********************/ -static int next_marker_exec(bContext *C, wmOperator *op) +static int next_marker_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); TextMarker *mrk; @@ -1276,7 +1296,7 @@ void TEXT_OT_next_marker(wmOperatorType *ot) /******************* clear all markers operator *********************/ -static int clear_all_markers_exec(bContext *C, wmOperator *op) +static int clear_all_markers_exec(bContext *C, wmOperator *UNUSED(op)) { Text *text= CTX_data_edit_text(C); @@ -1317,146 +1337,360 @@ static EnumPropertyItem move_type_items[]= { {NEXT_PAGE, "NEXT_PAGE", 0, "Next Page", ""}, {0, NULL, 0, NULL, NULL}}; +/* get cursor position in line by relative wrapped line and column positions */ +static int text_get_cursor_rel(SpaceText* st, ARegion *ar, TextLine *linein, int rell, int relc) +{ + int i, j, start, end, chars, max, chop, curs, loop, endj, found, selc; + char ch; + + max= wrap_width(st, ar); + + selc= start= chars= endj= curs= found= 0; + end= max; + chop= loop= 1; + + for(i=0, j=0; loop; j++) { + /* Mimic replacement of tabs */ + ch= linein->line[j]; + if(ch=='\t') { + chars= st->tabnumber-i%st->tabnumber; + ch= ' '; + } + else chars= 1; + + while(chars--) { + if(rell==0 && i-start==relc) { + /* current position could be wrapped to next line */ + /* this should be checked when end of current line would be reached */ + selc= j; + found= 1; + } + else if(i-end==relc) { + curs= j; + } + if(i-start>=max) { + if(found) { + /* exact cursor position was found, check if it's */ + /* still on needed line (hasn't been wrapped) */ + if(selc>endj && !chop) selc= endj; + loop= 0; + break; + } + + if(chop) endj= j; + + start= end; + end += max; + chop= 1; + rell--; + + if(rell==0 && i-start>=relc) { + selc= curs; + loop= 0; + break; + } + } + else if (ch=='\0') { + if(!found) selc= linein->len; + loop= 0; + break; + } + else if(ch==' ' || ch=='-') { + if(found) { + loop= 0; + break; + } + + if(rell==0 && i-start>=relc) { + selc= curs; + loop= 0; + break; + } + end= i+1; + endj= j; + chop= 0; + } + i++; + } + } + + return selc; +} + +static int cursor_skip_find_line(SpaceText* st, ARegion *ar, + int lines, TextLine **linep, int *charp, int *rell, int *relc) +{ + int offl, offc, visible_lines; + + wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); + *relc= text_get_char_pos(st, (*linep)->line, *charp) + offc; + *rell= lines; + + /* handle current line */ + if(lines>0) { + visible_lines= text_get_visible_lines(st, ar, (*linep)->line); + + if(*rell-visible_lines+offl>=0) { + if(!(*linep)->next) { + if(offl < visible_lines-1) { + *rell= visible_lines-1; + return 1; + } + + *charp= (*linep)->len; + return 0; + } + + *rell-= visible_lines-offl; + *linep=(*linep)->next; + } else { + *rell+= offl; + return 1; + } + } else { + if(*rell+offl<=0) { + if(!(*linep)->prev) { + if(offl) { + *rell= 0; + return 1; + } + + *charp= 0; + return 0; + } + + *rell+= offl; + *linep=(*linep)->prev; + } else { + *rell+= offl; + return 1; + } + } + + /* skip lines and find destination line and offsets */ + while(*linep) { + visible_lines= text_get_visible_lines(st, ar, (*linep)->line); + + if(lines<0) { /* moving top */ + if(*rell+visible_lines >= 0) { + *rell+= visible_lines; + break; + } + + if(!(*linep)->prev) { + *rell= 0; + break; + } + + *rell+= visible_lines; + *linep=(*linep)->prev; + } else { /* moving bottom */ + if(*rell-visible_lines < 0) break; + + if(!(*linep)->next) { + *rell= visible_lines-1; + break; + } + + *rell-= visible_lines; + *linep=(*linep)->next; + } + } + + return 1; +} + static void wrap_move_bol(SpaceText *st, ARegion *ar, short sel) { Text *text= st->text; - int offl, offc, lin; + TextLine **linep; + int *charp; + int oldl, oldc, i, j, max, start, end, chars, endj, chop, loop; + char ch; text_update_character_width(st); - lin= txt_get_span(text->lines.first, text->sell); - wrap_offset(st, ar, text->sell, text->selc, &offl, &offc); + if (sel) linep= &text->sell, charp= &text->selc; + else linep= &text->curl, charp= &text->curc; - if (sel) { - txt_undo_add_toop(text, UNDO_STO, lin, text->selc, lin, -offc); - text->selc= -offc; - } else { - txt_undo_add_toop(text, UNDO_CTO, lin, text->curc, lin, -offc); - text->curc= -offc; - txt_pop_sel(text); + oldc= *charp; + oldl= txt_get_span(text->lines.first, *linep); + + max= wrap_width(st, ar); + + start= chars= endj= 0; + end= max; + chop= loop= 1; + *charp= 0; + + for(i=0, j=0; loop; j++) { + /* Mimic replacement of tabs */ + ch= (*linep)->line[j]; + if(ch=='\t') { + chars= st->tabnumber-i%st->tabnumber; + ch= ' '; + } + else chars= 1; + + while(chars--) { + if(i-start>=max) { + *charp= endj; + + if(j>=oldc) { + loop= 0; + break; + } + + if(chop) endj= j; + + start= end; + end += max; + chop= 0; + } + else if(ch==' ' || ch=='-' || ch=='\0') { + if(j>=oldc) { + loop= 0; + break; + } + + end= i+1; + endj= j+1; + chop= 0; + } + i++; + } } + + if (!sel) txt_pop_sel(text); + txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, oldl, *charp); } static void wrap_move_eol(SpaceText *st, ARegion *ar, short sel) { Text *text= st->text; - int offl, offc, lin, startl, c; + TextLine **linep; + int *charp; + int oldl, oldc, i, j, max, start, end, chars, endj, chop, loop; + char ch; text_update_character_width(st); - lin= txt_get_span(text->lines.first, text->sell); - wrap_offset(st, ar, text->sell, text->selc, &offl, &offc); - startl= offl; - c= text->selc; - while (offl==startl && text->sell->line[c]!='\0') { - c++; - wrap_offset(st, ar, text->sell, c, &offl, &offc); - } if (offl!=startl) c--; - - if (sel) { - txt_undo_add_toop(text, UNDO_STO, lin, text->selc, lin, c); - text->selc= c; - } else { - txt_undo_add_toop(text, UNDO_CTO, lin, text->curc, lin, c); - text->curc= c; - txt_pop_sel(text); + if (sel) linep= &text->sell, charp= &text->selc; + else linep= &text->curl, charp= &text->curc; + + oldc= *charp; + oldl= txt_get_span(text->lines.first, *linep); + + max= wrap_width(st, ar); + + start= chars= endj= 0; + end= max; + chop= loop= 1; + *charp= 0; + + for(i=0, j=0; loop; j++) { + /* Mimic replacement of tabs */ + ch= (*linep)->line[j]; + if(ch=='\t') { + chars= st->tabnumber-i%st->tabnumber; + ch= ' '; + } + else chars= 1; + + while(chars--) { + if(i-start>=max) { + if(endj>=oldc) { + *charp= endj; + loop= 0; + break; + } + + if(chop) endj= j; + + start= end; + end += max; + chop= 0; + } else if(ch=='\0') { + *charp= (*linep)->len; + loop= 0; + break; + } else if(ch==' ' || ch=='-') { + end= i+1; + endj= j; + chop= 0; + } + i++; + } } + + if (!sel) txt_pop_sel(text); + txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, oldl, *charp); } static void wrap_move_up(SpaceText *st, ARegion *ar, short sel) { Text *text= st->text; - int offl, offl_1, offc, fromline, toline, c, target; + TextLine **linep; + int *charp; + int oldl, oldc, offl, offc, col, newl; text_update_character_width(st); - wrap_offset(st, ar, text->sell, 0, &offl_1, &offc); - wrap_offset(st, ar, text->sell, text->selc, &offl, &offc); - fromline= toline= txt_get_span(text->lines.first, text->sell); - target= text->selc + offc; + if (sel) linep= &text->sell, charp= &text->selc; + else linep= &text->curl, charp= &text->curc; - if (offl==offl_1) { - if (!text->sell->prev) { - txt_move_bol(text, sel); - return; - } - toline--; - c= text->sell->prev->len; /* End of prev. line */ - wrap_offset(st, ar, text->sell->prev, c, &offl, &offc); - c= -offc+target; + /* store previous position */ + oldc= *charp; + newl= oldl= txt_get_span(text->lines.first, *linep); + + wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); + col= text_get_char_pos(st, (*linep)->line, *charp) + offc; + if(offl) { + *charp= text_get_cursor_rel(st, ar, *linep, offl-1, col); } else { - c= -offc-1; /* End of prev. line */ - wrap_offset(st, ar, text->sell, c, &offl, &offc); - c= -offc+target; - } - if (c<0) c=0; - - if (sel) { - txt_undo_add_toop(text, UNDO_STO, fromline, text->selc, toline, c); - if (toline<fromline) text->sell= text->sell->prev; - if(text->sell) { - if (c>text->sell->len) c= text->sell->len; - text->selc= c; - } - } - else if(text->curl) { - txt_undo_add_toop(text, UNDO_CTO, fromline, text->curc, toline, c); - if (toline<fromline) text->curl= text->curl->prev; - if(text->curl) { - if (c>text->curl->len) c= text->curl->len; - text->curc= c; - txt_pop_sel(text); - } + if((*linep)->prev) { + int visible_lines; + + *linep= (*linep)->prev; + visible_lines= text_get_visible_lines(st, ar, (*linep)->line); + *charp= text_get_cursor_rel(st, ar, *linep, visible_lines-1, col); + } else *charp= 0; } + + if (!sel) txt_pop_sel(text); + txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, newl, *charp); } static void wrap_move_down(SpaceText *st, ARegion *ar, short sel) { Text *text= st->text; - int offl, startoff, offc, fromline, toline, c, target; + TextLine **linep; + int *charp; + int oldl, oldc, offl, offc, col, newl, visible_lines; text_update_character_width(st); - wrap_offset(st, ar, text->sell, text->selc, &offl, &offc); - fromline= toline= txt_get_span(text->lines.first, text->sell); - target= text->selc + offc; - startoff= offl; - c= text->selc; - while (offl==startoff && text->sell->line[c]!='\0') { - c++; - wrap_offset(st, ar, text->sell, c, &offl, &offc); - } + if (sel) linep= &text->sell, charp= &text->selc; + else linep= &text->curl, charp= &text->curc; - if (text->sell->line[c]=='\0') { - if (!text->sell->next) { - txt_move_eol(text, sel); - return; - } - toline++; - c= target; + /* store previous position */ + oldc= *charp; + newl= oldl= txt_get_span(text->lines.first, *linep); + + wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); + col= text_get_char_pos(st, (*linep)->line, *charp) + offc; + visible_lines= text_get_visible_lines(st, ar, (*linep)->line); + if(offl<visible_lines-1) { + *charp= text_get_cursor_rel(st, ar, *linep, offl+1, col); } else { - c += target; - if (c > text->sell->len) c= text->sell->len; - } - if (c<0) c=0; - - if (sel) { - txt_undo_add_toop(text, UNDO_STO, fromline, text->selc, toline, c); - if (toline>fromline) text->sell= text->sell->next; - if(text->sell) { - if (c>text->sell->len) c= text->sell->len; - text->selc= c; - } - } - else if(text->curl) { - txt_undo_add_toop(text, UNDO_CTO, fromline, text->curc, toline, c); - if (toline>fromline) text->curl= text->curl->next; - if(text->curl) { - if (c > text->curl->len) c= text->curl->len; - text->curc= c; - txt_pop_sel(text); - } + if((*linep)->next) { + *linep= (*linep)->next; + *charp= text_get_cursor_rel(st, ar, *linep, 0, col); + } else *charp= (*linep)->len; } + + if (!sel) txt_pop_sel(text); + txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, newl, *charp); } /* Moves the cursor vertically by the specified number of lines. @@ -1465,7 +1699,7 @@ static void wrap_move_down(SpaceText *st, ARegion *ar, short sel) This is to replace screen_skip for PageUp/Down operations. */ -static void cursor_skip(Text *text, int lines, int sel) +static void cursor_skip(SpaceText* st, ARegion *ar, Text *text, int lines, int sel) { TextLine **linep; int oldl, oldc, *charp; @@ -1475,13 +1709,21 @@ static void cursor_skip(Text *text, int lines, int sel) oldl= txt_get_span(text->lines.first, *linep); oldc= *charp; - while (lines>0 && (*linep)->next) { - *linep= (*linep)->next; - lines--; - } - while (lines<0 && (*linep)->prev) { - *linep= (*linep)->prev; - lines++; + if(st && ar && st->wordwrap) { + int rell, relc; + + /* find line and offsets inside it needed to set cursor position */ + if(cursor_skip_find_line(st, ar, lines, linep, charp, &rell, &relc)) + *charp= text_get_cursor_rel (st, ar, *linep, rell, relc); + } else { + while (lines>0 && (*linep)->next) { + *linep= (*linep)->next; + lines--; + } + while (lines<0 && (*linep)->prev) { + *linep= (*linep)->prev; + lines++; + } } if (*charp > (*linep)->len) *charp= (*linep)->len; @@ -1546,18 +1788,18 @@ static int move_cursor(bContext *C, int type, int select) break; case PREV_PAGE: - if(st) cursor_skip(text, -st->viewlines, select); - else cursor_skip(text, -10, select); + if(st) cursor_skip(st, ar, st->text, -st->viewlines, select); + else cursor_skip(NULL, NULL, text, -10, select); break; case NEXT_PAGE: - if(st) cursor_skip(text, st->viewlines, select); - else cursor_skip(text, 10, select); + if(st) cursor_skip(st, ar, st->text, st->viewlines, select); + else cursor_skip(NULL, NULL, text, 10, select); break; } text_update_cursor_moved(C); - WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); + WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text); return OPERATOR_FINISHED; } @@ -1629,7 +1871,7 @@ static int jump_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int jump_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int jump_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { return WM_operator_props_dialog_popup(C,op,200,100); @@ -1665,6 +1907,8 @@ static int delete_exec(bContext *C, wmOperator *op) Text *text= CTX_data_edit_text(C); int type= RNA_enum_get(op->ptr, "type"); + text_drawcache_tag_update(CTX_wm_space_text(C), 0); + if(type == DEL_PREV_WORD) txt_backspace_word(text); else if(type == DEL_PREV_CHAR) @@ -1674,7 +1918,7 @@ static int delete_exec(bContext *C, wmOperator *op) else if(type == DEL_NEXT_CHAR) txt_delete_char(text); - text_update_line_edited(text, text->curl); + text_update_line_edited(text->curl); text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); @@ -1703,7 +1947,7 @@ void TEXT_OT_delete(wmOperatorType *ot) /******************* toggle overwrite operator **********************/ -static int toggle_overwrite_exec(bContext *C, wmOperator *op) +static int toggle_overwrite_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceText *st= CTX_wm_space_text(C); @@ -1729,13 +1973,13 @@ void TEXT_OT_overwrite_toggle(wmOperatorType *ot) /******************* scroll operator **********************/ /* Moves the view vertically by the specified number of lines */ -static void screen_skip(SpaceText *st, int lines) +static void screen_skip(SpaceText *st, ARegion *ar, int lines) { int last; - st->top += lines; + st->top += lines; - last= txt_get_span(st->text->lines.first, st->text->lines.last); + last= text_get_total_lines(st, ar); last= last - (st->viewlines/2); if(st->top>last) st->top= last; @@ -1756,12 +2000,14 @@ typedef struct TextScroll { static int scroll_exec(bContext *C, wmOperator *op) { SpaceText *st= CTX_wm_space_text(C); + ARegion *ar= CTX_wm_region(C); + int lines= RNA_int_get(op->ptr, "lines"); if(lines == 0) return OPERATOR_CANCELLED; - screen_skip(st, lines*U.wheellinescroll); + screen_skip(st, ar, lines*U.wheellinescroll); ED_area_tag_redraw(CTX_wm_area(C)); @@ -1771,6 +2017,7 @@ static int scroll_exec(bContext *C, wmOperator *op) static void scroll_apply(bContext *C, wmOperator *op, wmEvent *event) { SpaceText *st= CTX_wm_space_text(C); + ARegion *ar= CTX_wm_region(C); TextScroll *tsc= op->customdata; short *mval= event->mval; @@ -1792,7 +2039,7 @@ static void scroll_apply(bContext *C, wmOperator *op, wmEvent *event) tsc->delta[1]= (tsc->hold[1]-mval[1])*st->pix_per_line; if(tsc->delta[0] || tsc->delta[1]) { - screen_skip(st, tsc->delta[1]); + screen_skip(st, ar, tsc->delta[1]); tsc->lines += tsc->delta[1]; @@ -1969,7 +2216,7 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) Text *text= st->text; TextLine **linep; int *charp; - int w; + int w, tabs; text_update_character_width(st); @@ -1987,16 +2234,28 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) x = (x/st->cwidth) + st->left; if(st->wordwrap) { - int i, j, endj, curs, max, chop, start, end, chars, loop; + int i, j, endj, curs, max, chop, start, end, chars, loop, found; char ch; /* Point to first visible line */ *linep= text->lines.first; - for(i=0; i<st->top && (*linep)->next; i++) *linep= (*linep)->next; + i= st->top; + while(i>0 && *linep) { + int lines= text_get_visible_lines(st, ar, (*linep)->line); + + if (i-lines<0) { + y+= i; + break; + } else { + *linep= (*linep)->next; + i-= lines; + } + } max= wrap_width(st, ar); loop= 1; + found= 0; while(loop && *linep) { start= 0; end= max; @@ -2004,12 +2263,14 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) chars= 0; curs= 0; endj= 0; + tabs= 0; for(i=0, j=0; loop; j++) { /* Mimic replacement of tabs */ ch= (*linep)->line[j]; if(ch=='\t') { chars= st->tabnumber-i%st->tabnumber; + tabs+= chars-1; ch= ' '; } else @@ -2021,22 +2282,34 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) *charp= endj; loop= 0; break; - /* Exactly at the cursor, done */ + /* Exactly at the cursor */ } else if(y==0 && i-start==x) { + /* current position could be wrapped to next line */ + /* this should be checked when end of current line would be reached */ *charp= curs= j; - loop= 0; - break; + found= 1; /* Prepare curs for next wrap */ } else if(i-end==x) { curs= j; } if(i-start>=max) { + if(found) { + /* exact cursor position was found, check if it's */ + /* still on needed line (hasn't been wrapped) */ + if(*charp>endj && !chop) (*charp)= endj; + loop= 0; + break; + } + if(chop) endj= j; - y--; start= end; end += max; + + if(start-tabs<(*linep)->len) + y--; + chop= 1; if(y==0 && i-start>=x) { *charp= curs; @@ -2045,6 +2318,11 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) } } else if(ch==' ' || ch=='-' || ch=='\0') { + if(found) { + loop= 0; + break; + } + if(y==0 && i-start>=x) { *charp= curs; loop= 0; @@ -2102,7 +2380,7 @@ static void set_cursor_apply(bContext *C, wmOperator *op, wmEvent *event) if(event->mval[1]<0 || event->mval[1]>ar->winy) { int d= (scu->old[1]-event->mval[1])*st->pix_per_line; - if(d) screen_skip(st, d); + if(d) screen_skip(st, ar, d); set_cursor_to_pos(st, ar, event->mval[0], event->mval[1]<0?0:ar->winy, 1); @@ -2234,7 +2512,7 @@ void TEXT_OT_cursor_set(wmOperatorType *ot) /******************* line number operator **********************/ -static int line_number_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int line_number_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { SpaceText *st= CTX_wm_space_text(C); Text *text= CTX_data_edit_text(C); @@ -2290,6 +2568,8 @@ static int insert_exec(bContext *C, wmOperator *op) char *str; int done = 0, i; + text_drawcache_tag_update(st, 0); + str= RNA_string_get_alloc(op->ptr, "text", NULL, 0); if(st && st->overwrite) { @@ -2307,7 +2587,7 @@ static int insert_exec(bContext *C, wmOperator *op) if(!done) return OPERATOR_CANCELLED; - text_update_line_edited(text, text->curl); + text_update_line_edited(text->curl); text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); @@ -2317,18 +2597,18 @@ static int insert_exec(bContext *C, wmOperator *op) static int insert_invoke(bContext *C, wmOperator *op, wmEvent *event) { - char str[2]; int ret; - /* XXX old code from winqreadtextspace, is it still needed somewhere? */ - /* smartass code to prevent the CTRL/ALT events below from not working! */ - /*if(qual & (LR_ALTKEY|LR_CTRLKEY)) - if(!ispunct(ascii)) - ascii= 0;*/ - str[0]= event->ascii; - str[1]= '\0'; + // if(!RNA_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ + if(!RNA_string_length(op->ptr, "text")) { + char str[2] = {event->ascii, '\0'}; + /* if alt/ctrl/super are pressed pass through */ + if(event->ctrl || event->oskey) + return OPERATOR_PASS_THROUGH; + + RNA_string_set(op->ptr, "text", str); + } - RNA_string_set(op->ptr, "text", str); ret = insert_exec(C, op); /* run the script while editing, evil but useful */ @@ -2396,6 +2676,7 @@ static int find_and_replace(bContext *C, wmOperator *op, short mode) } text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); + text_drawcache_tag_update(CTX_wm_space_text(C), 1); } else if(mode==TEXT_MARK_ALL) { char color[4]; @@ -2529,7 +2810,7 @@ void TEXT_OT_find_set_selected(wmOperatorType *ot) /******************* replace set selected *********************/ -static int replace_set_selected_exec(bContext *C, wmOperator *op) +static int replace_set_selected_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceText *st= CTX_wm_space_text(C); Text *text= CTX_data_edit_text(C); @@ -2579,7 +2860,7 @@ int text_file_modified(Text *text) return 0; BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); - BLI_path_abs(file, G.sce); + BLI_path_abs(file, G.main->name); if(!BLI_exists(file)) return 2; @@ -2607,7 +2888,7 @@ static void text_ignore_modified(Text *text) if(!text || !text->name) return; BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); - BLI_path_abs(file, G.sce); + BLI_path_abs(file, G.main->name); if(!BLI_exists(file)) return; @@ -2639,7 +2920,7 @@ static int resolve_conflict_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static int resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { Text *text= CTX_data_edit_text(C); uiPopupMenu *pup; @@ -2741,6 +3022,7 @@ void ED_text_undo_step(bContext *C, int step) text_update_edited(text); text_update_cursor_moved(C); + text_drawcache_tag_update(CTX_wm_space_text(C), 1); WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text); } |