forked from bartvdbraak/blender
text editor changes
* out of sync text dosnt automatically popup a menu anymore since it was too easy to click on it without intending to, moved this to an alert button on the header. * "_" character was acting as a delimiter, but in python its not. * renamed "File" to "Text" (so as not to confuse with blenders file menu) * added redraw_alltext function to remove many duplicate loops where every text display is redrawn.
This commit is contained in:
parent
fe5dd01595
commit
ff6d4e84cb
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -30,22 +30,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#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 <sys/stat.h>
|
||||
|
||||
/***********************/ /*
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,22 @@
|
||||
#include "blendef.h"
|
||||
#include "mydevice.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
/* file time checking */
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#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;
|
||||
|
Loading…
Reference in New Issue
Block a user