code cleanup: favor braces when blocks have mixed brace use.
[blender.git] / source / blender / editors / space_text / text_ops.c
index f0275fb..e6f95c3 100644 (file)
  */
 
 
-#include <stdlib.h>
 #include <string.h>
-#include <ctype.h> /* ispunct */
-#include <sys/stat.h>
 #include <errno.h>
 
 #include "MEM_guardedalloc.h"
 
 #include "DNA_text_types.h"
-#include "DNA_userdef_types.h"
 
 #include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
 
 #include "PIL_time.h"
 
@@ -70,6 +67,7 @@
 #endif
 
 #include "text_intern.h"
+#include "text_format.h"
 
 /************************ poll ***************************/
 
@@ -93,14 +91,14 @@ static int text_edit_poll(bContext *C)
                return 0;
 
        if (text->id.lib) {
-               // BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
+               // BKE_report(op->reports, RPT_ERROR, "Cannot edit external libdata");
                return 0;
        }
 
        return 1;
 }
 
-static int text_space_edit_poll(bContext *C)
+int text_space_edit_poll(bContext *C)
 {
        SpaceText *st = CTX_wm_space_text(C);
        Text *text = CTX_data_edit_text(C);
@@ -109,7 +107,7 @@ static int text_space_edit_poll(bContext *C)
                return 0;
 
        if (text->id.lib) {
-               // BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
+               // BKE_report(op->reports, RPT_ERROR, "Cannot edit external libdata");
                return 0;
        }
 
@@ -129,7 +127,7 @@ static int text_region_edit_poll(bContext *C)
                return 0;
 
        if (text->id.lib) {
-               // BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
+               // BKE_report(op->reports, RPT_ERROR, "Cannot edit external libdata");
                return 0;
        }
 
@@ -163,11 +161,12 @@ void text_update_edited(Text *text)
 static int text_new_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceText *st = CTX_wm_space_text(C);
+       Main *bmain = CTX_data_main(C);
        Text *text;
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
 
-       text = BKE_text_add("Text");
+       text = BKE_text_add(bmain, "Text");
 
        /* hook into UI */
        uiIDContextProperty(C, &ptr, &prop);
@@ -228,6 +227,7 @@ static int text_open_cancel(bContext *UNUSED(C), wmOperator *op)
 static int text_open_exec(bContext *C, wmOperator *op)
 {
        SpaceText *st = CTX_wm_space_text(C);
+       Main *bmain = CTX_data_main(C);
        Text *text;
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
@@ -236,7 +236,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
 
        RNA_string_get(op->ptr, "filepath", str);
 
-       text = BKE_text_load(str, G.main->name);
+       text = BKE_text_load(bmain, str, G.main->name);
 
        if (!text) {
                if (op->customdata) MEM_freeN(op->customdata);
@@ -310,7 +310,8 @@ void TEXT_OT_open(wmOperatorType *ot)
        ot->flag = OPTYPE_UNDO;
        
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);  //XXX TODO, relative_path
+       WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE,
+                                      WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);  //XXX TODO, relative_path
        RNA_def_boolean(ot->srna, "internal", 0, "Make internal", "Make text file internal after loading");
 }
 
@@ -462,7 +463,8 @@ static void txt_write_file(Text *text, ReportList *reports)
        
        fp = BLI_fopen(filepath, "w");
        if (fp == NULL) {
-               BKE_reportf(reports, RPT_ERROR, "Unable to save \"%s\": %s", filepath, errno ? strerror(errno) : "Unknown error writing file");
+               BKE_reportf(reports, RPT_ERROR, "Unable to save '%s': %s",
+                           filepath, errno ? strerror(errno) : TIP_("unknown error writing file"));
                return;
        }
 
@@ -481,7 +483,8 @@ static void txt_write_file(Text *text, ReportList *reports)
        }
        else {
                text->mtime = 0;
-               BKE_reportf(reports, RPT_WARNING, "Unable to stat \"%s\": %s", filepath, errno ? strerror(errno) : "Unknown error starrng file");
+               BKE_reportf(reports, RPT_WARNING, "Unable to stat '%s': %s",
+                           filepath, errno ? strerror(errno) : TIP_("unknown error stating file"));
        }
        
        if (text->flags & TXT_ISDIRTY)
@@ -570,7 +573,8 @@ void TEXT_OT_save_as(wmOperatorType *ot)
        ot->poll = text_edit_poll;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);  //XXX TODO, relative_path
+       WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE,
+                                      WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);  //XXX TODO, relative_path
 }
 
 /******************* run script operator *********************/
