Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-20 17:58:53 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-20 17:58:53 +0400
commitcb8f7fd385251d22ab97a48466e33ce0e42d5e4d (patch)
treefac9b9510d58bc04ff94dbc658621c3de31ed466 /source
parentb8eec2b8fe123b118aef925ce2f786842764413d (diff)
Auto Save
Auto save is now working again in 2.5. It will also remember now what the location of the original file was when recovering it, so that library links still work and saving the restored file does not save to the temp directory. There is also a new Recover Auto Save operator which will open the filebrowser in the temp directory and show the auto saved .blends. Implemenation Notes: * Timer storage was moved from window to windowmanager, so we can have windowmanager level timers too now, doesn't make sense to have autosave timer attached to a particular window. * FileGlobal now has a filename field storing where the file was saved. Note that this is only used when loading a file through the recover operators, regular file read doesn't use it, so copying the quit.blend manually over the original file will still work as expected. * Jobs timer no longer uses operator now, this seems more like an internal thing, changing keymaps should not make it possible to break the jobs manager. * Autosave is postponed by 10 seconds when a modal operator is running, e.g. transform or file browsing. * Moved setting G.sce in setup_app_data before depsgraph updates, these can use the filename for pointcaches.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_global.h1
-rw-r--r--source/blender/blenkernel/intern/blender.c20
-rw-r--r--source/blender/blenloader/BLO_readfile.h1
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c7
-rw-r--r--source/blender/editors/interface/interface_handlers.c22
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/screen/screen_edit.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c10
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/makesdna/DNA_fileglobal_types.h3
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c8
-rw-r--r--source/blender/makesrna/intern/rna_wm.c2
-rw-r--r--source/blender/windowmanager/WM_api.h10
-rw-r--r--source/blender/windowmanager/WM_types.h3
-rw-r--r--source/blender/windowmanager/intern/wm.c11
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c171
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c27
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c79
-rw-r--r--source/blender/windowmanager/intern/wm_window.c98
-rw-r--r--source/blender/windowmanager/wm.h12
-rw-r--r--source/blender/windowmanager/wm_event_types.h3
-rw-r--r--source/blender/windowmanager/wm_window.h4
31 files changed, 322 insertions, 219 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 5d0b89220d5..ccd21603c49 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -145,6 +145,7 @@ typedef struct Global {
#define G_FILE_GLSL_NO_NODES (1 << 20) /* deprecated */
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */
#define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */
+#define G_FILE_RECOVER (1 << 23)
/* G.windowstate */
#define G_WINDOWSTATE_USERDEF 0
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2df5b7c173c..7570369827b 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -281,12 +281,15 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
Object *ob;
bScreen *curscreen= NULL;
Scene *curscene= NULL;
+ int recover;
char mode;
-
+
/* 'u' = undo save, 'n' = no UI load */
if(bfd->main->screen.first==NULL) mode= 'u';
else if(G.fileflags & G_FILE_NO_UI) mode= 'n';
else mode= 0;
+
+ recover= (G.fileflags & G_FILE_RECOVER);
clean_paths(bfd->main);
@@ -371,6 +374,16 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
if(G.main->versionfile < 250)
do_versions_ipos_to_animato(G.main); // XXX fixme... complicated versionpatching
+ /* in case of autosave or quit.blend, use original filename instead */
+ if(recover && bfd->filename[0])
+ filename= bfd->filename;
+
+ /* these are the same at times, should never copy to the same location */
+ if(G.sce != filename)
+ BLI_strncpy(G.sce, filename, FILE_MAX);
+
+ BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */
+
/* baseflags, groups, make depsgraph, etc */
set_scene_bg(CTX_data_scene(C));
@@ -383,11 +396,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
/* now tag update flags, to ensure deformers get calculated on redraw */
DAG_scene_update_flags(CTX_data_scene(C), CTX_data_scene(C)->lay);
- if (G.sce != filename) /* these are the same at times, should never copy to the same location */
- strcpy(G.sce, filename);
-
- BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */
-
MEM_freeN(bfd);
}
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 52295dc3092..408d07b965c 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -62,6 +62,7 @@ typedef struct BlendFileData {
int fileflags;
int displaymode;
int globalf;
+ char filename[240]; /* 240 = FILE_MAX */
struct bScreen* curscreen;
struct Scene* curscene;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 761fc8b079a..ca2e5f4de75 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4432,7 +4432,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->curswin= NULL;
win->tweak= NULL;
- win->timers.first= win->timers.last= NULL;
win->queue.first= win->queue.last= NULL;
win->handlers.first= win->handlers.last= NULL;
win->modalhandlers.first= win->modalhandlers.last= NULL;
@@ -4444,6 +4443,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->drawfail= 0;
}
+ wm->timers.first= wm->timers.last= NULL;
wm->operators.first= wm->operators.last= NULL;
wm->paintcursors.first= wm->paintcursors.last= NULL;
wm->queue.first= wm->queue.last= NULL;
@@ -5468,6 +5468,7 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->fileflags= fg->fileflags;
bfd->displaymode= fg->displaymode;
bfd->globalf= fg->globalf;
+ BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
bfd->curscreen= fg->curscreen;
bfd->curscene= fg->curscene;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index e3d061d8e4b..f0c584b6267 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2308,7 +2308,7 @@ static void write_scripts(WriteData *wd, ListBase *idbase)
/* context is usually defined by WM, two cases where no WM is available:
* - for forward compatibility, curscreen has to be saved
* - for undofile, curscene needs to be saved */
-static void write_global(WriteData *wd, Main *mainvar)
+static void write_global(WriteData *wd, int fileflags, Main *mainvar)
{
FileGlobal fg;
bScreen *screen;
@@ -2321,8 +2321,9 @@ static void write_global(WriteData *wd, Main *mainvar)
fg.curscene= screen->scene;
fg.displaymode= G.displaymode;
fg.winpos= G.winpos;
- fg.fileflags= (G.fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
+ fg.fileflags= (fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
fg.globalf= G.f;
+ BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
sprintf(subvstr, "%4d", BLENDER_SUBVERSION);
memcpy(fg.subvstr, subvstr, 4);
@@ -2351,7 +2352,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
mywrite(wd, buf, 12);
write_renderinfo(wd, mainvar);
- write_global(wd, mainvar);
+ write_global(wd, write_flags, mainvar);
/* no UI save in undo */
if(current==NULL) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 29d84076533..554e729e0e2 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -92,6 +92,7 @@ typedef enum uiHandleButtonState {
} uiHandleButtonState;
typedef struct uiHandleButtonData {
+ wmWindowManager *wm;
wmWindow *window;
ARegion *region;
@@ -3677,7 +3678,7 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
data= but->active;
if(data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
}
if(data->tooltip) {
@@ -3686,7 +3687,7 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
}
if(data->autoopentimer) {
- WM_event_remove_window_timer(data->window, data->autoopentimer);
+ WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
data->autoopentimer= NULL;
}
}
@@ -3698,13 +3699,13 @@ static void button_tooltip_timer_reset(uiBut *but)
data= but->active;
if(data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
}
if(U.flag & USER_TOOLTIPS)
if(!but->block->tooltipdisabled)
- data->tooltiptimer= WM_event_add_window_timer(data->window, TIMER, BUTTON_TOOLTIP_DELAY);
+ data->tooltiptimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_TOOLTIP_DELAY);
}
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state)
@@ -3732,7 +3733,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
else time= -1;
if(time >= 0)
- data->autoopentimer= WM_event_add_window_timer(data->window, TIMER, 0.02*(double)time);
+ data->autoopentimer= WM_event_add_timer(data->wm, data->window, TIMER, 0.02*(double)time);
}
}
}
@@ -3765,10 +3766,10 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
/* add a short delay before exiting, to ensure there is some feedback */
if(state == BUTTON_STATE_WAIT_FLASH) {
- data->flashtimer= WM_event_add_window_timer(data->window, TIMER, BUTTON_FLASH_DELAY);
+ data->flashtimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_FLASH_DELAY);
}
else if(data->flashtimer) {
- WM_event_remove_window_timer(data->window, data->flashtimer);
+ WM_event_remove_timer(data->wm, data->window, data->flashtimer);
data->flashtimer= NULL;
}
@@ -3799,6 +3800,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
/* setup struct */
data= MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
+ data->wm= CTX_wm_manager(C);
data->window= CTX_wm_window(C);
data->region= ar;
if( ELEM(but->type, BUT_CURVE, SEARCH_MENU) ); // XXX curve is temp
@@ -4036,7 +4038,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
case TIMER: {
/* handle tooltip timer */
if(event->customdata == data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
if(!data->tooltip)
@@ -4044,7 +4046,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
}
/* handle menu auto open timer */
else if(event->customdata == data->autoopentimer) {
- WM_event_remove_window_timer(data->window, data->autoopentimer);
+ WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
data->autoopentimer= NULL;
if(ui_mouse_inside_button(ar, but, event->x, event->y))
@@ -4058,7 +4060,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
case MIDDLEMOUSE:
/* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
if(data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
}
/* pass on purposedly */
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 2123b412d61..20cd6ebf971 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1189,7 +1189,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
pa->flag |= PNL_SELECT;
if(data && data->animtimer) {
- WM_event_remove_window_timer(win, data->animtimer);
+ WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer);
data->animtimer= NULL;
}
@@ -1208,7 +1208,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
}
if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG))
- data->animtimer= WM_event_add_window_timer(win, TIMER, ANIMATION_INTERVAL);
+ data->animtimer= WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL);
data->state= state;
data->startx= win->eventstate->x;
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 2cc5500c3ef..6b71ccaba10 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1040,7 +1040,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
/* wake up animtimer */
if(win->screen->animtimer)
- WM_event_window_timer_sleep(win, win->screen->animtimer, 0);
+ WM_event_timer_sleep(wm, win, win->screen->animtimer, 0);
if(G.f & G_DEBUG) printf("set screen\n");
win->screen->do_refresh= 0;
@@ -1097,6 +1097,7 @@ void ED_area_exit(bContext *C, ScrArea *sa)
void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *prevwin= CTX_wm_window(C);
ScrArea *sa;
ARegion *ar;
@@ -1104,7 +1105,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
CTX_wm_window_set(C, window);
if(screen->animtimer)
- WM_event_remove_window_timer(window, screen->animtimer);
+ WM_event_remove_timer(wm, window, screen->animtimer);
screen->animtimer= NULL;
if(screen->mainwin)
@@ -1232,6 +1233,7 @@ int ED_screen_area_active(const bContext *C)
/* Do NOT call in area/region queues! */
void ED_screen_set(bContext *C, bScreen *sc)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
bScreen *oldscreen= CTX_wm_screen(C);
ID *id;
@@ -1264,7 +1266,7 @@ void ED_screen_set(bContext *C, bScreen *sc)
/* we put timer to sleep, so screen_exit has to think there's no timer */
oldscreen->animtimer= NULL;
if(wt)
- WM_event_window_timer_sleep(win, wt, 1);
+ WM_event_timer_sleep(wm, win, wt, 1);
ED_screen_exit(C, win, oldscreen);
oldscreen->animtimer= wt;
@@ -1519,17 +1521,18 @@ void ED_screen_full_prevspace(bContext *C)
void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable)
{
bScreen *screen= CTX_wm_screen(C);
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
Scene *scene= CTX_data_scene(C);
if(screen->animtimer)
- WM_event_remove_window_timer(win, screen->animtimer);
+ WM_event_remove_timer(wm, win, screen->animtimer);
screen->animtimer= NULL;
if(enable) {
struct ScreenAnimData *sad= MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData");
- screen->animtimer= WM_event_add_window_timer(win, TIMER0, (1.0/FPS));
+ screen->animtimer= WM_event_add_timer(wm, win, TIMER0, (1.0/FPS));
sad->ar= CTX_wm_region(C);
sad->redraws= redraws;
sad->flag |= (enable < 0)? ANIMPLAY_FLAG_REVERSE: 0;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 7596191e781..21651afe417 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -4645,7 +4645,7 @@ static void paint_exit(bContext *C, wmOperator *op)
PaintOperation *pop= op->customdata;
if(pop->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), pop->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pop->timer);
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
imapaint_canvas_free(&pop->s);
@@ -4757,7 +4757,7 @@ static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
WM_event_add_modal_handler(C, op);
if(pop->s.brush->flag & BRUSH_AIRBRUSH)
- pop->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+ pop->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index b83352ae70c..6e256bee7f2 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -243,7 +243,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_smooth_stroke, stroke);
if(stroke->brush->flag & BRUSH_AIRBRUSH)
- stroke->timer = WM_event_add_window_timer(CTX_wm_window(C), TIMER, stroke->brush->rate);
+ stroke->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, stroke->brush->rate);
}
ED_region_tag_redraw(ar);
@@ -270,7 +270,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
WM_paint_cursor_end(CTX_wm_manager(C), stroke->smooth_stroke_cursor);
if(stroke->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), stroke->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), stroke->timer);
stroke->done(C, stroke);
MEM_freeN(stroke);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 77a1b671054..2a1bb8b4add 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -610,7 +610,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
}
if (!sfile->loadimage_timer)
- sfile->loadimage_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frames/sec. */
+ sfile->loadimage_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frames/sec. */
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 482750e5b2e..ffc737eb9af 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1680,7 +1680,7 @@ static void record_composite_exit(bContext *C, wmOperator *op)
WM_cursor_restore(CTX_wm_window(C));
if(rcd->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), rcd->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rcd->timer);
WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, sima->image);
@@ -1711,7 +1711,7 @@ static int record_composite_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
rcd= op->customdata;
- rcd->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.0f);
+ rcd->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.0f);
WM_event_add_modal_handler(C, op);
if(!record_composite_apply(C, op))
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index ae496158a46..12654bdac14 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -292,9 +292,9 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo
rv3d->sms= MEM_mallocN(sizeof(struct SmoothViewStore), "smoothview v3d");
*rv3d->sms= sms;
if(rv3d->smooth_timer)
- WM_event_remove_window_timer(CTX_wm_window(C), rv3d->smooth_timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
/* TIMER1 is hardcoded in keymap */
- rv3d->smooth_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frs/sec */
+ rv3d->smooth_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frs/sec */
return;
}
@@ -346,7 +346,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event)
MEM_freeN(rv3d->sms);
rv3d->sms= NULL;
- WM_event_remove_window_timer(CTX_wm_window(C), rv3d->smooth_timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
rv3d->smooth_timer= NULL;
}
else {
@@ -1798,7 +1798,7 @@ int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f;
- fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+ fly->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
/* we have to rely on events to give proper mousecoords after a warp_pointer */
@@ -1867,7 +1867,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
if(fly->state == FLY_RUNNING)
return OPERATOR_RUNNING_MODAL;
- WM_event_remove_window_timer(CTX_wm_window(C), fly->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer);
rv3d->dist= fly->dist_backup;
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index c7258e616fa..019ac33dfd0 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -303,7 +303,7 @@ static void minimize_stretch_exit(bContext *C, wmOperator *op, int cancel)
if(sa)
ED_area_headerprint(sa, NULL);
if(ms->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), ms->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ms->timer);
if(cancel)
param_flush_restore(ms->handle);
@@ -343,7 +343,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *event)
ms= op->customdata;
WM_event_add_modal_handler(C, op);
- ms->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+ ms->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/makesdna/DNA_fileglobal_types.h b/source/blender/makesdna/DNA_fileglobal_types.h
index 43ab895b398..271c8d2a33e 100644
--- a/source/blender/makesdna/DNA_fileglobal_types.h
+++ b/source/blender/makesdna/DNA_fileglobal_types.h
@@ -47,6 +47,9 @@ typedef struct FileGlobal {
struct Scene *curscene;
int fileflags;
int globalf;
+
+ /* file path where this was saved, for recover */
+ char filename[240]; /* 240 = FILE_MAX */
} FileGlobal;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 7a024e35ff0..5cdd74c8262 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -124,6 +124,9 @@ typedef struct wmWindowManager {
ListBase keyconfigs; /* known key configurations */
struct wmKeyConfig *defaultconf; /* default configuration, not saved */
int defaultactmap, pad2; /* active keymap from default for editing */
+
+ ListBase timers; /* active timers */
+ struct wmTimer *autosavetimer; /* timer for auto save */
} wmWindowManager;
/* wmWindowManager.initialized */
@@ -160,8 +163,6 @@ typedef struct wmWindow {
int drawmethod, drawfail; /* internal for wm_draw.c only */
void *drawdata; /* internal for wm_draw.c only */
- ListBase timers;
-
ListBase queue; /* all events (ghost level events were handled) */
ListBase handlers; /* window+screen handlers, handled last */
ListBase modalhandlers; /* priority handlers, handled first */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 1acf3c8effa..f9192a9473e 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -146,7 +146,11 @@ static void rna_UserDef_weight_color_update(bContext *C, PointerRNA *ptr)
rna_userdef_update(C, ptr);
}
-
+static void rna_userdef_autosave_update(bContext *C, PointerRNA *ptr)
+{
+ WM_autosave_init(C);
+ rna_userdef_update(C, ptr);
+}
#else
@@ -2344,11 +2348,13 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
prop= RNA_def_property(srna, "auto_save_temporary_files", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_AUTOSAVE);
RNA_def_property_ui_text(prop, "Auto Save Temporary Files", "Automatic saving of temporary files.");
+ RNA_def_property_update(prop, 0, "rna_userdef_autosave_update");
prop= RNA_def_property(srna, "auto_save_time", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "savetime");
RNA_def_property_range(prop, 1, 60);
RNA_def_property_ui_text(prop, "Auto Save Time", "The time (in minutes) to wait between automatic temporary saves.");
+ RNA_def_property_update(prop, 0, "rna_userdef_autosave_update");
prop= RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 2189412783a..e2e50b695fd 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -93,7 +93,6 @@ EnumPropertyItem event_timer_type_items[]= {
{TIMER0, "TIMER0", 0, "Timer 0", ""},
{TIMER1, "TIMER1", 0, "Timer 1", ""},
{TIMER2, "TIMER2", 0, "Timer 2", ""},
- {TIMERJOBS, "JOBS_TIMER", 0, "Jobs Timer", ""},
{0, NULL, 0, NULL, NULL}};
/* not returned: CAPSLOCKKEY, UNKNOWNKEY, GRLESSKEY */
@@ -229,7 +228,6 @@ EnumPropertyItem event_type_items[] = {
{TIMER0, "TIMER0", 0, "Timer 0", ""},
{TIMER1, "TIMER1", 0, "Timer 1", ""},
{TIMER2, "TIMER2", 0, "Timer 2", ""},
- {TIMERJOBS, "JOBS_TIMER", 0, "Jobs Timer", ""},
{0, NULL, 0, NULL, NULL}};
#define KMI_TYPE_KEYBOARD 0
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 59f3bcd4edc..224338e557a 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -67,9 +67,9 @@ void WM_window_open_temp (struct bContext *C, struct rcti *position, int type);
int WM_read_homefile (struct bContext *C, struct wmOperator *op);
int WM_write_homefile (struct bContext *C, struct wmOperator *op);
void WM_read_file (struct bContext *C, char *name, struct ReportList *reports);
-void WM_write_file (struct bContext *C, char *target, int compress, struct ReportList *reports);
+void WM_write_file (struct bContext *C, char *target, int fileflags, struct ReportList *reports);
void WM_read_autosavefile(struct bContext *C);
-void WM_write_autosave (struct bContext *C);
+void WM_autosave_init (struct bContext *C);
/* mouse cursors */
void WM_cursor_set (struct wmWindow *win, int curs);
@@ -141,9 +141,9 @@ void WM_main_add_notifier(unsigned int type, void *reference);
void wm_event_add (struct wmWindow *win, struct wmEvent *event_to_add); /* XXX only for warning */
/* at maximum, every timestep seconds it triggers event_type events */
-struct wmTimer *WM_event_add_window_timer(struct wmWindow *win, int event_type, double timestep);
-void WM_event_remove_window_timer(struct wmWindow *win, struct wmTimer *timer);
-void WM_event_window_timer_sleep(struct wmWindow *win, struct wmTimer *timer, int dosleep);
+struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep);
+void WM_event_remove_timer(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer);
+void WM_event_timer_sleep(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer, int dosleep);
/* operator api, default callbacks */
/* invoke callback, uses enum property named "type" */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 31cb5ee0832..0ef7e9670dc 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -289,6 +289,9 @@ typedef struct wmTabletData {
typedef struct wmTimer {
struct wmTimer *next, *prev;
+
+ struct wmWindow *win; /* window this timer is attached to (optional) */
+
double timestep; /* set by timer user */
int event_type; /* set by timer user, goes to event system */
void *customdata; /* set by timer user, to allow custom values */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index f4baa42515c..1d173005d85 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -209,8 +209,10 @@ void wm_check(bContext *C)
if(wm->windows.first==NULL) return;
/* case: fileread */
- if((wm->initialized & WM_INIT_WINDOW) == 0)
+ if((wm->initialized & WM_INIT_WINDOW) == 0) {
WM_keymap_init(C);
+ WM_autosave_init(C);
+ }
/* case: no open windows at all, for old file reads */
wm_window_add_ghostwindows(wm);
@@ -269,12 +271,15 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
wmWindow *win;
wmOperator *op;
wmKeyConfig *keyconf;
-
+
+ if(wm->autosavetimer)
+ wm_autosave_timer_ended(wm);
+
while((win= wm->windows.first)) {
BLI_remlink(&wm->windows, win);
win->screen= NULL; /* prevent draw clear to use screen */
wm_draw_window_clear(win);
- wm_window_free(C, win);
+ wm_window_free(C, wm, win);
}
while((op= wm->operators.first)) {
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 93ecd4076a3..e7c04141ad3 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -44,6 +44,8 @@
#include "ED_screen.h"
+#include "GPU_extensions.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 8eca0a1b416..f301a20a7c1 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -791,7 +791,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
static int wm_event_always_pass(wmEvent *event)
{
/* some events we always pass on, to ensure proper communication */
- return ELEM5(event->type, TIMER, TIMER0, TIMER1, TIMER2, TIMERJOBS);
+ return ELEM4(event->type, TIMER, TIMER0, TIMER1, TIMER2);
}
/* operator exists */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index ff0e69b74d4..b2e55c8532e 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -95,6 +95,7 @@
#include "WM_types.h"
#include "wm.h"
#include "wm_window.h"
+#include "wm_event_system.h"
static void writeBlog(void);
@@ -348,49 +349,6 @@ int WM_read_homefile(bContext *C, wmOperator *op)
}
-static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
-{
- char pidstr[32];
-#ifdef WIN32
- char subdir[9];
- char savedir[FILE_MAXDIR];
-#endif
-
- sprintf(pidstr, "%d.blend", abs(getpid()));
-
-#ifdef WIN32
- if (!BLI_exists(U.tempdir)) {
- BLI_strncpy(subdir, "autosave", sizeof(subdir));
- BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
-
- /* create a new autosave dir
- * function already checks for existence or not */
- BLI_recurdir_fileops(savedir);
-
- BLI_make_file_string("/", buf, savedir, pidstr);
- return;
- }
-#endif
-
- BLI_make_file_string("/", buf, U.tempdir, pidstr);
-}
-
-void WM_read_autosavefile(bContext *C)
-{
- char tstr[FILE_MAX], scestr[FILE_MAX];
- int save_over;
-
- BLI_strncpy(scestr, G.sce, FILE_MAX); /* temporal store */
-
- get_autosave_location(tstr);
-
- save_over = G.save_over;
- BKE_read_file(C, tstr, NULL, NULL);
- G.save_over = save_over;
- BLI_strncpy(G.sce, scestr, FILE_MAX);
-}
-
-
void read_Blog(void)
{
char name[FILE_MAX];
@@ -496,10 +454,10 @@ static void do_history(char *name, ReportList *reports)
BKE_report(reports, RPT_ERROR, "Unable to make version backup");
}
-void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
+void WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports)
{
Library *li;
- int writeflags, len;
+ int len;
char di[FILE_MAX];
len = strlen(target);
@@ -537,20 +495,14 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
do_history(di, reports);
- writeflags= G.fileflags;
-
- /* set compression flag */
- if(compress) writeflags |= G_FILE_COMPRESS;
- else writeflags &= ~G_FILE_COMPRESS;
-
- if (BLO_write_file(CTX_data_main(C), di, writeflags, reports)) {
+ if (BLO_write_file(CTX_data_main(C), di, fileflags, reports)) {
strcpy(G.sce, di);
G.relbase_valid = 1;
strcpy(G.main->name, di); /* is guaranteed current file */
G.save_over = 1; /* disable untitled.blend convention */
- if(compress) G.fileflags |= G_FILE_COMPRESS;
+ if(fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS;
else G.fileflags &= ~G_FILE_COMPRESS;
writeBlog();
@@ -562,56 +514,125 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
/* operator entry */
int WM_write_homefile(bContext *C, wmOperator *op)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
char tstr[FILE_MAXDIR+FILE_MAXFILE];
- int write_flags;
+ int fileflags;
/* check current window and close it if temp */
- if(win->screen->full == SCREENTEMP) {
- wm_window_close(C, win);
- }
+ if(win->screen->full == SCREENTEMP)
+ wm_window_close(C, wm, win);
BLI_make_file_string("/", tstr, BLI_gethome(), ".B25.blend");
/* force save as regular blend file */
- write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
+ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
- BLO_write_file(CTX_data_main(C), tstr, write_flags, op->reports);
+ BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports);
G.save_over= 0;
return OPERATOR_FINISHED;
}
-void WM_write_autosave(bContext *C)
+/************************ autosave ****************************/
+
+void wm_autosave_location(char *filename)
{
- char tstr[FILE_MAXDIR+FILE_MAXFILE];
- int write_flags;
+ char pidstr[32];
+#ifdef WIN32
+ char subdir[9];
+ char savedir[FILE_MAXDIR];
+#endif
+
+ sprintf(pidstr, "%d.blend", abs(getpid()));
+
+#ifdef WIN32
+ if (!BLI_exists(U.tempdir)) {
+ BLI_strncpy(subdir, "autosave", sizeof(subdir));
+ BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
+
+ /* create a new autosave dir
+ * function already checks for existence or not */
+ BLI_recurdir_fileops(savedir);
+
+ BLI_make_file_string("/", filename, savedir, pidstr);
+ return;
+ }
+#endif
- get_autosave_location(tstr);
+ BLI_make_file_string("/", filename, U.tempdir, pidstr);
+}
- /* force save as regular blend file */
- write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
+void WM_autosave_init(bContext *C)
+{
+ wmWindowManager *wm= CTX_wm_manager(C);
+ wm_autosave_timer_ended(wm);
- /* error reporting to console */
- BLO_write_file(CTX_data_main(C), tstr, write_flags, NULL);
+ if(U.flag & USER_AUTOSAVE)
+ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0);
}
-/* if global undo; remove tempsave, otherwise rename */
-void delete_autosave(void)
+void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
{
- char tstr[FILE_MAXDIR+FILE_MAXFILE];
+ wmWindow *win;
+ wmEventHandler *handler;
+ char filename[FILE_MAX];
+ int fileflags;
+
+ WM_event_remove_timer(wm, NULL, wm->autosavetimer);
+
+ /* if a modal operator is running, don't autosave, but try again in 10 seconds */
+ for(win=wm->windows.first; win; win=win->next) {
+ for(handler=win->modalhandlers.first; handler; handler=handler->next) {
+ if(handler->op) {
+ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0);
+ return;
+ }
+ }
+ }
- get_autosave_location(tstr);
+ wm_autosave_location(filename);
+
+ /* force save as regular blend file */
+ fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_LOCK|G_FILE_SIGN);
+
+ /* no error reporting to console */
+ BLO_write_file(CTX_data_main(C), filename, fileflags, NULL);
- if (BLI_exists(tstr)) {
+ /* do timer after file write, just in case file write takes a long time */
+ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0);
+}
+
+void wm_autosave_timer_ended(wmWindowManager *wm)
+{
+ if(wm->autosavetimer) {
+ WM_event_remove_timer(wm, NULL, wm->autosavetimer);
+ wm->autosavetimer= NULL;
+ }
+}
+
+void wm_autosave_delete(void)
+{
+ char filename[FILE_MAX];
+
+ wm_autosave_location(filename);
+
+ if(BLI_exists(filename)) {
char str[FILE_MAXDIR+FILE_MAXFILE];
BLI_make_file_string("/", str, U.tempdir, "quit.blend");
- if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
- else BLI_rename(tstr, str);
+ /* if global undo; remove tempsave, otherwise rename */
+ if(U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0);
+ else BLI_rename(filename, str);
}
}
-/***/
+void wm_autosave_read(bContext *C, ReportList *reports)
+{
+ char filename[FILE_MAX];
+
+ wm_autosave_location(filename);
+ WM_read_file(C, filename, reports);
+}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 2e456669cb1..8097822acbc 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -283,7 +283,7 @@ void WM_exit(bContext *C)
printf("Error Totblock: %d\n", MEM_get_memory_blocks_in_use());
MEM_printmemlist();
}
-// delete_autosave();
+ wm_autosave_delete();
printf("\nBlender quit\n");
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 498306484e9..c2ecf0c59e7 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -255,7 +255,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
/* restarted job has timer already */
if(steve->wt==NULL)
- steve->wt= WM_event_add_window_timer(steve->win, TIMERJOBS, steve->timestep);
+ steve->wt= WM_event_add_timer(wm, steve->win, TIMERJOBS, steve->timestep);
}
else printf("job fails, not initialized\n");
}
@@ -271,7 +271,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *steve)
}
if(steve->wt)
- WM_event_remove_window_timer(steve->win, steve->wt);
+ WM_event_remove_timer(wm, steve->win, steve->wt);
if(steve->customdata)
steve->free(steve->customdata);
if(steve->run_customdata)
@@ -317,14 +317,13 @@ void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
}
/* hardcoded to event TIMERJOBS */
-static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
+void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
{
- wmWindowManager *wm= CTX_wm_manager(C);
wmJob *steve= wm->jobs.first;
for(; steve; steve= steve->next) {
- if(evt->customdata==steve->wt) {
+ if(steve->wt==wt) {
/* running threads */
if(steve->threads.first) {
@@ -358,7 +357,7 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
WM_jobs_start(wm, steve);
}
else {
- WM_event_remove_window_timer(steve->win, steve->wt);
+ WM_event_remove_timer(wm, steve->win, steve->wt);
steve->wt= NULL;
/* remove steve */
@@ -370,23 +369,7 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
else if(steve->suspended) {
WM_jobs_start(wm, steve);
}
-
- return OPERATOR_FINISHED;
}
}
- return OPERATOR_PASS_THROUGH;
}
-void WM_OT_jobs_timer(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Jobs timer";
- ot->idname= "WM_OT_jobs_timer";
- ot->description="Jobs timer operator.";
-
- /* api callbacks */
- ot->invoke= wm_jobs_timer;
-
- ot->poll= ED_operator_screenactive;
-
-}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index cc5967ab23a..7a97ebf0de7 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -972,7 +972,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
WM_read_file(C, path, op->reports);
- return 0;
+ return OPERATOR_FINISHED;
}
static void WM_OT_open_mainfile(wmOperatorType *ot)
@@ -1154,12 +1154,9 @@ static void WM_OT_link_append(wmOperatorType *ot)
static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
{
- char scestr[FILE_MAX], filename[FILE_MAX];
- int save_over;
+ char filename[FILE_MAX];
- /* back up some values */
- BLI_strncpy(scestr, G.sce, sizeof(scestr));
- save_over = G.save_over;
+ G.fileflags |= G_FILE_RECOVER;
// XXX wm in context is not set correctly after WM_read_file -> crash
// do it before for now, but is this correct with multiple windows?
@@ -1169,11 +1166,9 @@ static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
BLI_make_file_string("/", filename, btempdir, "quit.blend");
WM_read_file(C, filename, op->reports);
- /* restore */
- G.save_over = save_over;
- BLI_strncpy(G.sce, scestr, sizeof(G.sce));
+ G.fileflags &= ~G_FILE_RECOVER;
- return 0;
+ return OPERATOR_FINISHED;
}
static void WM_OT_recover_last_session(wmOperatorType *ot)
@@ -1186,6 +1181,52 @@ static void WM_OT_recover_last_session(wmOperatorType *ot)
ot->poll= WM_operator_winactive;
}
+/* *************** recover auto save **************** */
+
+static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
+{
+ char path[FILE_MAX];
+
+ RNA_string_get(op->ptr, "path", path);
+
+ G.fileflags |= G_FILE_RECOVER;
+
+ // XXX wm in context is not set correctly after WM_read_file -> crash
+ // do it before for now, but is this correct with multiple windows?
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ /* load file */
+ WM_read_file(C, path, op->reports);
+
+ G.fileflags &= ~G_FILE_RECOVER;
+
+ return OPERATOR_FINISHED;
+}
+
+static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ char filename[FILE_MAX];
+
+ wm_autosave_location(filename);
+ RNA_string_set(op->ptr, "path", filename);
+ WM_event_add_fileselect(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void WM_OT_recover_auto_save(wmOperatorType *ot)
+{
+ ot->name= "Recover Auto Save";
+ ot->idname= "WM_OT_recover_auto_save";
+ ot->description="Open an automatically saved file to recover it.";
+
+ ot->exec= wm_recover_auto_save_exec;
+ ot->invoke= wm_recover_auto_save_invoke;
+ ot->poll= WM_operator_winactive;
+
+ WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER);
+}
+
/* *************** save file as **************** */
static void untitled(char *name)
@@ -1229,10 +1270,9 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even
static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
{
char path[FILE_MAX];
- int compress;
+ int fileflags;
save_set_compress(op);
- compress= RNA_boolean_get(op->ptr, "compress");
if(RNA_property_is_set(op->ptr, "path"))
RNA_string_get(op->ptr, "path", path);
@@ -1241,7 +1281,15 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
untitled(path);
}
- WM_write_file(C, path, compress, op->reports);
+ fileflags= G.fileflags;
+
+ /* set compression flag */
+ if(RNA_boolean_get(op->ptr, "compress"))
+ fileflags |= G_FILE_COMPRESS;
+ else
+ fileflags &= ~G_FILE_COMPRESS;
+
+ WM_write_file(C, path, fileflags, op->reports);
WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL);
@@ -2173,7 +2221,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_open_mainfile);
WM_operatortype_append(WM_OT_link_append);
WM_operatortype_append(WM_OT_recover_last_session);
- WM_operatortype_append(WM_OT_jobs_timer);
+ WM_operatortype_append(WM_OT_recover_auto_save);
WM_operatortype_append(WM_OT_save_as_mainfile);
WM_operatortype_append(WM_OT_save_mainfile);
WM_operatortype_append(WM_OT_redraw_timer);
@@ -2188,9 +2236,6 @@ void wm_window_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0);
wmKeyMapItem *km;
- /* items to make WM work */
- WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0);
-
/* note, this doesn't replace existing keymap items */
WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
#ifdef __APPLE__
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index f7116a2bd1f..70d40df4532 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -130,37 +130,39 @@ static void wm_ghostwindow_destroy(wmWindow *win)
/* including window itself, C can be NULL.
ED_screen_exit should have been called */
-void wm_window_free(bContext *C, wmWindow *win)
+void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmTimer *wt, *wtnext;
/* update context */
if(C) {
- wmWindowManager *wm= CTX_wm_manager(C);
-
- if(wm->windrawable==win)
- wm->windrawable= NULL;
- if(wm->winactive==win)
- wm->winactive= NULL;
- if(CTX_wm_window(C)==win)
- CTX_wm_window_set(C, NULL);
-
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
- /* end running jobs, a job end also removes its timer */
- for(wt= win->timers.first; wt; wt= wtnext) {
- wtnext= wt->next;
- if(wt->event_type==TIMERJOBS)
- wm_jobs_timer_ended(wm, wt);
- }
+ if(CTX_wm_window(C)==win)
+ CTX_wm_window_set(C, NULL);
}
-
- if(win->eventstate) MEM_freeN(win->eventstate);
+
+ if(wm->windrawable==win)
+ wm->windrawable= NULL;
+ if(wm->winactive==win)
+ wm->winactive= NULL;
+
+ /* end running jobs, a job end also removes its timer */
+ for(wt= wm->timers.first; wt; wt= wtnext) {
+ wtnext= wt->next;
+ if(wt->win==win && wt->event_type==TIMERJOBS)
+ wm_jobs_timer_ended(wm, wt);
+ }
/* timer removing, need to call this api function */
- while((wt= win->timers.first))
- WM_event_remove_window_timer(win, wt);
+ for(wt= wm->timers.first; wt; wt=wtnext) {
+ wtnext= wt->next;
+ if(wt->win==win)
+ WM_event_remove_timer(wm, win, wt);
+ }
+
+ if(win->eventstate) MEM_freeN(win->eventstate);
wm_event_free_all(win);
wm_subwindows_free(win);
@@ -223,14 +225,13 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
}
/* this is event from ghost, or exit-blender op */
-void wm_window_close(bContext *C, wmWindow *win)
+void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
- wmWindowManager *wm= CTX_wm_manager(C);
BLI_remlink(&wm->windows, win);
wm_draw_window_clear(win);
ED_screen_exit(C, win, win->screen);
- wm_window_free(C, win);
+ wm_window_free(C, wm, win);
/* check remaining windows */
if(wm->windows.first) {
@@ -544,6 +545,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win)
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
{
bContext *C= private;
+ wmWindowManager *wm= CTX_wm_manager(C);
GHOST_TEventType type= GHOST_GetEventType(evt);
if (type == GHOST_kEventQuit) {
@@ -576,7 +578,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
GHOST_TEventKeyData kdata;
int cx, cy, wx, wy;
- CTX_wm_manager(C)->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */
+ wm->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */
win->active= 1;
// window_handle(win, INPUTCHANGE, win->active);
@@ -619,7 +621,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
break;
}
case GHOST_kEventWindowClose: {
- wm_window_close(C, win);
+ wm_window_close(C, wm, win);
break;
}
case GHOST_kEventWindowUpdate: {
@@ -719,22 +721,29 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
static int wm_window_timer(const bContext *C)
{
wmWindowManager *wm= CTX_wm_manager(C);
+ wmTimer *wt, *wtnext;
wmWindow *win;
double time= PIL_check_seconds_timer();
int retval= 0;
- for(win= wm->windows.first; win; win= win->next) {
- wmTimer *wt;
- for(wt= win->timers.first; wt; wt= wt->next) {
- if(wt->sleep==0) {
- if(time > wt->ntime) {
+ for(wt= wm->timers.first; wt; wt= wtnext) {
+ wtnext= wt->next; /* in case timer gets removed */
+ win= wt->win;
+
+ if(wt->sleep==0) {
+ if(time > wt->ntime) {
+ wt->delta= time - wt->ltime;
+ wt->duration += wt->delta;
+ wt->ltime= time;
+ wt->ntime= wt->stime + wt->timestep*ceil(wt->duration/wt->timestep);
+
+ if(wt->event_type == TIMERJOBS)
+ wm_jobs_timer(C, wm, wt);
+ else if(wt->event_type == TIMERAUTOSAVE)
+ wm_autosave_timer(C, wm, wt);
+ else if(win) {
wmEvent event= *(win->eventstate);
- wt->delta= time - wt->ltime;
- wt->duration += wt->delta;
- wt->ltime= time;
- wt->ntime= wt->stime + wt->timestep*ceil(wt->duration/wt->timestep);
-
event.type= wt->event_type;
event.custom= EVT_DATA_TIMER;
event.customdata= wt;
@@ -810,19 +819,19 @@ void wm_ghost_exit(void)
/* **************** timer ********************** */
/* to (de)activate running timers temporary */
-void WM_event_window_timer_sleep(wmWindow *win, wmTimer *timer, int dosleep)
+void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *win, wmTimer *timer, int dosleep)
{
wmTimer *wt;
- for(wt= win->timers.first; wt; wt= wt->next)
+ for(wt= wm->timers.first; wt; wt= wt->next)
if(wt==timer)
break;
- if(wt) {
+
+ if(wt)
wt->sleep= dosleep;
- }
}
-wmTimer *WM_event_add_window_timer(wmWindow *win, int event_type, double timestep)
+wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep)
{
wmTimer *wt= MEM_callocN(sizeof(wmTimer), "window timer");
@@ -831,23 +840,24 @@ wmTimer *WM_event_add_window_timer(wmWindow *win, int event_type, double timeste
wt->ntime= wt->ltime + timestep;
wt->stime= wt->ltime;
wt->timestep= timestep;
+ wt->win= win;
- BLI_addtail(&win->timers, wt);
+ BLI_addtail(&wm->timers, wt);
return wt;
}
-void WM_event_remove_window_timer(wmWindow *win, wmTimer *timer)
+void WM_event_remove_timer(wmWindowManager *wm, wmWindow *win, wmTimer *timer)
{
wmTimer *wt;
/* extra security check */
- for(wt= win->timers.first; wt; wt= wt->next)
+ for(wt= wm->timers.first; wt; wt= wt->next)
if(wt==timer)
break;
if(wt) {
- BLI_remlink(&win->timers, wt);
+ BLI_remlink(&wm->timers, wt);
if(wt->customdata)
MEM_freeN(wt->customdata);
MEM_freeN(wt);
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 832558b961f..609b6142640 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -29,6 +29,7 @@
#define WM_H
struct wmWindow;
+struct ReportList;
typedef struct wmPaintCursor {
struct wmPaintCursor *next, *prev;
@@ -64,9 +65,16 @@ void wm_gesture_draw(struct wmWindow *win);
int wm_gesture_evaluate(bContext *C, wmGesture *gesture);
void wm_gesture_tag_redraw(bContext *C);
-/* wm_jobs.h */
-void WM_OT_jobs_timer(struct wmOperatorType *ot);
+/* wm_jobs.c */
+void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt);
void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt);
+/* wm_files.c */
+void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt);
+void wm_autosave_timer_ended(wmWindowManager *wm);
+void wm_autosave_delete(void);
+void wm_autosave_read(bContext *C, struct ReportList *reports);
+void wm_autosave_location(char *filename);
+
#endif /* WM_H */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index b33c4bd14e8..c7588795a15 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -75,6 +75,7 @@
#define TIMER1 0x0112 /* timer event, slot for internal use */
#define TIMER2 0x0113 /* timer event, slot for internal use */
#define TIMERJOBS 0x0114 /* timer event, internal use */
+#define TIMERAUTOSAVE 0x0115 /* timer event, internal use */
/* standard keyboard */
#define AKEY 'a'
@@ -203,7 +204,7 @@
#define ISMOUSE(event) (event >= LEFTMOUSE && event <= WHEELOUTMOUSE)
/* test wether the event is timer event */
-#define ISTIMER(event) (event >= TIMER && event <= TIMERJOBS)
+#define ISTIMER(event) (event >= TIMER && event <= TIMERAUTOSAVE)
/* test wether the event is tweak event */
#define ISTWEAK(event) (event >= EVT_TWEAK_L && event <= EVT_GESTURE)
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 44c31e7cb69..f0a2c0ec9a9 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -36,8 +36,8 @@ void wm_ghost_init (bContext *C);
void wm_ghost_exit(void);
wmWindow *wm_window_new (bContext *C);
-void wm_window_free (bContext *C, wmWindow *win);
-void wm_window_close (bContext *C, wmWindow *win);
+void wm_window_free (bContext *C, wmWindowManager *wm, wmWindow *win);
+void wm_window_close (bContext *C, wmWindowManager *wm, wmWindow *win);
void wm_window_title (wmWindowManager *wm, wmWindow *win);
void wm_window_add_ghostwindows (wmWindowManager *wm);