Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_files.c
index 605a226500f9735ef26c7279d1b74f602631a5d6..221baeadbee874c0872324d3432655874d7016c1 100644 (file)
@@ -69,6 +69,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BKE_appdir.h"
 #include "BKE_utildefines.h"
 
 #include "BKE_appdir.h"
 #include "BKE_utildefines.h"
@@ -77,7 +78,6 @@
 #include "BKE_blendfile.h"
 #include "BKE_blender_undo.h"
 #include "BKE_context.h"
 #include "BKE_blendfile.h"
 #include "BKE_blender_undo.h"
 #include "BKE_context.h"
-#include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
@@ -86,6 +86,7 @@
 #include "BKE_sound.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
 #include "BKE_sound.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
+#include "BKE_workspace.h"
 
 #include "BLO_readfile.h"
 #include "BLO_writefile.h"
 
 #include "BLO_readfile.h"
 #include "BLO_writefile.h"
 #include "BPY_extern.h"
 #endif
 
 #include "BPY_extern.h"
 #endif
 
+#include "DEG_depsgraph.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 #include "wm.h"
 #include "WM_api.h"
 #include "WM_types.h"
 #include "wm.h"
@@ -159,7 +162,7 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist)
                        CTX_wm_window_set(C, win);  /* needed by operator close callbacks */
                        WM_event_remove_handlers(C, &win->handlers);
                        WM_event_remove_handlers(C, &win->modalhandlers);
                        CTX_wm_window_set(C, win);  /* needed by operator close callbacks */
                        WM_event_remove_handlers(C, &win->handlers);
                        WM_event_remove_handlers(C, &win->modalhandlers);
-                       ED_screen_exit(C, win, win->screen);
+                       ED_screen_exit(C, win, WM_window_get_active_screen(win));
                }
        }
        
                }
        }
        
@@ -248,16 +251,23 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
 
                                /* match oldwm to new dbase, only old files */
                                for (wm = oldwmlist->first; wm; wm = wm->id.next) {
 
                                /* match oldwm to new dbase, only old files */
                                for (wm = oldwmlist->first; wm; wm = wm->id.next) {
-                                       
                                        for (win = wm->windows.first; win; win = win->next) {
                                        for (win = wm->windows.first; win; win = win->next) {
+                                               WorkSpace *workspace = WM_window_get_active_workspace(win);
+
                                                /* all windows get active screen from file */
                                                /* all windows get active screen from file */
-                                               if (screen->winid == 0)
-                                                       win->screen = screen;
-                                               else 
-                                                       win->screen = ED_screen_duplicate(win, screen);
-                                               
-                                               BLI_strncpy(win->screenname, win->screen->id.name + 2, sizeof(win->screenname));
-                                               win->screen->winid = win->winid;
+                                               if (screen->winid == 0) {
+                                                       WM_window_set_active_screen(win, workspace, screen);
+                                               }
+                                               else {
+                                                       WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
+                                                       WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(workspace, layout_old, win);
+
+                                                       WM_window_set_active_layout(win, workspace, layout_new);
+                                               }
+
+                                               bScreen *win_screen = WM_window_get_active_screen(win);
+                                               BLI_strncpy(win->screenname, win_screen->id.name + 2, sizeof(win->screenname));
+                                               win_screen->winid = win->winid;
                                        }
                                }
                        }
                                        }
                                }
                        }
@@ -316,10 +326,8 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
 }
 
 /* in case UserDef was read, we re-initialize all, and do versioning */
 }
 
 /* in case UserDef was read, we re-initialize all, and do versioning */