@@ -600,12 +604,17 @@ static int text_run_script(bContext *C, ReportList *reports)
 
        /* Don't report error messages while live editing */
        if (!is_live) {
-               if (text->curl != curl_prev || curc_prev != text->curc) {
-                       text_update_cursor_moved(C);
-                       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+               /* text may have freed its self */
+               if (CTX_data_edit_text(C) == text) {
+                       if (text->curl != curl_prev || curc_prev != text->curc) {
+                               text_update_cursor_moved(C);
+                               WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+                       }
                }
 
                BKE_report(reports, RPT_ERROR, "Python script fail, look in the console for now...");
+
+               return OPERATOR_FINISHED;
        }
 #else
        (void)C;
@@ -965,21 +974,17 @@ static int text_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);
-               txt_unindent(text);
+       text_drawcache_tag_update(CTX_wm_space_text(C), 0);
 
-               text_update_edited(text);
+       txt_order_cursors(text);
+       txt_unindent(text);
 
-               text_update_cursor_moved(C);
-               WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+       text_update_edited(text);
 
-               return OPERATOR_FINISHED;
-       }
+       text_update_cursor_moved(C);
+       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
 
-       return OPERATOR_CANCELLED;
+       return OPERATOR_FINISHED;
 }
 
 void TEXT_OT_unindent(wmOperatorType *ot)
@@ -1124,20 +1129,20 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
        TextLine *tmp;
        FlattenString fs;
        size_t a, j;
-       char *text_check_line, *new_line;
+       char *new_line;
        int extra, number; //unknown for now
        int type = RNA_enum_get(op->ptr, "type");
