Unify string stepping delimiter code for text buttons, text editor and console (all...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 7 Mar 2012 15:55:12 +0000 (15:55 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 7 Mar 2012 15:55:12 +0000 (15:55 +0000)
this is also a step toward the console working with utf8 though many todo's remain.

source/blender/blenkernel/intern/text.c
source/blender/blenlib/BLI_string_cursor_utf8.h [new file with mode: 0644]
source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/intern/string_cursor_utf8.c [new file with mode: 0644]
source/blender/editors/interface/interface_handlers.c
source/blender/editors/space_console/console_ops.c

index a60ea87..61c69d9 100644 (file)
@@ -29,7 +29,7 @@
  *  \ingroup bke
  */
 
-
+#include <stdlib.h> /* abort */
 #include <string.h> /* strstr */
 #include <sys/types.h>
 #include <sys/stat.h>
 
 #include "MEM_guardedalloc.h"
 
-#include "BLI_blenlib.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_string_cursor_utf8.h"
+#include "BLI_string_utf8.h"
+#include "BLI_listbase.h"
 #include "BLI_utildefines.h"
 
 #include "DNA_constraint_types.h"
@@ -731,14 +735,6 @@ static void txt_make_dirty (Text *text)
 #endif
 }
 
-/* 0:whitespace, 1:punct, 2:alphanumeric */
-static short txt_char_type(unsigned int ch)
-{
-       if (iswspace(ch)) return 0;
-       if (iswalpha(ch) || iswdigit(ch)) return 2;
-       return 1;
-}
-
 /****************************/
 /* Cursor utility functions */
 /****************************/
@@ -957,32 +953,32 @@ void txt_move_right(Text *text, short sel)
 void txt_jump_left(Text *text, short sel)
 {
        TextLine **linep, *oldl;
-       int *charp, oldc, count, i;
+       int *charp, oldc, oldflags, i;
        unsigned char oldu;
+       short pos;
 
        if (!text) return;
        if(sel) txt_curs_sel(text, &linep, &charp);
        else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
        if (!*linep) return;
 
+       oldflags = text->flags;
+       text->flags &= ~TXT_TABSTOSPACES;
+
        oldl= *linep;
        oldc= *charp;
        oldu= undoing;
        undoing= 1; /* Don't push individual moves to undo stack */
 
-       count= 0;
-       for (i=0; i<3; i++) {
-               if (count < 2) {
-                       while (*charp>0) {
-                               char *sym= BLI_str_prev_char_utf8((*linep)->line + *charp);
-                               if (txt_char_type(BLI_str_utf8_as_unicode(sym))==i) {
-                                       txt_move_left(text, sel);
-                                       count++;
-                               } else break;
-                       }
-               }
+       pos = *charp;
+       BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
+                                &pos, STRCUR_DIR_PREV,
+                                STRCUR_JUMP_DELIM);
+       for (i = *charp; i > pos; i--) {
+               txt_move_left(text, sel);
        }
-       if (count==0) txt_move_left(text, sel);
+
+       text->flags = oldflags;
 
        undoing= oldu;
        if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
@@ -991,32 +987,32 @@ void txt_jump_left(Text *text, short sel)
 void txt_jump_right(Text *text, short sel)
 {
        TextLine **linep, *oldl;
-       int *charp, oldc, count, i;
+       int *charp, oldc, oldflags, i;
        unsigned char oldu;
+       short pos;
 
        if (!text) return;
        if(sel) txt_curs_sel(text, &linep, &charp);
        else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
        if (!*linep) return;
 
+       oldflags = text->flags;
+       text->flags &= ~TXT_TABSTOSPACES;
+
        oldl= *linep;
        oldc= *charp;
        oldu= undoing;
        undoing= 1; /* Don't push individual moves to undo stack */
 
-       count= 0;
-       for (i=0; i<3; i++) {
-               if (count < 2) {
-                       while (*charp<(*linep)->len) {
-                               char *sym= (*linep)->line + *charp;
-                               if (txt_char_type(BLI_str_utf8_as_unicode(sym))==i) {
-                                       txt_move_right(text, sel);
-                                       count++;
-                               } else break;
-                       }
-               }
+       pos = *charp;
+       BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
+                                &pos, STRCUR_DIR_NEXT,
+                                STRCUR_JUMP_DELIM);
+       for (i = *charp; i < pos; i++) {
+               txt_move_right(text, sel);
        }
-       if (count==0) txt_move_right(text, sel);
+
+       text->flags = oldflags;
 
        undoing= oldu;
        if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
new file mode 100644 (file)
index 0000000..4bdc7f6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_STRING_CURSOR_UTF8_H__
+#define __BLI_STRING_CURSOR_UTF8_H__
+
+/** \file BLI_string_utf8.h
+ *  \ingroup bli
+ */
+
+typedef enum strCursorDelimType {
+       STRCUR_DELIM_NONE,
+       STRCUR_DELIM_ALPHA,
+       STRCUR_DELIM_PUNCT,
+       STRCUR_DELIM_BRACE,
+       STRCUR_DELIM_OPERATOR,
+       STRCUR_DELIM_QUOTE,
+       STRCUR_DELIM_WHITESPACE,
+       STRCUR_DELIM_OTHER
+} strCursorDelimType;
+
+typedef enum strCursorJumpType {
+       STRCUR_JUMP_NONE,
+       STRCUR_JUMP_DELIM,
+       STRCUR_JUMP_ALL
+} strCursorJumpType;
+
+typedef enum strCursorJumpDirection {
+       STRCUR_DIR_PREV,
+       STRCUR_DIR_NEXT
+} strCursorJumpDirection;
+
+int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, short *pos);
+int BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, short *pos);
+
+void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
+                              short *pos, strCursorJumpDirection direction,
+                              strCursorJumpType jump);
+
+#endif /* __BLI_STRING_CURSOR_UTF8_H__ */
index 90fd8d1..76019f0 100644 (file)
@@ -82,6 +82,7 @@ set(SRC
        intern/smallhash.c
        intern/storage.c
        intern/string.c
+       intern/string_cursor_utf8.c
        intern/string_utf8.c
        intern/threads.c
        intern/time.c
@@ -132,6 +133,7 @@ set(SRC
        BLI_rect.h
        BLI_scanfill.h
        BLI_string.h
+       BLI_string_cursor_utf8.h
        BLI_string_utf8.h
        BLI_threads.h
        BLI_utildefines.h
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
new file mode 100644 (file)
index 0000000..6dc88ec
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Campbell Barton.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/blenlib/intern/string_cursor_utf8.c
+  *  \ingroup bli
+  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_string_utf8.h"
+
+#include "BLI_string_cursor_utf8.h" /* own include */
+
+
+/* return 1 if char ch is special character, otherwise return 0 */
+static strCursorDelimType test_special_char(const char ch)
+{
+       /* TODO - use BLI_str_utf8_as_unicode rather then assuming ascii */
+
+       if ((ch >= 'a' && ch <= 'z') ||
+           (ch >= 'A' && ch <= 'Z') ||
+           (ch == '_') /* not quite correct but allow for python, could become configurable */
+           )
+       {
+               return STRCUR_DELIM_ALPHA;
+       }
+
+       switch (ch) {
+               case ',':
+               case '.':
+                       return STRCUR_DELIM_PUNCT;
+
+               case '{':
+               case '}':
+               case '[':
+               case ']':
+               case '(':
+               case ')':
+                       return STRCUR_DELIM_BRACE;
+
+               case '+':
+               case '-':
+               case '=':
+               case '~':
+               case '%':
+               case '/':
+               case '<':
+               case '>':
+               case '^':
+               case '*':
+               case '&':
+                       return STRCUR_DELIM_OPERATOR;
+
+               case '\'':
+               case '\"': // " - an extra closing one for Aligorith's text editor
+                       return STRCUR_DELIM_QUOTE;
+
+               case ' ':
+                       return STRCUR_DELIM_WHITESPACE;
+
+               case '\\':
+               case '!':
+               case '@':
+               case '#':
+               case '$':
+               case ':':
+               case ';':
+               case '?':
+               /* case '_': */ /* special case, for python */
+                       return STRCUR_DELIM_OTHER;
+
+               default:
+                       break;
+       }
+       return STRCUR_DELIM_NONE;
+}
+
+int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, short *pos)
+{
+       const char *str_end= str + (maxlen + 1);
+       const char *str_pos= str + (*pos);
+       const char *str_next= BLI_str_find_next_char_utf8(str_pos, str_end);
+       if (str_next) {
+               (*pos) += (str_next - str_pos);
+               if((*pos) > maxlen) (*pos)= maxlen;
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), short *pos)
+{
+       if((*pos) > 0) {
+               const char *str_pos= str + (*pos);
+               const char *str_prev= BLI_str_find_prev_char_utf8(str, str_pos);
+               if (str_prev) {
+                       (*pos) -= (str_pos - str_prev);
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
+                              short *pos, strCursorJumpDirection direction,
+                              strCursorJumpType jump)
+{
+       const short pos_prev= *pos;
+
+       if (direction == STRCUR_DIR_NEXT) {
+               BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+
+               if (jump != STRCUR_JUMP_NONE) {
+                       const strCursorDelimType is_special= (*pos) < maxlen ? test_special_char(str[(*pos)]) : STRCUR_DELIM_NONE;
+                       /* jump between special characters (/,\,_,-, etc.),
+                        * look at function test_special_char() for complete
+                        * list of special character, ctr -> */
+                       while ((*pos) < maxlen) {
+                               if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) {
+                                       if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break;
+                               }
+                               else {
+                                       break; /* unlikely but just incase */
+                               }
+                       }
+               }
+       }
+       else if (direction == STRCUR_DIR_PREV) {
+               BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
+
+               if(jump != STRCUR_JUMP_NONE) {
+                       const strCursorDelimType is_special= (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : STRCUR_DELIM_NONE;
+                       /* jump between special characters (/,\,_,-, etc.),
+                        * look at function test_special_char() for complete
+                        * list of special character, ctr -> */
+                       while ((*pos) > 0) {
+                               if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
+                                       if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break;
+                               }
+                               else {
+                                       break;
+                               }
+                       }
+
+                       /* left only: compensate for index/change in direction */
+                       if (((*pos) != 0) && ABS(pos_prev - (*pos)) >= 1) {
+                               BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+                       }
+               }
+       }
+       else {
+               BLI_assert(0);
+       }
+}
index 3d9295b..8504677 100644 (file)
@@ -48,6 +48,7 @@
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
+#include "BLI_string_cursor_utf8.h"
 
 #include "PIL_time.h"
 
@@ -108,23 +109,6 @@ typedef enum uiHandleButtonState {
        BUTTON_STATE_EXIT
 } uiHandleButtonState;
 
-typedef enum uiButtonJumpType {
-       BUTTON_EDIT_JUMP_NONE,
-       BUTTON_EDIT_JUMP_DELIM,
-       BUTTON_EDIT_JUMP_ALL
-} uiButtonJumpType;
-
-typedef enum uiButtonDelimType {
-       BUTTON_DELIM_NONE,
-       BUTTON_DELIM_ALPHA,
-       BUTTON_DELIM_PUNCT,
-       BUTTON_DELIM_BRACE,
-       BUTTON_DELIM_OPERATOR,
-       BUTTON_DELIM_QUOTE,
-       BUTTON_DELIM_WHITESPACE,
-       BUTTON_DELIM_OTHER
-} uiButtonDelimType;
-
 typedef struct uiHandleButtonData {
        wmWindowManager *wm;
        wmWindow *window;
@@ -1238,139 +1222,6 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
 
 /* ************* in-button text selection/editing ************* */
 
-/* return 1 if char ch is special character, otherwise return 0 */
-static uiButtonDelimType test_special_char(const char ch)
-{
-       if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
-               return BUTTON_DELIM_ALPHA;
-       }
-
-       switch(ch) {
-               case ',':
-               case '.':
-                       return BUTTON_DELIM_PUNCT;
-
-               case '{':
-               case '}':
-               case '[':
-               case ']':
-               case '(':
-               case ')':
-                       return BUTTON_DELIM_BRACE;
-
-               case '+':
-               case '-':
-               case '=':
-               case '~':
-               case '%':
-               case '/':
-               case '<':
-               case '>':
-               case '^':
-               case '*':
-               case '&':
-                       return BUTTON_DELIM_OPERATOR;
-
-               case '\'':
-               case '\"': // " - an extra closing one for Aligorith's text editor
-                       return BUTTON_DELIM_QUOTE;
-
-               case ' ':
-                       return BUTTON_DELIM_WHITESPACE;
-
-               case '\\':
-               case '!':
-               case '@':
-               case '#':
-               case '$':
-               case ':':
-               case ';':
-               case '?':
-               case '_':
-                       return BUTTON_DELIM_OTHER;
-
-               default:
-                       break;
-       }
-       return BUTTON_DELIM_NONE;
-}
-
-static int ui_textedit_step_next_utf8(const char *str, size_t maxlen, short *pos)
-{
-       const char *str_end= str + (maxlen + 1);
-       const char *str_pos= str + (*pos);
-       const char *str_next= BLI_str_find_next_char_utf8(str_pos, str_end);
-       if (str_next) {
-               (*pos) += (str_next - str_pos);
-               if((*pos) > maxlen) (*pos)= maxlen;
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-static int ui_textedit_step_prev_utf8(const char *str, size_t UNUSED(maxlen), short *pos)
-{
-       if((*pos) > 0) {
-               const char *str_pos= str + (*pos);
-               const char *str_prev= BLI_str_find_prev_char_utf8(str, str_pos);
-               if (str_prev) {
-                       (*pos) -= (str_pos - str_prev);
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
-static void ui_textedit_step_utf8(const char *str, size_t maxlen,
-                                  short *pos, const char direction,
-                                  uiButtonJumpType jump)
-{
-       const short pos_prev= *pos;
-
-       if (direction) { /* right */
-               ui_textedit_step_next_utf8(str, maxlen, pos);
-
-               if (jump != BUTTON_EDIT_JUMP_NONE) {
-                       const uiButtonDelimType is_special= (*pos) < maxlen ? test_special_char(str[(*pos)]) : BUTTON_DELIM_NONE;
-                       /* jump between special characters (/,\,_,-, etc.),
-                        * look at function test_special_char() for complete
-                        * list of special character, ctr -> */
-                       while ((*pos) < maxlen) {
-                               if (ui_textedit_step_next_utf8(str, maxlen, pos)) {
-                                       if ((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break;
-                               }
-                               else {
-                                       break; /* unlikely but just incase */
-                               }
-                       }
-               }
-       }
-       else { /* left */
-               ui_textedit_step_prev_utf8(str, maxlen, pos);
-
-               if(jump != BUTTON_EDIT_JUMP_NONE) {
-                       const uiButtonDelimType is_special= (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : BUTTON_DELIM_NONE;
-                       /* jump between special characters (/,\,_,-, etc.),
-                        * look at function test_special_char() for complete
-                        * list of special character, ctr -> */
-                       while ((*pos) > 0) {
-                               if (ui_textedit_step_prev_utf8(str, maxlen, pos)) {
-                                       if ((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break;
-                               }
-                               else {
-                                       break;
-                               }
-                       }
-
-                       /* left only: compensate for index/change in direction */
-                       if (((*pos) != 0) && ABS(pos_prev - (*pos)) >= 1) {
-                               ui_textedit_step_next_utf8(str, maxlen, pos);
-                       }
-               }
-       }
-}
 
 static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
 {
@@ -1419,7 +1270,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
                origstr[but->ofs] = 0;
                
                while (i > 0) {
-                       if (ui_textedit_step_prev_utf8(origstr, but->ofs, &i)) {
+                       if (BLI_str_cursor_step_prev_utf8(origstr, but->ofs, &i)) {
                                if (BLF_width(fstyle->uifont_id, origstr+i) > (startx - x)*0.25f) break;        // 0.25 == scale factor for less sensitivity
                        }
                        else {
@@ -1438,7 +1289,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
                /* XXX does not take zoom level into account */
                while (startx + aspect_sqrt * BLF_width(fstyle->uifont_id, origstr+but->ofs) > x) {
                        if (but->pos <= 0) break;
-                       if (ui_textedit_step_prev_utf8(origstr, but->ofs, &but->pos)) {
+                       if (BLI_str_cursor_step_prev_utf8(origstr, but->ofs, &but->pos)) {
                                origstr[but->pos+but->ofs] = 0;
                        }
                        else {
@@ -1515,7 +1366,7 @@ static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char asc
        return ui_textedit_type_buf(but, data, buf, 1);
 }
 
-static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, uiButtonJumpType jump)
+static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJumpDirection direction, int select, strCursorJumpType jump)
 {
        const char *str= data->str;
        const int len= strlen(str);
@@ -1526,7 +1377,7 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
 
        /* special case, quit selection and set cursor */
        if (has_sel && !select) {
-               if (jump == BUTTON_EDIT_JUMP_ALL) {
+               if (jump == STRCUR_JUMP_ALL) {
                        but->selsta = but->selend= but->pos = direction ? len : 0;
                }
                else {
@@ -1540,7 +1391,7 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
                data->selextend = 0;
        }
        else {
-               ui_textedit_step_utf8(str, len, &but->pos, direction, jump);
+               BLI_str_cursor_step_utf8(str, len, &but->pos, direction, jump);
 
                if(select) {
                        /* existing selection */
@@ -1589,14 +1440,14 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
        }
 }
 
-static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, uiButtonJumpType jump)
+static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, strCursorJumpType jump)
 {
        char *str= data->str;
        const int len= strlen(str);
 
        int changed= 0;
 
-       if(jump == BUTTON_EDIT_JUMP_ALL) {
+       if (jump == STRCUR_JUMP_ALL) {
                if(len) changed=1;
                str[0]= '\0';
                but->pos= 0;
@@ -1608,7 +1459,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
                else if (but->pos>=0 && but->pos<len) {
                        short pos= but->pos;
                        int step;
-                       ui_textedit_step_utf8(str, len, &pos, direction, jump);
+                       BLI_str_cursor_step_utf8(str, len, &pos, direction, jump);
                        step= pos - but->pos;
                        memmove(&str[but->pos], &str[but->pos + step], (len + 1) - but->pos);
                        changed= 1;
@@ -1623,7 +1474,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
                                short pos= but->pos;
                                int step;
 
-                               ui_textedit_step_utf8(str, len, &pos, direction, jump);
+                               BLI_str_cursor_step_utf8(str, len, &pos, direction, jump);
                                step= but->pos - pos;
                                memmove(&str[but->pos - step], &str[but->pos], (len + 1) - but->pos);
                                but->pos -= step;
@@ -1915,11 +1766,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                                break;
                        case RIGHTARROWKEY:
-                               ui_textedit_move(but, data, 1, event->shift, event->ctrl ? BUTTON_EDIT_JUMP_DELIM : BUTTON_EDIT_JUMP_NONE);
+                               ui_textedit_move(but, data, STRCUR_DIR_NEXT, event->shift, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case LEFTARROWKEY:
-                               ui_textedit_move(but, data, 0, event->shift, event->ctrl ? BUTTON_EDIT_JUMP_DELIM : BUTTON_EDIT_JUMP_NONE);
+                               ui_textedit_move(but, data, STRCUR_DIR_PREV, event->shift, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case DOWNARROWKEY:
@@ -1929,7 +1780,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                                /* pass on purposedly */
                        case ENDKEY:
-                               ui_textedit_move(but, data, 1, event->shift, BUTTON_EDIT_JUMP_ALL);
+                               ui_textedit_move(but, data, STRCUR_DIR_NEXT, event->shift, STRCUR_JUMP_ALL);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case UPARROWKEY:
@@ -1939,7 +1790,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                                /* pass on purposedly */
                        case HOMEKEY:
-                               ui_textedit_move(but, data, 0, event->shift, BUTTON_EDIT_JUMP_ALL);
+                               ui_textedit_move(but, data, STRCUR_DIR_PREV, event->shift, STRCUR_JUMP_ALL);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case PADENTER:
@@ -1948,12 +1799,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case DELKEY:
-                               changed= ui_textedit_delete(but, data, 1, event->ctrl ? BUTTON_EDIT_JUMP_DELIM : BUTTON_EDIT_JUMP_NONE);
+                               changed= ui_textedit_delete(but, data, 1, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
 
                        case BACKSPACEKEY:
-                               changed= ui_textedit_delete(but, data, 0, event->shift ? BUTTON_EDIT_JUMP_ALL :  (event->ctrl ? BUTTON_EDIT_JUMP_DELIM : BUTTON_EDIT_JUMP_NONE));
+                               changed= ui_textedit_delete(but, data, 0, event->shift ? STRCUR_JUMP_ALL :  (event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE));
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                                
index 427776e..ab1cada 100644 (file)
@@ -34,7 +34,9 @@
 
 #include "DNA_userdef_types.h"
 
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
+#include "BLI_string_cursor_utf8.h"
+#include "BLI_string.h"
 #include "BLI_dynstr.h"
 #include "BLI_utildefines.h"
 
@@ -115,43 +117,20 @@ static ConsoleLine * console_history_find(SpaceConsole *sc, const char *str, Con
 static int console_line_cursor_set(ConsoleLine *cl, int cursor)
 {
        int cursor_new;
+
+       if      (cursor < 0)        cursor_new = 0;
+       else if (cursor > cl->len)  cursor_new = cl->len;
+       else                        cursor_new = cursor;
        
-       if(cursor < 0)                          cursor_new= 0;
-       else if(cursor > cl->len)       cursor_new= cl->len;
-       else                                            cursor_new= cursor;
-       
-       if(cursor_new == cl->cursor)
-               return 0;
+       if (cursor_new == cl->cursor) {
+               return FALSE;
+       }
        
-       cl->cursor= cursor_new;
-       return 1;
-}
-
-static char cursor_char(ConsoleLine *cl)
-{
-       /* assume cursor is clamped */
-       return cl->line[cl->cursor];
-}
-
-static char cursor_char_prev(ConsoleLine *cl)
-{
-       /* assume cursor is clamped */
-       if(cl->cursor <= 0)
-               return '\0';
-
-       return cl->line[cl->cursor-1];
+       cl->cursor = cursor_new;
+       return TRUE;
 }
 
 #if 0 // XXX unused 
-static char cursor_char_next(ConsoleLine *cl)
-{
-       /* assume cursor is clamped */
-       if(cl->cursor + 1 >= cl->len)
-               return '\0';
-
-       return cl->line[cl->cursor+1];
-}
-
 static void console_lb_debug__internal(ListBase *lb)
 {
        ConsoleLine *cl;
@@ -297,50 +276,53 @@ static int console_move_exec(bContext *C, wmOperator *op)
        
        int type= RNA_enum_get(op->ptr, "type");
        int done= 0;
+       short pos;
        
        switch(type) {
        case LINE_BEGIN:
-               done= console_line_cursor_set(ci, 0);
+                       pos = ci->cursor;
+                       BLI_str_cursor_step_utf8(ci->line, ci->len,
+                                                &pos, STRCUR_DIR_PREV,
+                                                STRCUR_JUMP_ALL);
+                       done = console_line_cursor_set(ci, pos);
                break;
        case LINE_END:
-               done= console_line_cursor_set(ci, INT_MAX);
+                       pos = ci->cursor;
+                       BLI_str_cursor_step_utf8(ci->line, ci->len,
+                                                &pos, STRCUR_DIR_NEXT,
+                                                STRCUR_JUMP_ALL);
+                       done = console_line_cursor_set(ci, pos);
                break;
        case PREV_CHAR:
-               done= console_line_cursor_set(ci, ci->cursor-1);
+                       pos = ci->cursor;
+                       BLI_str_cursor_step_utf8(ci->line, ci->len,
+                                                &pos, STRCUR_DIR_PREV,
+                                                STRCUR_JUMP_NONE);
+                       done = console_line_cursor_set(ci, pos);
                break;
        case NEXT_CHAR:
-               done= console_line_cursor_set(ci, ci->cursor+1);
+                       pos = ci->cursor;
+                       BLI_str_cursor_step_utf8(ci->line, ci->len,
+                                                &pos, STRCUR_DIR_NEXT,
+                                                STRCUR_JUMP_NONE);
+                       done = console_line_cursor_set(ci, pos);
                break;
 
        /* - if the character is a delimiter then skip delimiters (including white space)
         * - when jump over the word */
        case PREV_WORD:
-               while(text_check_delim(cursor_char_prev(ci)))
-                       if(console_line_cursor_set(ci, ci->cursor-1)==FALSE)
-                               break;
-
-               while(text_check_delim(cursor_char_prev(ci))==FALSE)
-                       if(console_line_cursor_set(ci, ci->cursor-1)==FALSE)
-                               break;
-
-               /* This isnt used for NEXT_WORD because when going back
-                * its more useful to have the cursor directly after a word then whitespace */
-               while(text_check_whitespace(cursor_char_prev(ci))==TRUE)
-                       if(console_line_cursor_set(ci, ci->cursor-1)==FALSE)
-                               break;
-
-               done= 1; /* assume changed */
+               pos = ci->cursor;
+               BLI_str_cursor_step_utf8(ci->line, ci->len,
+                                        &pos, STRCUR_DIR_PREV,
+                                        STRCUR_JUMP_DELIM);
+               done = console_line_cursor_set(ci, pos);
                break;
        case NEXT_WORD:
-               while(text_check_delim(cursor_char(ci))==TRUE)
-                       if (console_line_cursor_set(ci, ci->cursor+1)==FALSE)
-                               break;
-
-               while(text_check_delim(cursor_char(ci))==FALSE)
-                       if (console_line_cursor_set(ci, ci->cursor+1)==FALSE)
-                               break;
-
-               done= 1; /* assume changed */
+               pos = ci->cursor;
+               BLI_str_cursor_step_utf8(ci->line, ci->len,
+                                        &pos, STRCUR_DIR_NEXT,
+                                        STRCUR_JUMP_DELIM);
+               done = console_line_cursor_set(ci, pos);
                break;
        }