diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 5f1a1e63da4..ff9a6298bf4 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -577,13 +577,14 @@ static void txt_make_dirty (Text *text) /* 0:whitespace, 1:punct, 2:alphanumeric */ static short txt_char_type (char ch) { - if (ch <= ' ') return 0; - if (ch <= '/') return 1; - if (ch <= '9') return 2; - if (ch <= '@') return 1; - if (ch <= 'Z') return 2; - if (ch <= '`') return 1; - if (ch <= 'z') return 2; + 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 */ return 1; } diff --git a/source/blender/include/BIF_drawtext.h b/source/blender/include/BIF_drawtext.h index 51000f8c81a..db2889d4e9d 100644 --- a/source/blender/include/BIF_drawtext.h +++ b/source/blender/include/BIF_drawtext.h @@ -39,7 +39,6 @@ void unlink_text(struct Text *text); void free_textspace(struct SpaceText *st); -int txt_file_modified(struct Text *text); void txt_write_file(struct Text *text); void add_text_fs(char *file); diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c index 3120d1931e4..7f913eb5d49 100644 --- a/source/blender/src/drawtext.c +++ b/source/blender/src/drawtext.c @@ -30,22 +30,12 @@ #include #include #include -#include -#include -#include #ifdef HAVE_CONFIG_H #include #endif -#ifndef _WIN32 -#include -#else -#include -#include "BLI_winstuff.h" -#endif #include "MEM_guardedalloc.h" -#include "PIL_time.h" #include "BMF_Api.h" @@ -88,6 +78,8 @@ #include "blendef.h" #include "winlay.h" +#include + /***********************/ /* Notes on word-wrap @@ -133,6 +125,7 @@ void drawtextspace(ScrArea *sa, void *spacedata); void winqreadtextspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt); void txt_copy_selectbuffer (Text *text); void draw_brackets(SpaceText *st); +void redraw_alltext(void); static void get_selection_buffer(Text *text); static int check_bracket(char ch); @@ -152,7 +145,6 @@ static char *g_find_str= NULL; static char *g_replace_str= NULL; static int doc_scroll= 0; -static double last_check_time= 0; static int jump_to= 0; static double last_jump= 0; @@ -1763,60 +1755,6 @@ void free_textspace(SpaceText *st) st->text= NULL; } -/* returns 0 if file on disk is the same or Text is in memory only - returns 1 if file has been modified on disk since last local edit - returns 2 if file on disk has been deleted - -1 is returned if an error occurs -*/ -int txt_file_modified(Text *text) -{ - struct stat st; - int result; - char file[FILE_MAXDIR+FILE_MAXFILE]; - - if (!text || !text->name) - return 0; - - BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); - BLI_convertstringcode(file, G.sce); - - if (!BLI_exists(file)) - return 2; - - result = stat(file, &st); - - if(result == -1) - return -1; - - if((st.st_mode & S_IFMT) != S_IFREG) - return -1; - - if (st.st_mtime > text->mtime) - return 1; - - return 0; -} - -void txt_ignore_modified(Text *text) { - struct stat st; - int result; - char file[FILE_MAXDIR+FILE_MAXFILE]; - - if (!text || !text->name) return; - - BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); - BLI_convertstringcode(file, G.sce); - - if (!BLI_exists(file)) return; - - result = stat(file, &st); - - if(result == -1 || (st.st_mode & S_IFMT) != S_IFREG) - return; - - text->mtime= st.st_mtime; -} - static void save_mem_text(char *str) { SpaceText *st= curarea->spacedata.first; @@ -2459,18 +2397,9 @@ static short do_texttools(SpaceText *st, char ascii, unsigned short evnt, short } } - if (draw) { - ScrArea *sa; - - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } - } - + if (draw) + redraw_alltext(); + return swallow; } @@ -2632,80 +2561,12 @@ static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short va } } - if (draw) { - ScrArea *sa; - - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } - } + if (draw) + redraw_alltext(); + return swallow; } -static short do_modification_check(SpaceText *st) { - Text *text= st->text; - - if (last_check_time < PIL_check_seconds_timer() - 2.0) { - switch (txt_file_modified(text)) { - case 1: - /* Modified locally and externally, ahhh. Offer more possibilites. */ - if (text->flags & TXT_ISDIRTY) { - switch (pupmenu("File Modified Outside and Inside Blender %t|Load outside changes (ignore local changes) %x0|Save local changes (ignore outside changes) %x1|Make text internal (separate copy) %x2")) { - case 0: - reopen_text(text); - if (st->showsyntax) txt_format_text(st); - return 1; - case 1: - txt_write_file(text); - return 1; - case 2: - text->flags |= TXT_ISMEM | TXT_ISDIRTY | TXT_ISTMP; - MEM_freeN(text->name); - text->name= NULL; - return 1; - } - } else { - switch (pupmenu("File Modified Outside Blender %t|Reload from disk %x0|Make text internal (separate copy) %x1|Ignore %x2")) { - case 0: - if (text->compiled) BPY_free_compiled_text(text); - text->compiled = NULL; - reopen_text(text); - if (st->showsyntax) txt_format_text(st); - return 1; - case 1: - text->flags |= TXT_ISMEM | TXT_ISDIRTY | TXT_ISTMP; - MEM_freeN(text->name); - text->name= NULL; - return 1; - case 2: - txt_ignore_modified(text); - return 1; - } - } - break; - case 2: - switch (pupmenu("File Deleted Outside Blender %t|Make text internal %x0|Recreate file %x1")) { - case 0: - text->flags |= TXT_ISMEM | TXT_ISDIRTY | TXT_ISTMP; - MEM_freeN(text->name); - text->name= NULL; - return 1; - case 1: - txt_write_file(text); - return 1; - } - break; - default: - break; - } - last_check_time = PIL_check_seconds_timer(); - } - return 0; -} void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) { @@ -3315,19 +3176,8 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } } - if (do_modification_check(st)) do_draw= 1; - - if (do_draw) { - ScrArea *sa; - - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } - } + if (do_draw) + redraw_alltext(); } void draw_brackets(SpaceText *st) @@ -3582,3 +3432,19 @@ void convert_tabs (struct SpaceText *st, int tab) if (st->showsyntax) txt_format_text(st); } + +void redraw_alltext(void) +{ + ScrArea *sa; + + if(!G.curscreen) + return; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + SpaceText *st= sa->spacedata.first; + + if (st && st->spacetype==SPACE_TEXT) { + scrarea_queue_redraw(sa); + } + } +} diff --git a/source/blender/src/header_text.c b/source/blender/src/header_text.c index eeea43ec57a..b9d694600e2 100644 --- a/source/blender/src/header_text.c +++ b/source/blender/src/header_text.c @@ -76,6 +76,22 @@ #include "blendef.h" #include "mydevice.h" +#include "PIL_time.h" + +/* file time checking */ +#include +#include +#include + +#ifndef _WIN32 +#include +#else +#include +#include "BLI_winstuff.h" +#endif + +extern void redraw_alltext(void); /* defined in drawtext.c */ + void do_text_buttons(unsigned short event) { SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ @@ -362,12 +378,8 @@ static void do_text_filemenu(void *arg, int event) default: break; } - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } + + redraw_alltext(); } /* action executed after clicking in Edit menu */ @@ -428,12 +440,7 @@ static void do_text_editmenu(void *arg, int event) break; } - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } + redraw_alltext(); } /* action executed after clicking in View menu */ @@ -459,13 +466,8 @@ static void do_text_editmenu_viewmenu(void *arg, int event) default: break; } - - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } + + redraw_alltext(); } /* action executed after clicking in Select menu */ @@ -490,12 +492,7 @@ static void do_text_editmenu_selectmenu(void *arg, int event) break; } - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } + redraw_alltext(); } /* action executed after clicking in Markers menu */ @@ -541,12 +538,7 @@ static void do_text_editmenu_markermenu(void *arg, int event) break; } - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } + redraw_alltext(); } /* action executed after clicking in Format menu */ @@ -614,12 +606,7 @@ static void do_text_formatmenu(void *arg, int event) break; } - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - SpaceText *st= sa->spacedata.first; - if (st && st->spacetype==SPACE_TEXT) { - scrarea_queue_redraw(sa); - } - } + redraw_alltext(); } /* View menu */ @@ -861,6 +848,133 @@ static uiBlock *text_filemenu(void *arg_unused) return block; } + +/* text sync functions */ + +/* returns 0 if file on disk is the same or Text is in memory only + returns 1 if file has been modified on disk since last local edit + returns 2 if file on disk has been deleted + -1 is returned if an error occurs +*/ +static int txt_file_modified(Text *text) +{ + struct stat st; + int result; + char file[FILE_MAXDIR+FILE_MAXFILE]; + + if (!text || !text->name) + return 0; + + BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); + BLI_convertstringcode(file, G.sce); + + if (!BLI_exists(file)) + return 2; + + result = stat(file, &st); + + if(result == -1) + return -1; + + if((st.st_mode & S_IFMT) != S_IFREG) + return -1; + + if (st.st_mtime > text->mtime) + return 1; + + return 0; +} + +static void txt_ignore_modified(Text *text) { + struct stat st; + int result; + char file[FILE_MAXDIR+FILE_MAXFILE]; + + if (!text || !text->name) return; + + BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); + BLI_convertstringcode(file, G.sce); + + if (!BLI_exists(file)) return; + + result = stat(file, &st); + + if(result == -1 || (st.st_mode & S_IFMT) != S_IFREG) + return; + + text->mtime= st.st_mtime; +} + +static double last_check_time= 0; + +static short do_modification_check(SpaceText *st_v) { + SpaceText *st = (SpaceText *)st_v; + Text *text= st->text; + + if (last_check_time < PIL_check_seconds_timer() - 2.0) { + switch (txt_file_modified(text)) { + case 1: + /* Modified locally and externally, ahhh. Offer more possibilites. */ + if (text->flags & TXT_ISDIRTY) { + switch (pupmenu("File Modified Outside and Inside Blender %t|Load outside changes (ignore local changes) %x0|Save local changes (ignore outside changes) %x1|Make text internal (separate copy) %x2")) { + case 0: + reopen_text(text); + if (st->showsyntax) txt_format_text(st); + return 1; + case 1: + txt_write_file(text); + return 1; + case 2: + text->flags |= TXT_ISMEM | TXT_ISDIRTY | TXT_ISTMP; + MEM_freeN(text->name); + text->name= NULL; + return 1; + } + } else { + switch (pupmenu("File Modified Outside Blender %t|Reload from disk %x0|Make text internal (separate copy) %x1|Ignore %x2")) { + case 0: + if (text->compiled) BPY_free_compiled_text(text); + text->compiled = NULL; + reopen_text(text); + if (st->showsyntax) txt_format_text(st); + return 1; + case 1: + text->flags |= TXT_ISMEM | TXT_ISDIRTY | TXT_ISTMP; + MEM_freeN(text->name); + text->name= NULL; + return 1; + case 2: + txt_ignore_modified(text); + return 1; + } + } + break; + case 2: + switch (pupmenu("File Deleted Outside Blender %t|Make text internal %x0|Recreate file %x1")) { + case 0: + text->flags |= TXT_ISMEM | TXT_ISDIRTY | TXT_ISTMP; + MEM_freeN(text->name); + text->name= NULL; + return 1; + case 1: + txt_write_file(text); + return 1; + } + break; + default: + break; + } + last_check_time = PIL_check_seconds_timer(); + } + return 0; +} + +static void do_modification_func(void *st_v, void *dummy) +{ + if (do_modification_check((SpaceText *)st_v)) + redraw_alltext(); +} + /* header */ #define HEADER_PATH_MAX 260 void text_buttons(void) @@ -905,8 +1019,8 @@ void text_buttons(void) if((curarea->flag & HEADER_NO_PULLDOWN)==0) { uiBlockSetEmboss(block, UI_EMBOSSP); - xmax= GetButStringLength("File"); - uiDefPulldownBut(block,text_filemenu, NULL, "File", xco, 0, xmax, 20, ""); + xmax= GetButStringLength("Text"); + uiDefPulldownBut(block,text_filemenu, NULL, "Text", xco, 0, xmax, 20, ""); xco+=xmax; if(text) { @@ -933,10 +1047,20 @@ void text_buttons(void) uiDefIconButI(block, ICONTOG, B_TEXTPLUGINS, ICON_PYTHON, xco+=XIC,0,XIC,YIC, &st->doplugins, 0, 0, 0, 0, "Enables Python text plugins"); uiBlockEndAlign(block); + /* Warning button if text is out of date*/ + if (text && txt_file_modified(text)) { + xco+= XIC; + uiBlockSetCol(block, TH_REDALERT); + uiBut *bt= uiDefIconBut(block, BUT, B_NOP, ICON_HELP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "External text is out of sync, click for options to resolve the conflict"); + uiButSetFunc(bt, do_modification_func, (void *)st, NULL); + uiBlockSetCol(block, TH_AUTO); + } + /* STD TEXT BUTTONS */ xco+= 2*XIC; xco= std_libbuttons(block, xco, 0, 0, NULL, B_TEXTBROWSE, ID_TXT, 0, (ID*)st->text, 0, &(st->menunr), 0, 0, B_TEXTDELETE, 0, 0); - + xco+=XIC; + /* if (st->text) { if (st->text->flags & TXT_ISDIRTY && (st->text->flags & TXT_ISEXT || !(st->text->flags & TXT_ISMEM))) @@ -949,7 +1073,7 @@ void text_buttons(void) } */ - xco+=XIC; + if(st->font_id>1) st->font_id= 0; uiDefButI(block, MENU, B_TEXTFONT, "Screen 12 %x0|Screen 15%x1", xco,0,100,YIC, &st->font_id, 0, 0, 0, 0, "Displays available fonts"); xco+=110;