-       
-       tmp = text->lines.first;
-       
-       //first convert to all space, this make it a lot easier to convert to tabs because there is no mixtures of ' ' && '\t'
-       while (tmp) {
-               text_check_line = tmp->line;
+
+       /* first convert to all space, this make it a lot easier to convert to tabs
+        * because there is no mixtures of ' ' && '\t' */
+       for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+               const char *text_check_line     = tmp->line;
+               const int   text_check_line_len = tmp->len;
                number = flatten_string(st, &fs, text_check_line) + 1;
                flatten_string_free(&fs);
                new_line = MEM_callocN(number, "Converted_Line");
                j = 0;
-               for (a = 0; a < strlen(text_check_line); a++) { //foreach char in line
+               for (a = 0; a < text_check_line_len; a++) { //foreach char in line
                        if (text_check_line[a] == '\t') { //checking for tabs
                                //get the number of spaces this tabs is showing
                                //i don't like doing it this way but will look into it later
@@ -1167,20 +1172,19 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
                tmp->line = new_line;
                tmp->len = strlen(new_line);
                tmp->format = NULL;
-               tmp = tmp->next;
        }
        
        if (type == TO_TABS) { // Converting to tabs
                //start over from the beginning
-               tmp = text->lines.first;
                
-               while (tmp) {
-                       text_check_line = tmp->line;
+               for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+                       const char *text_check_line     = tmp->line;
+                       const int   text_check_line_len = tmp->len;
                        extra = 0;
-                       for (a = 0; a < strlen(text_check_line); a++) {
+                       for (a = 0; a < text_check_line_len; a++) {
                                number = 0;
                                for (j = 0; j < (size_t)st->tabnumber; j++) {
-                                       if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line
+                                       if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
                                                if (text_check_line[a + j] != ' ') {
                                                        number = 1;
                                                }
@@ -1193,12 +1197,12 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
                        }
                        
                        if (extra > 0) {   //got tabs make malloc and do what you have to do
-                               new_line = MEM_callocN(strlen(text_check_line) - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
+                               new_line = MEM_callocN(text_check_line_len - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
                                extra = 0; //reuse vars
-                               for (a = 0; a < strlen(text_check_line); a++) {
+                               for (a = 0; a < text_check_line_len; a++) {
                                        number = 0;
                                        for (j = 0; j < (size_t)st->tabnumber; j++) {
-                                               if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line
+                                               if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
                                                        if (text_check_line[a + j] != ' ') {
                                                                number = 1;
                                                        }
@@ -1225,7 +1229,6 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
                                tmp->len = strlen(new_line);
                                tmp->format = NULL;
                        }
-                       tmp = tmp->next;
                }
        }
 
@@ -1309,9 +1312,11 @@ void TEXT_OT_select_line(wmOperatorType *ot)
 static int text_select_word_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Text *text = CTX_data_edit_text(C);
+       /* don't advance cursor before stepping */
+       const bool use_init_step = false;
 
-       txt_jump_left(text, 0);
-       txt_jump_right(text, 1);
+       txt_jump_left(text, false, use_init_step);
+       txt_jump_right(text, true, use_init_step);
 
        text_update_cursor_moved(C);
        WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
@@ -1371,104 +1376,6 @@ void TEXT_OT_move_lines(wmOperatorType *ot)
        RNA_def_enum(ot->srna, "direction", direction_items, 1, "Direction", "");
 }
 
-/******************* previous marker operator *********************/
-
-static int text_previous_marker_exec(bContext *C, wmOperator *UNUSED(op))
-{
-       Text *text = CTX_data_edit_text(C);
-       TextMarker *mrk;
-       int lineno;
-
-       lineno = txt_get_span(text->lines.first, text->curl);
-       mrk = text->markers.last;
-       while (mrk && (mrk->lineno > lineno || (mrk->lineno == lineno && mrk->end > text->curc)))
-               mrk = mrk->prev;
-       if (!mrk) mrk = text->markers.last;
-       if (mrk) {
-               txt_move_to(text, mrk->lineno, mrk->start, 0);
-               txt_move_to(text, mrk->lineno, mrk->end, 1);
-       }
-
-       text_update_cursor_moved(C);
-       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-
-       return OPERATOR_FINISHED;
-}
-
-void TEXT_OT_previous_marker(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name = "Previous Marker";
-       ot->idname = "TEXT_OT_previous_marker";
-       ot->description = "Move to previous marker";
-       
-       /* api callbacks */
-       ot->exec = text_previous_marker_exec;
-       ot->poll = text_edit_poll;
-}
-
-/******************* next marker operator *********************/
-
-static int text_next_marker_exec(bContext *C, wmOperator *UNUSED(op))
-{
-       Text *text = CTX_data_edit_text(C);
-       TextMarker *mrk;
-       int lineno;
-
-       lineno = txt_get_span(text->lines.first, text->curl);
-       mrk = text->markers.first;
-       while (mrk && (mrk->lineno < lineno || (mrk->lineno == lineno && mrk->start <= text->curc)))
-               mrk = mrk->next;
-       if (!mrk) mrk = text->markers.first;
-       if (mrk) {
-               txt_move_to(text, mrk->lineno, mrk->start, 0);
-               txt_move_to(text, mrk->lineno, mrk->end, 1);
-       }
-
-       text_update_cursor_moved(C);
-       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-
-       return OPERATOR_FINISHED;
-}
-
-void TEXT_OT_next_marker(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name = "Next Marker";
-       ot->idname = "TEXT_OT_next_marker";
-       ot->description = "Move to next marker";
-       
-       /* api callbacks */
-       ot->exec = text_next_marker_exec;
-       ot->poll = text_edit_poll;
-}
-
-/******************* clear all markers operator *********************/
-
-static int text_clear_all_markers_exec(bContext *C, wmOperator *UNUSED(op))
-{
-       Text *text = CTX_data_edit_text(C);
-
-       txt_clear_markers(text, 0, 0);
-
-       text_update_cursor_moved(C);
-       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-
-       return OPERATOR_FINISHED;
-}
-
-void TEXT_OT_markers_clear(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name = "Clear All Markers";
-       ot->idname = "TEXT_OT_markers_clear";
-       ot->description = "Clear all markers";
-       
-       /* api callbacks */
-       ot->exec = text_clear_all_markers_exec;
-       ot->poll = text_edit_poll;
-}
-
 /************************ move operator ************************/
 
 static EnumPropertyItem move_type_items[] = {
@@ -1498,7 +1405,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
        end = max;
        chop = loop = 1;
 
-       for (i = 0, j = 0; loop; j += BLI_str_utf8_size(linein->line + j)) {
+       for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe(linein->line + j)) {
                int chars;
                /* Mimic replacement of tabs */
                ch = linein->line[j];
@@ -1506,7 +1413,9 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
                        chars = st->tabnumber - i % st->tabnumber;
                        ch = ' ';
                }
-               else chars = 1;
+               else {
+                       chars = 1;
+               }
 
                while (chars--) {
                        if (rell == 0 && i - start == relc) {
@@ -1659,16 +1568,15 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
        Text *text = st->text;
        TextLine **linep;
        int *charp;
-       int oldl, oldc, i, j, max, start, end, endj, chop, loop;
+       int oldc, i, j, max, start, end, endj, chop, loop;
        char ch;
 
        text_update_character_width(st);
 
-       if (sel) linep = &text->sell, charp = &text->selc;
-       else linep = &text->curl, charp = &text->curc;
+       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);
 
@@ -1677,7 +1585,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
        chop = loop = 1;
        *charp = 0;
 
-       for (i = 0, j = 0; loop; j += BLI_str_utf8_size((*linep)->line + j)) {
+       for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) {
                int chars;
                /* Mimic replacement of tabs */
                ch = (*linep)->line[j];
@@ -1685,7 +1593,9 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
                        chars = st->tabnumber - i % st->tabnumber;
                        ch = ' ';
                }
-               else chars = 1;
+               else {
+                       chars = 1;
+               }
 
                while (chars--) {
                        if (i - start >= max) {
@@ -1719,7 +1629,6 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
        }
 
        if (!sel) txt_pop_sel(text);
-       txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp);
 }
 
 static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
@@ -1727,16 +1636,15 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
        Text *text = st->text;
        TextLine **linep;
        int *charp;
-       int oldl, oldc, i, j, max, start, end, endj, chop, loop;
+       int oldc, i, j, max, start, end, endj, chop, loop;
        char ch;
 
        text_update_character_width(st);
 
-       if (sel) linep = &text->sell, charp = &text->selc;
-       else linep = &text->curl, charp = &text->curc;
+       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);
 
@@ -1745,7 +1653,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
        chop = loop = 1;
        *charp = 0;
 
-       for (i = 0, j = 0; loop; j += BLI_str_utf8_size((*linep)->line + j)) {
+       for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) {
                int chars;
                /* Mimic replacement of tabs */
                ch = (*linep)->line[j];
@@ -1753,7 +1661,9 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
                        chars = st->tabnumber - i % st->tabnumber;
                        ch = ' ';
                }
-               else chars = 1;
+               else {
+                       chars = 1;
+               }
 
                while (chars--) {
                        if (i - start >= max) {
@@ -1785,7 +1695,6 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
        }
 
        if (!sel) txt_pop_sel(text);
-       txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp);
 }
 
 static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
@@ -1793,22 +1702,17 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
        Text *text = st->text;
        TextLine **linep;
        int *charp;
-       int oldl, oldc, offl, offc, col, newl;
+       int offl, offc, col;
 
        text_update_character_width(st);
 
-       if (sel) linep = &text->sell, charp = &text->selc;
-       else linep = &text->curl, charp = &text->curc;
-
-       /* store previous position */
-       oldc = *charp;
-       newl = oldl = txt_get_span(text->lines.first, *linep);
+       if (sel) { linep = &text->sell; charp = &text->selc; }
+       else     { linep = &text->curl; charp = &text->curc; }
 
        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);
-               newl = BLI_findindex(&text->lines, linep);
        }
        else {
                if ((*linep)->prev) {
@@ -1817,13 +1721,13 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
                        *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);
-                       newl--;
                }
-               else *charp = 0;
+               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 txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
@@ -1831,35 +1735,30 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
        Text *text = st->text;
        TextLine **linep;
        int *charp;
-       int oldl, oldc, offl, offc, col, newl, visible_lines;
+       int offl, offc, col, visible_lines;
 
        text_update_character_width(st);
 
-       if (sel) linep = &text->sell, charp = &text->selc;
-       else linep = &text->curl, charp = &text->curc;
-
-       /* store previous position */
-       oldc = *charp;
-       newl = oldl = txt_get_span(text->lines.first, *linep);
+       if (sel) { linep = &text->sell; charp = &text->selc; }
+       else     { linep = &text->curl; charp = &text->curc; }
 
        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);
-               newl = BLI_findindex(&text->lines, linep);
        }
        else {
                if ((*linep)->next) {
                        *linep = (*linep)->next;
                        *charp = text_get_cursor_rel(st, ar, *linep, 0, col);
-                       newl++;
                }
-               else *charp = (*linep)->len;
+               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.
@@ -1871,12 +1770,10 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
 static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int sel)
 {
        TextLine **linep;
-       int oldl, oldc, *charp;
+       int *charp;
        
-       if (sel) linep = &text->sell, charp = &text->selc;
-       else linep = &text->curl, charp = &text->curc;
-       oldl = txt_get_span(text->lines.first, *linep);
-       oldc = *charp;
+       if (sel) { linep = &text->sell; charp = &text->selc; }
+       else     { linep = &text->curl; charp = &text->curc; }
 
        if (st && ar && st->wordwrap) {
                int rell, relc;
@@ -1899,7 +1796,6 @@ static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int s
        if (*charp > (*linep)->len) *charp = (*linep)->len;
 
        if (!sel) txt_pop_sel(text);
-       txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, *linep), *charp);
 }
 
 static int text_move_cursor(bContext *C, int type, int select)
@@ -1932,18 +1828,18 @@ static int text_move_cursor(bContext *C, int type, int select)
                        break;
 
                case PREV_WORD:
-                       txt_jump_left(text, select);
+                       txt_jump_left(text, select, true);
                        break;
 
                case NEXT_WORD:
-                       txt_jump_right(text, select);
+                       txt_jump_right(text, select, true);
                        break;
 
                case PREV_CHAR:
                        txt_move_left(text, select);
                        break;
 
-               case NEXT_CHAR: 
+               case NEXT_CHAR:
                        txt_move_right(text, select);
                        break;
 
@@ -2043,12 +1939,14 @@ static int text_jump_exec(bContext *C, wmOperator *op)
 
 static int text_jump_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
-       return WM_operator_props_dialog_popup(C, op, 200, 100);
+       return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
 
 }
 
 void TEXT_OT_jump(wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+
        /* identifiers */
        ot->name = "Jump";
        ot->idname = "TEXT_OT_jump";
@@ -2060,7 +1958,8 @@ void TEXT_OT_jump(wmOperatorType *ot)
        ot->poll = text_edit_poll;
 
        /* properties */
-       RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to", 1, 10000);
+       prop = RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to", 1, 10000);
+       RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
 }
 
 /******************* delete operator **********************/
@@ -2217,10 +2116,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
 
        if (!tsc->scrollbar) {
                txtdelta[0] = -tsc->delta[0] / st->cwidth;
-               txtdelta[1] = tsc->delta[1] / st->lheight;
+               txtdelta[1] = tsc->delta[1] / (st->lheight_dpi + TXT_LINE_SPACING);
 
                tsc->delta[0] %= st->cwidth;
-               tsc->delta[1] %= st->lheight;
+               tsc->delta[1] %= (st->lheight_dpi + TXT_LINE_SPACING);
        }
        else {
                txtdelta[1] = -tsc->delta[1] * st->pix_per_line;
@@ -2315,7 +2214,7 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
                tsc->old[1] = event->y;
                /* Sensitivity of scroll set to 4pix per line/char */
                tsc->delta[0] = (event->x - event->prevx) * st->cwidth / 4;
-               tsc->delta[1] = (event->y - event->prevy) * st->lheight / 4;
+               tsc->delta[1] = (event->y - event->prevy) * st->lheight_dpi / 4;
                tsc->first = 0;
                tsc->scrollbar = 0;
                text_scroll_apply(C, op, event);
@@ -2407,8 +2306,8 @@ static int text_scroll_bar_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
        /* jump scroll, works in v2d but needs to be added here too :S */
        if (event->type == MIDDLEMOUSE) {
-               tsc->old[0] = ar->winrct.xmin + (st->txtbar.xmax + st->txtbar.xmin) / 2;
-               tsc->old[1] = ar->winrct.ymin + (st->txtbar.ymax + st->txtbar.ymin) / 2;
+               tsc->old[0] = ar->winrct.xmin + BLI_rcti_cent_x(&st->txtbar);
+               tsc->old[1] = ar->winrct.ymin + BLI_rcti_cent_y(&st->txtbar);
 
                tsc->delta[0] = 0;
                tsc->delta[1] = 0;
@@ -2457,11 +2356,13 @@ static int flatten_len(SpaceText *st, const char *str)
 {
        int i, total = 0;
 
-       for (i = 0; str[i]; i += BLI_str_utf8_size(str + i)) {
+       for (i = 0; str[i]; i += BLI_str_utf8_size_safe(str + i)) {
                if (str[i] == '\t') {
                        total += st->tabnumber - total % st->tabnumber;
                }
-               else total++;
+               else {
+                       total++;
+               }
        }
        
        return total;
@@ -2470,7 +2371,7 @@ static int flatten_len(SpaceText *st, const char *str)
 static int flatten_index_to_offset(SpaceText *st, const char *str, int index)
 {
        int i, j;
-       for (i = 0, j = 0; i < index; j += BLI_str_utf8_size(str + j))
+       for (i = 0, j = 0; i < index; j += BLI_str_utf8_size_safe(str + j))
                if (str[j] == '\t')
                        i += st->tabnumber - i % st->tabnumber;
                else
@@ -2514,7 +2415,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
                int j = 0, curs = 0, endj = 0;   /* mem */
                int chop = 1;                    /* flags */
                
-               for (; loop; j += BLI_str_utf8_size(linep->line + j)) {
+               for (; loop; j += BLI_str_utf8_size_safe(linep->line + j)) {
                        int chars;
                        
                        /* Mimic replacement of tabs */
@@ -2523,7 +2424,9 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
                                chars = st->tabnumber - i % st->tabnumber;
                                ch = ' ';
                        }
-                       else chars = 1;
+                       else {
+                               chars = 1;
+                       }
                        
                        while (chars--) {
                                /* Gone too far, go back to last wrap point */
@@ -2606,7 +2509,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
 
        if (linep && charp != -1) {
                if (sel) { text->sell = linep; text->selc = charp; }
-               else { text->curl = linep; text->curc = charp; }
+               else     { text->curl = linep; text->curc = charp; }
        }
 }
 
@@ -2614,7 +2517,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
 {
        Text *text = st->text;
        text_update_character_width(st);
-       y = (ar->winy - 2 - y) / st->lheight;
+       y = (ar->winy - 2 - y) / (st->lheight_dpi + TXT_LINE_SPACING);
 
        if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC;
        else x -= TXT_OFFSET;
@@ -2631,7 +2534,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
                int w;
                
                if (sel) { linep = &text->sell; charp = &text->selc; }
-               else { linep = &text->curl; charp = &text->curc; }
+               else     { linep = &text->curl; charp = &text->curc; }
                
                y -= txt_get_span(text->lines.first, *linep) - st->top;
                
@@ -2664,7 +2567,7 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, wmEvent *event)
 
                text_update_cursor_moved(C);
                WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
-       } 
+       }
        else if (!st->wordwrap && (event->mval[0] < 0 || event->mval[0] > ar->winx)) {
                if (event->mval[0] > ar->winx) st->left++;
                else if (event->mval[0] < 0 && st->left > 0) st->left--;
@@ -2674,7 +2577,7 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, wmEvent *event)
                text_update_cursor_moved(C);
                WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
                // XXX PIL_sleep_ms(10);
-       } 
+       }
        else {
                text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1);
 
@@ -2683,7 +2586,7 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, wmEvent *event)
 
                ssel->old[0] = event->mval[0];
                ssel->old[1] = event->mval[1];
-       } 
+       }
 }
 
 static void text_cursor_set_exit(bContext *C, wmOperator *op)