-static void wm_init_userdef(bContext *C, const bool read_userdef_from_memory)
+static void wm_init_userdef(Main *bmain, const bool read_userdef_from_memory)
 {
 {
-       Main *bmain = CTX_data_main(C);
-
        /* versioning is here */
        UI_init_userdef();
        
        /* versioning is here */
        UI_init_userdef();
        
@@ -462,7 +470,7 @@ static void wm_file_read_post(bContext *C, bool is_startup_file)
        CTX_wm_window_set(C, wm->windows.first);
 
        ED_editors_init(C);
        CTX_wm_window_set(C, wm->windows.first);
 
        ED_editors_init(C);
-       DAG_on_visible_update(CTX_data_main(C), true);
+       DEG_on_visible_update(CTX_data_main(C), true);
 
 #ifdef WITH_PYTHON
        if (is_startup_file) {
 
 #ifdef WITH_PYTHON
        if (is_startup_file) {
@@ -579,7 +587,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
 
                if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {
                        /* in case a userdef is read from regular .blend */
 
                if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {
                        /* in case a userdef is read from regular .blend */
-                       wm_init_userdef(C, false);
+                       wm_init_userdef(G.main, false);
                }
                
                if (retval != BKE_BLENDFILE_READ_FAIL) {
                }
                
                if (retval != BKE_BLENDFILE_READ_FAIL) {
@@ -828,7 +836,7 @@ int wm_homefile_read(
        G.fileflags &= ~G_FILE_RELATIVE_REMAP;
        
        /* check userdef before open window, keymaps etc */
        G.fileflags &= ~G_FILE_RELATIVE_REMAP;
        
        /* check userdef before open window, keymaps etc */
-       wm_init_userdef(C, read_userdef_from_memory);
+       wm_init_userdef(CTX_data_main(C), read_userdef_from_memory);
        
        /* match the read WM with current WM */
        wm_window_match_do(C, &wmbase); 
        
        /* match the read WM with current WM */
        wm_window_match_do(C, &wmbase); 
@@ -975,7 +983,7 @@ static void wm_history_file_update(void)
 
 
 /* screen can be NULL */
 
 
 /* screen can be NULL */
-static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **thumb_pt)
+static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, SceneLayer *sl, bScreen *screen, BlendThumbnail **thumb_pt)
 {
        /* will be scaled down, but gives some nice oversampling */
        ImBuf *ibuf;
 {
        /* will be scaled down, but gives some nice oversampling */
        ImBuf *ibuf;
@@ -987,6 +995,10 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **t
        ARegion *ar = NULL;
        View3D *v3d = NULL;
 
        ARegion *ar = NULL;
        View3D *v3d = NULL;
 
+       EvaluationContext eval_ctx;
+
+       CTX_data_eval_ctx(C, &eval_ctx);
+
        /* In case we are given a valid thumbnail data, just generate image from it. */
        if (*thumb_pt) {
                thumb = *thumb_pt;
        /* In case we are given a valid thumbnail data, just generate image from it. */
        if (*thumb_pt) {
                thumb = *thumb_pt;
@@ -1012,14 +1024,14 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **t
        /* gets scaled to BLEN_THUMB_SIZE */
        if (scene->camera) {
                ibuf = ED_view3d_draw_offscreen_imbuf_simple(
        /* gets scaled to BLEN_THUMB_SIZE */
        if (scene->camera) {
                ibuf = ED_view3d_draw_offscreen_imbuf_simple(
-                       scene, scene->camera,
+                       &eval_ctx, scene, sl, scene->camera,
                        BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
                        IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, 0, false, NULL,
                        NULL, NULL, err_out);
        }
        else {
                ibuf = ED_view3d_draw_offscreen_imbuf(
                        BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
                        IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, 0, false, NULL,
                        NULL, NULL, err_out);
        }
        else {
                ibuf = ED_view3d_draw_offscreen_imbuf(
-                       scene, v3d, ar,
+                       &eval_ctx, scene, sl, v3d, ar,
                        BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
                        IB_rect, false, R_ALPHAPREMUL, 0, false, NULL,
                        NULL, NULL, err_out);
                        BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
                        IB_rect, false, R_ALPHAPREMUL, 0, false, NULL,
                        NULL, NULL, err_out);
@@ -1115,7 +1127,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
        /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */
        main_thumb = thumb = CTX_data_main(C)->blen_thumb;
        if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) {
        /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */
        main_thumb = thumb = CTX_data_main(C)->blen_thumb;
        if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) {
-               ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb);
+               ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_data_scene_layer(C), CTX_wm_screen(C), &thumb);
        }
 
        /* operator now handles overwrite checks */
        }
 
        /* operator now handles overwrite checks */
@@ -1370,7 +1382,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
        BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE);
 
        /* check current window and close it if temp */
        BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE);
 
        /* check current window and close it if temp */
-       if (win && win->screen->temp)
+       if (win && WM_window_is_temp_screen(win))
                wm_window_close(C, wm, win);
 
        /* update keymaps in user preferences */
                wm_window_close(C, wm, win);
 
        /* update keymaps in user preferences */
@@ -1505,6 +1517,42 @@ void WM_OT_save_userpref(wmOperatorType *ot)
        ot->exec = wm_userpref_write_exec;
 }
 
        ot->exec = wm_userpref_write_exec;
 }
 
+static int wm_workspace_configuration_file_write_exec(bContext *C, wmOperator *op)
+{
+       Main *bmain = CTX_data_main(C);
+       char filepath[FILE_MAX];
+
+       const char *app_template = U.app_template[0] ? U.app_template : NULL;
+       const char * const cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, app_template);
+       if (cfgdir == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Unable to create workspace configuration file path");
+               return OPERATOR_CANCELLED;
+       }
+
+       BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_WORKSPACES_FILE, NULL);
+       printf("trying to save workspace configuration file at %s ", filepath);
+
+       if (BKE_blendfile_workspace_config_write(bmain, filepath, op->reports) != 0) {
+               printf("ok\n");
+               return OPERATOR_FINISHED;
+       }
+       else {
+               printf("fail\n");
+       }
+
+       return OPERATOR_CANCELLED;
+}
+
+void WM_OT_save_workspace_file(wmOperatorType *ot)
+{
+       ot->name = "Save Workspace Configuration";
+       ot->idname = "WM_OT_save_workspace_file";
+       ot->description = "Save workspaces of the current file as part of the user configuration";
+
+       ot->invoke = WM_operator_confirm;
+       ot->exec = wm_workspace_configuration_file_write_exec;
+}
+
 static int wm_history_file_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
 {
        ED_file_read_bookmarks();
 static int wm_history_file_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
 {
        ED_file_read_bookmarks();