patch [#29859] UTF-8 support for text editor.
This also fixes cursor movement in the beginning of line and adds do_versions block for converting text files with old extended ascii encoding into UTF-8.
This commit is contained in:
@@ -46,6 +46,7 @@ void free_text (struct Text *text);
|
||||
void txt_set_undostate (int u);
|
||||
int txt_get_undostate (void);
|
||||
struct Text* add_empty_text (const char *name);
|
||||
int txt_extended_ascii_as_utf8(char **str);
|
||||
int reopen_text (struct Text *text);
|
||||
struct Text* add_text (const char *file, const char *relpath);
|
||||
struct Text* copy_text (struct Text *ta);
|
||||
@@ -59,6 +60,8 @@ void txt_order_cursors (struct Text *text);
|
||||
int txt_find_string (struct Text *text, const char *findstr, int wrap, int match_case);
|
||||
int txt_has_sel (struct Text *text);
|
||||
int txt_get_span (struct TextLine *from, struct TextLine *to);
|
||||
int txt_utf8_offset_to_index(char *str, int offset);
|
||||
int txt_utf8_index_to_offset(char *str, int index);
|
||||
void txt_move_up (struct Text *text, short sel);
|
||||
void txt_move_down (struct Text *text, short sel);
|
||||
void txt_move_left (struct Text *text, short sel);
|
||||
@@ -86,9 +89,9 @@ void txt_do_redo (struct Text *text);
|
||||
void txt_split_curline (struct Text *text);
|
||||
void txt_backspace_char (struct Text *text);
|
||||
void txt_backspace_word (struct Text *text);
|
||||
int txt_add_char (struct Text *text, char add);
|
||||
int txt_add_raw_char (struct Text *text, char add);
|
||||
int txt_replace_char (struct Text *text, char add);
|
||||
int txt_add_char (struct Text *text, unsigned int add);
|
||||
int txt_add_raw_char (struct Text *text, unsigned int add);
|
||||
int txt_replace_char (struct Text *text, unsigned int add);
|
||||
void txt_export_to_object(struct Text *text);
|
||||
void txt_export_to_objects(struct Text *text);
|
||||
void txt_unindent (struct Text *text);
|
||||
@@ -127,34 +130,48 @@ int text_check_whitespace(char ch);
|
||||
#define UNDO_SLEFT 005
|
||||
#define UNDO_SRIGHT 006
|
||||
#define UNDO_SUP 007
|
||||
#define UNDO_SDOWN 021
|
||||
#define UNDO_SDOWN 010
|
||||
|
||||
/* Complex movement (opcode is followed
|
||||
* by 4 character line ID + a 2 character
|
||||
* position ID and opcode (repeat)) */
|
||||
#define UNDO_CTO 022
|
||||
#define UNDO_STO 023
|
||||
#define UNDO_CTO 011
|
||||
#define UNDO_STO 012
|
||||
|
||||
/* Complex editing (opcode is followed
|
||||
* by 1 character ID and opcode (repeat)) */
|
||||
#define UNDO_INSERT 024
|
||||
#define UNDO_BS 025
|
||||
#define UNDO_DEL 026
|
||||
/* Complex editing */
|
||||
/* 1 - opcode is followed by 1 byte for ascii character and opcode (repeat)) */
|
||||
/* 2 - opcode is followed by 2 bytes for utf-8 character and opcode (repeat)) */
|
||||
/* 3 - opcode is followed by 3 bytes for utf-8 character and opcode (repeat)) */
|
||||
/* 4 - opcode is followed by 4 bytes for unicode character and opcode (repeat)) */
|
||||
#define UNDO_INSERT_1 013
|
||||
#define UNDO_INSERT_2 014
|
||||
#define UNDO_INSERT_3 015
|
||||
#define UNDO_INSERT_4 016
|
||||
|
||||
#define UNDO_BS_1 017
|
||||
#define UNDO_BS_2 020
|
||||
#define UNDO_BS_3 021
|
||||
#define UNDO_BS_4 022
|
||||
|
||||
#define UNDO_DEL_1 023
|
||||
#define UNDO_DEL_2 024
|
||||
#define UNDO_DEL_3 025
|
||||
#define UNDO_DEL_4 026
|
||||
|
||||
/* Text block (opcode is followed
|
||||
* by 4 character length ID + the text
|
||||
* block itself + the 4 character length
|
||||
* ID (repeat) and opcode (repeat)) */
|
||||
#define UNDO_DBLOCK 027 /* Delete block */
|
||||
#define UNDO_IBLOCK 030 /* Insert block */
|
||||
#define UNDO_DBLOCK 027 /* Delete block */
|
||||
#define UNDO_IBLOCK 030 /* Insert block */
|
||||
|
||||
/* Misc */
|
||||
#define UNDO_SWAP 031 /* Swap cursors */
|
||||
#define UNDO_SWAP 031 /* Swap cursors */
|
||||
|
||||
#define UNDO_INDENT 032
|
||||
#define UNDO_UNINDENT 033
|
||||
#define UNDO_COMMENT 034
|
||||
#define UNDO_UNCOMMENT 035
|
||||
#define UNDO_INDENT 032
|
||||
#define UNDO_UNINDENT 033
|
||||
#define UNDO_COMMENT 034
|
||||
#define UNDO_UNCOMMENT 035
|
||||
|
||||
/* Marker flags */
|
||||
#define TMARK_TEMP 0x01 /* Remove on non-editing events, don't save */
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <string.h> /* strstr */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -215,8 +217,48 @@ Text *add_empty_text(const char *name)
|
||||
return ta;
|
||||
}
|
||||
|
||||
/* this function replaces extended ascii characters */
|
||||
/* to a valid utf-8 sequences */
|
||||
int txt_extended_ascii_as_utf8(char **str)
|
||||
{
|
||||
int bad_char, added= 0, i= 0;
|
||||
int length = strlen(*str);
|
||||
|
||||
while ((*str)[i]) {
|
||||
if((bad_char= BLI_utf8_invalid_byte(*str+i, length)) == -1)
|
||||
break;
|
||||
|
||||
added++;
|
||||
i+= bad_char + 1;
|
||||
}
|
||||
|
||||
if (added != 0) {
|
||||
char *newstr = MEM_mallocN(length+added+1, "text_line");
|
||||
int mi = 0;
|
||||
i= 0;
|
||||
|
||||
while ((*str)[i]) {
|
||||
if((bad_char= BLI_utf8_invalid_byte((*str)+i, length)) == -1) {
|
||||
memcpy(newstr+mi, (*str)+i, length - i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(newstr+mi, (*str)+i, bad_char);
|
||||
|
||||
BLI_str_utf8_from_unicode((*str)[i+bad_char], newstr+mi+bad_char);
|
||||
i+= bad_char+1;
|
||||
mi+= bad_char+2;
|
||||
}
|
||||
newstr[length+added] = '\0';
|
||||
MEM_freeN(*str);
|
||||
*str = newstr;
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
// this function removes any control characters from
|
||||
// a textline
|
||||
// a textline and fixes invalid utf-8 sequences
|
||||
|
||||
static void cleanup_textline(TextLine * tl)
|
||||
{
|
||||
@@ -229,6 +271,7 @@ static void cleanup_textline(TextLine * tl)
|
||||
i--;
|
||||
}
|
||||
}
|
||||
tl->len+= txt_extended_ascii_as_utf8(&tl->line);
|
||||
}
|
||||
|
||||
int reopen_text(Text *text)
|
||||
@@ -689,16 +732,10 @@ static void txt_make_dirty (Text *text)
|
||||
}
|
||||
|
||||
/* 0:whitespace, 1:punct, 2:alphanumeric */
|
||||
static short txt_char_type (char ch)
|
||||
static short txt_char_type(unsigned int ch)
|
||||
{
|
||||
if (ch <= ' ') return 0; /* 32 */
|
||||
if (ch <= '/') return 1; /* 47 */
|
||||
if (ch <= '9') return 2; /* 57 */
|
||||
if (ch <= '@') return 1; /* 64 */
|
||||
if (ch <= 'Z') return 2; /* 90 */
|
||||
if (ch == '_') return 2; /* 95, dont delimit '_' */
|
||||
if (ch <= '`') return 1; /* 96 */
|
||||
if (ch <= 'z') return 2; /* 122 */
|
||||
if (iswspace(ch)) return 0;
|
||||
if (iswalpha(ch) || iswdigit(ch)) return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -731,9 +768,42 @@ static void txt_curs_first (Text *text, TextLine **linep, int *charp)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/*****************************/
|
||||
/* Cursor movement functions */
|
||||
/****************************/
|
||||
/*****************************/
|
||||
|
||||
int txt_utf8_offset_to_index(char *str, int offset)
|
||||
{
|
||||
int index= 0, pos= 0;
|
||||
while (pos != offset) {
|
||||
pos += BLI_str_utf8_size(str + pos);
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
int txt_utf8_index_to_offset(char *str, int index)
|
||||
{
|
||||
int offset= 0, pos= 0;
|
||||
while (pos != index) {
|
||||
offset += BLI_str_utf8_size(str + offset);
|
||||
pos++;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* returns the real number of characters in string */
|
||||
/* not the same as BLI_strlen_utf8, which returns length for wide characters */
|
||||
static int txt_utf8_len(const char *src)
|
||||
{
|
||||
int len;
|
||||
|
||||
for (len=0; *src; len++) {
|
||||
src += BLI_str_utf8_size(src);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void txt_move_up(Text *text, short sel)
|
||||
{
|
||||
@@ -747,13 +817,13 @@ void txt_move_up(Text *text, short sel)
|
||||
old= *charp;
|
||||
|
||||
if((*linep)->prev) {
|
||||
int index = txt_utf8_offset_to_index((*linep)->line, *charp);
|
||||
*linep= (*linep)->prev;
|
||||
if (*charp > (*linep)->len) {
|
||||
*charp= (*linep)->len;
|
||||
if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, (*linep)->next), old, txt_get_span(text->lines.first, *linep), (unsigned short) *charp);
|
||||
} else {
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP);
|
||||
}
|
||||
if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len;
|
||||
else *charp= txt_utf8_index_to_offset((*linep)->line, index);
|
||||
|
||||
if(!undoing)
|
||||
txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP);
|
||||
} else {
|
||||
txt_move_bol(text, sel);
|
||||
}
|
||||
@@ -773,12 +843,13 @@ void txt_move_down(Text *text, short sel)
|
||||
old= *charp;
|
||||
|
||||
if((*linep)->next) {
|
||||
int index = txt_utf8_offset_to_index((*linep)->line, *charp);
|
||||
*linep= (*linep)->next;
|
||||
if (*charp > (*linep)->len) {
|
||||
*charp= (*linep)->len;
|
||||
if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, (*linep)->prev), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
|
||||
} else
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN);
|
||||
if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len;
|
||||
else *charp= txt_utf8_index_to_offset((*linep)->line, index);
|
||||
|
||||
if(!undoing)
|
||||
txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN);
|
||||
} else {
|
||||
txt_move_eol(text, sel);
|
||||
}
|
||||
@@ -790,7 +861,7 @@ void txt_move_left(Text *text, short sel)
|
||||
{
|
||||
TextLine **linep;
|
||||
int *charp, oundoing= undoing;
|
||||
int tabsize = 1, i=0;
|
||||
int tabsize= 0, i= 0;
|
||||
|
||||
if (!text) return;
|
||||
if(sel) txt_curs_sel(text, &linep, &charp);
|
||||
@@ -799,32 +870,36 @@ void txt_move_left(Text *text, short sel)
|
||||
|
||||
undoing= 1;
|
||||
|
||||
// do nice left only if there are only spaces
|
||||
// TXT_TABSIZE hardcoded in DNA_text_types.h
|
||||
if (text->flags & TXT_TABSTOSPACES) {
|
||||
tabsize = TXT_TABSIZE;
|
||||
|
||||
if (*charp < tabsize)
|
||||
tabsize = *charp;
|
||||
else {
|
||||
for (i=0;i<(*charp);i++)
|
||||
if ((*linep)->line[i] != ' ') {
|
||||
tabsize = 1;
|
||||
break;
|
||||
}
|
||||
// if in the middle of the space-tab
|
||||
if ((*charp) % tabsize != 0)
|
||||
tabsize = ((*charp) % tabsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (*charp== 0) {
|
||||
if ((*linep)->prev) {
|
||||
txt_move_up(text, sel);
|
||||
*charp= (*linep)->len;
|
||||
}
|
||||
}
|
||||
else (*charp)-= tabsize;
|
||||
else {
|
||||
// do nice left only if there are only spaces
|
||||
// TXT_TABSIZE hardcoded in DNA_text_types.h
|
||||
if (text->flags & TXT_TABSTOSPACES) {
|
||||
tabsize= (*charp < TXT_TABSIZE) ? *charp : TXT_TABSIZE;
|
||||
|
||||
for (i=0; i<(*charp); i++)
|
||||
if ((*linep)->line[i] != ' ') {
|
||||
tabsize= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// if in the middle of the space-tab
|
||||
if (tabsize && (*charp) % TXT_TABSIZE != 0)
|
||||
tabsize= ((*charp) % TXT_TABSIZE);
|
||||
}
|
||||
|
||||
if (tabsize)
|
||||
(*charp)-= tabsize;
|
||||
else {
|
||||
const char *prev= BLI_str_prev_char_utf8((*linep)->line + *charp);
|
||||
*charp= prev - (*linep)->line;
|
||||
}
|
||||
}
|
||||
|
||||
undoing= oundoing;
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SLEFT:UNDO_CLEFT);
|
||||
@@ -835,8 +910,7 @@ void txt_move_left(Text *text, short sel)
|
||||
void txt_move_right(Text *text, short sel)
|
||||
{
|
||||
TextLine **linep;
|
||||
int *charp, oundoing= undoing;
|
||||
int tabsize=1, i=0;
|
||||
int *charp, oundoing= undoing, do_tab= 0, i;
|
||||
|
||||
if (!text) return;
|
||||
if(sel) txt_curs_sel(text, &linep, &charp);
|
||||
@@ -845,32 +919,33 @@ void txt_move_right(Text *text, short sel)
|
||||
|
||||
undoing= 1;
|
||||
|
||||
// do nice right only if there are only spaces
|
||||
// spaces hardcoded in DNA_text_types.h
|
||||
if (text->flags & TXT_TABSTOSPACES) {
|
||||
tabsize = TXT_TABSIZE;
|
||||
|
||||
if ((*charp) + tabsize > (*linep)->len)
|
||||
tabsize = 1;
|
||||
else {
|
||||
for (i=0;i<(*charp) + tabsize - ((*charp) % tabsize);i++)
|
||||
if ((*linep)->line[i] != ' ') {
|
||||
tabsize = 1;
|
||||
break;
|
||||
}
|
||||
// if in the middle of the space-tab
|
||||
tabsize -= (*charp) % tabsize;
|
||||
}
|
||||
}
|
||||
|
||||
if (*charp== (*linep)->len) {
|
||||
if ((*linep)->next) {
|
||||
txt_move_down(text, sel);
|
||||
*charp= 0;
|
||||
}
|
||||
} else {
|
||||
(*charp)+=tabsize;
|
||||
}
|
||||
else {
|
||||
// do nice right only if there are only spaces
|
||||
// spaces hardcoded in DNA_text_types.h
|
||||
if (text->flags & TXT_TABSTOSPACES && (*linep)->line[*charp]== ' ') {
|
||||
do_tab= 1;
|
||||
for (i=0; i<*charp; i++)
|
||||
if ((*linep)->line[i]!= ' ') {
|
||||
do_tab= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_tab) {
|
||||
int tabsize= (*charp) % TXT_TABSIZE + 1;
|
||||
for (i=*charp+1; (*linep)->line[i]==' ' && tabsize<TXT_TABSIZE; i++)
|
||||
tabsize++;
|
||||
(*charp)= i;
|
||||
}
|
||||
else (*charp)+= BLI_str_utf8_size((*linep)->line + *charp);
|
||||
}
|
||||
|
||||
undoing= oundoing;
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SRIGHT:UNDO_CRIGHT);
|
||||
|
||||
@@ -896,9 +971,12 @@ void txt_jump_left(Text *text, short sel)
|
||||
count= 0;
|
||||
for (i=0; i<3; i++) {
|
||||
if (count < 2) {
|
||||
while (*charp>0 && txt_char_type((*linep)->line[*charp-1])==i) {
|
||||
txt_move_left(text, sel);
|
||||
count++;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -927,9 +1005,12 @@ void txt_jump_right(Text *text, short sel)
|
||||
count= 0;
|
||||
for (i=0; i<3; i++) {
|
||||
if (count < 2) {
|
||||
while (*charp<(*linep)->len && txt_char_type((*linep)->line[*charp])==i) {
|
||||
txt_move_right(text, sel);
|
||||
count++;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1014,6 +1095,7 @@ void txt_move_toline (Text *text, unsigned int line, short sel)
|
||||
txt_move_to(text, line, 0, sel);
|
||||
}
|
||||
|
||||
/* Moves to a certain byte in a line, not a certain utf8-character! */
|
||||
void txt_move_to (Text *text, unsigned int line, unsigned int ch, short sel)
|
||||
{
|
||||
TextLine **linep, *oldl;
|
||||
@@ -1396,42 +1478,45 @@ static void txt_shift_markers(Text *text, int lineno, int count)
|
||||
|
||||
void txt_insert_buf(Text *text, const char *in_buffer)
|
||||
{
|
||||
int i=0, l=0, j, u, len, lineno= -1, count= 0;
|
||||
int l=0, u, len, lineno= -1, count= 0;
|
||||
size_t i=0, j;
|
||||
TextLine *add;
|
||||
char *buffer;
|
||||
|
||||
if (!text) return;
|
||||
if (!in_buffer) return;
|
||||
|
||||
txt_delete_sel(text);
|
||||
|
||||
if(!undoing) txt_undo_add_block (text, UNDO_IBLOCK, in_buffer);
|
||||
len= strlen(in_buffer);
|
||||
buffer= BLI_strdupn(in_buffer, len);
|
||||
len+= txt_extended_ascii_as_utf8(&buffer);
|
||||
|
||||
if(!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer);
|
||||
|
||||
u= undoing;
|
||||
undoing= 1;
|
||||
|
||||
/* Read the first line (or as close as possible */
|
||||
while (in_buffer[i] && in_buffer[i]!='\n') {
|
||||
txt_add_raw_char(text, in_buffer[i]);
|
||||
i++;
|
||||
}
|
||||
while (buffer[i] && buffer[i]!='\n')
|
||||
txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &i));
|
||||
|
||||
if (in_buffer[i]=='\n') txt_split_curline(text);
|
||||
else { undoing = u; return; }
|
||||
if (buffer[i]=='\n') txt_split_curline(text);
|
||||
else { undoing = u; MEM_freeN(buffer); return; }
|
||||
i++;
|
||||
|
||||
/* Read as many full lines as we can */
|
||||
len= strlen(in_buffer);
|
||||
lineno= txt_get_span(text->lines.first, text->curl);
|
||||
|
||||
while (i<len) {
|
||||
l=0;
|
||||
|
||||
while (in_buffer[i] && in_buffer[i]!='\n') {
|
||||
while (buffer[i] && buffer[i]!='\n') {
|
||||
i++; l++;
|
||||
}
|
||||
|
||||
if(in_buffer[i]=='\n') {
|
||||
add= txt_new_linen(in_buffer +(i-l), l);
|
||||
if(buffer[i]=='\n') {
|
||||
add= txt_new_linen(buffer +(i-l), l);
|
||||
BLI_insertlinkbefore(&text->lines, text->curl, add);
|
||||
i++;
|
||||
count++;
|
||||
@@ -1441,21 +1526,19 @@ void txt_insert_buf(Text *text, const char *in_buffer)
|
||||
count= 0;
|
||||
}
|
||||
|
||||
for (j= i-l; j<i && j<(int)strlen(in_buffer); j++) {
|
||||
txt_add_raw_char(text, in_buffer[j]);
|
||||
}
|
||||
for (j= i-l; j<i && j<len; )
|
||||
txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &j));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(buffer);
|
||||
|
||||
if(count) {
|
||||
txt_shift_markers(text, lineno, count);
|
||||
count= 0;
|
||||
}
|
||||
|
||||
undoing= u;
|
||||
|
||||
(void)count;
|
||||
}
|
||||
|
||||
/******************/
|
||||
@@ -1525,12 +1608,30 @@ void txt_print_undo(Text *text)
|
||||
ops= "Selection ";
|
||||
} else if (op==UNDO_CTO) {
|
||||
ops= "Cursor ";
|
||||
} else if (op==UNDO_INSERT) {
|
||||
ops= "Insert";
|
||||
} else if (op==UNDO_BS) {
|
||||
ops= "Backspace";
|
||||
} else if (op==UNDO_DEL) {
|
||||
ops= "Delete";
|
||||
} else if (op==UNDO_INSERT_1) {
|
||||
ops= "Insert ascii ";
|
||||
} else if (op==UNDO_INSERT_2) {
|
||||
ops= "Insert 2 bytes ";
|
||||
} else if (op==UNDO_INSERT_3) {
|
||||
ops= "Insert 3 bytes ";
|
||||
} else if (op==UNDO_INSERT_4) {
|
||||
ops= "Insert unicode ";
|
||||
} else if (op==UNDO_BS_1) {
|
||||
ops= "Backspace for ascii ";
|
||||
} else if (op==UNDO_BS_2) {
|
||||
ops= "Backspace for 2 bytes ";
|
||||
} else if (op==UNDO_BS_3) {
|
||||
ops= "Backspace for 3 bytes ";
|
||||
} else if (op==UNDO_BS_4) {
|
||||
ops= "Backspace for unicode ";
|
||||
} else if (op==UNDO_DEL_1) {
|
||||
ops= "Delete ascii ";
|
||||
} else if (op==UNDO_DEL_2) {
|
||||
ops= "Delete 2 bytes ";
|
||||
} else if (op==UNDO_DEL_3) {
|
||||
ops= "Delete 3 bytes ";
|
||||
} else if (op==UNDO_DEL_4) {
|
||||
ops= "Delete unicode ";
|
||||
} else if (op==UNDO_SWAP) {
|
||||
ops= "Cursor swap";
|
||||
} else if (op==UNDO_DBLOCK) {
|
||||
@@ -1550,10 +1651,35 @@ void txt_print_undo(Text *text)
|
||||
}
|
||||
|
||||
printf ("Op (%o) at %d = %s", op, i, ops);
|
||||
if (op==UNDO_INSERT || op==UNDO_BS || op==UNDO_DEL) {
|
||||
i++;
|
||||
printf (" - Char is %c", text->undo_buf[i]);
|
||||
if (op >= UNDO_INSERT_1 && op <= UNDO_DEL_4) {
|
||||
i++;
|
||||
printf (" - Char is ");
|
||||
switch (op) {
|
||||
case UNDO_INSERT_1: case UNDO_BS_1: case UNDO_DEL_1:
|
||||
printf ("%c", text->undo_buf[i]);
|
||||
i++;
|
||||
break;
|
||||
case UNDO_INSERT_2: case UNDO_BS_2: case UNDO_DEL_2:
|
||||
printf ("%c%c", text->undo_buf[i], text->undo_buf[i+1]);
|
||||
i+=2;
|
||||
break;
|
||||
case UNDO_INSERT_3: case UNDO_BS_3: case UNDO_DEL_3:
|
||||
printf ("%c%c%c", text->undo_buf[i], text->undo_buf[i+1], text->undo_buf[i+2]);
|
||||
i+=3;
|
||||
break;
|
||||
case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4: {
|
||||
unsigned int uc;
|
||||
char c[BLI_UTF8_MAX+1];
|
||||
size_t c_len;
|
||||
uc= text->undo_buf[i]; i++;
|
||||
uc= uc+(text->undo_buf[i]<<8); i++;
|
||||
uc= uc+(text->undo_buf[i]<<16); i++;
|
||||
uc= uc+(text->undo_buf[i]<<24); i++;
|
||||
c_len= BLI_str_utf8_from_unicode(uc, c);
|
||||
c[c_len]= '\0';
|
||||
printf ("%s", c);
|
||||
}
|
||||
}
|
||||
} else if (op==UNDO_STO || op==UNDO_CTO) {
|
||||
i++;
|
||||
|
||||
@@ -1635,40 +1761,43 @@ static void txt_undo_add_op(Text *text, int op)
|
||||
text->undo_buf[text->undo_pos+1]= 0;
|
||||
}
|
||||
|
||||
static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value)
|
||||
{
|
||||
undo_buf[*undo_pos]= (value)&0xff;
|
||||
(*undo_pos)++;
|
||||
undo_buf[*undo_pos]= (value>>8)&0xff;
|
||||
(*undo_pos)++;
|
||||
}
|
||||
|
||||
static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int value)
|
||||
{
|
||||
undo_buf[*undo_pos]= (value)&0xff;
|
||||
(*undo_pos)++;
|
||||
undo_buf[*undo_pos]= (value>>8)&0xff;
|
||||
(*undo_pos)++;
|
||||
undo_buf[*undo_pos]= (value>>16)&0xff;
|
||||
(*undo_pos)++;
|
||||
undo_buf[*undo_pos]= (value>>24)&0xff;
|
||||
(*undo_pos)++;
|
||||
}
|
||||
|
||||
static void txt_undo_add_block(Text *text, int op, const char *buf)
|
||||
{
|
||||
int length;
|
||||
|
||||
length= strlen(buf);
|
||||
unsigned int length= strlen(buf);
|
||||
|
||||
if(!max_undo_test(text, length+11))
|
||||
return;
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= op;
|
||||
text->undo_pos++;
|
||||
|
||||
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length);
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length>>8)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length>>16)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length>>24)&0xff;
|
||||
|
||||
text->undo_pos++;
|
||||
strncpy(text->undo_buf+text->undo_pos, buf, length);
|
||||
text->undo_pos+=length;
|
||||
|
||||
text->undo_buf[text->undo_pos]= (length)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length>>8)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length>>16)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (length>>24)&0xff;
|
||||
|
||||
text->undo_pos++;
|
||||
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length);
|
||||
text->undo_buf[text->undo_pos]= op;
|
||||
|
||||
text->undo_buf[text->undo_pos+1]= 0;
|
||||
@@ -1685,53 +1814,141 @@ void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fr
|
||||
text->undo_buf[text->undo_pos]= op;
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (fromc)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (fromc>>8)&0xff;
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (froml)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (froml>>8)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (froml>>16)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (froml>>24)&0xff;
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (toc)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (toc>>8)&0xff;
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (tol)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (tol>>8)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (tol>>16)&0xff;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= (tol>>24)&0xff;
|
||||
|
||||
text->undo_pos++;
|
||||
|
||||
txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc);
|
||||
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml);
|
||||
txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc);
|
||||
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol);
|
||||
|
||||
text->undo_buf[text->undo_pos]= op;
|
||||
|
||||
text->undo_buf[text->undo_pos+1]= 0;
|
||||
}
|
||||
|
||||
static void txt_undo_add_charop(Text *text, int op, char c)
|
||||
static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
|
||||
{
|
||||
if(!max_undo_test(text, 4))
|
||||
char utf8[BLI_UTF8_MAX];
|
||||
size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8);
|
||||
|
||||
if(!max_undo_test(text, 3 + utf8_size))
|
||||
return;
|
||||
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= op;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= c;
|
||||
text->undo_pos++;
|
||||
text->undo_buf[text->undo_pos]= op;
|
||||
|
||||
if (utf8_size < 4) {
|
||||
text->undo_buf[text->undo_pos]= op_start + utf8_size - 1;
|
||||
text->undo_pos++;
|
||||
|
||||
for (i = 0; i < utf8_size; i++) {
|
||||
text->undo_buf[text->undo_pos]= utf8[i];
|
||||
text->undo_pos++;
|
||||
}
|
||||
|
||||
text->undo_buf[text->undo_pos]= op_start + utf8_size - 1;
|
||||
} else {
|
||||
text->undo_buf[text->undo_pos]= op_start + 3;
|
||||
text->undo_pos++;
|
||||
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c);
|
||||
text->undo_buf[text->undo_pos]= op_start + 3;
|
||||
}
|
||||
|
||||
text->undo_buf[text->undo_pos+1]= 0;
|
||||
}
|
||||
|
||||
static unsigned short txt_undo_read_uint16(const char *undo_buf, int *undo_pos)
|
||||
{
|
||||
unsigned short val;
|
||||
val= undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
return val;
|
||||
}
|
||||
|
||||
static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos)
|
||||
{
|
||||
unsigned int val;
|
||||
val= undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
return val;
|
||||
}
|
||||
|
||||
static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
|
||||
{
|
||||
unsigned int unicode;
|
||||
char utf8[BLI_UTF8_MAX+1];
|
||||
|
||||
switch (bytes) {
|
||||
case 1: /* ascii */
|
||||
unicode = undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
break;
|
||||
case 2: /* 2-byte symbol */
|
||||
utf8[2] = '\0';
|
||||
utf8[1] = undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
utf8[0] = undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
unicode= BLI_str_utf8_as_unicode(utf8);
|
||||
break;
|
||||
case 3: /* 3-byte symbol */
|
||||
utf8[3] = '\0';
|
||||
utf8[2] = undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
utf8[1] = undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
utf8[0] = undo_buf[*undo_pos]; (*undo_pos)--;
|
||||
unicode= BLI_str_utf8_as_unicode(utf8);
|
||||
break;
|
||||
case 4: /* 32-bit unicode symbol */
|
||||
unicode= txt_undo_read_uint32(undo_buf, undo_pos);
|
||||
}
|
||||
|
||||
return unicode;
|
||||
}
|
||||
|
||||
static unsigned short txt_redo_read_uint16(const char *undo_buf, int *undo_pos)
|
||||
{
|
||||
unsigned short val;
|
||||
val = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
val = val+(undo_buf[*undo_pos]<<8); (*undo_pos)++;
|
||||
return val;
|
||||
}
|
||||
|
||||
static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos)
|
||||
{
|
||||
unsigned int val;
|
||||
val= undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
val= val+(undo_buf[*undo_pos]<<8); (*undo_pos)++;
|
||||
val= val+(undo_buf[*undo_pos]<<16); (*undo_pos)++;
|
||||
val= val+(undo_buf[*undo_pos]<<24); (*undo_pos)++;
|
||||
return val;
|
||||
}
|
||||
|
||||
static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
|
||||
{
|
||||
unsigned int unicode;
|
||||
char utf8[BLI_UTF8_MAX+1];
|
||||
|
||||
switch (bytes) {
|
||||
case 1: /* ascii */
|
||||
unicode = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
break;
|
||||
case 2: /* 2-byte symbol */
|
||||
utf8[0] = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
utf8[1] = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
utf8[2] = '\0';
|
||||
unicode= BLI_str_utf8_as_unicode(utf8);
|
||||
break;
|
||||
case 3: /* 3-byte symbol */
|
||||
utf8[0] = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
utf8[1] = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
utf8[2] = undo_buf[*undo_pos]; (*undo_pos)++;
|
||||
utf8[3] = '\0';
|
||||
unicode= BLI_str_utf8_as_unicode(utf8);
|
||||
break;
|
||||
case 4: /* 32-bit unicode symbol */
|
||||
unicode= txt_undo_read_uint32(undo_buf, undo_pos);
|
||||
}
|
||||
|
||||
return unicode;
|
||||
}
|
||||
|
||||
void txt_do_undo(Text *text)
|
||||
{
|
||||
int op= text->undo_buf[text->undo_pos];
|
||||
@@ -1792,13 +2009,8 @@ void txt_do_undo(Text *text)
|
||||
text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
|
||||
charp= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
charp= (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
charp= txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
|
||||
|
||||
if (op==UNDO_CTO) {
|
||||
txt_move_toline(text, linep, 0);
|
||||
@@ -1812,23 +2024,23 @@ void txt_do_undo(Text *text)
|
||||
text->undo_pos--;
|
||||
break;
|
||||
|
||||
case UNDO_INSERT:
|
||||
case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
|
||||
txt_backspace_char(text);
|
||||
text->undo_pos--;
|
||||
text->undo_pos-= op - UNDO_INSERT_1 + 1;
|
||||
text->undo_pos--;
|
||||
break;
|
||||
|
||||
case UNDO_BS:
|
||||
txt_add_char(text, text->undo_buf[text->undo_pos]);
|
||||
case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
|
||||
charp = op - UNDO_BS_1 + 1;
|
||||
txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
|
||||
text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
break;
|
||||
|
||||
case UNDO_DEL:
|
||||
txt_add_char(text, text->undo_buf[text->undo_pos]);
|
||||
break;
|
||||
|
||||
case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
|
||||
charp = op - UNDO_DEL_1 + 1;
|
||||
txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
|
||||
txt_move_left(text, 0);
|
||||
text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
break;
|
||||
|
||||
case UNDO_SWAP:
|
||||
@@ -1836,10 +2048,7 @@ void txt_do_undo(Text *text)
|
||||
break;
|
||||
|
||||
case UNDO_DBLOCK:
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
|
||||
buf= MEM_mallocN(linep+1, "dblock buffer");
|
||||
for (i=0; i < linep; i++){
|
||||
@@ -1863,25 +2072,31 @@ void txt_do_undo(Text *text)
|
||||
}
|
||||
text->curc= holdc;
|
||||
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
text->undo_pos--;
|
||||
|
||||
text->undo_pos--;
|
||||
|
||||
break;
|
||||
|
||||
case UNDO_IBLOCK:
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
|
||||
linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
txt_delete_sel(text);
|
||||
|
||||
/* txt_backspace_char removes utf8-characters, not bytes */
|
||||
buf= MEM_mallocN(linep+1, "iblock buffer");
|
||||
for (i=0; i < linep; i++){
|
||||
buf[(linep-1)-i]= text->undo_buf[text->undo_pos];
|
||||
text->undo_pos--;
|
||||
}
|
||||
buf[i]= 0;
|
||||
linep= txt_utf8_len(buf);
|
||||
MEM_freeN(buf);
|
||||
|
||||
while (linep>0) {
|
||||
txt_backspace_char(text);
|
||||
text->undo_pos--;
|
||||
linep--;
|
||||
}
|
||||
|
||||
@@ -1897,30 +2112,23 @@ void txt_do_undo(Text *text)
|
||||
case UNDO_UNINDENT:
|
||||
case UNDO_COMMENT:
|
||||
case UNDO_UNCOMMENT:
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
//linep is now the end line of the selection
|
||||
|
||||
charp = text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
|
||||
//charp is the last char selected or text->line->len
|
||||
//set the selcetion for this now
|
||||
|
||||
//set the selection for this now
|
||||
text->selc = charp;
|
||||
text->sell = text->lines.first;
|
||||
for (i= 0; i < linep; i++) {
|
||||
text->sell = text->sell->next;
|
||||
}
|
||||
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
//first line to be selected
|
||||
|
||||
charp = text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
|
||||
charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
|
||||
//first postion to be selected
|
||||
text->curc = charp;
|
||||
text->curl = text->lines.first;
|
||||
@@ -2014,22 +2222,22 @@ void txt_do_redo(Text *text)
|
||||
txt_move_down(text, 1);
|
||||
break;
|
||||
|
||||
case UNDO_INSERT:
|
||||
text->undo_pos++;
|
||||
txt_add_char(text, text->undo_buf[text->undo_pos]);
|
||||
case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
|
||||
text->undo_pos++;
|
||||
charp = op - UNDO_INSERT_1 + 1;
|
||||
txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp));
|
||||
break;
|
||||
|
||||
case UNDO_BS:
|
||||
case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
|
||||
text->undo_pos++;
|
||||
txt_backspace_char(text);
|
||||
text->undo_pos++;
|
||||
text->undo_pos+= op - UNDO_BS_1 + 1;
|
||||
break;
|
||||
|
||||
case UNDO_DEL:
|
||||
case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
|
||||
text->undo_pos++;
|
||||
txt_delete_char(text);
|
||||
text->undo_pos++;
|
||||
text->undo_pos+= op - UNDO_DEL_1 + 1;
|
||||
break;
|
||||
|
||||
case UNDO_SWAP:
|
||||
@@ -2049,15 +2257,8 @@ void txt_do_redo(Text *text)
|
||||
|
||||
text->undo_pos++;
|
||||
|
||||
charp= text->undo_buf[text->undo_pos];
|
||||
text->undo_pos++;
|
||||
charp= charp+(text->undo_buf[text->undo_pos]<<8);
|
||||
|
||||
text->undo_pos++;
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
|
||||
charp= txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
|
||||
linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
|
||||
if (op==UNDO_CTO) {
|
||||
txt_move_toline(text, linep, 0);
|
||||
@@ -2072,12 +2273,9 @@ void txt_do_redo(Text *text)
|
||||
|
||||
case UNDO_DBLOCK:
|
||||
text->undo_pos++;
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
|
||||
|
||||
linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
txt_delete_sel(text);
|
||||
|
||||
text->undo_pos+=linep;
|
||||
|
||||
text->undo_pos++;
|
||||
@@ -2089,10 +2287,7 @@ void txt_do_redo(Text *text)
|
||||
|
||||
case UNDO_IBLOCK:
|
||||
text->undo_pos++;
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
|
||||
linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
|
||||
buf= MEM_mallocN(linep+1, "iblock buffer");
|
||||
memcpy (buf, &text->undo_buf[text->undo_pos], linep);
|
||||
@@ -2102,26 +2297,21 @@ void txt_do_redo(Text *text)
|
||||
txt_insert_buf(text, buf);
|
||||
MEM_freeN(buf);
|
||||
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
|
||||
linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
|
||||
(void)linep;
|
||||
|
||||
text->undo_pos++;
|
||||
text->undo_pos++;
|
||||
text->undo_pos++;
|
||||
text->undo_pos++;
|
||||
break;
|
||||
|
||||
case UNDO_INDENT:
|
||||
case UNDO_UNINDENT:
|
||||
case UNDO_COMMENT:
|
||||
case UNDO_UNCOMMENT:
|
||||
text->undo_pos++;
|
||||
charp = text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
|
||||
//charp is the first char selected or 0
|
||||
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
|
||||
linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
|
||||
linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
//linep is now the first line of the selection
|
||||
//set the selcetion for this now
|
||||
text->curc = charp;
|
||||
@@ -2130,13 +2320,10 @@ void txt_do_redo(Text *text)
|
||||
text->curl = text->curl->next;
|
||||
}
|
||||
|
||||
charp = text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
|
||||
//last postion to be selected
|
||||
linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
|
||||
linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
|
||||
linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
|
||||
linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
|
||||
|
||||
linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
|
||||
//Last line to be selected
|
||||
|
||||
text->selc = charp;
|
||||
@@ -2203,8 +2390,7 @@ void txt_split_curline (Text *text)
|
||||
left[text->curc]=0;
|
||||
|
||||
right= MEM_mallocN(text->curl->len - text->curc+1, "textline_string");
|
||||
if (text->curl->len - text->curc) memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc);
|
||||
right[text->curl->len - text->curc]=0;
|
||||
memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc+1);
|
||||
|
||||
MEM_freeN(text->curl->line);
|
||||
if (text->curl->format) MEM_freeN(text->curl->format);
|
||||
@@ -2228,7 +2414,7 @@ void txt_split_curline (Text *text)
|
||||
txt_clean_text(text);
|
||||
|
||||
txt_pop_sel(text);
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_INSERT, '\n');
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n');
|
||||
}
|
||||
|
||||
static void txt_delete_line (Text *text, TextLine *line)
|
||||
@@ -2296,9 +2482,9 @@ static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
|
||||
txt_clean_text(text);
|
||||
}
|
||||
|
||||
void txt_delete_char (Text *text)
|
||||
void txt_delete_char(Text *text)
|
||||
{
|
||||
char c='\n';
|
||||
unsigned int c='\n';
|
||||
|
||||
if (!text) return;
|
||||
if (!text->curl) return;
|
||||
@@ -2314,12 +2500,14 @@ void txt_delete_char (Text *text)
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
} else { /* Just deleting a char */
|
||||
int i= text->curc;
|
||||
size_t c_len = 0;
|
||||
TextMarker *mrk;
|
||||
c= BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &c_len);
|
||||
|
||||
TextMarker *mrk= txt_find_marker_region(text, text->curl, i-1, text->curl->len, 0, 0);
|
||||
mrk= txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
|
||||
if (mrk) {
|
||||
int lineno= mrk->lineno;
|
||||
if (mrk->end==i) {
|
||||
if (mrk->end==text->curc) {
|
||||
if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
|
||||
txt_clear_markers(text, mrk->group, TMARK_TEMP);
|
||||
} else {
|
||||
@@ -2328,18 +2516,15 @@ void txt_delete_char (Text *text)
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (mrk->start>i) mrk->start--;
|
||||
mrk->end--;
|
||||
if (mrk->start>text->curc) mrk->start-= c_len;
|
||||
mrk->end-= c_len;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
c= text->curl->line[i];
|
||||
while(i< text->curl->len) {
|
||||
text->curl->line[i]= text->curl->line[i+1];
|
||||
i++;
|
||||
}
|
||||
text->curl->len--;
|
||||
memmove(text->curl->line+text->curc, text->curl->line+text->curc+c_len, text->curl->len-text->curc-c_len+1);
|
||||
|
||||
text->curl->len-= c_len;
|
||||
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
@@ -2347,7 +2532,7 @@ void txt_delete_char (Text *text)
|
||||
txt_make_dirty(text);
|
||||
txt_clean_text(text);
|
||||
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_DEL, c);
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_DEL_1, c);
|
||||
}
|
||||
|
||||
void txt_delete_word (Text *text)
|
||||
@@ -2358,7 +2543,7 @@ void txt_delete_word (Text *text)
|
||||
|
||||
void txt_backspace_char (Text *text)
|
||||
{
|
||||
char c='\n';
|
||||
unsigned int c='\n';
|
||||
|
||||
if (!text) return;
|
||||
if (!text->curl) return;
|
||||
@@ -2378,12 +2563,15 @@ void txt_backspace_char (Text *text)
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
else { /* Just backspacing a char */
|
||||
int i= text->curc-1;
|
||||
size_t c_len = 0;
|
||||
TextMarker *mrk;
|
||||
char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc);
|
||||
c= BLI_str_utf8_as_unicode_and_size(prev, &c_len);
|
||||
|
||||
TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0, 0);
|
||||
mrk= txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
|
||||
if (mrk) {
|
||||
int lineno= mrk->lineno;
|
||||
if (mrk->start==i+1) {
|
||||
if (mrk->start==text->curc) {
|
||||
if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
|
||||
txt_clear_markers(text, mrk->group, TMARK_TEMP);
|
||||
} else {
|
||||
@@ -2392,19 +2580,16 @@ void txt_backspace_char (Text *text)
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (mrk->start>i) mrk->start--;
|
||||
mrk->end--;
|
||||
if (mrk->start>text->curc - c_len) mrk->start-= c_len;
|
||||
mrk->end-= c_len;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
c= text->curl->line[i];
|
||||
while(i< text->curl->len) {
|
||||
text->curl->line[i]= text->curl->line[i+1];
|
||||
i++;
|
||||
}
|
||||
text->curl->len--;
|
||||
text->curc--;
|
||||
memcpy(text->curl->line + text->curc - c_len, text->curl->line + text->curc, text->curl->len-text->curc+1);
|
||||
|
||||
text->curl->len-= c_len;
|
||||
text->curc-= c_len;
|
||||
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
@@ -2412,7 +2597,7 @@ void txt_backspace_char (Text *text)
|
||||
txt_make_dirty(text);
|
||||
txt_clean_text(text);
|
||||
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_BS, c);
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_BS_1, c);
|
||||
}
|
||||
|
||||
void txt_backspace_word (Text *text)
|
||||
@@ -2436,11 +2621,12 @@ static void txt_convert_tab_to_spaces (Text *text)
|
||||
txt_insert_buf(text, sb);
|
||||
}
|
||||
|
||||
static int txt_add_char_intern (Text *text, char add, int replace_tabs)
|
||||
static int txt_add_char_intern (Text *text, unsigned int add, int replace_tabs)
|
||||
{
|
||||
int len, lineno;
|
||||
char *tmp;
|
||||
int lineno;
|
||||
char *tmp, ch[BLI_UTF8_MAX];
|
||||
TextMarker *mrk;
|
||||
size_t add_len;
|
||||
|
||||
if (!text) return 0;
|
||||
if (!text->curl) return 0;
|
||||
@@ -2458,43 +2644,42 @@ static int txt_add_char_intern (Text *text, char add, int replace_tabs)
|
||||
|
||||
txt_delete_sel(text);
|
||||
|
||||
add_len = BLI_str_utf8_from_unicode(add, ch);
|
||||
mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0);
|
||||
if (mrk) {
|
||||
lineno= mrk->lineno;
|
||||
do {
|
||||
if (mrk->start>text->curc) mrk->start++;
|
||||
mrk->end++;
|
||||
if (mrk->start>text->curc) mrk->start+= add_len;
|
||||
mrk->end+= add_len;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
tmp= MEM_mallocN(text->curl->len+2, "textline_string");
|
||||
tmp= MEM_mallocN(text->curl->len+add_len+1, "textline_string");
|
||||
|
||||
if(text->curc) memcpy(tmp, text->curl->line, text->curc);
|
||||
tmp[text->curc]= add;
|
||||
|
||||
len= text->curl->len - text->curc;
|
||||
if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len);
|
||||
tmp[text->curl->len+1]=0;
|
||||
memcpy(tmp, text->curl->line, text->curc);
|
||||
memcpy(tmp+text->curc, ch, add_len);
|
||||
memcpy(tmp+text->curc+add_len, text->curl->line+text->curc, text->curl->len-text->curc+1);
|
||||
|
||||
make_new_line(text->curl, tmp);
|
||||
|
||||
text->curc++;
|
||||
text->curc+= add_len;
|
||||
|
||||
txt_pop_sel(text);
|
||||
|
||||
txt_make_dirty(text);
|
||||
txt_clean_text(text);
|
||||
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_INSERT, add);
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int txt_add_char (Text *text, char add)
|
||||
int txt_add_char (Text *text, unsigned int add)
|
||||
{
|
||||
return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES);
|
||||
}
|
||||
|
||||
int txt_add_raw_char (Text *text, char add)
|
||||
int txt_add_raw_char (Text *text, unsigned int add)
|
||||
{
|
||||
return txt_add_char_intern(text, add, 0);
|
||||
}
|
||||
@@ -2505,34 +2690,48 @@ void txt_delete_selected(Text *text)
|
||||
txt_make_dirty(text);
|
||||
}
|
||||
|
||||
int txt_replace_char (Text *text, char add)
|
||||
int txt_replace_char (Text *text, unsigned int add)
|
||||
{
|
||||
char del;
|
||||
unsigned int del;
|
||||
size_t del_size = 0, add_size;
|
||||
char ch[BLI_UTF8_MAX];
|
||||
|
||||
if (!text) return 0;
|
||||
if (!text->curl) return 0;
|
||||
|
||||
/* If text is selected or we're at the end of the line just use txt_add_char */
|
||||
if (text->curc==text->curl->len || txt_has_sel(text) || add=='\n') {
|
||||
TextMarker *mrk;
|
||||
int i= txt_add_char(text, add);
|
||||
mrk= txt_find_marker(text, text->curl, text->curc, 0, 0);
|
||||
if (mrk && mrk->end==text->curc) mrk->end--;
|
||||
TextMarker *mrk= txt_find_marker(text, text->curl, text->curc, 0, 0);
|
||||
if (mrk) BLI_freelinkN(&text->markers, mrk);
|
||||
return i;
|
||||
}
|
||||
|
||||
del= text->curl->line[text->curc];
|
||||
text->curl->line[text->curc]= (unsigned char) add;
|
||||
text->curc++;
|
||||
txt_pop_sel(text);
|
||||
del= BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &del_size);
|
||||
add_size= BLI_str_utf8_from_unicode(add, ch);
|
||||
|
||||
if (add_size > del_size) {
|
||||
char *tmp= MEM_mallocN(text->curl->len+add_size-del_size+1, "textline_string");
|
||||
memcpy(tmp, text->curl->line, text->curc);
|
||||
memcpy(tmp+text->curc+add_size, text->curl->line+text->curc+del_size, text->curl->len-text->curc-del_size+1);
|
||||
MEM_freeN(text->curl->line);
|
||||
text->curl->line = tmp;
|
||||
} else if (add_size < del_size) {
|
||||
char *tmp= text->curl->line;
|
||||
memmove(tmp+text->curc+add_size, tmp+text->curc+del_size, text->curl->len-text->curc-del_size+1);
|
||||
}
|
||||
|
||||
memcpy(text->curl->line + text->curc, ch, add_size);
|
||||
text->curc+= add_size;
|
||||
|
||||
txt_pop_sel(text);
|
||||
txt_make_dirty(text);
|
||||
txt_clean_text(text);
|
||||
|
||||
/* Should probably create a new op for this */
|
||||
if(!undoing) {
|
||||
txt_undo_add_charop(text, UNDO_DEL, del);
|
||||
txt_undo_add_charop(text, UNDO_INSERT, add);
|
||||
txt_undo_add_charop(text, UNDO_DEL_1, del);
|
||||
txt_undo_add_charop(text, UNDO_INSERT_1, add);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_text.h" // for txt_extended_ascii_as_utf8
|
||||
#include "BKE_texture.h" // for open_plugin_tex
|
||||
#include "BKE_tracking.h"
|
||||
#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
|
||||
@@ -12976,6 +12977,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
|
||||
/* put compatibility code here until next subversion bump */
|
||||
{
|
||||
{
|
||||
/* convert extended ascii to utf-8 for text editor */
|
||||
Text *text;
|
||||
for (text= main->text.first; text; text= text->id.next)
|
||||
if(!(text->flags & TXT_ISEXT)) {
|
||||
TextLine *tl;
|
||||
|
||||
for (tl= text->lines.first; tl; tl= tl->next) {
|
||||
int added= txt_extended_ascii_as_utf8(&tl->line);
|
||||
tl->len+= added;
|
||||
|
||||
/* reset cursor position if line was changed */
|
||||
if (added && tl == text->curl)
|
||||
text->curc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
|
||||
@@ -72,7 +72,7 @@ static void text_font_end(SpaceText *UNUSED(st))
|
||||
{
|
||||
}
|
||||
|
||||
static int text_font_draw(SpaceText *UNUSED(st), int x, int y, char *str)
|
||||
static int text_font_draw(SpaceText *UNUSED(st), int x, int y, const char *str)
|
||||
{
|
||||
BLF_position(mono, x, y, 0);
|
||||
BLF_draw(mono, str, BLF_DRAW_STR_DUMMY_MAX);
|
||||
@@ -92,19 +92,28 @@ static int text_font_draw_character(SpaceText *st, int x, int y, char c)
|
||||
return st->cwidth;
|
||||
}
|
||||
|
||||
int text_font_width(SpaceText *UNUSED(st), const char *str)
|
||||
static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c)
|
||||
{
|
||||
return BLF_width(mono, str);
|
||||
char str[BLI_UTF8_MAX+1];
|
||||
size_t len = BLI_str_utf8_size(c);
|
||||
memcpy(str, c, len);
|
||||
str[len]= '\0';
|
||||
|
||||
BLF_position(mono, x, y, 0);
|
||||
BLF_draw(mono, str, len);
|
||||
|
||||
return st->cwidth;
|
||||
}
|
||||
|
||||
/****************** flatten string **********************/
|
||||
|
||||
static void flatten_string_append(FlattenString *fs, char c, int accum)
|
||||
static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
|
||||
{
|
||||
if(fs->pos>=fs->len && fs->pos>=sizeof(fs->fixedbuf)-1) {
|
||||
int i;
|
||||
|
||||
if(fs->pos+len > fs->len) {
|
||||
char *nbuf; int *naccum;
|
||||
if(fs->len) fs->len*= 2;
|
||||
else fs->len= sizeof(fs->fixedbuf) * 2;
|
||||
fs->len*= 2;
|
||||
|
||||
nbuf= MEM_callocN(sizeof(*fs->buf)*fs->len, "fs->buf");
|
||||
naccum= MEM_callocN(sizeof(*fs->accum)*fs->len, "fs->accum");
|
||||
@@ -121,35 +130,45 @@ static void flatten_string_append(FlattenString *fs, char c, int accum)
|
||||
fs->accum= naccum;
|
||||
}
|
||||
|
||||
fs->buf[fs->pos]= c;
|
||||
fs->accum[fs->pos]= accum;
|
||||
|
||||
fs->pos++;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
fs->buf[fs->pos+i]= c[i];
|
||||
fs->accum[fs->pos+i]= accum;
|
||||
}
|
||||
|
||||
fs->pos+= len;
|
||||
}
|
||||
|
||||
int flatten_string(SpaceText *st, FlattenString *fs, const char *in)
|
||||
{
|
||||
int r = 0, i = 0;
|
||||
int r, i, total = 0;
|
||||
|
||||
memset(fs, 0, sizeof(FlattenString));
|
||||
fs->buf= fs->fixedbuf;
|
||||
fs->accum= fs->fixedaccum;
|
||||
|
||||
for(r=0, i=0; *in; r++, in++) {
|
||||
fs->len = sizeof(fs->fixedbuf);
|
||||
|
||||
for(r = 0, i = 0; *in; r++) {
|
||||
if(*in=='\t') {
|
||||
if(fs->pos && *(in-1)=='\t')
|
||||
i= st->tabnumber;
|
||||
else if(st->tabnumber > 0)
|
||||
i= st->tabnumber - (fs->pos%st->tabnumber);
|
||||
|
||||
i= st->tabnumber - (total%st->tabnumber);
|
||||
total+= i;
|
||||
|
||||
while(i--)
|
||||
flatten_string_append(fs, ' ', r);
|
||||
flatten_string_append(fs, " ", r, 1);
|
||||
|
||||
in++;
|
||||
}
|
||||
else {
|
||||
size_t len= BLI_str_utf8_size(in);
|
||||
flatten_string_append(fs, in, r, len);
|
||||
in += len;
|
||||
total++;
|
||||
}
|
||||
else
|
||||
flatten_string_append(fs, *in, r);
|
||||
}
|
||||
|
||||
flatten_string_append(fs, "\0", r, 1);
|
||||
|
||||
return fs->pos;
|
||||
return total;
|
||||
}
|
||||
|
||||
void flatten_string_free(FlattenString *fs)
|
||||
@@ -304,9 +323,8 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
|
||||
}
|
||||
else orig = 0xFF;
|
||||
|
||||
flatten_string(st, &fs, line->line);
|
||||
len = flatten_string(st, &fs, line->line);
|
||||
str = fs.buf;
|
||||
len = strlen(str);
|
||||
if(!text_check_format_len(line, len)) {
|
||||
flatten_string_free(&fs);
|
||||
return;
|
||||
@@ -318,7 +336,7 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
|
||||
if(*str == '\\') {
|
||||
*fmt = prev; fmt++; str++;
|
||||
if(*str == '\0') break;
|
||||
*fmt = prev; fmt++; str++;
|
||||
*fmt = prev; fmt++; str += BLI_str_utf8_size(str);
|
||||
continue;
|
||||
}
|
||||
/* Handle continuations */
|
||||
@@ -339,14 +357,16 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
|
||||
}
|
||||
|
||||
*fmt = 'l';
|
||||
str += BLI_str_utf8_size(str) - 1;
|
||||
}
|
||||
/* Not in a string... */
|
||||
else {
|
||||
/* Deal with comments first */
|
||||
if(prev == '#' || *str == '#')
|
||||
if(prev == '#' || *str == '#') {
|
||||
*fmt = '#';
|
||||
/* Strings */
|
||||
else if(*str == '"' || *str == '\'') {
|
||||
str += BLI_str_utf8_size(str) - 1;
|
||||
} else if(*str == '"' || *str == '\'') {
|
||||
/* Strings */
|
||||
find = *str;
|
||||
cont = (*str== '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR;
|
||||
if(*(str+1) == find && *(str+2) == find) {
|
||||
@@ -371,14 +391,18 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
|
||||
}
|
||||
*fmt = 'n';
|
||||
}
|
||||
else
|
||||
else {
|
||||
str += BLI_str_utf8_size(str) - 1;
|
||||
*fmt = 'q';
|
||||
}
|
||||
/* Punctuation */
|
||||
else if(text_check_delim(*str))
|
||||
*fmt = '!';
|
||||
/* Identifiers and other text (no previous ws. or delims. so text continues) */
|
||||
else if(prev == 'q')
|
||||
else if(prev == 'q') {
|
||||
str += BLI_str_utf8_size(str) - 1;
|
||||
*fmt = 'q';
|
||||
}
|
||||
/* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
|
||||
else {
|
||||
/* Special vars(v) or built-in keywords(b) */
|
||||
@@ -395,8 +419,10 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
|
||||
}
|
||||
*fmt = prev;
|
||||
}
|
||||
else
|
||||
else {
|
||||
str += BLI_str_utf8_size(str) - 1;
|
||||
*fmt = 'q';
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = *fmt;
|
||||
@@ -408,14 +434,11 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
|
||||
*fmt = '\0'; fmt++;
|
||||
*fmt = cont;
|
||||
|
||||
/* Debugging */
|
||||
//print_format(st, line);
|
||||
|
||||
/* If continuation has changed and we're allowed, process the next line */
|
||||
if(cont!=orig && do_next && line->next) {
|
||||
txt_format_line(st, line->next, do_next);
|
||||
}
|
||||
|
||||
|
||||
flatten_string_free(&fs);
|
||||
}
|
||||
|
||||
@@ -539,13 +562,14 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
|
||||
}
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
cursin = txt_utf8_offset_to_index(linein->line, cursin);
|
||||
|
||||
while(linep) {
|
||||
start= 0;
|
||||
end= max;
|
||||
chop= 1;
|
||||
*offc= 0;
|
||||
for(i=0, j=0; linep->line[j]!='\0'; j++) {
|
||||
for(i=0, j=0; linep->line[j]; j+=BLI_str_utf8_size(linep->line+j)) {
|
||||
int chars;
|
||||
|
||||
/* Mimic replacement of tabs */
|
||||
@@ -591,6 +615,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
|
||||
}
|
||||
}
|
||||
|
||||
/* cursin - mem, offc - view */
|
||||
void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc)
|
||||
{
|
||||
int i, j, start, end, chars, max, chop;
|
||||
@@ -607,8 +632,9 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
|
||||
end= max;
|
||||
chop= 1;
|
||||
*offc= 0;
|
||||
cursin = txt_utf8_offset_to_index(linein->line, cursin);
|
||||
|
||||
for(i=0, j=0; linein->line[j]!='\0'; j++) {
|
||||
for(i=0, j=0; linein->line[j]; j += BLI_str_utf8_size(linein->line + j)) {
|
||||
|
||||
/* Mimic replacement of tabs */
|
||||
ch= linein->line[j];
|
||||
@@ -653,7 +679,7 @@ int text_get_char_pos(SpaceText *st, const char *line, int cur)
|
||||
{
|
||||
int a=0, i;
|
||||
|
||||
for(i=0; i<cur && line[i]; i++) {
|
||||
for(i=0; i<cur && line[i]; i += BLI_str_utf8_size(line + i)) {
|
||||
if(line[i]=='\t')
|
||||
a += st->tabnumber-a%st->tabnumber;
|
||||
else
|
||||
@@ -662,54 +688,65 @@ int text_get_char_pos(SpaceText *st, const char *line, int cur)
|
||||
return a;
|
||||
}
|
||||
|
||||
static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char *format, int skip)
|
||||
static const char *txt_utf8_get_nth(const char *str, int n)
|
||||
{
|
||||
int pos= 0;
|
||||
while (str[pos] && n--) {
|
||||
pos+= BLI_str_utf8_size(str + pos);
|
||||
}
|
||||
return str + pos;
|
||||
}
|
||||
|
||||
static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w, const char *format, int skip)
|
||||
{
|
||||
FlattenString fs;
|
||||
int basex, i, a, len, start, end, max, lines;
|
||||
int basex, i, a, start, end, max, lines; /* view */
|
||||
int mi, ma, mstart, mend; /* mem */
|
||||
|
||||
len= flatten_string(st, &fs, str);
|
||||
flatten_string(st, &fs, str);
|
||||
str= fs.buf;
|
||||
max= w/st->cwidth;
|
||||
if(max<8) max= 8;
|
||||
basex= x;
|
||||
|
||||
lines= 1;
|
||||
start= 0;
|
||||
end= max;
|
||||
for(i=0; i<len; i++) {
|
||||
|
||||
start= 0; mstart= 0;
|
||||
end= max; mend= txt_utf8_get_nth(str, max) - str;
|
||||
|
||||
for(i=0, mi=0; str[mi]; i++, mi+=BLI_str_utf8_size(str+mi)) {
|
||||
if(i-start >= max) {
|
||||
/* skip hidden part of line */
|
||||
if(skip) {
|
||||
skip--;
|
||||
start= end;
|
||||
end += max;
|
||||
start= end; mstart= mend;
|
||||
end += max; mend= txt_utf8_get_nth(str+mend, max) - str;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Draw the visible portion of text on the overshot line */
|
||||
for(a=start; a<end; a++) {
|
||||
for(a=start, ma=mstart; a<end; a++, ma+=BLI_str_utf8_size(str+ma)) {
|
||||
if(st->showsyntax && format) format_draw_color(format[a]);
|
||||
x += text_font_draw_character(st, x, y, str[a]);
|
||||
x += text_font_draw_character_utf8(st, x, y, str + ma);
|
||||
}
|
||||
y -= st->lheight;
|
||||
x= basex;
|
||||
lines++;
|
||||
start= end;
|
||||
end += max;
|
||||
start= end; mstart= mend;
|
||||
end += max; mend= txt_utf8_get_nth(str+mend, max) - str;
|
||||
|
||||
if(y<=0) break;
|
||||
}
|
||||
else if(str[i]==' ' || str[i]=='-') {
|
||||
end = i+1;
|
||||
else if(str[mi]==' ' || str[mi]=='-') {
|
||||
end = i+1; mend = mi+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the remaining text */
|
||||
for(a=start; a<len && y > 0; a++) {
|
||||
for(a=start, ma=mstart; str[ma] && y > 0; a++, ma+=BLI_str_utf8_size(str+ma)) {
|
||||
if(st->showsyntax && format)
|
||||
format_draw_color(format[a]);
|
||||
|
||||
x += text_font_draw_character(st, x, y, str[a]);
|
||||
x += text_font_draw_character_utf8(st, x, y, str+ma);
|
||||
}
|
||||
|
||||
flatten_string_free(&fs);
|
||||
@@ -717,45 +754,36 @@ static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char
|
||||
return lines;
|
||||
}
|
||||
|
||||
static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, char *format)
|
||||
static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, const char *format)
|
||||
{
|
||||
FlattenString fs;
|
||||
int r=0, w= 0, amount;
|
||||
int *acc;
|
||||
char *in;
|
||||
int *acc, r=0;
|
||||
const char *in;
|
||||
|
||||
w= flatten_string(st, &fs, str);
|
||||
int w= flatten_string(st, &fs, str);
|
||||
if(w < cshift) {
|
||||
flatten_string_free(&fs);
|
||||
return 0; /* String is shorter than shift */
|
||||
}
|
||||
|
||||
in= fs.buf+cshift;
|
||||
in= txt_utf8_get_nth(fs.buf, cshift);
|
||||
acc= fs.accum+cshift;
|
||||
w= w-cshift;
|
||||
|
||||
if(draw) {
|
||||
if(st->showsyntax && format) {
|
||||
int a;
|
||||
format = format+cshift;
|
||||
int amount = maxwidth ? MIN2(w, maxwidth) : w;
|
||||
|
||||
amount = strlen(in);
|
||||
if(maxwidth)
|
||||
amount= MIN2(amount, maxwidth);
|
||||
|
||||
if(st->showsyntax && format) {
|
||||
int a, str_shift= 0;
|
||||
format = format+cshift;
|
||||
|
||||
for(a = 0; a < amount; a++) {
|
||||
format_draw_color(format[a]);
|
||||
x += text_font_draw_character(st, x, y, in[a]);
|
||||
x += text_font_draw_character_utf8(st, x, y, in + str_shift);
|
||||
str_shift += BLI_str_utf8_size(in + str_shift);
|
||||
}
|
||||
}
|
||||
else {
|
||||
amount = strlen(in);
|
||||
if(maxwidth)
|
||||
amount= MIN2(amount, maxwidth);
|
||||
|
||||
in[amount]= 0;
|
||||
text_font_draw(st, x, y, in);
|
||||
}
|
||||
else text_font_draw(st, x, y, in);
|
||||
}
|
||||
else {
|
||||
while(w-- && *acc++ < maxwidth)
|
||||
@@ -976,8 +1004,8 @@ int text_get_visible_lines(SpaceText *st, ARegion *ar, const char *str)
|
||||
max= wrap_width(st, ar);
|
||||
lines= 1;
|
||||
start= 0;
|
||||
end= max;
|
||||
for(i= 0, j= 0; str[j] != '\0'; j++) {
|
||||
end= max;
|
||||
for(i= 0, j= 0; str[j]; j+=BLI_str_utf8_size(str+j)) {
|
||||
/* Mimic replacement of tabs */
|
||||
ch= str[j];
|
||||
if(ch=='\t') {
|
||||
@@ -1421,7 +1449,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
|
||||
|
||||
BLI_strncpy(str, item->name, SUGG_LIST_WIDTH);
|
||||
|
||||
w = text_font_width(st, str);
|
||||
w = BLF_width(mono, str);
|
||||
|
||||
if(item == sel) {
|
||||
UI_ThemeColor(TH_SHADE2);
|
||||
@@ -1496,8 +1524,6 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
|
||||
glRecti(x-4, y, ar->winx, y-st->lheight), y-=st->lheight;
|
||||
|
||||
glRecti(x-4, y, x+toc*st->cwidth, y-st->lheight); y-=st->lheight;
|
||||
|
||||
(void)y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1569,8 +1595,9 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
|
||||
{
|
||||
TextLine *startl, *endl, *linep;
|
||||
Text *text = st->text;
|
||||
int b, c, startc, endc, find, stack;
|
||||
int viewc, viewl, offl, offc, x, y;
|
||||
int b, fc, find, stack, viewc, viewl, offl, offc, x, y;
|
||||
int startc, endc, c;
|
||||
|
||||
char ch;
|
||||
|
||||
// showsyntax must be on or else the format string will be null
|
||||
@@ -1584,21 +1611,23 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
|
||||
|
||||
linep= startl;
|
||||
c= startc;
|
||||
fc= txt_utf8_offset_to_index(linep->line, startc);
|
||||
endl= NULL;
|
||||
endc= -1;
|
||||
find= -b;
|
||||
stack= 0;
|
||||
|
||||
/* Dont highlight backets if syntax HL is off or bracket in string or comment. */
|
||||
if(!linep->format || linep->format[c] == 'l' || linep->format[c] == '#')
|
||||
if(!linep->format || linep->format[fc] == 'l' || linep->format[fc] == '#')
|
||||
return;
|
||||
|
||||
if(b>0) {
|
||||
/* opening bracket, search forward for close */
|
||||
c++;
|
||||
fc++;
|
||||
c+= BLI_str_utf8_size(linep->line+c);
|
||||
while(linep) {
|
||||
while(c<linep->len) {
|
||||
if(linep->format && linep->format[c] != 'l' && linep->format[c] != '#') {
|
||||
if(linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') {
|
||||
b= text_check_bracket(linep->line[c]);
|
||||
if(b==find) {
|
||||
if(stack==0) {
|
||||
@@ -1612,19 +1641,22 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
|
||||
stack++;
|
||||
}
|
||||
}
|
||||
c++;
|
||||
fc++;
|
||||
c+= BLI_str_utf8_size(linep->line+c);
|
||||
}
|
||||
if(endl) break;
|
||||
linep= linep->next;
|
||||
c= 0;
|
||||
fc= 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* closing bracket, search backward for open */
|
||||
c--;
|
||||
fc--;
|
||||
if (c>0) c -= linep->line+c-BLI_str_prev_char_utf8(linep->line+c);
|
||||
while(linep) {
|
||||
while(c>=0) {
|
||||
if(linep->format && linep->format[c] != 'l' && linep->format[c] != '#') {
|
||||
while(fc>=0) {
|
||||
if(linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') {
|
||||
b= text_check_bracket(linep->line[c]);
|
||||
if(b==find) {
|
||||
if(stack==0) {
|
||||
@@ -1638,11 +1670,17 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
|
||||
stack++;
|
||||
}
|
||||
}
|
||||
c--;
|
||||
fc--;
|
||||
if (c>0) c -= linep->line+c-BLI_str_prev_char_utf8(linep->line+c);
|
||||
}
|
||||
if(endl) break;
|
||||
linep= linep->prev;
|
||||
if(linep) c= linep->len-1;
|
||||
if(linep) {
|
||||
if (linep->format) fc= strlen(linep->format)-1;
|
||||
else fc= -1;
|
||||
if (linep->len) c= BLI_str_prev_char_utf8(linep->line+linep->len)-linep->line;
|
||||
else fc= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,6 @@ struct wmWindowManager;
|
||||
/* text_draw.c */
|
||||
void draw_text_main(struct SpaceText *st, struct ARegion *ar);
|
||||
|
||||
int text_font_width_character(struct SpaceText *st);
|
||||
int text_font_width(struct SpaceText *st, const char *str);
|
||||
|
||||
void text_update_line_edited(struct TextLine *line);
|
||||
void text_update_edited(struct Text *text);
|
||||
void text_update_character_width(struct SpaceText *st);
|
||||
|
||||
@@ -1420,7 +1420,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++) {
|
||||
for(i=0, j=0; loop; j+=BLI_str_utf8_size(linein->line+j)) {
|
||||
int chars;
|
||||
/* Mimic replacement of tabs */
|
||||
ch= linein->line[j];
|
||||
@@ -1595,7 +1595,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++) {
|
||||
for(i=0, j=0; loop; j+=BLI_str_utf8_size((*linep)->line+j)) {
|
||||
int chars;
|
||||
/* Mimic replacement of tabs */
|
||||
ch= (*linep)->line[j];
|
||||
@@ -1610,7 +1610,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
|
||||
*charp= endj;
|
||||
|
||||
if(j>=oldc) {
|
||||
if(ch=='\0') *charp= start;
|
||||
if(ch=='\0') *charp= txt_utf8_index_to_offset((*linep)->line, start);
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
@@ -1623,7 +1623,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
|
||||
}
|
||||
else if(ch==' ' || ch=='-' || ch=='\0') {
|
||||
if(j>=oldc) {
|
||||
*charp= start;
|
||||
*charp= txt_utf8_index_to_offset((*linep)->line, start);
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
@@ -1663,7 +1663,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++) {
|
||||
for(i=0, j=0; loop; j+=BLI_str_utf8_size((*linep)->line+j)) {
|
||||
int chars;
|
||||
/* Mimic replacement of tabs */
|
||||
ch= (*linep)->line[j];
|
||||
@@ -1675,7 +1675,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
|
||||
|
||||
while(chars--) {
|
||||
if(i-start>=max) {
|
||||
if(chop) endj= j-1;
|
||||
if(chop) endj= BLI_str_prev_char_utf8((*linep)->line+j)-(*linep)->line;
|
||||
|
||||
if(endj>=oldc) {
|
||||
if(ch=='\0') *charp= (*linep)->len;
|
||||
@@ -2364,148 +2364,183 @@ typedef struct SetSelection {
|
||||
short old[2];
|
||||
} SetSelection;
|
||||
|
||||
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)) {
|
||||
if(str[i]=='\t') {
|
||||
total += st->tabnumber - total%st->tabnumber;
|
||||
}
|
||||
else total++;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
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))
|
||||
if(str[j]=='\t')
|
||||
i += st->tabnumber - i%st->tabnumber;
|
||||
else
|
||||
i++;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y)
|
||||
{
|
||||
TextLine *linep = st->text->lines.first;
|
||||
int i;
|
||||
for (i = st->top; 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;
|
||||
}
|
||||
}
|
||||
return linep;
|
||||
}
|
||||
|
||||
static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
{
|
||||
Text *text = st->text;
|
||||
int max = wrap_width(st, ar); /* view */
|
||||
int charp; /* mem */
|
||||
int loop = 1, found = 0; /* flags */
|
||||
char ch;
|
||||
|
||||
/* Point to first visible line */
|
||||
TextLine *linep = get_first_visible_line(st, ar, &y);
|
||||
|
||||
while(loop && linep) {
|
||||
int i = 0, start = 0, end = max; /* view */
|
||||
int j = 0, curs = 0, endj = 0; /* mem */
|
||||
int chop = 1; /* flags */
|
||||
|
||||
for (; loop; j += BLI_str_utf8_size(linep->line+j)) {
|
||||
int chars;
|
||||
|
||||
/* Mimic replacement of tabs */
|
||||
ch = linep->line[j];
|
||||
if(ch == '\t') {
|
||||
chars = st->tabnumber - i%st->tabnumber;
|
||||
ch = ' ';
|
||||
}
|
||||
else chars = 1;
|
||||
|
||||
while (chars--) {
|
||||
/* Gone too far, go back to last wrap point */
|
||||
if (y < 0) {
|
||||
charp = endj;
|
||||
loop = 0;
|
||||
break;
|
||||
/* 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;
|
||||
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 && ch!='\0') charp = endj;
|
||||
loop = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(chop) endj = j;
|
||||
start = end;
|
||||
end += max;
|
||||
|
||||
if(j < linep->len)
|
||||
y--;
|
||||
|
||||
chop = 1;
|
||||
if (y == 0 && i-start >= x) {
|
||||
charp = curs;
|
||||
loop = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ch == ' ' || ch == '-' || ch == '\0') {
|
||||
if (found) {
|
||||
loop = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(y == 0 && i-start >= x) {
|
||||
charp = curs;
|
||||
loop = 0;
|
||||
break;
|
||||
}
|
||||
end = i + 1;
|
||||
endj = j;
|
||||
chop = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if(ch == '\0') break;
|
||||
}
|
||||
|
||||
if(!loop || found) break;
|
||||
|
||||
if(!linep->next) {
|
||||
charp = linep->len;
|
||||
break;
|
||||
}
|
||||
|
||||
/* On correct line but didn't meet cursor, must be at end */
|
||||
if (y == 0) {
|
||||
charp = linep->len;
|
||||
break;
|
||||
}
|
||||
linep = linep->next;
|
||||
|
||||
y--;
|
||||
}
|
||||
|
||||
if(sel) { text->sell = linep; text->selc = charp; }
|
||||
else { text->curl = linep; text->curc = charp; }
|
||||
}
|
||||
|
||||
static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
{
|
||||
FlattenString fs;
|
||||
Text *text= st->text;
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int w;
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
if(sel) { linep= &text->sell; charp= &text->selc; }
|
||||
else { linep= &text->curl; charp= &text->curc; }
|
||||
|
||||
y= (ar->winy - 2 - y)/st->lheight;
|
||||
|
||||
if(st->showlinenrs)
|
||||
x-= TXT_OFFSET+TEXTXLOC;
|
||||
else
|
||||
x-= TXT_OFFSET;
|
||||
if(st->showlinenrs) x-= TXT_OFFSET+TEXTXLOC;
|
||||
else x-= TXT_OFFSET;
|
||||
|
||||
if(x<0) x= 0;
|
||||
x = (x/st->cwidth) + st->left;
|
||||
|
||||
if(st->wordwrap) {
|
||||
int i, j, endj, curs, max, chop, start, end, loop, found;
|
||||
char ch;
|
||||
|
||||
/* Point to first visible line */
|
||||
*linep= text->lines.first;
|
||||
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;
|
||||
chop= 1;
|
||||
curs= 0;
|
||||
endj= 0;
|
||||
for(i=0, j=0; loop; j++) {
|
||||
int chars;
|
||||
|
||||
/* Mimic replacement of tabs */
|
||||
ch= (*linep)->line[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
ch= ' ';
|
||||
}
|
||||
else
|
||||
chars= 1;
|
||||
|
||||
while(chars--) {
|
||||
/* Gone too far, go back to last wrap point */
|
||||
if(y<0) {
|
||||
*charp= endj;
|
||||
loop= 0;
|
||||
break;
|
||||
/* 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;
|
||||
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 && ch!='\0') (*charp)= endj;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(chop) endj= j;
|
||||
start= end;
|
||||
end += max;
|
||||
|
||||
if(j<(*linep)->len)
|
||||
y--;
|
||||
|
||||
chop= 1;
|
||||
if(y==0 && i-start>=x) {
|
||||
*charp= curs;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(ch==' ' || ch=='-' || ch=='\0') {
|
||||
if(found) {
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(y==0 && i-start>=x) {
|
||||
*charp= curs;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
end = i+1;
|
||||
endj = j;
|
||||
chop= 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(ch=='\0') break;
|
||||
}
|
||||
if(!loop || found) break;
|
||||
|
||||
if(!(*linep)->next) {
|
||||
*charp= (*linep)->len;
|
||||
break;
|
||||
}
|
||||
|
||||
/* On correct line but didn't meet cursor, must be at end */
|
||||
if(y==0) {
|
||||
*charp= (*linep)->len;
|
||||
break;
|
||||
}
|
||||
*linep= (*linep)->next;
|
||||
y--;
|
||||
}
|
||||
|
||||
text_cursor_set_to_pos_wrapped(st, ar, x, y, sel);
|
||||
}
|
||||
else {
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int w;
|
||||
|
||||
if(sel) { linep= &text->sell; charp= &text->selc; }
|
||||
else { linep= &text->curl; charp= &text->curc; }
|
||||
|
||||
y-= txt_get_span(text->lines.first, *linep) - st->top;
|
||||
|
||||
if(y>0) {
|
||||
@@ -2516,10 +2551,9 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
|
||||
}
|
||||
|
||||
|
||||
w= flatten_string(st, &fs, (*linep)->line);
|
||||
if(x<w) *charp= fs.accum[x];
|
||||
w= flatten_len(st, (*linep)->line);
|
||||
if(x<w) *charp= flatten_index_to_offset(st, (*linep)->line, x);
|
||||
else *charp= (*linep)->len;
|
||||
flatten_string_free(&fs);
|
||||
}
|
||||
if(!sel) txt_pop_sel(text);
|
||||
}
|
||||
@@ -2762,19 +2796,23 @@ static int text_insert_exec(bContext *C, wmOperator *op)
|
||||
SpaceText *st= CTX_wm_space_text(C);
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
char *str;
|
||||
int done = 0, i;
|
||||
int done = 0;
|
||||
size_t i = 0;
|
||||
unsigned int code;
|
||||
|
||||
text_drawcache_tag_update(st, 0);
|
||||
|
||||
str= RNA_string_get_alloc(op->ptr, "text", NULL, 0);
|
||||
|
||||
if(st && st->overwrite) {
|
||||
for(i=0; str[i]; i++) {
|
||||
done |= txt_replace_char(text, str[i]);
|
||||
while (str[i]) {
|
||||
code = BLI_str_utf8_as_unicode_step(str, &i);
|
||||
done |= txt_replace_char(text, code);
|
||||
}
|
||||
} else {
|
||||
for(i=0; str[i]; i++) {
|
||||
done |= txt_add_char(text, str[i]);
|
||||
while (str[i]) {
|
||||
code = BLI_str_utf8_as_unicode_step(str, &i);
|
||||
done |= txt_add_char(text, code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2802,9 +2840,17 @@ static int text_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
else {
|
||||
char str[2];
|
||||
str[0]= event->ascii;
|
||||
str[1]= '\0';
|
||||
char str[BLI_UTF8_MAX+1];
|
||||
size_t len;
|
||||
|
||||
if (event->utf8_buf[0]) {
|
||||
len = BLI_str_utf8_size(event->utf8_buf);
|
||||
memcpy(str, event->utf8_buf, len);
|
||||
} else {
|
||||
/* in theory, ghost can set value to extended ascii here */
|
||||
len = BLI_str_utf8_from_unicode(event->ascii, str);
|
||||
}
|
||||
str[len]= '\0';
|
||||
RNA_string_set(op->ptr, "text", str);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user