@@ -2691,7 +2594,6 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
        SpaceText *st = CTX_wm_space_text(C);
        Text *text = st->text;
        SetSelection *ssel = op->customdata;
-       int linep2, charp2;
        char *buffer;
 
        if (txt_has_sel(text)) {
@@ -2700,12 +2602,6 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
                MEM_freeN(buffer);
        }
 
-       linep2 = txt_get_span(st->text->lines.first, st->text->sell);
-       charp2 = st->text->selc;
-               
-       if (ssel->sell != linep2 || ssel->selc != charp2)
-               txt_undo_add_toop(st->text, UNDO_STO, ssel->sell, ssel->selc, linep2, charp2);
-
        text_update_cursor_moved(C);
        WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
 
@@ -2781,19 +2677,12 @@ void TEXT_OT_selection_set(wmOperatorType *ot)
 static int text_cursor_set_exec(bContext *C, wmOperator *op)
 {
        SpaceText *st = CTX_wm_space_text(C);
-       Text *text = st->text;
        ARegion *ar = CTX_wm_region(C);
        int x = RNA_int_get(op->ptr, "x");
        int y = RNA_int_get(op->ptr, "y");
-       int oldl, oldc;
-
-       oldl = txt_get_span(text->lines.first, text->curl);
-       oldc = text->curc;
 
        text_cursor_set_to_pos(st, ar, x, y, 0);
 
-       txt_undo_add_toop(text, UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, text->curl), text->curc);
-
        text_update_cursor_moved(C);
        WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
 
@@ -2928,8 +2817,11 @@ static int text_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
        // if (!RNA_struct_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */
        if (!RNA_string_length(op->ptr, "text")) {
-               /* if alt/ctrl/super are pressed pass through */
-               if (event->ctrl || event->oskey) {
+               /* if alt/ctrl/super are pressed pass through except for utf8 character event
+                * (when input method are used for utf8 inputs, the user may assign key event
+                * including alt/ctrl/super like ctrl+m to commit utf8 string.  in such case,
+                * the modifiers in the utf8 character event make no sense.) */
+               if ((event->ctrl || event->oskey) && !event->utf8_buf[0]) {
                        return OPERATOR_PASS_THROUGH;
                }
                else {
@@ -2937,7 +2829,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
                        size_t len;
                        
                        if (event->utf8_buf[0]) {
-                               len = BLI_str_utf8_size(event->utf8_buf);
+                               len = BLI_str_utf8_size_safe(event->utf8_buf);
                                memcpy(str, event->utf8_buf, len);
                        }
                        else {
@@ -2982,14 +2874,13 @@ void TEXT_OT_insert(wmOperatorType *ot)
 /* mode */
 #define TEXT_FIND       0
 #define TEXT_REPLACE    1
-#define TEXT_MARK_ALL   2
 
 static int text_find_and_replace(bContext *C, wmOperator *op, short mode)
 {
        Main *bmain = CTX_data_main(C);
        SpaceText *st = CTX_wm_space_text(C);
-       Text *start = NULL, *text = st->text;
-       int flags, first = 1;
+       Text *text = st->text;
+       int flags;
        int found = 0;
        char *tmp;
 
@@ -2998,79 +2889,48 @@ static int text_find_and_replace(bContext *C, wmOperator *op, short mode)
 
        flags = st->flags;
        if (flags & ST_FIND_ALL)
-               flags ^= ST_FIND_WRAP;
+               flags &= ~ST_FIND_WRAP;
 
-       do {
-               int proceed = 0;
+       /* Replace current */
+       if (mode != TEXT_FIND && txt_has_sel(text)) {
+               tmp = txt_sel_to_buf(text);
 
-               if (first) {
-                       if (text->markers.first)
-                               WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+               if (flags & ST_MATCH_CASE) found = strcmp(st->findstr, tmp) == 0;
+               else found = BLI_strcasecmp(st->findstr, tmp) == 0;
 
-                       txt_clear_markers(text, TMARK_GRP_FINDALL, 0);
-               }
-
-               first = 0;
-               
-               /* Replace current */
-               if (mode != TEXT_FIND && txt_has_sel(text)) {
-                       tmp = txt_sel_to_buf(text);
-
-                       if (flags & ST_MATCH_CASE) proceed = strcmp(st->findstr, tmp) == 0;
-                       else proceed = BLI_strcasecmp(st->findstr, tmp) == 0;
-
-                       if (proceed) {
-                               if (mode == TEXT_REPLACE) {
-                                       txt_insert_buf(text, st->replacestr);
-                                       if (text->curl && text->curl->format) {
-                                               MEM_freeN(text->curl->format);
-                                               text->curl->format = NULL;
-                                       }
-                                       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) {
-                                       unsigned char color[4];
-                                       UI_GetThemeColor4ubv(TH_SHADE2, color);
-
-                                       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, color, TMARK_GRP_FINDALL, TMARK_EDITALL);
-                                       text_update_cursor_moved(C);
-                                       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+               if (found) {
+                       if (mode == TEXT_REPLACE) {
+                               txt_insert_buf(text, st->replacestr);
+                               if (text->curl && text->curl->format) {
+                                       MEM_freeN(text->curl->format);
+                                       text->curl->format = NULL;
                                }
+                               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);
                        }
-                       MEM_freeN(tmp);
-                       tmp = NULL;
                }
+               MEM_freeN(tmp);
+               tmp = NULL;
+       }
 
-               /* Find next */
-               if (txt_find_string(text, st->findstr, flags & ST_FIND_WRAP, flags & ST_MATCH_CASE)) {
-                       text_update_cursor_moved(C);
-                       WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
-               }
-               else if (flags & ST_FIND_ALL) {
-                       if (text == start) break;
-                       if (!start) start = text;
-                       if (text->id.next)
-                               text = st->text = text->id.next;
-                       else
-                               text = st->text = bmain->text.first;
-                       txt_move_toline(text, 0, 0);
-                       text_update_cursor_moved(C);
-                       WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
-                       first = 1;
-               }
-               else {
-                       if (!found && !proceed) BKE_reportf(op->reports, RPT_ERROR, "Text not found: %s", st->findstr);
-                       break;
-               }
-               found = 1;
-       } while (mode == TEXT_MARK_ALL);
+       /* Find next */
+       if (txt_find_string(text, st->findstr, flags & ST_FIND_WRAP, flags & ST_MATCH_CASE)) {
+               text_update_cursor_moved(C);
+               WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
+       }
+       else if (flags & ST_FIND_ALL) {
+               if (text->id.next)
+                       text = st->text = text->id.next;
+               else
+                       text = st->text = bmain->text.first;
+               txt_move_toline(text, 0, 0);
+               text_update_cursor_moved(C);
+               WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
+       }
+       else {
+               if (!found) BKE_reportf(op->reports, RPT_ERROR, "Text not found: %s", st->findstr);
+       }
 
        return OPERATOR_FINISHED;
 }
@@ -3111,25 +2971,6 @@ void TEXT_OT_replace(wmOperatorType *ot)
        ot->poll = text_space_edit_poll;
 }
 
-/******************* mark all operator *********************/
-
-static int text_mark_all_exec(bContext *C, wmOperator *op)
-{
-       return text_find_and_replace(C, op, TEXT_MARK_ALL);
-}
-
-void TEXT_OT_mark_all(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name = "Mark All";
-       ot->idname = "TEXT_OT_mark_all";
-       ot->description = "Mark all specified text";
-       
-       /* api callbacks */
-       ot->exec = text_mark_all_exec;
-       ot->poll = text_space_edit_poll;
-}
-
 /******************* find set selected *********************/
 
 static int text_find_set_selected_exec(bContext *C, wmOperator *op)
@@ -3283,27 +3124,31 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *UN
                case 1:
                        if (text->flags & TXT_ISDIRTY) {
                                /* modified locally and externally, ahhh. offer more possibilites. */
-                               pup = uiPupMenuBegin(C, "File Modified Outside and Inside Blender", ICON_NONE);
+                               pup = uiPupMenuBegin(C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE);
                                layout = uiPupMenuLayout(pup);
-                               uiItemEnumO_ptr(layout, op->type, "Reload from disk (ignore local changes)", 0, "resolution", RESOLVE_RELOAD);
-                               uiItemEnumO_ptr(layout, op->type, "Save to disk (ignore outside changes)", 0, "resolution", RESOLVE_SAVE);
-                               uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL);
+                               uiItemEnumO_ptr(layout, op->type, IFACE_("Reload from disk (ignore local changes)"),
+                                               0, "resolution", RESOLVE_RELOAD);
+                               uiItemEnumO_ptr(layout, op->type, IFACE_("Save to disk (ignore outside changes)"),
+                                               0, "resolution", RESOLVE_SAVE);
+                               uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal (separate copy)"),
+                                               0, "resolution", RESOLVE_MAKE_INTERNAL);
                                uiPupMenuEnd(C, pup);
                        }
                        else {
-                               pup = uiPupMenuBegin(C, "File Modified Outside Blender", ICON_NONE);
+                               pup = uiPupMenuBegin(C, IFACE_("File Modified Outside Blender"), ICON_NONE);
                                layout = uiPupMenuLayout(pup);
-                               uiItemEnumO_ptr(layout, op->type, "Reload from disk", 0, "resolution", RESOLVE_RELOAD);
-                               uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL);
-                               uiItemEnumO_ptr(layout, op->type, "Ignore", 0, "resolution", RESOLVE_IGNORE);
+                               uiItemEnumO_ptr(layout, op->type, IFACE_("Reload from disk"), 0, "resolution", RESOLVE_RELOAD);
+                               uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal (separate copy)"),
+                                               0, "resolution", RESOLVE_MAKE_INTERNAL);
+                               uiItemEnumO_ptr(layout, op->type, IFACE_("Ignore"), 0, "resolution", RESOLVE_IGNORE);
                                uiPupMenuEnd(C, pup);
                        }
                        break;
                case 2:
-                       pup = uiPupMenuBegin(C, "File Deleted Outside Blender", ICON_NONE);
+                       pup = uiPupMenuBegin(C, IFACE_("File Deleted Outside Blender"), ICON_NONE);
                        layout = uiPupMenuLayout(pup);
-                       uiItemEnumO_ptr(layout, op->type, "Make text internal", 0, "resolution", RESOLVE_MAKE_INTERNAL);
-                       uiItemEnumO_ptr(layout, op->type, "Recreate file", 0, "resolution", RESOLVE_SAVE);
+                       uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal"), 0, "resolution", RESOLVE_MAKE_INTERNAL);
+                       uiItemEnumO_ptr(layout, op->type, IFACE_("Recreate file"), 0, "resolution", RESOLVE_SAVE);
                        uiPupMenuEnd(C, pup);
                        break;
        }
@@ -3344,7 +3189,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot)
        /* identifiers */
        ot->name = "To 3D Object";
        ot->idname = "TEXT_OT_to_3d_object";
-       ot->description = "Create 3d text object from active text data block";
+       ot->description = "Create 3D text object from active text data block";
        
        /* api callbacks */
        ot->exec = text_to_3d_object_exec;