2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2002-10-12 11:37:38 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup wm
|
2014-01-19 23:14:24 +11:00
|
|
|
*
|
2016-04-19 17:08:31 +02:00
|
|
|
* User level access for blend file read/write, file-history and userprefs (including relevant operators).
|
2011-02-25 14:04:21 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
/* placed up here because of crappy
|
|
|
|
* winsock stuff.
|
|
|
|
*/
|
2011-04-12 15:55:38 +00:00
|
|
|
#include <stddef.h>
|
2002-10-12 11:37:38 +00:00
|
|
|
#include <string.h>
|
2010-07-03 17:47:06 +00:00
|
|
|
#include <errno.h>
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2011-05-05 18:50:17 +00:00
|
|
|
#include "zlib.h" /* wm_read_exotic() */
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#ifdef WIN32
|
2019-01-14 16:15:33 +11:00
|
|
|
/* Need to include windows.h so _WIN32_IE is defined. */
|
|
|
|
# include <windows.h>
|
2012-04-15 07:54:07 +00:00
|
|
|
# ifndef _WIN32_IE
|
2019-01-14 16:15:33 +11:00
|
|
|
/* Minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already. */
|
|
|
|
# define _WIN32_IE 0x0400
|
2012-04-15 07:54:07 +00:00
|
|
|
# endif
|
2019-01-14 16:15:33 +11:00
|
|
|
/* For SHGetSpecialFolderPath, has to be done before BLI_winstuff
|
|
|
|
* because 'near' is disabled through BLI_windstuff */
|
|
|
|
# include <shlobj.h>
|
2012-04-15 07:54:07 +00:00
|
|
|
# include "BLI_winstuff.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#endif
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
2006-02-05 19:30:37 +00:00
|
|
|
#include "MEM_CacheLimiterC-Api.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_linklist.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2012-10-05 12:18:07 +00:00
|
|
|
#include "BLI_threads.h"
|
2011-06-24 16:54:30 +00:00
|
|
|
#include "BLI_callbacks.h"
|
2014-04-02 11:43:54 +02:00
|
|
|
#include "BLI_system.h"
|
|
|
|
#include BLI_SYSTEM_PID_H
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2011-06-15 08:28:56 +00:00
|
|
|
|
2018-03-26 14:38:47 +02:00
|
|
|
#include "BLF_api.h"
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_space_types.h"
|
|
|
|
#include "DNA_userdef_types.h"
|
Giant commit!
A full detailed description of this will be done later... is several days
of work. Here's a summary:
Render:
- Full cleanup of render code, removing *all* globals and bad level calls
all over blender. Render module is now not called abusive anymore
- API-fied calls to rendering
- Full recode of internal render pipeline. Is now rendering tiles by
default, prepared for much smarter 'bucket' render later.
- Each thread now can render a full part
- Renders were tested with 4 threads, goes fine, apart from some lookup
tables in softshadow and AO still
- Rendering is prepared to do multiple layers and passes
- No single 32 bits trick in render code anymore, all 100% floats now.
Writing images/movies
- moved writing images to blender kernel (bye bye 'schrijfplaatje'!)
- made a new Movie handle system, also in kernel. This will enable much
easier use of movies in Blender
PreviewRender:
- Using new render API, previewrender (in buttons) now uses regular render
code to generate images.
- new datafile 'preview.blend.c' has the preview scenes in it
- previews get rendered in exact displayed size (1 pixel = 1 pixel)
3D Preview render
- new; press Pkey in 3d window, for a panel that continuously renders
(pkey is for games, i know... but we dont do that in orange now!)
- this render works nearly identical to buttons-preview render, so it stops
rendering on any event (mouse, keyboard, etc)
- on moving/scaling the panel, the render code doesn't recreate all geometry
- same for shifting/panning view
- all other operations (now) regenerate the full render database still.
- this is WIP... but big fun, especially for simple scenes!
Compositor
- Using same node system as now in use for shaders, you can composit images
- works pretty straightforward... needs much more options/tools and integration
with rendering still
- is not threaded yet, nor is so smart to only recalculate changes... will be
done soon!
- the "Render Result" node will get all layers/passes as output sockets
- The "Output" node renders to a builtin image, which you can view in the Image
window. (yes, output nodes to render-result, and to files, is on the list!)
The Bad News
- "Unified Render" is removed. It might come back in some stage, but this
system should be built from scratch. I can't really understand this code...
I expect it is not much needed, especially with advanced layer/passes
control
- Panorama render, Field render, Motion blur, is not coded yet... (I had to
recode every single feature in render, so...!)
- Lens Flare is also not back... needs total revision, might become composit
effect though (using zbuffer for visibility)
- Part render is gone! (well, thats obvious, its default now).
- The render window is only restored with limited functionality... I am going
to check first the option to render to a Image window, so Blender can become
a true single-window application. :)
For example, the 'Spare render buffer' (jkey) doesnt work.
- Render with border, now default creates a smaller image
- No zbuffers are written yet... on the todo!
- Scons files and MSVC will need work to get compiling again
OK... thats what I can quickly recall. Now go compiling!
2006-01-23 22:05:47 +00:00
|
|
|
#include "DNA_scene_types.h"
|
2006-07-04 12:10:37 +00:00
|
|
|
#include "DNA_screen_types.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "DNA_windowmanager_types.h"
|
2017-06-13 12:02:08 +02:00
|
|
|
#include "DNA_workspace_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2014-11-23 14:37:13 +01:00
|
|
|
#include "BKE_appdir.h"
|
2013-06-18 18:11:52 +00:00
|
|
|
#include "BKE_autoexec.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_blender.h"
|
2016-04-24 22:42:41 +10:00
|
|
|
#include "BKE_blendfile.h"
|
|
|
|
#include "BKE_blender_undo.h"
|
2008-12-18 02:56:48 +00:00
|
|
|
#include "BKE_context.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_global.h"
|
|
|
|
#include "BKE_main.h"
|
|
|
|
#include "BKE_packedFile.h"
|
2008-12-19 00:50:21 +00:00
|
|
|
#include "BKE_report.h"
|
2009-08-16 20:37:22 +00:00
|
|
|
#include "BKE_sound.h"
|
2015-10-08 15:56:46 +11:00
|
|
|
#include "BKE_scene.h"
|
2012-04-17 20:51:11 +00:00
|
|
|
#include "BKE_screen.h"
|
2018-03-19 14:17:59 +01:00
|
|
|
#include "BKE_undo_system.h"
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
#include "BKE_workspace.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "BLO_readfile.h"
|
|
|
|
#include "BLO_writefile.h"
|
2018-03-19 14:17:59 +01:00
|
|
|
#include "BLO_undofile.h" /* to save from an undo memfile */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2009-02-07 10:00:46 +00:00
|
|
|
#include "RNA_access.h"
|
2016-04-19 17:08:31 +02:00
|
|
|
#include "RNA_define.h"
|
2009-02-07 10:00:46 +00:00
|
|
|
|
2010-05-24 21:52:18 +00:00
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
#include "IMB_thumbs.h"
|
|
|
|
|
Port of part of the Interface code to 2.50.
This is based on the current trunk version, so these files should not need
merges. There's two things (clipboard and intptr_t) that are missing in 2.50
and commented out with XXX 2.48, these can be enabled again once trunk is
merged into this branch.
Further this is not all interface code, there are many parts commented out:
* interface.c: nearly all button types, missing: links, chartab, keyevent.
* interface_draw.c: almost all code, with some small exceptions.
* interface_ops.c: this replaces ui_do_but and uiDoBlocks with two operators,
making it non-blocking.
* interface_regions: this is a part of interface.c, split off, contains code to
create regions for tooltips, menus, pupmenu (that one is crashing currently),
color chooser, basically regions with buttons which is fairly independent of
core interface code.
* interface_panel.c and interface_icons.c: not ported over, so no panels and
icons yet. Panels should probably become (free floating) regions?
* text.c: (formerly language.c) for drawing text and translation. this works
but is using bad globals still and could be cleaned up.
Header Files:
* ED_datafiles.h now has declarations for datatoc_ files, so those extern
declarations can be #included instead of repeated.
* The user interface code is in UI_interface.h and other UI_* files.
Core:
* The API for creating blocks, buttons, etc is nearly the same still. Blocks
are now created per region instead of per area.
* The code was made non-blocking, which means that any changes and redraws
should be possible while editing a button. That means though that we need
some sort of persistence even though the blender model is to recreate buttons
for each redraw. So when a new block is created, some matching happens to
find out which buttons correspond to buttons in the previously created block,
and for activated buttons some data is then copied over to the new button.
* Added UI_init/UI_init_userdef/UI_exit functions that should initialize code
in this module, instead of multiple function calls in the windowmanager.
* Removed most static/globals from interface.c.
* Removed UIafterfunc_ I don't think it's needed anymore, and not sure how it
would integrate here?
* Currently only full window redraws are used, this should become per region
and maybe per button later.
Operators:
* Events are currently handled through two operators: button activate and menu
handle. Operators may not be the best way to implement this, since there are
currently some issues with events being missed, but they can become a special
handler type instead, this should not be a big change.
* The button activate operator runs as long as a button is active, and will
handle all interaction with that button until the button is not activated
anymore. This means clicking, text editing, number dragging, opening menu
blocks, etc.
* Since this operator has to be non-blocking, the ui_do_but code needed to made
non-blocking. That means variables that were previously on the stack, now
need to be stored away in a struct such that they can be accessed again when
the operator receives more events.
* Additionally the place in the ui_do_but code indicated the state, now that
needs to be set explicit in order to handle the right events in the right
state. So an activated button can be in one of these states: init, highlight,
wait_flash, wait_release, wait_key_event, num_editing, text_editing,
text_selecting, block_open, exit.
* For each button type an ui_apply_but_* function has also been separated out
from ui_do_but. This makes it possible to continuously apply the button as
text is being typed for example, and there is an option in the code to enable
this. Since the code non-blocking and can deal with the button being deleted
even, it should be safe to do this.
* When editing text, dragging numbers, etc, the actual data (but->poin) is not
being edited, since that would mean data is being edited without correct
updates happening, while some other part of blender may be accessing that
data in the meantime. So data values, strings, vectors are written to a
temporary location and only flush in the apply function.
Regions:
* Menus, color chooser, tooltips etc all create screen level regions. Such menu
blocks give a handle to the button that creates it, which will contain the
results of the menu block once a MESSAGE event is received from that menu
block.
* For this type of menu block the coordinates used to be in window space. They
are still created that way and ui_positionblock still works with window
coordinates, but after that the block and buttons are brought back to region
coordinates since these are now contained in a region.
* The flush/overdraw frontbuffer drawing code was removed, the windowmanager
should have enough information with these screen level regions to have full
control over what gets drawn when and to then do correct compositing.
Testing:
* The header in the time space currently has some buttons to test the UI code.
2008-11-11 18:31:32 +00:00
|
|
|
#include "ED_datafiles.h"
|
2013-12-20 17:39:22 +01:00
|
|
|
#include "ED_fileselect.h"
|
2008-11-27 17:58:46 +00:00
|
|
|
#include "ED_screen.h"
|
2010-05-24 21:52:18 +00:00
|
|
|
#include "ED_view3d.h"
|
2009-01-01 13:15:35 +00:00
|
|
|
#include "ED_util.h"
|
2018-04-02 15:02:08 +02:00
|
|
|
#include "ED_undo.h"
|
2008-11-27 17:58:46 +00:00
|
|
|
|
2009-01-23 17:42:36 +00:00
|
|
|
#include "GHOST_C-api.h"
|
2011-01-05 14:56:10 +00:00
|
|
|
#include "GHOST_Path-api.h"
|
2009-01-23 17:42:36 +00:00
|
|
|
|
Port of part of the Interface code to 2.50.
This is based on the current trunk version, so these files should not need
merges. There's two things (clipboard and intptr_t) that are missing in 2.50
and commented out with XXX 2.48, these can be enabled again once trunk is
merged into this branch.
Further this is not all interface code, there are many parts commented out:
* interface.c: nearly all button types, missing: links, chartab, keyevent.
* interface_draw.c: almost all code, with some small exceptions.
* interface_ops.c: this replaces ui_do_but and uiDoBlocks with two operators,
making it non-blocking.
* interface_regions: this is a part of interface.c, split off, contains code to
create regions for tooltips, menus, pupmenu (that one is crashing currently),
color chooser, basically regions with buttons which is fairly independent of
core interface code.
* interface_panel.c and interface_icons.c: not ported over, so no panels and
icons yet. Panels should probably become (free floating) regions?
* text.c: (formerly language.c) for drawing text and translation. this works
but is using bad globals still and could be cleaned up.
Header Files:
* ED_datafiles.h now has declarations for datatoc_ files, so those extern
declarations can be #included instead of repeated.
* The user interface code is in UI_interface.h and other UI_* files.
Core:
* The API for creating blocks, buttons, etc is nearly the same still. Blocks
are now created per region instead of per area.
* The code was made non-blocking, which means that any changes and redraws
should be possible while editing a button. That means though that we need
some sort of persistence even though the blender model is to recreate buttons
for each redraw. So when a new block is created, some matching happens to
find out which buttons correspond to buttons in the previously created block,
and for activated buttons some data is then copied over to the new button.
* Added UI_init/UI_init_userdef/UI_exit functions that should initialize code
in this module, instead of multiple function calls in the windowmanager.
* Removed most static/globals from interface.c.
* Removed UIafterfunc_ I don't think it's needed anymore, and not sure how it
would integrate here?
* Currently only full window redraws are used, this should become per region
and maybe per button later.
Operators:
* Events are currently handled through two operators: button activate and menu
handle. Operators may not be the best way to implement this, since there are
currently some issues with events being missed, but they can become a special
handler type instead, this should not be a big change.
* The button activate operator runs as long as a button is active, and will
handle all interaction with that button until the button is not activated
anymore. This means clicking, text editing, number dragging, opening menu
blocks, etc.
* Since this operator has to be non-blocking, the ui_do_but code needed to made
non-blocking. That means variables that were previously on the stack, now
need to be stored away in a struct such that they can be accessed again when
the operator receives more events.
* Additionally the place in the ui_do_but code indicated the state, now that
needs to be set explicit in order to handle the right events in the right
state. So an activated button can be in one of these states: init, highlight,
wait_flash, wait_release, wait_key_event, num_editing, text_editing,
text_selecting, block_open, exit.
* For each button type an ui_apply_but_* function has also been separated out
from ui_do_but. This makes it possible to continuously apply the button as
text is being typed for example, and there is an option in the code to enable
this. Since the code non-blocking and can deal with the button being deleted
even, it should be safe to do this.
* When editing text, dragging numbers, etc, the actual data (but->poin) is not
being edited, since that would mean data is being edited without correct
updates happening, while some other part of blender may be accessing that
data in the meantime. So data values, strings, vectors are written to a
temporary location and only flush in the apply function.
Regions:
* Menus, color chooser, tooltips etc all create screen level regions. Such menu
blocks give a handle to the button that creates it, which will contain the
results of the menu block once a MESSAGE event is received from that menu
block.
* For this type of menu block the coordinates used to be in window space. They
are still created that way and ui_positionblock still works with window
coordinates, but after that the block and buttons are brought back to region
coordinates since these are now contained in a region.
* The flush/overdraw frontbuffer drawing code was removed, the windowmanager
should have enough information with these screen level regions to have full
control over what gets drawn when and to then do correct compositing.
Testing:
* The header in the time space currently has some buttons to test the UI code.
2008-11-11 18:31:32 +00:00
|
|
|
#include "UI_interface.h"
|
2016-04-19 17:08:31 +02:00
|
|
|
#include "UI_resources.h"
|
2014-01-20 12:43:56 +11:00
|
|
|
#include "UI_view2d.h"
|
Giant commit!
A full detailed description of this will be done later... is several days
of work. Here's a summary:
Render:
- Full cleanup of render code, removing *all* globals and bad level calls
all over blender. Render module is now not called abusive anymore
- API-fied calls to rendering
- Full recode of internal render pipeline. Is now rendering tiles by
default, prepared for much smarter 'bucket' render later.
- Each thread now can render a full part
- Renders were tested with 4 threads, goes fine, apart from some lookup
tables in softshadow and AO still
- Rendering is prepared to do multiple layers and passes
- No single 32 bits trick in render code anymore, all 100% floats now.
Writing images/movies
- moved writing images to blender kernel (bye bye 'schrijfplaatje'!)
- made a new Movie handle system, also in kernel. This will enable much
easier use of movies in Blender
PreviewRender:
- Using new render API, previewrender (in buttons) now uses regular render
code to generate images.
- new datafile 'preview.blend.c' has the preview scenes in it
- previews get rendered in exact displayed size (1 pixel = 1 pixel)
3D Preview render
- new; press Pkey in 3d window, for a panel that continuously renders
(pkey is for games, i know... but we dont do that in orange now!)
- this render works nearly identical to buttons-preview render, so it stops
rendering on any event (mouse, keyboard, etc)
- on moving/scaling the panel, the render code doesn't recreate all geometry
- same for shifting/panning view
- all other operations (now) regenerate the full render database still.
- this is WIP... but big fun, especially for simple scenes!
Compositor
- Using same node system as now in use for shaders, you can composit images
- works pretty straightforward... needs much more options/tools and integration
with rendering still
- is not threaded yet, nor is so smart to only recalculate changes... will be
done soon!
- the "Render Result" node will get all layers/passes as output sockets
- The "Output" node renders to a builtin image, which you can view in the Image
window. (yes, output nodes to render-result, and to files, is on the list!)
The Bad News
- "Unified Render" is removed. It might come back in some stage, but this
system should be built from scratch. I can't really understand this code...
I expect it is not much needed, especially with advanced layer/passes
control
- Panorama render, Field render, Motion blur, is not coded yet... (I had to
recode every single feature in render, so...!)
- Lens Flare is also not back... needs total revision, might become composit
effect though (using zbuffer for visibility)
- Part render is gone! (well, thats obvious, its default now).
- The render window is only restored with limited functionality... I am going
to check first the option to render to a Image window, so Blender can become
a true single-window application. :)
For example, the 'Spare render buffer' (jkey) doesnt work.
- Render with border, now default creates a smaller image
- No zbuffers are written yet... on the todo!
- Scons files and MSVC will need work to get compiling again
OK... thats what I can quickly recall. Now go compiling!
2006-01-23 22:05:47 +00:00
|
|
|
|
2009-02-04 18:02:50 +00:00
|
|
|
#include "GPU_draw.h"
|
|
|
|
|
2015-09-22 13:30:12 +10:00
|
|
|
/* only to report a missing engine */
|
|
|
|
#include "RE_engine.h"
|
|
|
|
|
2010-10-31 04:11:39 +00:00
|
|
|
#ifdef WITH_PYTHON
|
2009-11-20 15:01:09 +00:00
|
|
|
#include "BPY_extern.h"
|
2010-09-12 12:09:31 +00:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2017-04-06 16:44:32 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "WM_api.h"
|
2008-01-01 15:53:38 +00:00
|
|
|
#include "WM_types.h"
|
2017-11-13 19:43:34 +11:00
|
|
|
#include "WM_message.h"
|
2018-05-23 08:20:46 +02:00
|
|
|
#include "WM_toolsystem.h"
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "wm.h"
|
2011-02-14 18:20:10 +00:00
|
|
|
#include "wm_files.h"
|
2009-02-13 13:33:01 +00:00
|
|
|
#include "wm_window.h"
|
2009-10-20 13:58:53 +00:00
|
|
|
#include "wm_event_system.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-08-09 12:53:09 +10:00
|
|
|
static RecentFile *wm_file_history_find(const char *filepath);
|
|
|
|
static void wm_history_file_free(RecentFile *recent);
|
|
|
|
static void wm_history_file_update(void);
|
|
|
|
static void wm_history_file_write(void);
|
|
|
|
|
Essential cleanup for mess involved with reading files, initializing UI and
patching versions for UI settings.
Currently four different levels of routines for .blend file reading exist;
/* interface level */
1) BIF_init() -> calls 3
2) BIF_read_file() -> calls 11, optional 4
3) BIF_read_homefile() -> calls 11 or 12, and then 4
4) init_userdef_file()
/* kernel level */
11) BKE_read_file() -> calls 21, and then 14
12) BKE_read_file_from_memory() -> calls 22, and then 14
13) BKE_read_file_from_memfile() -> calls 23, and then 14
14) setup_app_data()
/* loader module level */
21) BLO_read_from_file() -> calls 24
22) BLO_read_from_memory() -> calls 24
23) BLO_read_from_memfile() -> calls 24
/* loader module, internal */
24) blo_read_file_internal()
Note:
- BIF_read_homefile() has additional UI initialize calls, like windows fullscreen and executing commandline options
- Reading from memory (12) only happens for the compiled-in .B.blend
- The "memfile" here is a name I gave to the undo "file" structure. Which is constructed out of memory chunks with basic compression features.
- the kernel function setup_app_data() sets globals like "current screen" and "current scene".
So far, so good. The levels as mentioned here clearly distinguish UI from kernel, and should enable for example game loading (runtime) or background (no UI) loading. In the past years however, 'bad level' dependencies were added, and especially the patches for 'file versions' were added in too many places. The latter is evidently a result of the problem that the "UserDef" struct cannot be initialized/patched if there's not a need for a UI.
Here's how the flow goes in four different cases:
----- Starting up Blender, in foreground with UI --------------------
- creator/creator.c, main() -> calls 1
- If the commandline contains a filename, it calls 11
----- Starting up Blender, in background without UI --------------------
- creator/creator.c, main() -> calls 11 if the commandline has a filename
Note: no Userdef is read, nor initialized. Please note that this was already an existing problem for using Yafray, not setting proper file paths in background mode. The Yafray paths don't belong in the User menu.
----- Starting up Blender as a runtime executable --------------------
This only has calls to 22
----- Loading a file from within the UI (with F1, CTRL+O, using pulldowns) -----
Only calls allowed to 2. It detects if a UserDef has been read too, and in that case the init_userdef_file() will be executed.
Hope this is understandable :)
-Ton-
2004-12-08 14:12:47 +00:00
|
|
|
|
2012-03-09 18:28:30 +00:00
|
|
|
/* To be able to read files without windows closing, opening, moving
|
|
|
|
* we try to prepare for worst case:
|
|
|
|
* - active window gets active screen from file
|
|
|
|
* - restoring the screens from non-active windows
|
|
|
|
* Best case is all screens match, in that case they get assigned to proper window
|
|
|
|
*/
|
2007-12-24 18:27:28 +00:00
|
|
|
static void wm_window_match_init(bContext *C, ListBase *wmlist)
|
|
|
|
{
|
2011-01-12 03:41:12 +00:00
|
|
|
wmWindowManager *wm;
|
2010-01-13 21:37:13 +00:00
|
|
|
wmWindow *win, *active_win;
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
*wmlist = G_MAIN->wm;
|
|
|
|
BLI_listbase_clear(&G_MAIN->wm);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-01-13 21:37:13 +00:00
|
|
|
active_win = CTX_wm_window(C);
|
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
/* first wrap up running stuff */
|
|
|
|
/* code copied from wm_init_exit.c */
|
2012-03-27 01:24:16 +00:00
|
|
|
for (wm = wmlist->first; wm; wm = wm->id.next) {
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2012-10-29 17:41:19 +00:00
|
|
|
WM_jobs_kill_all(wm);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (win = wm->windows.first; win; win = win->next) {
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
CTX_wm_window_set(C, win); /* needed by operator close callbacks */
|
2009-11-23 11:49:23 +00:00
|
|
|
WM_event_remove_handlers(C, &win->handlers);
|
|
|
|
WM_event_remove_handlers(C, &win->modalhandlers);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
ED_screen_exit(C, win, WM_window_get_active_screen(win));
|
2008-12-21 12:43:34 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-01-13 21:37:13 +00:00
|
|
|
/* reset active window */
|
|
|
|
CTX_wm_window_set(C, active_win);
|
|
|
|
|
2016-03-01 12:40:04 +01:00
|
|
|
/* XXX Hack! We have to clear context menu here, because removing all modalhandlers above frees the active menu
|
|
|
|
* (at least, in the 'startup splash' case), causing use-after-free error in later handling of the button
|
|
|
|
* callbacks in UI code (see ui_apply_but_funcs_after()).
|
|
|
|
* Tried solving this by always NULL-ing context's menu when setting wm/win/etc., but it broke popups refreshing
|
|
|
|
* (see T47632), so for now just handling this specific case here. */
|
|
|
|
CTX_wm_menu_set(C, NULL);
|
|
|
|
|
2019-01-15 21:33:01 +11:00
|
|
|
ED_editors_exit(G_MAIN, true);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
2006-08-20 15:22:56 +00:00
|
|
|
|
2018-07-09 23:33:20 +02:00
|
|
|
static void wm_window_substitute_old(wmWindowManager *oldwm, wmWindowManager *wm, wmWindow *oldwin, wmWindow *win)
|
2014-10-19 20:50:43 +02:00
|
|
|
{
|
|
|
|
win->ghostwin = oldwin->ghostwin;
|
2018-07-18 00:12:21 +02:00
|
|
|
win->gpuctx = oldwin->gpuctx;
|
2014-10-19 20:50:43 +02:00
|
|
|
win->active = oldwin->active;
|
2018-07-09 23:33:20 +02:00
|
|
|
if (win->active) {
|
2014-10-19 20:50:43 +02:00
|
|
|
wm->winactive = win;
|
2018-07-09 23:33:20 +02:00
|
|
|
}
|
|
|
|
if (oldwm->windrawable == oldwin) {
|
|
|
|
oldwm->windrawable = NULL;
|
|
|
|
wm->windrawable = win;
|
|
|
|
}
|
2014-10-19 20:50:43 +02:00
|
|
|
|
|
|
|
if (!G.background) /* file loading in background mode still calls this */
|
|
|
|
GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */
|
|
|
|
|
|
|
|
oldwin->ghostwin = NULL;
|
2018-07-18 00:12:21 +02:00
|
|
|
oldwin->gpuctx = NULL;
|
2014-10-19 20:50:43 +02:00
|
|
|
|
|
|
|
win->eventstate = oldwin->eventstate;
|
|
|
|
oldwin->eventstate = NULL;
|
|
|
|
|
|
|
|
/* ensure proper screen rescaling */
|
|
|
|
win->sizex = oldwin->sizex;
|
|
|
|
win->sizey = oldwin->sizey;
|
|
|
|
win->posx = oldwin->posx;
|
|
|
|
win->posy = oldwin->posy;
|
|
|
|
}
|
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
static void wm_window_match_keep_current_wm(
|
|
|
|
const bContext *C, ListBase *current_wm_list,
|
|
|
|
const bool load_ui,
|
|
|
|
ListBase *r_new_wm_list)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2018-06-06 16:32:09 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2017-11-09 04:57:14 +01:00
|
|
|
wmWindowManager *wm = current_wm_list->first;
|
|
|
|
bScreen *screen = NULL;
|
|
|
|
|
|
|
|
/* match oldwm to new dbase, only old files */
|
|
|
|
wm->initialized &= ~WM_WINDOW_IS_INITIALIZED;
|
|
|
|
|
|
|
|
/* when loading without UI, no matching needed */
|
|
|
|
if (load_ui && (screen = CTX_wm_screen(C))) {
|
|
|
|
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
|
|
|
WorkSpace *workspace;
|
|
|
|
|
2018-06-14 12:42:30 +02:00
|
|
|
BKE_workspace_layout_find_global(bmain, screen, &workspace);
|
2017-11-09 04:57:14 +01:00
|
|
|
BKE_workspace_active_set(win->workspace_hook, workspace);
|
|
|
|
win->scene = CTX_data_scene(C);
|
|
|
|
|
|
|
|
/* all windows get active screen from file */
|
|
|
|
if (screen->winid == 0) {
|
|
|
|
WM_window_set_active_screen(win, workspace, screen);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
2017-11-09 04:57:14 +01:00
|
|
|
else {
|
|
|
|
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
|
2018-06-06 16:32:09 +02:00
|
|
|
WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win);
|
2017-11-08 23:51:30 +01:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
WM_window_set_active_layout(win, workspace, layout_new);
|
|
|
|
}
|
2014-10-19 20:50:43 +02:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
bScreen *win_screen = WM_window_get_active_screen(win);
|
|
|
|
win_screen->winid = win->winid;
|
|
|
|
}
|
|
|
|
}
|
2009-01-27 17:12:40 +00:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
*r_new_wm_list = *current_wm_list;
|
|
|
|
}
|
2011-09-28 19:05:47 +00:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
static void wm_window_match_replace_by_file_wm(
|
|
|
|
bContext *C, ListBase *current_wm_list, ListBase *readfile_wm_list,
|
|
|
|
ListBase *r_new_wm_list)
|
|
|
|
{
|
|
|
|
wmWindowManager *oldwm = current_wm_list->first;
|
|
|
|
wmWindowManager *wm = readfile_wm_list->first; /* will become our new WM */
|
|
|
|
bool has_match = false;
|
KEYMAP REFACTORING
Diff Keymaps
User edited keymaps now no longer override the builtin keymaps entirely, but
rather save only the difference and reapply those changes. This means they can
stay better in sync when the builtin keymaps change. The diff/patch algorithm
is not perfect, but better for the common case where only a few items are changed
rather than entire keymaps The main weakness is that if a builtin keymap item
changes, user modification of that item may need to be redone in some cases.
Keymap Editor
The most noticeable change here is that there is no longer an "Edit" button for
keymaps, all are editable immediately, but a "Restore" buttons shows for keymaps
and items that have been edited. Shortcuts for addons can also be edited in the
keymap editor.
Addons
Addons now should only modify the new addon keyconfiguration, the keymap items
there will be added to the builtin ones for handling events, and not get lost
when starting new files. Example code of register/unregister:
km = wm.keyconfigs.addon.keymaps.new("3D View", space_type="VIEW_3D")
km.keymap_items.new('my.operator', 'ESC', 'PRESS')
km = wm.keyconfigs.addon.keymaps["3D View"]
km.keymap_items.remove(km.keymap_items["my.operator"])
Compatibility
The changes made are not forward compatible, i.e. if you save user preferences
with newer versions, older versions will not have key configuration changes that
were made.
2011-08-05 20:45:26 +00:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
/* this code could move to setup_appdata */
|
2014-10-19 20:50:43 +02:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
/* preserve key configurations in new wm, to preserve their keymaps */
|
|
|
|
wm->keyconfigs = oldwm->keyconfigs;
|
|
|
|
wm->addonconf = oldwm->addonconf;
|
|
|
|
wm->defaultconf = oldwm->defaultconf;
|
|
|
|
wm->userconf = oldwm->userconf;
|
2009-09-28 15:34:15 +00:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
BLI_listbase_clear(&oldwm->keyconfigs);
|
|
|
|
oldwm->addonconf = NULL;
|
|
|
|
oldwm->defaultconf = NULL;
|
|
|
|
oldwm->userconf = NULL;
|
2010-06-26 13:24:52 +00:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
/* ensure making new keymaps and set space types */
|
|
|
|
wm->initialized = 0;
|
|
|
|
wm->winactive = NULL;
|
2014-10-19 20:50:43 +02:00
|
|
|
|
2018-07-23 17:44:16 +02:00
|
|
|
/* Clearing drawable of before deleting any context
|
|
|
|
* to avoid clearing the wrong wm. */
|
|
|
|
wm_window_clear_drawable(oldwm);
|
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
/* only first wm in list has ghostwins */
|
|
|
|
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
|
|
|
for (wmWindow *oldwin = oldwm->windows.first; oldwin; oldwin = oldwin->next) {
|
|
|
|
if (oldwin->winid == win->winid) {
|
|
|
|
has_match = true;
|
2014-10-19 20:50:43 +02:00
|
|
|
|
2018-07-09 23:33:20 +02:00
|
|
|
wm_window_substitute_old(oldwm, wm, oldwin, win);
|
2014-10-19 20:50:43 +02:00
|
|
|
}
|
2017-11-09 04:57:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* make sure at least one window is kept open so we don't lose the context, check T42303 */
|
|
|
|
if (!has_match) {
|
2018-07-09 23:33:20 +02:00
|
|
|
wm_window_substitute_old(oldwm, wm, oldwm->windows.first, wm->windows.first);
|
2017-11-09 04:57:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wm_close_and_free_all(C, current_wm_list);
|
2014-10-19 20:50:43 +02:00
|
|
|
|
2017-11-09 04:57:14 +01:00
|
|
|
*r_new_wm_list = *readfile_wm_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Match old WM with new, 4 cases:
|
|
|
|
* 1) No current WM, no WM in file: Make new default.
|
|
|
|
* 2) No current WM, but WM in file: Keep current WM, do nothing else.
|
|
|
|
* 3) Current WM, but not in file: Keep current WM, update windows with screens from file.
|
|
|
|
* 4) Current WM, and WM in file: Try to keep current GHOST windows, use WM from file.
|
|
|
|
*
|
|
|
|
* \param r_new_wm_list: Return argument for the wm list to be used from now on.
|
|
|
|
*/
|
|
|
|
static void wm_window_match_do(
|
|
|
|
bContext *C,
|
|
|
|
ListBase *current_wm_list, ListBase *readfile_wm_list,
|
|
|
|
ListBase *r_new_wm_list)
|
|
|
|
{
|
|
|
|
if (BLI_listbase_is_empty(current_wm_list)) {
|
|
|
|
/* case 1 */
|
|
|
|
if (BLI_listbase_is_empty(readfile_wm_list)) {
|
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
/* Neither current, no newly read file have a WM -> add the default one. */
|
|
|
|
wm_add_default(bmain, C);
|
|
|
|
*r_new_wm_list = bmain->wm;
|
|
|
|
}
|
|
|
|
/* case 2 */
|
|
|
|
else {
|
|
|
|
*r_new_wm_list = *readfile_wm_list;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* case 3 */
|
|
|
|
if (BLI_listbase_is_empty(readfile_wm_list)) {
|
|
|
|
/* We've read file without wm, keep current one entirely alive.
|
|
|
|
* Happens when reading pre 2.5 files (no WM back then) */
|
|
|
|
wm_window_match_keep_current_wm(C, current_wm_list, (G.fileflags & G_FILE_NO_UI) == 0, r_new_wm_list);
|
|
|
|
}
|
|
|
|
/* case 4 */
|
|
|
|
else {
|
|
|
|
wm_window_match_replace_by_file_wm(C, current_wm_list, readfile_wm_list, r_new_wm_list);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Summary of ain features:
- Themes and Styles are now editable.
- CTRL+U "Save user defaults" now goes to new .B25.blend, so you
can use 2.4x and 2.5x next to each other. If B25 doesn't exist, it
reads the regular .B.blend
- Press Tkey in 3d window for (unfinished) toolbar WIP. It now only
shows the last operator, if appropriate.
Nkey properties moved to the other side.
A lot of work was done on removing old themes for good and properly
getting it work with the 2.5 region system. Here's some notes;
- Buttons now all have a complete set of colors, based on button classifications
(See outliner -> user prefs -> Interface
- Theme colors have been extended with basic colors for region types.
Currently colors are defined for Window, Header, List/Channels and
for Button/Tool views.
The screen manager handles this btw, so a TH_BACK will always pick the
right backdrop color.
- Menu backdrops are in in Button theme colors. Floating Panels will be in
the per-space type Themes.
- Styles were added in RNA too, but only for the font settings now.
Only Panel font, widget font and widget-label work now. The 'group label'
will be for templates mostly.
Style settings will be expanded with spacing defaults, label conventions,
etc.
- Label text colors are stored in per-space Theme too, to make sure they fit.
Same goes for Panel title color.
Note that 'shadow' for fonts can conflict with text colors; shadow color is
currently stored in Style... shadow code needs a bit of work still.
2009-04-27 13:44:11 +00:00
|
|
|
/* in case UserDef was read, we re-initialize all, and do versioning */
|
2017-07-03 19:49:35 +03:00
|
|
|
static void wm_init_userdef(Main *bmain, const bool read_userdef_from_memory)
|
2.5
Summary of ain features:
- Themes and Styles are now editable.
- CTRL+U "Save user defaults" now goes to new .B25.blend, so you
can use 2.4x and 2.5x next to each other. If B25 doesn't exist, it
reads the regular .B.blend
- Press Tkey in 3d window for (unfinished) toolbar WIP. It now only
shows the last operator, if appropriate.
Nkey properties moved to the other side.
A lot of work was done on removing old themes for good and properly
getting it work with the 2.5 region system. Here's some notes;
- Buttons now all have a complete set of colors, based on button classifications
(See outliner -> user prefs -> Interface
- Theme colors have been extended with basic colors for region types.
Currently colors are defined for Window, Header, List/Channels and
for Button/Tool views.
The screen manager handles this btw, so a TH_BACK will always pick the
right backdrop color.
- Menu backdrops are in in Button theme colors. Floating Panels will be in
the per-space type Themes.
- Styles were added in RNA too, but only for the font settings now.
Only Panel font, widget font and widget-label work now. The 'group label'
will be for templates mostly.
Style settings will be expanded with spacing defaults, label conventions,
etc.
- Label text colors are stored in per-space Theme too, to make sure they fit.
Same goes for Panel title color.
Note that 'shadow' for fonts can conflict with text colors; shadow color is
currently stored in Style... shadow code needs a bit of work still.
2009-04-27 13:44:11 +00:00
|
|
|
{
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
/* versioning is here */
|
2018-06-08 12:16:37 +02:00
|
|
|
UI_init_userdef(bmain);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2012-01-31 11:11:56 +00:00
|
|
|
MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024);
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_init(bmain);
|
2010-02-27 12:34:49 +00:00
|
|
|
|
2011-02-21 02:40:48 +00:00
|
|
|
/* needed so loading a file from the command line respects user-pref [#26156] */
|
2017-11-20 01:35:49 +11:00
|
|
|
SET_FLAG_FROM_TEST(G.fileflags, U.flag & USER_FILENOUI, G_FILE_NO_UI);
|
2011-02-21 02:40:48 +00:00
|
|
|
|
2010-02-27 12:34:49 +00:00
|
|
|
/* set the python auto-execute setting from user prefs */
|
2011-03-15 08:04:11 +00:00
|
|
|
/* enabled by default, unless explicitly enabled in the command line which overrides */
|
2019-02-02 13:39:51 +11:00
|
|
|
if ((G.f & G_FLAG_SCRIPT_OVERRIDE_PREF) == 0) {
|
|
|
|
SET_FLAG_FROM_TEST(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_FLAG_SCRIPT_AUTOEXEC);
|
2011-03-15 08:04:11 +00:00
|
|
|
}
|
2011-10-21 17:37:38 +00:00
|
|
|
|
2013-11-25 11:45:12 +11:00
|
|
|
/* avoid re-saving for every small change to our prefs, allow overrides */
|
2017-07-03 02:24:40 +02:00
|
|
|
if (read_userdef_from_memory) {
|
2014-07-23 20:20:59 +10:00
|
|
|
BLO_update_defaults_userpref_blend();
|
2013-11-25 11:45:12 +11:00
|
|
|
}
|
|
|
|
|
2011-09-28 19:11:59 +00:00
|
|
|
/* update tempdir from user preferences */
|
2014-11-23 15:54:29 +01:00
|
|
|
BKE_tempdir_init(U.tempdir);
|
2.5
Summary of ain features:
- Themes and Styles are now editable.
- CTRL+U "Save user defaults" now goes to new .B25.blend, so you
can use 2.4x and 2.5x next to each other. If B25 doesn't exist, it
reads the regular .B.blend
- Press Tkey in 3d window for (unfinished) toolbar WIP. It now only
shows the last operator, if appropriate.
Nkey properties moved to the other side.
A lot of work was done on removing old themes for good and properly
getting it work with the 2.5 region system. Here's some notes;
- Buttons now all have a complete set of colors, based on button classifications
(See outliner -> user prefs -> Interface
- Theme colors have been extended with basic colors for region types.
Currently colors are defined for Window, Header, List/Channels and
for Button/Tool views.
The screen manager handles this btw, so a TH_BACK will always pick the
right backdrop color.
- Menu backdrops are in in Button theme colors. Floating Panels will be in
the per-space type Themes.
- Styles were added in RNA too, but only for the font settings now.
Only Panel font, widget font and widget-label work now. The 'group label'
will be for templates mostly.
Style settings will be expanded with spacing defaults, label conventions,
etc.
- Label text colors are stored in per-space Theme too, to make sure they fit.
Same goes for Panel title color.
Note that 'shadow' for fonts can conflict with text colors; shadow color is
currently stored in Style... shadow code needs a bit of work still.
2009-04-27 13:44:11 +00:00
|
|
|
}
|
|
|
|
|
2011-05-05 14:21:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* return codes */
|
2012-03-27 01:24:16 +00:00
|
|
|
#define BKE_READ_EXOTIC_FAIL_PATH -3 /* file format is not supported */
|
|
|
|
#define BKE_READ_EXOTIC_FAIL_FORMAT -2 /* file format is not supported */
|
|
|
|
#define BKE_READ_EXOTIC_FAIL_OPEN -1 /* Can't open the file */
|
|
|
|
#define BKE_READ_EXOTIC_OK_BLEND 0 /* .blend file */
|
2015-10-08 14:22:16 +11:00
|
|
|
#if 0
|
2012-03-27 01:24:16 +00:00
|
|
|
#define BKE_READ_EXOTIC_OK_OTHER 1 /* other supported formats */
|
2015-10-08 14:22:16 +11:00
|
|
|
#endif
|
2011-05-05 14:21:31 +00:00
|
|
|
|
2012-03-20 02:17:37 +00:00
|
|
|
|
2011-05-05 14:21:31 +00:00
|
|
|
/* intended to check for non-blender formats but for now it only reads blends */
|
2015-10-08 14:22:16 +11:00
|
|
|
static int wm_read_exotic(const char *name)
|
2011-05-05 14:21:31 +00:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
gzFile gzfile;
|
|
|
|
char header[7];
|
|
|
|
int retval;
|
|
|
|
|
2012-07-06 23:56:59 +00:00
|
|
|
/* make sure we're not trying to read a directory.... */
|
2011-05-05 14:21:31 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
len = strlen(name);
|
2013-06-10 02:05:38 +00:00
|
|
|
if (len > 0 && ELEM(name[len - 1], '/', '\\')) {
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = BKE_READ_EXOTIC_FAIL_PATH;
|
2011-05-05 14:21:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-27 01:24:16 +00:00
|
|
|
gzfile = BLI_gzopen(name, "rb");
|
2011-05-05 14:21:31 +00:00
|
|
|
if (gzfile == NULL) {
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = BKE_READ_EXOTIC_FAIL_OPEN;
|
2011-05-05 14:21:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-27 01:24:16 +00:00
|
|
|
len = gzread(gzfile, header, sizeof(header));
|
2011-05-05 14:21:31 +00:00
|
|
|
gzclose(gzfile);
|
2015-01-26 16:03:11 +01:00
|
|
|
if (len == sizeof(header) && STREQLEN(header, "BLENDER", 7)) {
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = BKE_READ_EXOTIC_OK_BLEND;
|
2011-05-05 14:21:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-27 01:24:16 +00:00
|
|
|
#if 0 /* historic stuff - no longer used */
|
2014-04-01 11:34:00 +11:00
|
|
|
WM_cursor_wait(true);
|
2012-05-21 09:00:35 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (is_foo_format(name)) {
|
2011-05-05 14:21:31 +00:00
|
|
|
read_foo(name);
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = BKE_READ_EXOTIC_OK_OTHER;
|
2011-05-05 14:21:31 +00:00
|
|
|
}
|
|
|
|
else
|
2012-03-09 18:28:30 +00:00
|
|
|
#endif
|
2011-05-05 14:21:31 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = BKE_READ_EXOTIC_FAIL_FORMAT;
|
2011-05-05 14:21:31 +00:00
|
|
|
}
|
2012-05-21 09:00:35 +00:00
|
|
|
#if 0
|
2014-04-01 11:34:00 +11:00
|
|
|
WM_cursor_wait(false);
|
2012-05-21 09:00:35 +00:00
|
|
|
#endif
|
2011-05-05 14:21:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2013-06-18 18:11:52 +00:00
|
|
|
void WM_file_autoexec_init(const char *filepath)
|
|
|
|
{
|
2019-02-02 13:39:51 +11:00
|
|
|
if (G.f & G_FLAG_SCRIPT_OVERRIDE_PREF) {
|
2013-06-18 18:11:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:39:51 +11:00
|
|
|
if (G.f & G_FLAG_SCRIPT_AUTOEXEC) {
|
2013-06-18 18:11:52 +00:00
|
|
|
char path[FILE_MAX];
|
|
|
|
BLI_split_dir_part(filepath, path, sizeof(path));
|
|
|
|
if (BKE_autoexec_match(path)) {
|
2019-02-02 13:39:51 +11:00
|
|
|
G.f &= ~G_FLAG_SCRIPT_AUTOEXEC;
|
2013-06-18 18:11:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
void wm_file_read_report(bContext *C, Main *bmain)
|
2015-09-22 16:45:23 +10:00
|
|
|
{
|
|
|
|
ReportList *reports = NULL;
|
|
|
|
Scene *sce;
|
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
for (sce = bmain->scene.first; sce; sce = sce->id.next) {
|
2018-04-17 13:35:05 +02:00
|
|
|
if (sce->r.engine[0] &&
|
|
|
|
BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL)
|
2015-09-22 16:45:23 +10:00
|
|
|
{
|
|
|
|
if (reports == NULL) {
|
|
|
|
reports = CTX_wm_reports(C);
|
|
|
|
}
|
|
|
|
|
|
|
|
BKE_reportf(reports, RPT_ERROR,
|
2016-06-01 20:38:30 +02:00
|
|
|
"Engine '%s' not available for scene '%s' (an add-on may need to be installed or enabled)",
|
2018-04-17 13:35:05 +02:00
|
|
|
sce->r.engine, sce->id.name + 2);
|
2015-09-22 16:45:23 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (reports) {
|
|
|
|
if (!G.background) {
|
2016-01-16 21:51:05 +01:00
|
|
|
WM_report_banner_show();
|
2015-09-22 16:45:23 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-22 12:50:41 +10:00
|
|
|
/**
|
|
|
|
* Logic shared between #WM_file_read & #wm_homefile_read,
|
|
|
|
* updates to make after reading a file.
|
|
|
|
*/
|
2018-11-30 13:33:13 +11:00
|
|
|
static void wm_file_read_post(
|
|
|
|
bContext *C, const bool is_startup_file, const bool is_factory_startup, const bool reset_app_template)
|
2015-09-22 12:50:41 +10:00
|
|
|
{
|
2015-09-22 16:45:23 +10:00
|
|
|
bool addons_loaded = false;
|
2015-10-07 00:27:27 +11:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
|
|
|
|
if (!G.background) {
|
|
|
|
/* remove windows which failed to be added via WM_check */
|
|
|
|
wm_window_ghostwindows_remove_invalid(C, wm);
|
|
|
|
}
|
|
|
|
|
|
|
|
CTX_wm_window_set(C, wm->windows.first);
|
2015-09-22 12:50:41 +10:00
|
|
|
|
2018-06-14 13:44:23 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2018-06-14 12:39:52 +02:00
|
|
|
DEG_on_visible_update(bmain, true);
|
2018-07-24 12:43:21 +02:00
|
|
|
wm_event_do_depsgraph(C);
|
2018-07-05 15:30:56 +02:00
|
|
|
|
|
|
|
ED_editors_init(C);
|
2015-09-22 12:50:41 +10:00
|
|
|
|
|
|
|
#ifdef WITH_PYTHON
|
|
|
|
if (is_startup_file) {
|
|
|
|
/* possible python hasn't been initialized */
|
|
|
|
if (CTX_py_init_get(C)) {
|
2018-10-01 16:23:41 +02:00
|
|
|
if (reset_app_template) {
|
2017-08-11 09:29:25 +10:00
|
|
|
/* Only run when we have a template path found. */
|
|
|
|
if (BKE_appdir_app_template_any()) {
|
2018-11-10 10:55:04 +11:00
|
|
|
BPY_execute_string(
|
|
|
|
C, (const char *[]){"bl_app_template_utils", NULL},
|
|
|
|
"bl_app_template_utils.reset()");
|
2017-08-11 09:29:25 +10:00
|
|
|
}
|
|
|
|
/* sync addons, these may have changed from the defaults */
|
2018-11-10 10:55:04 +11:00
|
|
|
BPY_execute_string(
|
|
|
|
C, (const char *[]){"addon_utils", NULL},
|
|
|
|
"addon_utils.reset_all()");
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
2015-09-22 12:50:41 +10:00
|
|
|
BPY_python_reset(C);
|
2015-09-22 16:45:23 +10:00
|
|
|
addons_loaded = true;
|
2015-09-22 12:50:41 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* run any texts that were loaded in and flagged as modules */
|
|
|
|
BPY_python_reset(C);
|
2015-09-22 16:45:23 +10:00
|
|
|
addons_loaded = true;
|
2015-09-22 12:50:41 +10:00
|
|
|
}
|
2018-03-02 11:09:24 +11:00
|
|
|
#else
|
2018-10-01 16:23:41 +02:00
|
|
|
UNUSED_VARS(is_startup_file, reset_app_template);
|
2015-09-22 12:50:41 +10:00
|
|
|
#endif /* WITH_PYTHON */
|
|
|
|
|
|
|
|
WM_operatortype_last_properties_clear_all();
|
|
|
|
|
|
|
|
/* important to do before NULL'ing the context */
|
2018-06-14 12:34:13 +02:00
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_VERSION_UPDATE);
|
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_LOAD_POST);
|
2018-11-30 13:33:13 +11:00
|
|
|
if (is_factory_startup) {
|
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_LOAD_FACTORY_STARTUP_POST);
|
|
|
|
}
|
2015-09-22 12:50:41 +10:00
|
|
|
|
2017-11-13 19:43:34 +11:00
|
|
|
#if 1
|
2015-09-22 12:50:41 +10:00
|
|
|
WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL);
|
2017-11-13 19:43:34 +11:00
|
|
|
#else
|
|
|
|
WM_msg_publish_static(CTX_wm_message_bus(C), WM_MSG_STATICTYPE_FILE_READ);
|
|
|
|
#endif
|
2015-09-22 12:50:41 +10:00
|
|
|
|
2015-09-22 16:45:23 +10:00
|
|
|
/* report any errors.
|
|
|
|
* currently disabled if addons aren't yet loaded */
|
|
|
|
if (addons_loaded) {
|
2018-06-14 12:34:13 +02:00
|
|
|
wm_file_read_report(C, bmain);
|
2015-09-22 13:30:12 +10:00
|
|
|
}
|
|
|
|
|
2015-10-08 15:56:46 +11:00
|
|
|
if (!G.background) {
|
2018-03-19 14:17:59 +01:00
|
|
|
if (wm->undo_stack == NULL) {
|
|
|
|
wm->undo_stack = BKE_undosys_stack_create();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BKE_undosys_stack_clear(wm->undo_stack);
|
|
|
|
}
|
2018-06-14 12:34:13 +02:00
|
|
|
BKE_undosys_stack_init_from_main(wm->undo_stack, bmain);
|
2018-05-15 19:30:59 +02:00
|
|
|
BKE_undosys_stack_init_from_context(wm->undo_stack, C);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!G.background) {
|
|
|
|
/* in background mode this makes it hard to load
|
|
|
|
* a blend file and do anything since the screen
|
|
|
|
* won't be set to a valid value again */
|
|
|
|
CTX_wm_window_set(C, NULL); /* exits queues */
|
2018-05-15 19:53:34 +02:00
|
|
|
|
|
|
|
/* Ensure tools are registered. */
|
|
|
|
WM_toolsystem_init(C);
|
2015-10-08 15:56:46 +11:00
|
|
|
}
|
2015-09-22 12:50:41 +10:00
|
|
|
}
|
|
|
|
|
2014-01-29 05:33:05 +11:00
|
|
|
bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
|
2007-12-24 18:27:28 +00:00
|
|
|
{
|
2015-08-05 21:25:28 +10:00
|
|
|
/* assume automated tasks with background, don't write recent file list */
|
|
|
|
const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
|
2014-01-29 05:33:05 +11:00
|
|
|
bool success = false;
|
2007-12-24 18:27:28 +00:00
|
|
|
int retval;
|
|
|
|
|
2010-07-03 17:47:06 +00:00
|
|
|
/* so we can get the error message */
|
|
|
|
errno = 0;
|
|
|
|
|
2010-11-29 13:14:51 +00:00
|
|
|
WM_cursor_wait(1);
|
|
|
|
|
2012-05-05 00:23:55 +00:00
|
|
|
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
|
2011-06-24 16:54:30 +00:00
|
|
|
|
2014-01-20 12:43:56 +11:00
|
|
|
UI_view2d_zoom_cache_reset();
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
/* first try to append data from exotic file formats... */
|
2011-11-03 03:00:45 +00:00
|
|
|
/* it throws error box when file doesn't exist and returns -1 */
|
2008-12-19 18:28:37 +00:00
|
|
|
/* note; it should set some error message somewhere... (ton) */
|
2015-10-08 14:22:16 +11:00
|
|
|
retval = wm_read_exotic(filepath);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
/* we didn't succeed, now try to read Blender file */
|
2011-01-07 06:50:29 +00:00
|
|
|
if (retval == BKE_READ_EXOTIC_OK_BLEND) {
|
2019-02-02 14:01:48 +11:00
|
|
|
const int G_f_orig = G.f;
|
2007-12-24 18:27:28 +00:00
|
|
|
ListBase wmbase;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2011-11-03 03:00:45 +00:00
|
|
|
/* put aside screens to match with persistent windows later */
|
2008-12-31 17:11:42 +00:00
|
|
|
/* also exit screens and editors */
|
2017-11-09 04:57:14 +01:00
|
|
|
wm_window_match_init(C, &wmbase);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
/* confusing this global... */
|
|
|
|
G.relbase_valid = 1;
|
2018-11-22 14:57:41 +11:00
|
|
|
retval = BKE_blendfile_read(
|
|
|
|
C, filepath,
|
|
|
|
&(const struct BlendFileReadParams){0},
|
|
|
|
reports);
|
2018-06-06 15:50:24 +02:00
|
|
|
|
|
|
|
/* BKE_file_read sets new Main into context. */
|
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
2013-04-10 09:49:44 +00:00
|
|
|
/* when loading startup.blend's, we can be left with a blank path */
|
2018-12-07 15:40:38 +11:00
|
|
|
if (BKE_main_blendfile_path(bmain)[0] != '\0') {
|
2013-04-10 09:49:44 +00:00
|
|
|
G.save_over = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
G.save_over = 0;
|
|
|
|
G.relbase_valid = 0;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2010-03-26 11:35:57 +00:00
|
|
|
/* this flag is initialized by the operator but overwritten on read.
|
|
|
|
* need to re-enable it here else drivers + registered scripts wont work. */
|
2019-02-02 14:01:48 +11:00
|
|
|
if (G.f != G_f_orig) {
|
|
|
|
const int flags_keep = G_FLAG_ALL_RUNTIME;
|
2019-02-02 14:45:42 +11:00
|
|
|
G.f &= G_FLAG_ALL_READFILE;
|
2019-02-02 14:01:48 +11:00
|
|
|
G.f = (G.f & ~flags_keep) | (G_f_orig & flags_keep);
|
2011-03-15 08:04:11 +00:00
|
|
|
}
|
2010-03-26 11:35:57 +00:00
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
/* match the read WM with current WM */
|
2018-06-06 16:25:28 +02:00
|
|
|
wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
|
2009-11-11 04:08:09 +00:00
|
|
|
WM_check(C); /* opens window(s), checks keymaps */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2016-04-24 22:42:41 +10:00
|
|
|
if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {
|
2012-02-19 06:00:20 +00:00
|
|
|
/* in case a userdef is read from regular .blend */
|
2018-06-06 15:50:24 +02:00
|
|
|
wm_init_userdef(bmain, false);
|
2012-02-19 06:00:20 +00:00
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2016-04-24 22:42:41 +10:00
|
|
|
if (retval != BKE_BLENDFILE_READ_FAIL) {
|
2012-05-21 08:24:03 +00:00
|
|
|
if (do_history) {
|
2015-08-09 12:53:09 +10:00
|
|
|
wm_history_file_update();
|
2012-05-21 08:24:03 +00:00
|
|
|
}
|
2009-09-01 00:52:03 +00:00
|
|
|
}
|
2006-08-20 14:41:13 +00:00
|
|
|
|
2018-11-30 13:33:13 +11:00
|
|
|
wm_file_read_post(C, false, false, false);
|
2011-01-03 12:48:16 +00:00
|
|
|
|
2014-01-29 05:33:05 +11:00
|
|
|
success = true;
|
2004-11-07 16:49:46 +00:00
|
|
|
}
|
2015-10-08 14:22:16 +11:00
|
|
|
#if 0
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (retval == BKE_READ_EXOTIC_OK_OTHER)
|
2015-04-18 15:41:12 +02:00
|
|
|
BKE_undo_write(C, "Import file");
|
2015-10-08 14:22:16 +11:00
|
|
|
#endif
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath,
|
|
|
|
errno ? strerror(errno) : TIP_("unable to open the file"));
|
2008-12-29 13:38:08 +00:00
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath);
|
2011-01-07 06:50:29 +00:00
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (retval == BKE_READ_EXOTIC_FAIL_PATH) {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath);
|
2011-01-07 06:50:29 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath);
|
2011-01-09 15:12:08 +00:00
|
|
|
BLI_assert(!"invalid 'retval'");
|
2011-01-07 06:50:29 +00:00
|
|
|
}
|
|
|
|
|
2015-08-05 21:25:28 +10:00
|
|
|
|
|
|
|
if (success == false) {
|
|
|
|
/* remove from recent files list */
|
|
|
|
if (do_history) {
|
2015-08-09 12:53:09 +10:00
|
|
|
RecentFile *recent = wm_file_history_find(filepath);
|
2015-08-05 21:25:28 +10:00
|
|
|
if (recent) {
|
2015-08-09 12:53:09 +10:00
|
|
|
wm_history_file_free(recent);
|
|
|
|
wm_history_file_write();
|
2015-08-05 21:25:28 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-29 13:14:51 +00:00
|
|
|
WM_cursor_wait(0);
|
|
|
|
|
2014-01-29 05:33:05 +11:00
|
|
|
return success;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2018-12-19 10:07:30 +11:00
|
|
|
static struct {
|
2018-08-17 16:34:51 +10:00
|
|
|
char app_template[64];
|
|
|
|
bool override;
|
2018-09-28 09:46:12 +02:00
|
|
|
} wm_init_state_app_template = {{0}};
|
2018-08-17 16:34:51 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Used for setting app-template from the command line:
|
|
|
|
* - non-empty string: overrides.
|
|
|
|
* - empty string: override, using no app template.
|
|
|
|
* - NULL: clears override.
|
|
|
|
*/
|
|
|
|
void WM_init_state_app_template_set(const char *app_template)
|
|
|
|
{
|
|
|
|
if (app_template) {
|
|
|
|
STRNCPY(wm_init_state_app_template.app_template, app_template);
|
|
|
|
wm_init_state_app_template.override = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
wm_init_state_app_template.app_template[0] = '\0';
|
|
|
|
wm_init_state_app_template.override = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *WM_init_state_app_template_get(void)
|
|
|
|
{
|
|
|
|
return wm_init_state_app_template.override ? wm_init_state_app_template.app_template : NULL;
|
|
|
|
}
|
2006-07-04 12:10:37 +00:00
|
|
|
|
2018-08-28 15:12:14 +02:00
|
|
|
|
|
|
|
static bool wm_app_template_has_userpref(const char *app_template)
|
|
|
|
{
|
|
|
|
/* Test if app template provides a userpref.blend. If not, we will
|
|
|
|
* share user preferences with the rest of Blender. */
|
|
|
|
if (!app_template && app_template[0]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char app_template_path[FILE_MAX];
|
|
|
|
if (!BKE_appdir_app_template_id_search(app_template, app_template_path, sizeof(app_template_path))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char userpref_path[FILE_MAX];
|
|
|
|
BLI_path_join(userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE, NULL);
|
|
|
|
return BLI_exists(userpref_path);
|
|
|
|
}
|
|
|
|
|
2015-01-25 21:15:27 +11:00
|
|
|
/**
|
2017-03-17 00:37:28 +11:00
|
|
|
* Called on startup, (context entirely filled with NULLs)
|
|
|
|
* or called for 'New File' both startup.blend and userpref.blend are checked.
|
|
|
|
*
|
2017-03-23 10:32:16 +11:00
|
|
|
* \param use_factory_settings: Ignore on-disk startup file, use bundled ``datatoc_startup_blend`` instead.
|
2017-03-17 00:37:28 +11:00
|
|
|
* Used for "Restore Factory Settings".
|
2017-08-11 09:29:25 +10:00
|
|
|
* \param use_userdef: Load factory settings as well as startup file.
|
|
|
|
* Disabled for "File New" we don't want to reload preferences.
|
2017-03-17 00:37:28 +11:00
|
|
|
* \param filepath_startup_override: Optional path pointing to an alternative blend file (may be NULL).
|
2017-03-25 09:29:51 +11:00
|
|
|
* \param app_template_override: Template to use instead of the template defined in user-preferences.
|
|
|
|
* When not-null, this is written into the user preferences.
|
2015-01-25 21:15:27 +11:00
|
|
|
*/
|
2018-11-30 13:21:12 +11:00
|
|
|
void wm_homefile_read(
|
2017-03-29 19:07:21 +11:00
|
|
|
bContext *C, ReportList *reports,
|
2017-08-11 09:29:25 +10:00
|
|
|
bool use_factory_settings, bool use_empty_data, bool use_userdef,
|
2018-11-30 13:33:13 +11:00
|
|
|
const char *filepath_startup_override, const char *app_template_override,
|
|
|
|
bool *r_is_factory_startup)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2018-06-14 12:34:13 +02:00
|
|
|
Main *bmain = G_MAIN; /* Context does not always have valid main pointer here... */
|
2011-09-15 13:20:18 +00:00
|
|
|
ListBase wmbase;
|
2017-03-25 09:29:51 +11:00
|
|
|
bool success = false;
|
|
|
|
|
2018-11-30 13:33:13 +11:00
|
|
|
bool filepath_startup_is_factory = true;
|
2017-03-17 00:37:28 +11:00
|
|
|
char filepath_startup[FILE_MAX];
|
|
|
|
char filepath_userdef[FILE_MAX];
|
2017-03-25 09:29:51 +11:00
|
|
|
|
|
|
|
/* When 'app_template' is set: '{BLENDER_USER_CONFIG}/{app_template}' */
|
|
|
|
char app_template_system[FILE_MAX];
|
|
|
|
/* When 'app_template' is set: '{BLENDER_SYSTEM_SCRIPTS}/startup/bl_app_templates_system/{app_template}' */
|
|
|
|
char app_template_config[FILE_MAX];
|
2012-08-21 10:39:02 +00:00
|
|
|
|
2014-03-15 20:08:29 +11:00
|
|
|
/* Indicates whether user preferences were really load from memory.
|
2013-12-05 19:32:48 +06:00
|
|
|
*
|
2017-03-23 10:32:16 +11:00
|
|
|
* This is used for versioning code, and for this we can not rely on use_factory_settings
|
2013-12-05 19:32:48 +06:00
|
|
|
* passed via argument. This is because there might be configuration folder
|
2013-12-06 01:10:16 +06:00
|
|
|
* exists but it might not have userpref.blend and in this case we fallback to
|
2013-12-05 19:32:48 +06:00
|
|
|
* reading home file from memory.
|
|
|
|
*
|
|
|
|
* And in this case versioning code is to be run.
|
|
|
|
*/
|
2017-07-03 02:24:40 +02:00
|
|
|
bool read_userdef_from_memory = false;
|
2017-08-11 09:29:25 +10:00
|
|
|
eBLOReadSkip skip_flags = use_userdef ? 0 : BLO_READ_SKIP_USERDEF;
|
2013-12-05 19:32:48 +06:00
|
|
|
|
2018-11-30 13:33:13 +11:00
|
|
|
/* True if we load startup.blend from memory or use app-template startup.blend which the user hasn't saved. */
|
|
|
|
bool is_factory_startup = true;
|
|
|
|
|
2013-11-30 18:39:55 +11:00
|
|
|
/* options exclude eachother */
|
2017-03-23 10:32:16 +11:00
|
|
|
BLI_assert((use_factory_settings && filepath_startup_override) == 0);
|
2013-11-30 18:39:55 +11:00
|
|
|
|
2019-02-02 13:39:51 +11:00
|
|
|
if ((G.f & G_FLAG_SCRIPT_OVERRIDE_PREF) == 0) {
|
|
|
|
SET_FLAG_FROM_TEST(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_FLAG_SCRIPT_AUTOEXEC);
|
2015-01-20 16:38:31 +11:00
|
|
|
}
|
|
|
|
|
2012-09-10 23:36:07 +00:00
|
|
|
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
|
|
|
|
|
2014-01-20 12:43:56 +11:00
|
|
|
UI_view2d_zoom_cache_reset();
|
|
|
|
|
2006-08-20 14:41:13 +00:00
|
|
|
G.relbase_valid = 0;
|
2013-11-27 20:48:07 +01:00
|
|
|
|
2017-03-23 10:32:16 +11:00
|
|
|
/* put aside screens to match with persistent windows later */
|
|
|
|
wm_window_match_init(C, &wmbase);
|
|
|
|
|
|
|
|
filepath_startup[0] = '\0';
|
|
|
|
filepath_userdef[0] = '\0';
|
2017-03-25 09:29:51 +11:00
|
|
|
app_template_system[0] = '\0';
|
|
|
|
app_template_config[0] = '\0';
|
2017-03-23 10:32:16 +11:00
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
|
2017-03-23 10:32:16 +11:00
|
|
|
if (!use_factory_settings) {
|
|
|
|
if (cfgdir) {
|
2017-03-25 09:29:51 +11:00
|
|
|
BLI_path_join(filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE, NULL);
|
2018-11-30 13:33:13 +11:00
|
|
|
filepath_startup_is_factory = false;
|
2017-08-11 09:29:25 +10:00
|
|
|
if (use_userdef) {
|
|
|
|
BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL);
|
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2017-03-23 10:32:16 +11:00
|
|
|
use_factory_settings = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filepath_startup_override) {
|
|
|
|
BLI_strncpy(filepath_startup, filepath_startup_override, FILE_MAX);
|
2018-11-30 13:33:13 +11:00
|
|
|
filepath_startup_is_factory = false;
|
2010-07-04 15:35:23 +00:00
|
|
|
}
|
2.5
Summary of ain features:
- Themes and Styles are now editable.
- CTRL+U "Save user defaults" now goes to new .B25.blend, so you
can use 2.4x and 2.5x next to each other. If B25 doesn't exist, it
reads the regular .B.blend
- Press Tkey in 3d window for (unfinished) toolbar WIP. It now only
shows the last operator, if appropriate.
Nkey properties moved to the other side.
A lot of work was done on removing old themes for good and properly
getting it work with the 2.5 region system. Here's some notes;
- Buttons now all have a complete set of colors, based on button classifications
(See outliner -> user prefs -> Interface
- Theme colors have been extended with basic colors for region types.
Currently colors are defined for Window, Header, List/Channels and
for Button/Tool views.
The screen manager handles this btw, so a TH_BACK will always pick the
right backdrop color.
- Menu backdrops are in in Button theme colors. Floating Panels will be in
the per-space type Themes.
- Styles were added in RNA too, but only for the font settings now.
Only Panel font, widget font and widget-label work now. The 'group label'
will be for templates mostly.
Style settings will be expanded with spacing defaults, label conventions,
etc.
- Label text colors are stored in per-space Theme too, to make sure they fit.
Same goes for Panel title color.
Note that 'shadow' for fonts can conflict with text colors; shadow color is
currently stored in Style... shadow code needs a bit of work still.
2009-04-27 13:44:11 +00:00
|
|
|
}
|
2017-03-23 10:32:16 +11:00
|
|
|
|
2017-03-16 03:54:58 +11:00
|
|
|
/* load preferences before startup.blend */
|
2017-08-11 09:29:25 +10:00
|
|
|
if (use_userdef) {
|
|
|
|
if (!use_factory_settings && BLI_exists(filepath_userdef)) {
|
|
|
|
UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL);
|
|
|
|
if (userdef != NULL) {
|
2017-11-23 03:10:58 +11:00
|
|
|
BKE_blender_userdef_data_set_and_free(userdef);
|
|
|
|
userdef = NULL;
|
2017-08-11 09:29:25 +10:00
|
|
|
|
|
|
|
skip_flags |= BLO_READ_SKIP_USERDEF;
|
|
|
|
printf("Read prefs: %s\n", filepath_userdef);
|
|
|
|
}
|
2017-03-16 03:54:58 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
const char *app_template = NULL;
|
2018-09-12 11:28:49 +02:00
|
|
|
bool update_defaults = false;
|
2018-10-01 16:23:41 +02:00
|
|
|
bool reset_app_template = false;
|
2017-03-25 09:29:51 +11:00
|
|
|
|
|
|
|
if (filepath_startup_override != NULL) {
|
|
|
|
/* pass */
|
|
|
|
}
|
2017-08-07 21:17:14 +10:00
|
|
|
else if (app_template_override) {
|
|
|
|
/* This may be clearing the current template by setting to an empty string. */
|
2017-03-25 09:29:51 +11:00
|
|
|
app_template = app_template_override;
|
|
|
|
}
|
|
|
|
else if (!use_factory_settings && U.app_template[0]) {
|
|
|
|
app_template = U.app_template;
|
|
|
|
}
|
|
|
|
|
2018-10-01 16:23:41 +02:00
|
|
|
if ((!app_template && U.app_template[0]) ||
|
|
|
|
(app_template && !STREQ(app_template, U.app_template)))
|
|
|
|
{
|
|
|
|
/* Always load UI when switching to another template. */
|
|
|
|
G.fileflags &= ~G_FILE_NO_UI;
|
|
|
|
reset_app_template = true;
|
|
|
|
}
|
|
|
|
|
2017-08-07 21:17:14 +10:00
|
|
|
if ((app_template != NULL) && (app_template[0] != '\0')) {
|
2018-11-30 13:33:13 +11:00
|
|
|
if (!BKE_appdir_app_template_id_search(
|
|
|
|
app_template, app_template_system, sizeof(app_template_system)))
|
|
|
|
{
|
2018-08-17 17:05:04 +10:00
|
|
|
/* Can safely continue with code below, just warn it's not found. */
|
2018-12-23 21:58:59 +01:00
|
|
|
BKE_reportf(reports, RPT_WARNING, "Application Template '%s' not found", app_template);
|
2018-08-17 17:05:04 +10:00
|
|
|
}
|
2017-03-25 09:29:51 +11:00
|
|
|
|
2017-08-07 21:17:14 +10:00
|
|
|
/* Insert template name into startup file. */
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
/* note that the path is being set even when 'use_factory_settings == true'
|
|
|
|
* this is done so we can load a templates factory-settings */
|
|
|
|
if (!use_factory_settings) {
|
2017-08-23 22:06:42 +10:00
|
|
|
BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template, NULL);
|
2017-03-25 09:29:51 +11:00
|
|
|
BLI_path_join(filepath_startup, sizeof(filepath_startup), app_template_config, BLENDER_STARTUP_FILE, NULL);
|
2018-11-30 13:33:13 +11:00
|
|
|
filepath_startup_is_factory = false;
|
2017-03-25 09:29:51 +11:00
|
|
|
if (BLI_access(filepath_startup, R_OK) != 0) {
|
|
|
|
filepath_startup[0] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
filepath_startup[0] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filepath_startup[0] == '\0') {
|
|
|
|
BLI_path_join(filepath_startup, sizeof(filepath_startup), app_template_system, BLENDER_STARTUP_FILE, NULL);
|
2018-11-30 13:33:13 +11:00
|
|
|
filepath_startup_is_factory = true;
|
2018-09-12 11:28:49 +02:00
|
|
|
|
|
|
|
/* Update defaults only for system templates. */
|
|
|
|
update_defaults = true;
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!use_factory_settings || (filepath_startup[0] != '\0')) {
|
2017-03-17 00:37:28 +11:00
|
|
|
if (BLI_access(filepath_startup, R_OK) == 0) {
|
2018-11-22 14:57:41 +11:00
|
|
|
success = BKE_blendfile_read(
|
|
|
|
C, filepath_startup,
|
|
|
|
&(const struct BlendFileReadParams){
|
|
|
|
.is_startup = true,
|
|
|
|
.skip_flags = skip_flags,
|
|
|
|
},
|
|
|
|
NULL) != BKE_BLENDFILE_READ_FAIL;
|
2013-02-09 13:58:37 +00:00
|
|
|
}
|
2014-02-08 06:07:10 +11:00
|
|
|
if (BLI_listbase_is_empty(&U.themes)) {
|
2013-03-13 20:00:39 +00:00
|
|
|
if (G.debug & G_DEBUG)
|
2017-03-17 00:37:28 +11:00
|
|
|
printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", filepath_startup);
|
|
|
|
success = false;
|
2013-02-09 13:58:37 +00:00
|
|
|
}
|
2018-11-30 13:33:13 +11:00
|
|
|
if (success) {
|
|
|
|
if (update_defaults) {
|
|
|
|
BLO_update_defaults_startup_blend(CTX_data_main(C), app_template);
|
|
|
|
}
|
|
|
|
is_factory_startup = filepath_startup_is_factory;
|
2018-09-12 11:28:49 +02:00
|
|
|
}
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 00:37:28 +11:00
|
|
|
if (success == false && filepath_startup_override && reports) {
|
2017-03-25 09:29:51 +11:00
|
|
|
/* We can not return from here because wm is already reset */
|
2017-03-17 00:37:28 +11:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "Could not read '%s'", filepath_startup_override);
|
2013-11-27 20:48:07 +01:00
|
|
|
}
|
|
|
|
|
2017-03-17 00:37:28 +11:00
|
|
|
if (success == false) {
|
2017-03-16 03:54:58 +11:00
|
|
|
success = BKE_blendfile_read_from_memory(
|
2018-11-22 14:57:41 +11:00
|
|
|
C, datatoc_startup_blend, datatoc_startup_blend_size, true,
|
|
|
|
&(const struct BlendFileReadParams){
|
|
|
|
.is_startup = true,
|
|
|
|
.skip_flags = skip_flags,
|
|
|
|
},
|
|
|
|
NULL);
|
2017-08-11 09:29:25 +10:00
|
|
|
if (success) {
|
|
|
|
if (use_userdef) {
|
|
|
|
if ((skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
|
|
|
|
read_userdef_from_memory = true;
|
|
|
|
}
|
|
|
|
}
|
2017-07-03 02:24:40 +02:00
|
|
|
}
|
2014-02-08 06:07:10 +11:00
|
|
|
if (BLI_listbase_is_empty(&wmbase)) {
|
|
|
|
wm_clear_default_size(C);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2017-03-25 09:29:51 +11:00
|
|
|
|
2017-03-29 19:07:21 +11:00
|
|
|
if (use_empty_data) {
|
|
|
|
BKE_blendfile_read_make_empty(C);
|
|
|
|
}
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
/* Load template preferences,
|
|
|
|
* unlike regular preferences we only use some of the settings,
|
|
|
|
* see: BKE_blender_userdef_set_app_template */
|
|
|
|
if (app_template_system[0] != '\0') {
|
|
|
|
char temp_path[FILE_MAX];
|
|
|
|
temp_path[0] = '\0';
|
|
|
|
if (!use_factory_settings) {
|
|
|
|
BLI_path_join(temp_path, sizeof(temp_path), app_template_config, BLENDER_USERPREF_FILE, NULL);
|
|
|
|
if (BLI_access(temp_path, R_OK) != 0) {
|
|
|
|
temp_path[0] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (temp_path[0] == '\0') {
|
|
|
|
BLI_path_join(temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE, NULL);
|
|
|
|
}
|
|
|
|
|
2017-08-11 09:29:25 +10:00
|
|
|
if (use_userdef) {
|
|
|
|
UserDef *userdef_template = NULL;
|
|
|
|
/* just avoids missing file warning */
|
|
|
|
if (BLI_exists(temp_path)) {
|
|
|
|
userdef_template = BKE_blendfile_userdef_read(temp_path, NULL);
|
|
|
|
}
|
|
|
|
if (userdef_template == NULL) {
|
|
|
|
/* we need to have preferences load to overwrite preferences from previous template */
|
|
|
|
userdef_template = BKE_blendfile_userdef_read_from_memory(
|
|
|
|
datatoc_startup_blend, datatoc_startup_blend_size, NULL);
|
|
|
|
read_userdef_from_memory = true;
|
|
|
|
}
|
|
|
|
if (userdef_template) {
|
2017-11-23 03:10:58 +11:00
|
|
|
BKE_blender_userdef_app_template_data_set_and_free(userdef_template);
|
|
|
|
userdef_template = NULL;
|
2017-08-11 09:29:25 +10:00
|
|
|
}
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (app_template_override) {
|
|
|
|
BLI_strncpy(U.app_template, app_template_override, sizeof(U.app_template));
|
|
|
|
}
|
|
|
|
|
2010-09-06 12:54:54 +00:00
|
|
|
/* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise
|
|
|
|
* can remove this eventually, only in a 2.53 and older, now its not written */
|
|
|
|
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
|
2017-08-11 10:33:39 +10:00
|
|
|
|
2018-06-05 17:51:17 +02:00
|
|
|
bmain = CTX_data_main(C);
|
|
|
|
|
2017-08-11 09:29:25 +10:00
|
|
|
if (use_userdef) {
|
|
|
|
/* check userdef before open window, keymaps etc */
|
2018-06-05 17:51:17 +02:00
|
|
|
wm_init_userdef(bmain, read_userdef_from_memory);
|
2018-10-01 16:23:41 +02:00
|
|
|
reset_app_template = true;
|
2017-08-11 09:29:25 +10:00
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
/* match the read WM with current WM */
|
2018-06-05 17:56:18 +02:00
|
|
|
wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
|
2018-11-22 10:51:27 +11:00
|
|
|
|
|
|
|
if (use_factory_settings) {
|
|
|
|
/* Clear keymaps because the current default keymap may have been initialized from user preferences,
|
|
|
|
* which have been reset. */
|
|
|
|
for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
|
|
|
|
if (wm->defaultconf) {
|
|
|
|
wm->defaultconf->flag &= ~KEYCONF_INIT_DEFAULT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-11 04:08:09 +00:00
|
|
|
WM_check(C); /* opens window(s), checks keymaps */
|
2009-01-23 17:42:36 +00:00
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
bmain->name[0] = '\0';
|
2010-08-25 04:03:38 +00:00
|
|
|
|
2017-03-23 10:32:16 +11:00
|
|
|
/* start with save preference untitled.blend */
|
|
|
|
G.save_over = 0;
|
2012-05-21 09:00:35 +00:00
|
|
|
|
2018-11-30 13:33:13 +11:00
|
|
|
wm_file_read_post(C, true, is_factory_startup, reset_app_template);
|
|
|
|
|
|
|
|
if (r_is_factory_startup) {
|
|
|
|
*r_is_factory_startup = is_factory_startup;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2015-08-09 12:53:09 +10:00
|
|
|
/** \name WM History File API
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
void wm_history_file_read(void)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2009-09-02 17:13:47 +00:00
|
|
|
char name[FILE_MAX];
|
2002-10-12 11:37:38 +00:00
|
|
|
LinkNode *l, *lines;
|
2006-05-30 13:38:22 +00:00
|
|
|
struct RecentFile *recent;
|
2014-04-27 00:21:43 +10:00
|
|
|
const char *line;
|
2006-05-14 19:42:48 +00:00
|
|
|
int num;
|
2014-11-23 15:54:29 +01:00
|
|
|
const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
|
2010-07-04 15:35:23 +00:00
|
|
|
|
|
|
|
if (!cfgdir) return;
|
|
|
|
|
|
|
|
BLI_make_file_string("/", name, cfgdir, BLENDER_HISTORY_FILE);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
lines = BLI_file_read_as_lines(name);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&G.recent_files);
|
2006-05-30 13:38:22 +00:00
|
|
|
|
2011-11-03 03:00:45 +00:00
|
|
|
/* read list of recent opened files from recent-files.txt to memory */
|
2012-03-27 01:24:16 +00:00
|
|
|
for (l = lines, num = 0; l && (num < U.recent_files); l = l->next) {
|
2006-05-14 19:42:48 +00:00
|
|
|
line = l->link;
|
2015-07-16 16:57:10 +10:00
|
|
|
/* don't check if files exist, causes slow startup for remote/external drives */
|
|
|
|
if (line[0]) {
|
2012-03-27 01:24:16 +00:00
|
|
|
recent = (RecentFile *)MEM_mallocN(sizeof(RecentFile), "RecentFile");
|
2006-05-30 13:38:22 +00:00
|
|
|
BLI_addtail(&(G.recent_files), recent);
|
2011-02-13 03:21:27 +00:00
|
|
|
recent->filepath = BLI_strdup(line);
|
2010-01-19 11:11:56 +00:00
|
|
|
num++;
|
2006-05-14 19:42:48 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2011-10-22 15:35:49 +00:00
|
|
|
BLI_file_free_lines(lines);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2015-08-09 12:53:09 +10:00
|
|
|
static RecentFile *wm_history_file_new(const char *filepath)
|
|
|
|
{
|
|
|
|
RecentFile *recent = MEM_mallocN(sizeof(RecentFile), "RecentFile");
|
|
|
|
recent->filepath = BLI_strdup(filepath);
|
|
|
|
return recent;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wm_history_file_free(RecentFile *recent)
|
|
|
|
{
|
|
|
|
BLI_assert(BLI_findindex(&G.recent_files, recent) != -1);
|
|
|
|
MEM_freeN(recent->filepath);
|
|
|
|
BLI_freelinkN(&G.recent_files, recent);
|
|
|
|
}
|
|
|
|
|
|
|
|
static RecentFile *wm_file_history_find(const char *filepath)
|
|
|
|
{
|
|
|
|
return BLI_findstring_ptr(&G.recent_files, filepath, offsetof(RecentFile, filepath));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write #BLENDER_HISTORY_FILE as-is, without checking the environment
|
2018-09-24 17:27:41 +02:00
|
|
|
* (that's handled by #wm_history_file_update).
|
2015-08-09 12:53:09 +10:00
|
|
|
*/
|
|
|
|
static void wm_history_file_write(void)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2013-03-05 03:17:46 +00:00
|
|
|
const char *user_config_dir;
|
2015-08-09 12:53:09 +10:00
|
|
|
char name[FILE_MAX];
|
2002-10-12 11:37:38 +00:00
|
|
|
FILE *fp;
|
|
|
|
|
2010-10-20 23:13:12 +00:00
|
|
|
/* will be NULL in background mode */
|
2014-11-23 15:54:29 +01:00
|
|
|
user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!user_config_dir)
|
2010-10-20 23:13:12 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
BLI_make_file_string("/", name, user_config_dir, BLENDER_HISTORY_FILE);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-08-09 12:53:09 +10:00
|
|
|
fp = BLI_fopen(name, "w");
|
|
|
|
if (fp) {
|
|
|
|
struct RecentFile *recent;
|
|
|
|
for (recent = G.recent_files.first; recent; recent = recent->next) {
|
|
|
|
fprintf(fp, "%s\n", recent->filepath);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run after saving a file to refresh the #BLENDER_HISTORY_FILE list.
|
|
|
|
*/
|
|
|
|
static void wm_history_file_update(void)
|
|
|
|
{
|
|
|
|
RecentFile *recent;
|
2018-06-05 15:10:33 +02:00
|
|
|
const char *blendfile_name = BKE_main_blendfile_path_from_global();
|
2015-08-09 12:53:09 +10:00
|
|
|
|
|
|
|
/* no write history for recovered startup files */
|
2018-06-05 15:10:33 +02:00
|
|
|
if (blendfile_name[0] == '\0') {
|
2015-08-09 12:53:09 +10:00
|
|
|
return;
|
2018-06-05 15:10:33 +02:00
|
|
|
}
|
2015-08-09 12:53:09 +10:00
|
|
|
|
2006-05-31 09:54:26 +00:00
|
|
|
recent = G.recent_files.first;
|
2010-07-15 11:51:43 +00:00
|
|
|
/* refresh recent-files.txt of recent opened files, when current file was changed */
|
2018-06-05 15:10:33 +02:00
|
|
|
if (!(recent) || (BLI_path_cmp(recent->filepath, blendfile_name) != 0)) {
|
2015-08-09 12:53:09 +10:00
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
recent = wm_file_history_find(blendfile_name);
|
2015-08-09 12:53:09 +10:00
|
|
|
if (recent) {
|
|
|
|
BLI_remlink(&G.recent_files, recent);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
RecentFile *recent_next;
|
|
|
|
for (recent = BLI_findlink(&G.recent_files, U.recent_files - 1); recent; recent = recent_next) {
|
|
|
|
recent_next = recent->next;
|
|
|
|
wm_history_file_free(recent);
|
2006-05-29 15:30:43 +00:00
|
|
|
}
|
2018-06-05 15:10:33 +02:00
|
|
|
recent = wm_history_file_new(blendfile_name);
|
2006-05-14 19:42:48 +00:00
|
|
|
}
|
2011-01-05 14:56:10 +00:00
|
|
|
|
2015-08-09 12:53:09 +10:00
|
|
|
/* add current file to the beginning of list */
|
|
|
|
BLI_addhead(&(G.recent_files), recent);
|
|
|
|
|
|
|
|
/* write current file to recent-files.txt */
|
|
|
|
wm_history_file_write();
|
|
|
|
|
2011-01-05 14:56:10 +00:00
|
|
|
/* also update most recent files on System */
|
2018-06-05 15:10:33 +02:00
|
|
|
GHOST_addToSystemRecentFiles(blendfile_name);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-09 12:53:09 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
2012-04-17 20:51:11 +00:00
|
|
|
/* screen can be NULL */
|
Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually
do it. Here it goes; Blender Internal. Bye bye, you did great!
* Point density, voxel data, ocean, environment map textures were removed,
as these only worked within BI rendering. Note that the ocean modifier
and the Cycles point density shader node continue to work.
* Dynamic paint using material shading was removed, as this only worked
with BI. If we ever wanted to support this again probably it should go
through the baking API.
* GPU shader export through the Python API was removed. This only worked
for the old BI GLSL shaders, which no longer exists. Doing something
similar for Eevee would be significantly more complicated because it
uses a lot of multiplass rendering and logic outside the shader, it's
probably impractical.
* Collada material import / export code is mostly gone, as it only worked
for BI materials. We need to add Cycles / Eevee material support at some
point.
* The mesh noise operator was removed since it only worked with BI
material texture slots. A displacement modifier can be used instead.
* The delete texture paint slot operator was removed since it only worked
for BI material texture slots. Could be added back with node support.
* Not all legacy viewport features are supported in the new viewport, but
their code was removed. If we need to bring anything back we can look at
older git revisions.
* There is some legacy viewport code that I could not remove yet, and some
that I probably missed.
* Shader node execution code was left mostly intact, even though it is not
used anywhere now. We may eventually use this to replace the texture
nodes with Cycles / Eevee shader nodes.
* The Cycles Bake panel now includes settings for baking multires normal
and displacement maps. The underlying code needs to be merged properly,
and we plan to add back support for multires AO baking and add support
to Cycles baking for features like vertex color, displacement, and other
missing baking features.
* This commit removes DNA and the Python API for BI material, lamp, world
and scene settings. This breaks a lot of addons.
* There is more DNA that can be removed or renamed, where Cycles or Eevee
are reusing some old BI properties but the names are not really correct
anymore.
* Texture slots for materials, lamps and world were removed. They remain
for brushes, particles and freestyle linestyles.
* 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and
other renderers use this to find all panels to show, minus a few panels
that they have their own replacement for.
2018-04-19 17:34:44 +02:00
|
|
|
static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, bScreen *screen, BlendThumbnail **thumb_pt)
|
2010-05-24 21:52:18 +00:00
|
|
|
{
|
|
|
|
/* will be scaled down, but gives some nice oversampling */
|
|
|
|
ImBuf *ibuf;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
BlendThumbnail *thumb;
|
2012-03-27 01:24:16 +00:00
|
|
|
char err_out[256] = "unknown";
|
2010-05-24 21:52:18 +00:00
|
|
|
|
2012-04-17 20:51:11 +00:00
|
|
|
/* screen if no camera found */
|
|
|
|
ScrArea *sa = NULL;
|
|
|
|
ARegion *ar = NULL;
|
|
|
|
View3D *v3d = NULL;
|
|
|
|
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
/* In case we are given a valid thumbnail data, just generate image from it. */
|
|
|
|
if (*thumb_pt) {
|
|
|
|
thumb = *thumb_pt;
|
|
|
|
return BKE_main_thumbnail_to_imbuf(NULL, thumb);
|
|
|
|
}
|
2011-07-04 05:23:36 +00:00
|
|
|
|
|
|
|
/* scene can be NULL if running a script at startup and calling the save operator */
|
2012-04-17 20:51:11 +00:00
|
|
|
if (G.background || scene == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if ((scene->camera == NULL) && (screen != NULL)) {
|
|
|
|
sa = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0);
|
|
|
|
ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
|
|
|
|
if (ar) {
|
|
|
|
v3d = sa->spacedata.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scene->camera == NULL && v3d == NULL) {
|
2010-05-30 19:21:28 +00:00
|
|
|
return NULL;
|
2012-04-17 20:51:11 +00:00
|
|
|
}
|
2010-05-26 10:52:39 +00:00
|
|
|
|
2010-05-24 21:52:18 +00:00
|
|
|
/* gets scaled to BLEN_THUMB_SIZE */
|
2018-04-06 12:07:27 +02:00
|
|
|
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
2018-04-06 10:55:11 +02:00
|
|
|
|
2012-04-17 20:51:11 +00:00
|
|
|
if (scene->camera) {
|
2015-10-14 12:39:52 +11:00
|
|
|
ibuf = ED_view3d_draw_offscreen_imbuf_simple(
|
Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually
do it. Here it goes; Blender Internal. Bye bye, you did great!
* Point density, voxel data, ocean, environment map textures were removed,
as these only worked within BI rendering. Note that the ocean modifier
and the Cycles point density shader node continue to work.
* Dynamic paint using material shading was removed, as this only worked
with BI. If we ever wanted to support this again probably it should go
through the baking API.
* GPU shader export through the Python API was removed. This only worked
for the old BI GLSL shaders, which no longer exists. Doing something
similar for Eevee would be significantly more complicated because it
uses a lot of multiplass rendering and logic outside the shader, it's
probably impractical.
* Collada material import / export code is mostly gone, as it only worked
for BI materials. We need to add Cycles / Eevee material support at some
point.
* The mesh noise operator was removed since it only worked with BI
material texture slots. A displacement modifier can be used instead.
* The delete texture paint slot operator was removed since it only worked
for BI material texture slots. Could be added back with node support.
* Not all legacy viewport features are supported in the new viewport, but
their code was removed. If we need to bring anything back we can look at
older git revisions.
* There is some legacy viewport code that I could not remove yet, and some
that I probably missed.
* Shader node execution code was left mostly intact, even though it is not
used anywhere now. We may eventually use this to replace the texture
nodes with Cycles / Eevee shader nodes.
* The Cycles Bake panel now includes settings for baking multires normal
and displacement maps. The underlying code needs to be merged properly,
and we plan to add back support for multires AO baking and add support
to Cycles baking for features like vertex color, displacement, and other
missing baking features.
* This commit removes DNA and the Python API for BI material, lamp, world
and scene settings. This breaks a lot of addons.
* There is more DNA that can be removed or renamed, where Cycles or Eevee
are reusing some old BI properties but the names are not really correct
anymore.
* Texture slots for materials, lamps and world were removed. They remain
for brushes, particles and freestyle linestyles.
* 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and
other renderers use this to find all panels to show, minus a few panels
that they have their own replacement for.
2018-04-19 17:34:44 +02:00
|
|
|
depsgraph, scene, OB_SOLID, scene->camera,
|
2015-10-14 12:39:52 +11:00
|
|
|
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
|
2018-04-17 13:35:05 +02:00
|
|
|
IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL,
|
2018-03-22 16:10:54 +01:00
|
|
|
NULL, err_out);
|
2012-04-17 20:51:11 +00:00
|
|
|
}
|
|
|
|
else {
|
2015-10-14 12:39:52 +11:00
|
|
|
ibuf = ED_view3d_draw_offscreen_imbuf(
|
Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually
do it. Here it goes; Blender Internal. Bye bye, you did great!
* Point density, voxel data, ocean, environment map textures were removed,
as these only worked within BI rendering. Note that the ocean modifier
and the Cycles point density shader node continue to work.
* Dynamic paint using material shading was removed, as this only worked
with BI. If we ever wanted to support this again probably it should go
through the baking API.
* GPU shader export through the Python API was removed. This only worked
for the old BI GLSL shaders, which no longer exists. Doing something
similar for Eevee would be significantly more complicated because it
uses a lot of multiplass rendering and logic outside the shader, it's
probably impractical.
* Collada material import / export code is mostly gone, as it only worked
for BI materials. We need to add Cycles / Eevee material support at some
point.
* The mesh noise operator was removed since it only worked with BI
material texture slots. A displacement modifier can be used instead.
* The delete texture paint slot operator was removed since it only worked
for BI material texture slots. Could be added back with node support.
* Not all legacy viewport features are supported in the new viewport, but
their code was removed. If we need to bring anything back we can look at
older git revisions.
* There is some legacy viewport code that I could not remove yet, and some
that I probably missed.
* Shader node execution code was left mostly intact, even though it is not
used anywhere now. We may eventually use this to replace the texture
nodes with Cycles / Eevee shader nodes.
* The Cycles Bake panel now includes settings for baking multires normal
and displacement maps. The underlying code needs to be merged properly,
and we plan to add back support for multires AO baking and add support
to Cycles baking for features like vertex color, displacement, and other
missing baking features.
* This commit removes DNA and the Python API for BI material, lamp, world
and scene settings. This breaks a lot of addons.
* There is more DNA that can be removed or renamed, where Cycles or Eevee
are reusing some old BI properties but the names are not really correct
anymore.
* Texture slots for materials, lamps and world were removed. They remain
for brushes, particles and freestyle linestyles.
* 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and
other renderers use this to find all panels to show, minus a few panels
that they have their own replacement for.
2018-04-19 17:34:44 +02:00
|
|
|
depsgraph, scene, OB_SOLID, v3d, ar,
|
2015-10-14 12:39:52 +11:00
|
|
|
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
|
2017-11-24 11:43:16 +01:00
|
|
|
IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL,
|
2018-03-22 16:10:54 +01:00
|
|
|
NULL, err_out);
|
2012-04-17 20:51:11 +00:00
|
|
|
}
|
2012-02-19 06:00:20 +00:00
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
if (ibuf) {
|
2012-03-27 01:24:16 +00:00
|
|
|
float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp);
|
2010-05-30 09:16:50 +00:00
|
|
|
|
2010-05-24 21:52:18 +00:00
|
|
|
/* dirty oversampling */
|
|
|
|
IMB_scaleImBuf(ibuf, BLEN_THUMB_SIZE, BLEN_THUMB_SIZE);
|
2010-06-01 13:06:13 +00:00
|
|
|
|
|
|
|
/* add pretty overlay */
|
2015-04-08 07:35:53 +10:00
|
|
|
IMB_thumb_overlay_blend(ibuf->rect, ibuf->x, ibuf->y, aspect);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
thumb = BKE_main_thumbnail_from_imbuf(NULL, ibuf);
|
2010-05-26 10:52:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */
|
2011-03-06 23:12:12 +00:00
|
|
|
fprintf(stderr, "blend_file_thumb failed to create thumbnail: %s\n", err_out);
|
2012-03-27 01:24:16 +00:00
|
|
|
thumb = NULL;
|
2010-05-24 21:52:18 +00:00
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-05-24 21:52:18 +00:00
|
|
|
/* must be freed by caller */
|
2012-03-27 01:24:16 +00:00
|
|
|
*thumb_pt = thumb;
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-05-30 19:21:28 +00:00
|
|
|
return ibuf;
|
2010-05-24 21:52:18 +00:00
|
|
|
}
|
|
|
|
|
2010-06-22 08:38:12 +00:00
|
|
|
/* easy access from gdb */
|
2013-12-05 17:26:03 +11:00
|
|
|
bool write_crash_blend(void)
|
2010-06-22 08:38:12 +00:00
|
|
|
{
|
|
|
|
char path[FILE_MAX];
|
2011-06-02 12:44:59 +00:00
|
|
|
int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on crash file */
|
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_strncpy(path, BKE_main_blendfile_path_from_global(), sizeof(path));
|
2018-06-17 16:13:24 +02:00
|
|
|
BLI_path_extension_replace(path, sizeof(path), "_crash.blend");
|
2018-06-14 12:34:13 +02:00
|
|
|
if (BLO_write_file(G_MAIN, path, fileflags, NULL, NULL)) {
|
2010-06-22 08:38:12 +00:00
|
|
|
printf("written: %s\n", path);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("failed: %s\n", path);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-20 12:12:45 +11:00
|
|
|
/**
|
|
|
|
* \see #wm_homefile_write_exec wraps #BLO_write_file in a similar way.
|
|
|
|
*/
|
2018-10-22 15:08:26 +11:00
|
|
|
static bool wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2018-06-05 15:10:33 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2002-10-12 11:37:38 +00:00
|
|
|
Library *li;
|
2009-10-20 13:58:53 +00:00
|
|
|
int len;
|
2018-10-22 15:08:26 +11:00
|
|
|
int ok = false;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
BlendThumbnail *thumb, *main_thumb;
|
2012-03-27 01:24:16 +00:00
|
|
|
ImBuf *ibuf_thumb = NULL;
|
2010-05-24 21:52:18 +00:00
|
|
|
|
2013-08-29 04:26:40 +00:00
|
|
|
len = strlen(filepath);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-04-16 05:24:58 +00:00
|
|
|
if (len == 0) {
|
|
|
|
BKE_report(reports, RPT_ERROR, "Path is empty, cannot save");
|
2018-10-22 15:08:26 +11:00
|
|
|
return ok;
|
2010-04-16 05:24:58 +00:00
|
|
|
}
|
|
|
|
|
2007-10-21 09:32:18 +00:00
|
|
|
if (len >= FILE_MAX) {
|
2008-12-29 13:38:08 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Path too long, cannot save");
|
2018-10-22 15:08:26 +11:00
|
|
|
return ok;
|
2007-10-21 09:32:18 +00:00
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2013-12-19 09:54:02 +01:00
|
|
|
/* Check if file write permission is ok */
|
2013-12-20 02:23:21 +11:00
|
|
|
if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) {
|
2013-12-19 09:54:02 +01:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath);
|
2018-10-22 15:08:26 +11:00
|
|
|
return ok;
|
2013-12-19 09:54:02 +01:00
|
|
|
}
|
2017-06-12 13:35:00 +10:00
|
|
|
|
2013-08-29 04:26:40 +00:00
|
|
|
/* note: used to replace the file extension (to ensure '.blend'),
|
|
|
|
* no need to now because the operator ensures,
|
|
|
|
* its handy for scripts to save to a predefined name without blender editing it */
|
2018-06-07 16:43:52 +02:00
|
|
|
|
BPython:
- Made Blender.event var (previously only used by script links) hold ascii value -- where it applies -- of current event during events callback registered with Draw.Register(gui, events, button_events). Useful for gui scripts like Campbell's Python console. No problem using this var to hold the value, since in gui scripts it was not used (always None).
- Updated Window and Window.Theme with new theme vars and the Time space.
- Script links:
-- Added "Render" event for script links (runs twice, second time as "PostEvent", for clean-up actions). Now FrameChanged links don't run when a single pic is rendered.
-- Added "Enable Script Links" button in the script buttons tab. Now this bit gets saved in .blends along with the rest of G.f, so users can define per .blend if they are on or off by default. "blender -y" also disables all slinks as happened before with OnLoad ones only.
-- Other small changes in the script buttons tab:
When a link is added (button "new"), it becomes the active one for the window, no need to press a button to reach it.
Also, a pupmenu showing all available texts is shown when "new" is pressed, so users can choose a text w/o having to type. Cancel the popup to leave the string button empty (link exists, but has no script assigned). A pulldown would be better UI-wise, but it's kinda weird to show both scripts and normal texts (Blender doesn't differentiate them) in a script links pulldown. With a popup we can show only texts ending in ".py" (not done in this commit, need opinions) and if the script has no or another extension, case of many in old and current .blend's, there's still the string box for writing its name.
-- Implemented Ton's space handler script links:
Right now only for the 3d View, but it's trivial to add for others. There are two types: EVENT, to receive 3d View events from a chosen window and DRAW, to draw on the window. Ton's idea was to give scripts a controlled way to integrate better within Blender.
Here's how it works:
- scripts must have a proper header, like:
# SPACEHANDLER.VIEW3D.EVENT
and then they are shown in 3d View's View menu, "Space Handler Scripts" submenu. Check (mark, click on it) a script to make it active.
EVENT handlers should consult the Blender.event var to get the current event, which can be compared with values from the Draw module:
import Blender
from Blender import Draw
evt = Blender.event
if evt == Draw.AKEY:
print "a"
elif evt == Draw.LEFTMOUSE:
print "left mouse button"
else:
return # ignore, pass event back to Blender
Blender.event = None # tell Blender not to process itself the event
DRAW handlers are free to draw to their owner 3D View. OpenGL attributes and modelview and projection matrices are pushed before running the handler and poped when it finishes.
To communicate between EVENT and DRAW handler scripts we have the Blender.Registry module, as always.
Still need to code some nice example, which should also serve to test properly space handlers. Simple tests went fine.
- doc updates about the additions.
=======
Note: the UI part of the space handlers and script links is of course open for changes, I just tried to make it understandable. Probably we won't use the scriptlinks icon for "None Available" (check 3d View -> View -> Space Handler Scripts), though it hints at what space handlers are. The tooltips may not be accepted either, since other menus don't use them. Opinions welcomed.
2005-05-08 21:20:34 +00:00
|
|
|
/* send the OnSave event */
|
2018-06-05 15:10:33 +02:00
|
|
|
for (li = bmain->library.first; li; li = li->id.next) {
|
2011-05-18 06:27:32 +00:00
|
|
|
if (BLI_path_cmp(li->filepath, filepath) == 0) {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath);
|
2018-10-22 15:08:26 +11:00
|
|
|
return ok;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
/* Call pre-save callbacks befores writing preview, that way you can generate custom file thumbnail... */
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_SAVE_PRE);
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2011-06-25 15:54:20 +00:00
|
|
|
/* blend file thumbnail */
|
|
|
|
/* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */
|
2018-09-24 18:46:51 +02:00
|
|
|
/* Main now can store a .blend thumbnail, useful for background mode or thumbnail customization. */
|
2018-06-08 14:38:57 +02:00
|
|
|
main_thumb = thumb = bmain->blen_thumb;
|
2012-10-05 12:18:07 +00:00
|
|
|
if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) {
|
Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually
do it. Here it goes; Blender Internal. Bye bye, you did great!
* Point density, voxel data, ocean, environment map textures were removed,
as these only worked within BI rendering. Note that the ocean modifier
and the Cycles point density shader node continue to work.
* Dynamic paint using material shading was removed, as this only worked
with BI. If we ever wanted to support this again probably it should go
through the baking API.
* GPU shader export through the Python API was removed. This only worked
for the old BI GLSL shaders, which no longer exists. Doing something
similar for Eevee would be significantly more complicated because it
uses a lot of multiplass rendering and logic outside the shader, it's
probably impractical.
* Collada material import / export code is mostly gone, as it only worked
for BI materials. We need to add Cycles / Eevee material support at some
point.
* The mesh noise operator was removed since it only worked with BI
material texture slots. A displacement modifier can be used instead.
* The delete texture paint slot operator was removed since it only worked
for BI material texture slots. Could be added back with node support.
* Not all legacy viewport features are supported in the new viewport, but
their code was removed. If we need to bring anything back we can look at
older git revisions.
* There is some legacy viewport code that I could not remove yet, and some
that I probably missed.
* Shader node execution code was left mostly intact, even though it is not
used anywhere now. We may eventually use this to replace the texture
nodes with Cycles / Eevee shader nodes.
* The Cycles Bake panel now includes settings for baking multires normal
and displacement maps. The underlying code needs to be merged properly,
and we plan to add back support for multires AO baking and add support
to Cycles baking for features like vertex color, displacement, and other
missing baking features.
* This commit removes DNA and the Python API for BI material, lamp, world
and scene settings. This breaks a lot of addons.
* There is more DNA that can be removed or renamed, where Cycles or Eevee
are reusing some old BI properties but the names are not really correct
anymore.
* Texture slots for materials, lamps and world were removed. They remain
for brushes, particles and freestyle linestyles.
* 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and
other renderers use this to find all panels to show, minus a few panels
that they have their own replacement for.
2018-04-19 17:34:44 +02:00
|
|
|
ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb);
|
2011-07-13 19:16:25 +00:00
|
|
|
}
|
|
|
|
|
2010-09-17 08:53:39 +00:00
|
|
|
/* operator now handles overwrite checks */
|
|
|
|
|
2019-02-02 13:39:51 +11:00
|
|
|
if (G.fileflags & G_FILE_AUTOPACK) {
|
2018-06-05 15:10:33 +02:00
|
|
|
packAll(bmain, reports, false);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2013-03-21 14:12:04 +00:00
|
|
|
|
2010-12-27 18:54:43 +00:00
|
|
|
/* don't forget not to return without! */
|
|
|
|
WM_cursor_wait(1);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2019-01-15 21:25:22 +11:00
|
|
|
ED_editors_flush_edits(bmain, false);
|
2014-01-20 12:12:45 +11:00
|
|
|
|
2011-06-02 12:44:59 +00:00
|
|
|
fileflags |= G_FILE_HISTORY; /* write file history */
|
2010-07-15 10:51:05 +00:00
|
|
|
|
2012-12-14 18:54:22 +00:00
|
|
|
/* first time saving */
|
|
|
|
/* XXX temp solution to solve bug, real fix coming (ton) */
|
2018-06-05 15:10:33 +02:00
|
|
|
if ((BKE_main_blendfile_path(bmain)[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) {
|
|
|
|
BLI_strncpy(bmain->name, filepath, sizeof(bmain->name));
|
2013-10-09 20:27:38 +00:00
|
|
|
}
|
|
|
|
|
2012-12-14 18:54:22 +00:00
|
|
|
/* XXX temp solution to solve bug, real fix coming (ton) */
|
2018-06-05 15:10:33 +02:00
|
|
|
bmain->recovered = 0;
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2011-05-18 06:27:32 +00:00
|
|
|
if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
|
2016-01-29 17:00:32 +11:00
|
|
|
const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
|
|
|
|
|
2012-11-07 04:13:03 +00:00
|
|
|
if (!(fileflags & G_FILE_SAVE_COPY)) {
|
2010-07-19 15:39:12 +00:00
|
|
|
G.relbase_valid = 1;
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_strncpy(bmain->name, filepath, sizeof(bmain->name)); /* is guaranteed current file */
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-07-19 15:39:12 +00:00
|
|
|
G.save_over = 1; /* disable untitled.blend convention */
|
|
|
|
}
|
2009-07-23 21:35:11 +00:00
|
|
|
|
2017-11-20 01:35:49 +11:00
|
|
|
SET_FLAG_FROM_TEST(G.fileflags, fileflags & G_FILE_COMPRESS, G_FILE_COMPRESS);
|
2010-03-05 10:37:55 +00:00
|
|
|
|
2011-06-08 01:53:12 +00:00
|
|
|
/* prevent background mode scripts from clobbering history */
|
2016-01-29 17:00:32 +11:00
|
|
|
if (do_history) {
|
2015-08-09 12:53:09 +10:00
|
|
|
wm_history_file_update();
|
2011-06-08 01:53:12 +00:00
|
|
|
}
|
2010-05-24 21:52:18 +00:00
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_SAVE_POST);
|
2011-06-24 16:54:30 +00:00
|
|
|
|
2010-05-30 19:21:28 +00:00
|
|
|
/* run this function after because the file cant be written before the blend is */
|
|
|
|
if (ibuf_thumb) {
|
2012-04-16 14:34:48 +00:00
|
|
|
IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */
|
2015-06-05 19:42:00 +02:00
|
|
|
ibuf_thumb = IMB_thumb_create(filepath, THB_LARGE, THB_SOURCE_BLEND, ibuf_thumb);
|
2010-05-30 19:21:28 +00:00
|
|
|
}
|
|
|
|
|
2018-10-22 15:08:26 +11:00
|
|
|
/* Success. */
|
|
|
|
ok = true;
|
2010-05-24 21:52:18 +00:00
|
|
|
}
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
|
|
|
if (ibuf_thumb) {
|
|
|
|
IMB_freeImBuf(ibuf_thumb);
|
|
|
|
}
|
|
|
|
if (thumb && thumb != main_thumb) {
|
|
|
|
MEM_freeN(thumb);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2010-11-29 13:14:51 +00:00
|
|
|
WM_cursor_wait(0);
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2018-10-22 15:08:26 +11:00
|
|
|
return ok;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
/************************ autosave ****************************/
|
|
|
|
|
2011-05-18 06:27:32 +00:00
|
|
|
void wm_autosave_location(char *filepath)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2014-11-06 13:08:43 +01:00
|
|
|
const int pid = abs(getpid());
|
2014-11-06 12:42:47 +01:00
|
|
|
char path[1024];
|
2009-10-20 13:58:53 +00:00
|
|
|
#ifdef WIN32
|
2013-03-29 06:25:22 +00:00
|
|
|
const char *savedir;
|
2009-10-20 13:58:53 +00:00
|
|
|
#endif
|
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
if (G_MAIN && G.relbase_valid) {
|
2018-06-05 15:10:33 +02:00
|
|
|
const char *basename = BLI_path_basename(BKE_main_blendfile_path_from_global());
|
2014-11-06 13:08:43 +01:00
|
|
|
int len = strlen(basename) - 6;
|
2015-03-30 19:21:38 +02:00
|
|
|
BLI_snprintf(path, sizeof(path), "%.*s.blend", len, basename);
|
2014-11-06 13:08:43 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLI_snprintf(path, sizeof(path), "%d.blend", pid);
|
|
|
|
}
|
2011-02-12 16:54:24 +00:00
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
#ifdef WIN32
|
2010-07-17 00:38:34 +00:00
|
|
|
/* XXX Need to investigate how to handle default location of '/tmp/'
|
|
|
|
* This is a relative directory on Windows, and it may be
|
|
|
|
* found. Example:
|
|
|
|
* Blender installed on D:\ drive, D:\ drive has D:\tmp\
|
|
|
|
* Now, BLI_exists() will find '/tmp/' exists, but
|
|
|
|
* BLI_make_file_string will create string that has it most likely on C:\
|
|
|
|
* through get_default_root().
|
|
|
|
* If there is no C:\tmp autosave fails. */
|
2014-11-23 15:54:29 +01:00
|
|
|
if (!BLI_exists(BKE_tempdir_base())) {
|
|
|
|
savedir = BKE_appdir_folder_id_create(BLENDER_USER_AUTOSAVE, NULL);
|
2014-11-06 12:42:47 +01:00
|
|
|
BLI_make_file_string("/", filepath, savedir, path);
|
2009-10-20 13:58:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
2011-09-28 19:11:59 +00:00
|
|
|
|
2014-11-23 15:54:29 +01:00
|
|
|
BLI_make_file_string("/", filepath, BKE_tempdir_base(), path);
|
2009-10-20 13:58:53 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2009-12-08 17:23:48 +00:00
|
|
|
void WM_autosave_init(wmWindowManager *wm)
|
2009-10-20 13:58:53 +00:00
|
|
|
{
|
|
|
|
wm_autosave_timer_ended(wm);
|
2008-12-19 00:50:21 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (U.flag & USER_AUTOSAVE)
|
2012-03-27 01:24:16 +00:00
|
|
|
wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(wt))
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2009-10-20 13:58:53 +00:00
|
|
|
wmWindow *win;
|
|
|
|
wmEventHandler *handler;
|
2011-05-18 06:27:32 +00:00
|
|
|
char filepath[FILE_MAX];
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
|
|
|
|
|
|
|
|
/* if a modal operator is running, don't autosave, but try again in 10 seconds */
|
2012-03-27 01:24:16 +00:00
|
|
|
for (win = wm->windows.first; win; win = win->next) {
|
|
|
|
for (handler = win->modalhandlers.first; handler; handler = handler->next) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (handler->op) {
|
2012-03-27 01:24:16 +00:00
|
|
|
wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0);
|
2016-11-18 18:46:10 +01:00
|
|
|
if (G.debug) {
|
|
|
|
printf("Skipping auto-save, modal operator running, retrying in ten seconds...\n");
|
|
|
|
}
|
2009-10-20 13:58:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-08-01 09:04:40 +00:00
|
|
|
|
2011-05-18 06:27:32 +00:00
|
|
|
wm_autosave_location(filepath);
|
2009-10-20 13:58:53 +00:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
if (U.uiflag & USER_GLOBALUNDO) {
|
|
|
|
/* fast save of last undobuffer, now with UI */
|
2018-03-19 14:17:59 +01:00
|
|
|
struct MemFile *memfile = ED_undosys_stack_memfile_get_active(wm->undo_stack);
|
|
|
|
if (memfile) {
|
|
|
|
BLO_memfile_write_file(memfile, filepath);
|
|
|
|
}
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* save as regular blend file */
|
2019-01-15 21:25:22 +11:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2018-04-16 14:07:42 +02:00
|
|
|
int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_HISTORY);
|
2003-11-25 17:36:37 +00:00
|
|
|
|
2019-01-15 21:25:22 +11:00
|
|
|
ED_editors_flush_edits(bmain, false);
|
2015-04-18 15:50:29 +02:00
|
|
|
|
2016-11-18 18:46:10 +01:00
|
|
|
/* Error reporting into console */
|
2019-01-15 21:25:22 +11:00
|
|
|
BLO_write_file(bmain, filepath, fileflags, NULL, NULL);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
}
|
2009-10-20 13:58:53 +00:00
|
|
|
/* do timer after file write, just in case file write takes a long time */
|
2012-03-27 01:24:16 +00:00
|
|
|
wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0);
|
2009-10-20 13:58:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void wm_autosave_timer_ended(wmWindowManager *wm)
|
|
|
|
{
|
2012-03-24 06:24:53 +00:00
|
|
|
if (wm->autosavetimer) {
|
2009-10-20 13:58:53 +00:00
|
|
|
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
|
2012-03-27 01:24:16 +00:00
|
|
|
wm->autosavetimer = NULL;
|
2009-10-20 13:58:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void wm_autosave_delete(void)
|
|
|
|
{
|
|
|
|
char filename[FILE_MAX];
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
wm_autosave_location(filename);
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (BLI_exists(filename)) {
|
2011-11-26 04:07:38 +00:00
|
|
|
char str[FILE_MAX];
|
2014-11-23 15:54:29 +01:00
|
|
|
BLI_make_file_string("/", str, BKE_tempdir_base(), BLENDER_QUIT_FILE);
|
Another step in the undo evolution.
- Made unified API for undo calls, to be found in space.c
BIF_undo_push(char *str)
BIF_undo(void)
BIF_redo(void)
These calls will do all undo levels, including editmode and vpaint.
The transition is work in progress, because mesh undo needs recode.
- New global hotkey CTR+Z for undo
Note: 'shaded draw mode' still is SHIFT+Z, the old CTRL+Z was to recalc
the lighting in shaded mode, which already became much more interactive,
like during/after any transform().
Recalc hotkey now is SHIFT+ALT+Z
CTRL+<any modifier>+Z is redo.
- For OSX users; the Apple-key ("Command") now maps to CTRL as well. This
disables the one-mouse-button hack for rightmouse btw, will be fixed in
next commit. At least we can use Apple-Z :)
- Old Ukey for undo is still there, as a training period... my preference is
to restore Ukey to "reload original data" as in past, and only use new
CTRL+Z for undo.
- Added undo_push() for all of editobject.c and editview.c. Meaning we can
start using/testing global undo in the 3d window. Please dont comment on
missing parts for now, first I want someone to volunteer to tackle all of
that.
- Since the global undo has a full 'file' in memory, it can save extremely
fast on exit to <temp dir>/quit.blend. That's default now when global undo
is enabled. It prints "Saved session recovery to ..." in console then.
- In file menu, a new option is added "Recover Last Session". Note that this
reads the undo-save, which is without UI.
- With such nice new features we then can also kill the disputed
Cancel/Confirm menu on Q-KEY.
- Added fix which initializes seam/normal theme color on saved themes.
They showed black now.... (Note: that's in usiblender.c!)
2004-09-18 12:12:45 +00:00
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
/* if global undo; remove tempsave, otherwise rename */
|
2013-03-05 03:53:22 +00:00
|
|
|
if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false);
|
2009-10-20 13:58:53 +00:00
|
|
|
else BLI_rename(filename, str);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
void wm_autosave_read(bContext *C, ReportList *reports)
|
|
|
|
{
|
|
|
|
char filename[FILE_MAX];
|
|
|
|
|
|
|
|
wm_autosave_location(filename);
|
2012-08-11 21:35:24 +00:00
|
|
|
WM_file_read(C, filename, reports);
|
2009-10-20 13:58:53 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2014-04-03 11:04:02 +11:00
|
|
|
|
|
|
|
/** \name Initialize WM_OT_open_xxx properties
|
|
|
|
*
|
|
|
|
* Check if load_ui was set by the caller.
|
|
|
|
* Fall back to user preference when file flags not specified.
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
void wm_open_init_load_ui(wmOperator *op, bool use_prefs)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "load_ui");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
bool value = use_prefs ?
|
|
|
|
((U.flag & USER_FILENOUI) == 0) :
|
|
|
|
((G.fileflags & G_FILE_NO_UI) == 0);
|
|
|
|
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void wm_open_init_use_scripts(wmOperator *op, bool use_prefs)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
2019-02-02 13:39:51 +11:00
|
|
|
/* use G_FLAG_SCRIPT_AUTOEXEC rather than the userpref because this means if
|
2014-04-03 11:04:02 +11:00
|
|
|
* the flag has been disabled from the command line, then opening
|
|
|
|
* from the menu wont enable this setting. */
|
|
|
|
bool value = use_prefs ?
|
|
|
|
((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) :
|
2019-02-02 13:39:51 +11:00
|
|
|
((G.f & G_FLAG_SCRIPT_AUTOEXEC) != 0);
|
2014-04-03 11:04:02 +11:00
|
|
|
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
2015-10-28 04:10:00 +05:00
|
|
|
|
2018-02-16 23:37:47 +11:00
|
|
|
void WM_file_tag_modified(void)
|
2015-10-28 04:10:00 +05:00
|
|
|
{
|
2018-06-14 12:34:13 +02:00
|
|
|
wmWindowManager *wm = G_MAIN->wm.first;
|
2015-10-28 04:10:00 +05:00
|
|
|
if (wm->file_saved) {
|
|
|
|
wm->file_saved = 0;
|
|
|
|
/* notifier that data changed, for save-over warning or header */
|
2018-02-16 23:37:47 +11:00
|
|
|
WM_main_add_notifier(NC_WM | ND_DATACHANGED, NULL);
|
2015-10-28 04:10:00 +05:00
|
|
|
}
|
|
|
|
}
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/** \name Preferences/startup save & load.
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \see #wm_file_write wraps #BLO_write_file in a similar way.
|
2018-10-22 15:08:26 +11:00
|
|
|
* \return success.
|
2016-04-19 17:08:31 +02:00
|
|
|
*/
|
|
|
|
static int wm_homefile_write_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2018-06-14 12:34:13 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2016-04-19 17:08:31 +02:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
int fileflags;
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
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 user config path");
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_SAVE_PRE);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/* check current window and close it if temp */
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
if (win && WM_window_is_temp_screen(win))
|
2016-04-19 17:08:31 +02:00
|
|
|
wm_window_close(C, wm, win);
|
|
|
|
|
|
|
|
/* update keymaps in user preferences */
|
|
|
|
WM_keyconfig_update(wm);
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_STARTUP_FILE, NULL);
|
|
|
|
|
2018-11-28 08:29:02 +11:00
|
|
|
printf("Writing homefile: '%s' ", filepath);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
2019-01-15 21:25:22 +11:00
|
|
|
ED_editors_flush_edits(bmain, false);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/* force save as regular blend file */
|
2018-04-16 14:07:42 +02:00
|
|
|
fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_HISTORY);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
if (BLO_write_file(bmain, filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) {
|
2016-04-19 17:08:31 +02:00
|
|
|
printf("fail\n");
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("ok\n");
|
|
|
|
|
|
|
|
G.save_over = 0;
|
|
|
|
|
2018-06-14 12:34:13 +02:00
|
|
|
BLI_callback_exec(bmain, NULL, BLI_CB_EVT_SAVE_POST);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_save_homefile(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Save Startup File";
|
|
|
|
ot->idname = "WM_OT_save_homefile";
|
2018-08-28 15:12:14 +02:00
|
|
|
ot->description = "Make the current file the default .blend file";
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
ot->exec = wm_homefile_write_exec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_userpref_autoexec_add_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
|
|
|
{
|
|
|
|
bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
|
|
|
|
BLI_addtail(&U.autoexec_paths, path_cmp);
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_userpref_autoexec_path_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Add Autoexec Path";
|
|
|
|
ot->idname = "WM_OT_userpref_autoexec_path_add";
|
|
|
|
ot->description = "Add path to exclude from autoexecution";
|
|
|
|
|
|
|
|
ot->exec = wm_userpref_autoexec_add_exec;
|
|
|
|
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_userpref_autoexec_remove_exec(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
const int index = RNA_int_get(op->ptr, "index");
|
|
|
|
bPathCompare *path_cmp = BLI_findlink(&U.autoexec_paths, index);
|
|
|
|
if (path_cmp) {
|
|
|
|
BLI_freelinkN(&U.autoexec_paths, path_cmp);
|
|
|
|
}
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_userpref_autoexec_path_remove(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Remove Autoexec Path";
|
|
|
|
ot->idname = "WM_OT_userpref_autoexec_path_remove";
|
|
|
|
ot->description = "Remove path to exclude from autoexecution";
|
|
|
|
|
|
|
|
ot->exec = wm_userpref_autoexec_remove_exec;
|
|
|
|
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
|
|
|
|
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only save the prefs block. operator entry */
|
|
|
|
static int wm_userpref_write_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
char filepath[FILE_MAX];
|
2017-03-25 09:29:51 +11:00
|
|
|
const char *cfgdir;
|
2017-11-22 17:11:03 +11:00
|
|
|
bool ok = true;
|
2018-08-28 15:12:14 +02:00
|
|
|
bool use_template_userpref = wm_app_template_has_userpref(U.app_template);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/* update keymaps in user preferences */
|
|
|
|
WM_keyconfig_update(wm);
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
|
2017-11-23 03:10:58 +11:00
|
|
|
bool ok_write;
|
2017-03-25 09:29:51 +11:00
|
|
|
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
|
2017-11-23 03:10:58 +11:00
|
|
|
|
2018-11-28 08:29:02 +11:00
|
|
|
printf("Writing userprefs: '%s' ", filepath);
|
2018-08-28 15:12:14 +02:00
|
|
|
if (use_template_userpref) {
|
2017-11-23 03:10:58 +11:00
|
|
|
ok_write = BKE_blendfile_userdef_write_app_template(filepath, op->reports);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ok_write = BKE_blendfile_userdef_write(filepath, op->reports);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ok_write) {
|
2017-03-25 09:29:51 +11:00
|
|
|
printf("ok\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("fail\n");
|
2017-11-22 17:11:03 +11:00
|
|
|
ok = false;
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Unable to create userpref path");
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
2018-08-28 15:12:14 +02:00
|
|
|
if (use_template_userpref) {
|
2017-11-22 17:11:03 +11:00
|
|
|
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) {
|
|
|
|
/* Also save app-template prefs */
|
|
|
|
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
|
2018-11-28 08:29:02 +11:00
|
|
|
|
|
|
|
printf("Writing userprefs app-template: '%s' ", filepath);
|
2017-11-22 17:11:03 +11:00
|
|
|
if (BKE_blendfile_userdef_write(filepath, op->reports) != 0) {
|
|
|
|
printf("ok\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("fail\n");
|
|
|
|
ok = false;
|
|
|
|
}
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
else {
|
2017-11-22 17:11:03 +11:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Unable to create app-template userpref path");
|
|
|
|
ok = false;
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
}
|
2016-04-19 17:08:31 +02:00
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_save_userpref(wmOperatorType *ot)
|
|
|
|
{
|
2018-11-28 12:21:49 +01:00
|
|
|
ot->name = "Save Preferences";
|
2016-04-19 17:08:31 +02:00
|
|
|
ot->idname = "WM_OT_save_userpref";
|
2019-01-04 21:40:16 +01:00
|
|
|
ot->description = "Save preferences separately, overrides startup file preferences";
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
ot->exec = wm_userpref_write_exec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_history_file_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
|
|
|
{
|
|
|
|
ED_file_read_bookmarks();
|
|
|
|
wm_history_file_read();
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_read_history(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Reload History File";
|
|
|
|
ot->idname = "WM_OT_read_history";
|
|
|
|
ot->description = "Reloads history and bookmarks";
|
|
|
|
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
ot->exec = wm_history_file_read_exec;
|
|
|
|
|
|
|
|
/* this operator is only used for loading settings from a previous blender install */
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_homefile_read_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2017-03-23 10:32:16 +11:00
|
|
|
const bool use_factory_settings = (STREQ(op->type->idname, "WM_OT_read_factory_settings"));
|
2017-08-11 09:29:25 +10:00
|
|
|
bool use_userdef = false;
|
2016-04-19 17:08:31 +02:00
|
|
|
char filepath_buf[FILE_MAX];
|
|
|
|
const char *filepath = NULL;
|
|
|
|
|
2017-03-23 10:32:16 +11:00
|
|
|
if (!use_factory_settings) {
|
2016-04-19 17:08:31 +02:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
|
|
|
|
|
|
|
|
/* This can be used when loading of a start-up file should only change
|
|
|
|
* the scene content but keep the blender UI as it is. */
|
|
|
|
wm_open_init_load_ui(op, true);
|
2017-11-20 01:35:49 +11:00
|
|
|
SET_FLAG_FROM_TEST(G.fileflags, !RNA_boolean_get(op->ptr, "load_ui"), G_FILE_NO_UI);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
if (RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
RNA_property_string_get(op->ptr, prop, filepath_buf);
|
|
|
|
filepath = filepath_buf;
|
|
|
|
if (BLI_access(filepath, R_OK)) {
|
|
|
|
BKE_reportf(op->reports, RPT_ERROR, "Can't read alternative start-up file: '%s'", filepath);
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* always load UI for factory settings (prefs will re-init) */
|
|
|
|
G.fileflags &= ~G_FILE_NO_UI;
|
2017-08-11 09:29:25 +10:00
|
|
|
/* Always load preferences with factory settings. */
|
|
|
|
use_userdef = true;
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
char app_template_buf[sizeof(U.app_template)];
|
|
|
|
const char *app_template;
|
|
|
|
PropertyRNA *prop_app_template = RNA_struct_find_property(op->ptr, "app_template");
|
|
|
|
const bool use_splash = !use_factory_settings && RNA_boolean_get(op->ptr, "use_splash");
|
2017-03-29 19:07:21 +11:00
|
|
|
const bool use_empty_data = RNA_boolean_get(op->ptr, "use_empty");
|
2017-03-25 09:29:51 +11:00
|
|
|
|
|
|
|
if (prop_app_template && RNA_property_is_set(op->ptr, prop_app_template)) {
|
|
|
|
RNA_property_string_get(op->ptr, prop_app_template, app_template_buf);
|
|
|
|
app_template = app_template_buf;
|
2017-08-11 09:29:25 +10:00
|
|
|
|
2018-08-28 15:12:14 +02:00
|
|
|
/* Always load preferences when switching templates with own preferences. */
|
|
|
|
use_userdef = wm_app_template_has_userpref(app_template) ||
|
|
|
|
wm_app_template_has_userpref(U.app_template);
|
2018-08-17 16:34:51 +10:00
|
|
|
|
|
|
|
/* Turn override off, since we're explicitly loading a different app-template. */
|
|
|
|
WM_init_state_app_template_set(NULL);
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
else {
|
2018-08-17 16:34:51 +10:00
|
|
|
/* Normally NULL, only set when overriding from the command-line. */
|
|
|
|
app_template = WM_init_state_app_template_get();
|
2017-03-25 09:29:51 +11:00
|
|
|
}
|
|
|
|
|
2018-11-30 13:33:13 +11:00
|
|
|
wm_homefile_read(C, op->reports, use_factory_settings, use_empty_data, use_userdef, filepath, app_template, NULL);
|
2018-11-30 13:21:12 +11:00
|
|
|
if (use_splash) {
|
|
|
|
WM_init_splash(C);
|
2017-03-14 21:05:00 +11:00
|
|
|
}
|
2018-11-30 13:21:12 +11:00
|
|
|
return OPERATOR_FINISHED;
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
2018-08-28 15:12:14 +02:00
|
|
|
static int wm_homefile_read_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
|
|
|
|
{
|
|
|
|
/* Draw menu which includes default startup and application templates. */
|
2018-10-01 10:45:50 +02:00
|
|
|
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("New File"), ICON_FILE_NEW);
|
2018-08-28 15:12:14 +02:00
|
|
|
uiLayout *layout = UI_popup_menu_layout(pup);
|
|
|
|
|
|
|
|
MenuType *mt = WM_menutype_find("TOPBAR_MT_file_new", false);
|
|
|
|
if (mt) {
|
|
|
|
UI_menutype_draw(C, mt, layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
UI_popup_menu_end(C, pup);
|
|
|
|
|
|
|
|
return OPERATOR_INTERFACE;
|
|
|
|
}
|
|
|
|
|
2016-04-19 17:08:31 +02:00
|
|
|
void WM_OT_read_homefile(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
ot->name = "Reload Start-Up File";
|
|
|
|
ot->idname = "WM_OT_read_homefile";
|
|
|
|
ot->description = "Open the default file (doesn't save the current file)";
|
|
|
|
|
2018-08-28 15:12:14 +02:00
|
|
|
ot->invoke = wm_homefile_read_invoke;
|
2016-04-19 17:08:31 +02:00
|
|
|
ot->exec = wm_homefile_read_exec;
|
|
|
|
|
|
|
|
prop = RNA_def_string_file_path(ot->srna, "filepath", NULL,
|
|
|
|
FILE_MAX, "File Path",
|
|
|
|
"Path to an alternative start-up file");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
|
|
|
/* So scripts can use an alternative start-up file without the UI */
|
|
|
|
prop = RNA_def_boolean(ot->srna, "load_ui", true, "Load UI",
|
|
|
|
"Load user interface setup from the .blend file");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
|
2017-03-29 19:07:21 +11:00
|
|
|
prop = RNA_def_boolean(ot->srna, "use_empty", false, "Empty", "");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
|
2017-03-14 21:05:00 +11:00
|
|
|
/* So the splash can be kept open after loading a file (for templates). */
|
2017-03-20 12:46:20 +11:00
|
|
|
prop = RNA_def_boolean(ot->srna, "use_splash", false, "Splash", "");
|
2017-03-14 21:05:00 +11:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
|
2017-03-25 09:29:51 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "app_template", "Template", sizeof(U.app_template), "", "");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
|
2016-04-19 17:08:31 +02:00
|
|
|
/* omit poll to run in background mode */
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_read_factory_settings(wmOperatorType *ot)
|
|
|
|
{
|
2017-03-25 09:29:51 +11:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
2016-04-19 17:08:31 +02:00
|
|
|
ot->name = "Load Factory Settings";
|
|
|
|
ot->idname = "WM_OT_read_factory_settings";
|
2019-01-04 21:40:16 +01:00
|
|
|
ot->description = "Load default file and preferences";
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
ot->exec = wm_homefile_read_exec;
|
2017-03-25 09:29:51 +11:00
|
|
|
|
|
|
|
prop = RNA_def_string(ot->srna, "app_template", "Template", sizeof(U.app_template), "", "");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
|
2017-03-29 19:07:21 +11:00
|
|
|
prop = RNA_def_boolean(ot->srna, "use_empty", false, "Empty", "");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
|
2016-04-19 17:08:31 +02:00
|
|
|
/* omit poll to run in background mode */
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/** \name Open main .blend file.
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrap #WM_file_read, shared by file reading operators.
|
|
|
|
*/
|
|
|
|
static bool wm_file_read_opwrap(bContext *C, const char *filepath, ReportList *reports,
|
|
|
|
const bool autoexec_init)
|
|
|
|
{
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
/* XXX wm in context is not set correctly after WM_file_read -> crash */
|
|
|
|
/* do it before for now, but is this correct with multiple windows? */
|
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
|
|
|
|
|
|
|
if (autoexec_init) {
|
|
|
|
WM_file_autoexec_init(filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
success = WM_file_read(C, filepath, reports);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* currently fits in a pointer */
|
|
|
|
struct FileRuntime {
|
|
|
|
bool is_untrusted;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
{
|
2018-06-05 15:10:33 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
const char *openname = BKE_main_blendfile_path(bmain);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
if (CTX_wm_window(C) == NULL) {
|
|
|
|
/* in rare cases this could happen, when trying to invoke in background
|
|
|
|
* mode on load for example. Don't use poll for this because exec()
|
|
|
|
* can still run without a window */
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Context window not set");
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if possible, get the name of the most recently used .blend file */
|
|
|
|
if (G.recent_files.first) {
|
|
|
|
struct RecentFile *recent = G.recent_files.first;
|
|
|
|
openname = recent->filepath;
|
|
|
|
}
|
|
|
|
|
|
|
|
RNA_string_set(op->ptr, "filepath", openname);
|
|
|
|
wm_open_init_load_ui(op, true);
|
|
|
|
wm_open_init_use_scripts(op, true);
|
|
|
|
op->customdata = NULL;
|
|
|
|
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
|
|
|
|
|
|
|
/* re-use last loaded setting so we can reload a file without changing */
|
|
|
|
wm_open_init_load_ui(op, false);
|
|
|
|
wm_open_init_use_scripts(op, false);
|
|
|
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "load_ui"))
|
|
|
|
G.fileflags &= ~G_FILE_NO_UI;
|
|
|
|
else
|
|
|
|
G.fileflags |= G_FILE_NO_UI;
|
|
|
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "use_scripts"))
|
2019-02-02 13:39:51 +11:00
|
|
|
G.f |= G_FLAG_SCRIPT_AUTOEXEC;
|
2016-04-19 17:08:31 +02:00
|
|
|
else
|
2019-02-02 13:39:51 +11:00
|
|
|
G.f &= ~G_FLAG_SCRIPT_AUTOEXEC;
|
2016-04-19 17:08:31 +02:00
|
|
|
|
2019-02-02 13:39:51 +11:00
|
|
|
success = wm_file_read_opwrap(C, filepath, op->reports, !(G.f & G_FLAG_SCRIPT_AUTOEXEC));
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/* for file open also popup for warnings, not only errors */
|
|
|
|
BKE_report_print_level_set(op->reports, RPT_WARNING);
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
|
|
|
|
bool is_untrusted = false;
|
|
|
|
char path[FILE_MAX];
|
|
|
|
char *lslash;
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
|
|
|
|
|
|
|
/* get the dir */
|
|
|
|
lslash = (char *)BLI_last_slash(path);
|
|
|
|
if (lslash) *(lslash + 1) = '\0';
|
|
|
|
|
|
|
|
if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) {
|
|
|
|
if (BKE_autoexec_match(path) == true) {
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, false);
|
|
|
|
is_untrusted = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file_info) {
|
|
|
|
file_info->is_untrusted = is_untrusted;
|
|
|
|
}
|
|
|
|
|
|
|
|
return is_untrusted;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
|
|
|
|
uiLayout *layout = op->layout;
|
|
|
|
uiLayout *col = op->layout;
|
|
|
|
const char *autoexec_text;
|
|
|
|
|
|
|
|
uiItemR(layout, op->ptr, "load_ui", 0, NULL, ICON_NONE);
|
|
|
|
|
|
|
|
col = uiLayoutColumn(layout, false);
|
|
|
|
if (file_info->is_untrusted) {
|
|
|
|
autoexec_text = IFACE_("Trusted Source [Untrusted Path]");
|
|
|
|
uiLayoutSetActive(col, false);
|
|
|
|
uiLayoutSetEnabled(col, false);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
autoexec_text = IFACE_("Trusted Source");
|
|
|
|
}
|
|
|
|
|
|
|
|
uiItemR(col, op->ptr, "use_scripts", 0, autoexec_text, ICON_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_open_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Open Blender File";
|
|
|
|
ot->idname = "WM_OT_open_mainfile";
|
|
|
|
ot->description = "Open a Blender file";
|
|
|
|
|
|
|
|
ot->invoke = wm_open_mainfile_invoke;
|
|
|
|
ot->exec = wm_open_mainfile_exec;
|
|
|
|
ot->check = wm_open_mainfile_check;
|
|
|
|
ot->ui = wm_open_mainfile_ui;
|
|
|
|
/* omit window poll so this can work in background mode */
|
|
|
|
|
|
|
|
WM_operator_properties_filesel(
|
|
|
|
ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_OPENFILE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
|
|
|
|
|
|
|
|
RNA_def_boolean(ot->srna, "load_ui", true, "Load UI", "Load user interface setup in the .blend file");
|
|
|
|
RNA_def_boolean(ot->srna, "use_scripts", true, "Trusted Source",
|
|
|
|
"Allow .blend file to execute scripts automatically, default available from system preferences");
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/** \name Reload (revert) main .blend file.
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
static int wm_revert_mainfile_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2018-06-05 15:10:33 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2016-04-19 17:08:31 +02:00
|
|
|
bool success;
|
2016-04-26 14:24:57 +02:00
|
|
|
char filepath[FILE_MAX];
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
wm_open_init_use_scripts(op, false);
|
|
|
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "use_scripts"))
|
2019-02-02 13:39:51 +11:00
|
|
|
G.f |= G_FLAG_SCRIPT_AUTOEXEC;
|
2016-04-19 17:08:31 +02:00
|
|
|
else
|
2019-02-02 13:39:51 +11:00
|
|
|
G.f &= ~G_FLAG_SCRIPT_AUTOEXEC;
|
2016-04-19 17:08:31 +02:00
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
|
2019-02-02 13:39:51 +11:00
|
|
|
success = wm_file_read_opwrap(C, filepath, op->reports, !(G.f & G_FLAG_SCRIPT_AUTOEXEC));
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
if (success) {
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool wm_revert_mainfile_poll(bContext *UNUSED(C))
|
2016-04-19 17:08:31 +02:00
|
|
|
{
|
|
|
|
return G.relbase_valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_revert_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Revert";
|
|
|
|
ot->idname = "WM_OT_revert_mainfile";
|
|
|
|
ot->description = "Reload the saved file";
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
|
|
|
|
RNA_def_boolean(ot->srna, "use_scripts", true, "Trusted Source",
|
|
|
|
"Allow .blend file to execute scripts automatically, default available from system preferences");
|
|
|
|
|
|
|
|
ot->exec = wm_revert_mainfile_exec;
|
|
|
|
ot->poll = wm_revert_mainfile_poll;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/** \name Recover last session & auto-save.
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
void WM_recover_last_session(bContext *C, ReportList *reports)
|
|
|
|
{
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
|
|
|
|
BLI_make_file_string("/", filepath, BKE_tempdir_base(), BLENDER_QUIT_FILE);
|
|
|
|
/* if reports==NULL, it's called directly without operator, we add a quick check here */
|
|
|
|
if (reports || BLI_exists(filepath)) {
|
|
|
|
G.fileflags |= G_FILE_RECOVER;
|
|
|
|
|
|
|
|
wm_file_read_opwrap(C, filepath, reports, true);
|
|
|
|
|
|
|
|
G.fileflags &= ~G_FILE_RECOVER;
|
|
|
|
|
|
|
|
/* XXX bad global... fixme */
|
2018-12-07 15:04:57 +11:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2018-06-05 15:10:33 +02:00
|
|
|
if (BKE_main_blendfile_path(bmain)[0] != '\0') {
|
2016-04-19 17:08:31 +02:00
|
|
|
G.file_loaded = 1; /* prevents splash to show */
|
2018-06-05 15:10:33 +02:00
|
|
|
}
|
2016-04-19 17:08:31 +02:00
|
|
|
else {
|
|
|
|
G.relbase_valid = 0;
|
|
|
|
G.save_over = 0; /* start with save preference untitled.blend */
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
WM_recover_last_session(C, op->reports);
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_recover_last_session(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Recover Last Session";
|
|
|
|
ot->idname = "WM_OT_recover_last_session";
|
|
|
|
ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")";
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
|
|
|
|
ot->exec = wm_recover_last_session_exec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
|
|
|
|
|
|
|
G.fileflags |= G_FILE_RECOVER;
|
|
|
|
|
|
|
|
success = wm_file_read_opwrap(C, filepath, op->reports, true);
|
|
|
|
|
|
|
|
G.fileflags &= ~G_FILE_RECOVER;
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
{
|
|
|
|
char filename[FILE_MAX];
|
|
|
|
|
|
|
|
wm_autosave_location(filename);
|
|
|
|
RNA_string_set(op->ptr, "filepath", filename);
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
WM_operator_properties_filesel(
|
|
|
|
ot, FILE_TYPE_BLENDER, FILE_BLENDER, FILE_OPENFILE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_LONGDISPLAY, FILE_SORT_TIME);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/** \name Save main .blend file.
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
static void wm_filepath_default(char *filepath)
|
|
|
|
{
|
|
|
|
if (G.save_over == false) {
|
|
|
|
BLI_ensure_filename(filepath, FILE_MAX, "untitled.blend");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void save_set_compress(wmOperator *op)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
prop = RNA_struct_find_property(op->ptr, "compress");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
if (G.save_over) { /* keep flag for existing file */
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, (G.fileflags & G_FILE_COMPRESS) != 0);
|
|
|
|
}
|
|
|
|
else { /* use userdef for new file */
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, (U.flag & USER_FILECOMPRESS) != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
static void save_set_filepath(bContext *C, wmOperator *op)
|
2016-04-19 17:08:31 +02:00
|
|
|
{
|
2018-06-05 15:10:33 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2016-04-19 17:08:31 +02:00
|
|
|
PropertyRNA *prop;
|
|
|
|
char name[FILE_MAX];
|
|
|
|
|
|
|
|
prop = RNA_struct_find_property(op->ptr, "filepath");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
/* if not saved before, get the name of the most recently used .blend file */
|
2018-06-05 15:10:33 +02:00
|
|
|
if (BKE_main_blendfile_path(bmain)[0] == '\0' && G.recent_files.first) {
|
2016-04-19 17:08:31 +02:00
|
|
|
struct RecentFile *recent = G.recent_files.first;
|
|
|
|
BLI_strncpy(name, recent->filepath, FILE_MAX);
|
|
|
|
}
|
|
|
|
else {
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_strncpy(name, bmain->name, FILE_MAX);
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
wm_filepath_default(name);
|
|
|
|
RNA_property_string_set(op->ptr, prop, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
{
|
|
|
|
|
|
|
|
save_set_compress(op);
|
2018-06-05 15:10:33 +02:00
|
|
|
save_set_filepath(C, op);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* function used for WM_OT_save_mainfile too */
|
|
|
|
static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2018-06-05 15:10:33 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2016-04-19 17:08:31 +02:00
|
|
|
char path[FILE_MAX];
|
2018-10-22 14:51:06 +11:00
|
|
|
const bool is_save_as = (op->type->invoke == wm_save_as_mainfile_invoke);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
save_set_compress(op);
|
|
|
|
|
|
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
|
|
|
}
|
|
|
|
else {
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_strncpy(path, BKE_main_blendfile_path(bmain), FILE_MAX);
|
2016-04-19 17:08:31 +02:00
|
|
|
wm_filepath_default(path);
|
|
|
|
}
|
|
|
|
|
2018-10-22 15:08:26 +11:00
|
|
|
const int fileflags_orig = G.fileflags;
|
|
|
|
int fileflags = G.fileflags & ~G_FILE_USERPREFS;
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/* set compression flag */
|
2017-11-20 01:35:49 +11:00
|
|
|
SET_FLAG_FROM_TEST(
|
|
|
|
fileflags, RNA_boolean_get(op->ptr, "compress"),
|
|
|
|
G_FILE_COMPRESS);
|
|
|
|
SET_FLAG_FROM_TEST(
|
|
|
|
fileflags, RNA_boolean_get(op->ptr, "relative_remap"),
|
|
|
|
G_FILE_RELATIVE_REMAP);
|
|
|
|
SET_FLAG_FROM_TEST(
|
|
|
|
fileflags,
|
|
|
|
(RNA_struct_property_is_set(op->ptr, "copy") &&
|
|
|
|
RNA_boolean_get(op->ptr, "copy")),
|
|
|
|
G_FILE_SAVE_COPY);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
2018-10-22 15:08:26 +11:00
|
|
|
const bool ok = wm_file_write(C, path, fileflags, op->reports);
|
2018-10-12 10:24:07 +02:00
|
|
|
|
|
|
|
if ((op->flag & OP_IS_INVOKE) == 0) {
|
|
|
|
/* OP_IS_INVOKE is set when the operator is called from the GUI.
|
|
|
|
* If it is not set, the operator is called from a script and
|
|
|
|
* shouldn't influence G.fileflags. */
|
2018-10-22 15:08:26 +11:00
|
|
|
G.fileflags = fileflags_orig;
|
2018-10-12 10:24:07 +02:00
|
|
|
}
|
|
|
|
|
2018-10-22 15:08:26 +11:00
|
|
|
if (ok == false) {
|
2016-04-19 17:08:31 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
2018-10-12 10:24:07 +02:00
|
|
|
}
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL);
|
|
|
|
|
2018-10-22 14:51:06 +11:00
|
|
|
if (!is_save_as && RNA_boolean_get(op->ptr, "exit")) {
|
2018-03-22 23:29:48 +01:00
|
|
|
wm_exit_schedule_delayed(C);
|
2018-03-21 16:00:18 +01:00
|
|
|
}
|
|
|
|
|
2016-04-19 17:08:31 +02:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* function used for WM_OT_save_mainfile too */
|
|
|
|
static bool blend_save_check(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
|
|
|
if (!BLO_has_bfile_extension(filepath)) {
|
2018-06-17 16:13:24 +02:00
|
|
|
/* some users would prefer BLI_path_extension_replace(),
|
2016-04-19 17:08:31 +02:00
|
|
|
* we keep getting nitpicking bug reports about this - campbell */
|
2018-06-17 16:13:24 +02:00
|
|
|
BLI_path_extension_ensure(filepath, FILE_MAX, ".blend");
|
2016-04-19 17:08:31 +02:00
|
|
|
RNA_string_set(op->ptr, "filepath", filepath);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_save_as_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
ot->name = "Save As Blender File";
|
|
|
|
ot->idname = "WM_OT_save_as_mainfile";
|
|
|
|
ot->description = "Save the current file in the desired location";
|
|
|
|
|
|
|
|
ot->invoke = wm_save_as_mainfile_invoke;
|
|
|
|
ot->exec = wm_save_as_mainfile_exec;
|
|
|
|
ot->check = blend_save_check;
|
|
|
|
/* omit window poll so this can work in background mode */
|
|
|
|
|
|
|
|
WM_operator_properties_filesel(
|
|
|
|
ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
|
|
|
|
RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file");
|
|
|
|
RNA_def_boolean(ot->srna, "relative_remap", true, "Remap Relative",
|
|
|
|
"Remap relative paths when saving in a different directory");
|
|
|
|
prop = RNA_def_boolean(ot->srna, "copy", false, "Save Copy",
|
|
|
|
"Save a copy of the actual working state but does not make saved file active");
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* cancel if no active window */
|
|
|
|
if (CTX_wm_window(C) == NULL)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
save_set_compress(op);
|
2018-06-05 15:10:33 +02:00
|
|
|
save_set_filepath(C, op);
|
2016-04-19 17:08:31 +02:00
|
|
|
|
|
|
|
/* if we're saving for the first time and prefer relative paths - any existing paths will be absolute,
|
|
|
|
* enable the option to remap paths to avoid confusion [#37240] */
|
|
|
|
if ((G.relbase_valid == false) && (U.flag & USER_RELPATHS)) {
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "relative_remap");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (G.save_over) {
|
|
|
|
char path[FILE_MAX];
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
2018-02-27 13:33:59 +11:00
|
|
|
if (RNA_boolean_get(op->ptr, "check_existing") && BLI_exists(path)) {
|
2016-04-19 17:08:31 +02:00
|
|
|
ret = WM_operator_confirm_message_ex(C, op, IFACE_("Save Over?"), ICON_QUESTION, path);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ret = wm_save_as_mainfile_exec(C, op);
|
2018-02-27 13:33:59 +11:00
|
|
|
/* Without this there is no feedback the file was saved. */
|
|
|
|
BKE_reportf(op->reports, RPT_INFO, "Saved \"%s\"", BLI_path_basename(path));
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
ret = OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_save_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Save Blender File";
|
|
|
|
ot->idname = "WM_OT_save_mainfile";
|
|
|
|
ot->description = "Save the current Blender file";
|
|
|
|
|
|
|
|
ot->invoke = wm_save_mainfile_invoke;
|
|
|
|
ot->exec = wm_save_as_mainfile_exec;
|
|
|
|
ot->check = blend_save_check;
|
|
|
|
/* omit window poll so this can work in background mode */
|
|
|
|
|
2018-03-21 16:00:18 +01:00
|
|
|
PropertyRNA *prop;
|
2016-04-19 17:08:31 +02:00
|
|
|
WM_operator_properties_filesel(
|
|
|
|
ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
|
|
|
|
RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file");
|
|
|
|
RNA_def_boolean(ot->srna, "relative_remap", false, "Remap Relative",
|
|
|
|
"Remap relative paths when saving in a different directory");
|
2018-03-21 16:00:18 +01:00
|
|
|
|
|
|
|
prop = RNA_def_boolean(ot->srna, "exit", false, "Exit", "Exit Blender after saving");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2016-04-19 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
2018-11-01 18:32:37 +01:00
|
|
|
|
|
|
|
/** \name Auto-execution of scripts warning popup
|
|
|
|
*
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
static void wm_block_autorun_warning_ignore(bContext *C, void *arg_block, void *UNUSED(arg))
|
|
|
|
{
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
UI_popup_block_close(C, win, arg_block);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wm_block_autorun_warning_allow(bContext *C, void *arg_block, void *UNUSED(arg))
|
|
|
|
{
|
|
|
|
PointerRNA props_ptr;
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
|
|
|
|
UI_popup_block_close(C, win, arg_block);
|
|
|
|
|
2018-11-02 17:24:19 +01:00
|
|
|
/* Save user preferences for permanent execution. */
|
|
|
|
if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) {
|
|
|
|
WM_operator_name_call(C, "WM_OT_save_userpref", WM_OP_EXEC_DEFAULT, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load file again with scripts enabled. */
|
2018-11-01 18:32:37 +01:00
|
|
|
wmOperatorType *ot = WM_operatortype_find("WM_OT_revert_mainfile", false);
|
|
|
|
|
|
|
|
WM_operator_properties_create_ptr(&props_ptr, ot);
|
|
|
|
RNA_boolean_set(&props_ptr, "use_scripts", true);
|
|
|
|
WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
|
|
|
|
WM_operator_properties_free(&props_ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Build the autorun warning dialog UI */
|
|
|
|
static uiBlock *block_create_autorun_warning(struct bContext *C, struct ARegion *ar, void *UNUSED(arg1))
|
|
|
|
{
|
|
|
|
uiStyle *style = UI_style_get();
|
|
|
|
uiBlock *block = UI_block_begin(C, ar, "autorun_warning_popup", UI_EMBOSS);
|
|
|
|
|
|
|
|
UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
|
|
|
|
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
|
|
|
|
|
|
|
uiLayout *layout = UI_block_layout(
|
|
|
|
block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.widget_unit * 24, U.widget_unit * 6, 0, style);
|
|
|
|
|
|
|
|
/* Text and some vertical space */
|
|
|
|
uiLayout *col = uiLayoutColumn(layout, true);
|
|
|
|
uiItemL(col, IFACE_("For security reasons, automatic execution of Python scripts in this file was disabled:"), ICON_ERROR);
|
|
|
|
uiLayout *sub = uiLayoutRow(col, true);
|
|
|
|
uiLayoutSetRedAlert(sub, true);
|
|
|
|
uiItemL(sub, G.autoexec_fail, ICON_BLANK1);
|
2018-12-24 12:31:39 +01:00
|
|
|
uiItemL(col, IFACE_("This may lead to unexpected behavior"), ICON_BLANK1);
|
2018-11-01 18:32:37 +01:00
|
|
|
|
|
|
|
uiItemS(layout);
|
2018-11-02 17:24:19 +01:00
|
|
|
|
2018-12-21 12:47:44 +11:00
|
|
|
PointerRNA pref_ptr;
|
2019-01-11 15:43:53 +11:00
|
|
|
RNA_pointer_create(NULL, &RNA_PreferencesFilePaths, &U, &pref_ptr);
|
2018-12-21 12:47:44 +11:00
|
|
|
uiItemR(layout, &pref_ptr, "use_scripts_auto_execute", 0, IFACE_("Permanently allow execution of scripts"), ICON_NONE);
|
2018-11-02 17:24:19 +01:00
|
|
|
|
2018-11-01 18:32:37 +01:00
|
|
|
uiItemS(layout);
|
|
|
|
|
|
|
|
/* Buttons */
|
|
|
|
uiBut *but;
|
|
|
|
uiLayout *split = uiLayoutSplit(layout, 0.0f, true);
|
|
|
|
col = uiLayoutColumn(split, false);
|
|
|
|
|
|
|
|
/* Allow reload if we have a saved file. */
|
|
|
|
if (G.relbase_valid) {
|
|
|
|
but = uiDefIconTextBut(
|
2018-11-02 01:19:34 +01:00
|
|
|
block, UI_BTYPE_BUT, 0, ICON_NONE, IFACE_("Allow Execution"), 0, 0, 50, UI_UNIT_Y,
|
2018-11-02 06:59:51 +11:00
|
|
|
NULL, 0, 0, 0, 0, TIP_("Reload file with execution of Python scripts enabled"));
|
2018-11-01 18:32:37 +01:00
|
|
|
UI_but_func_set(but, wm_block_autorun_warning_allow, block, NULL);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uiItemS(col);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* empty space between buttons */
|
|
|
|
col = uiLayoutColumn(split, false);
|
|
|
|
uiItemS(col);
|
|
|
|
|
|
|
|
col = uiLayoutColumn(split, 1);
|
|
|
|
but = uiDefIconTextBut(
|
|
|
|
block, UI_BTYPE_BUT, 0, ICON_NONE, IFACE_("Ignore"), 0, 0, 50, UI_UNIT_Y,
|
|
|
|
NULL, 0, 0, 0, 0, TIP_("Continue using file without Python scripts"));
|
|
|
|
UI_but_func_set(but, wm_block_autorun_warning_ignore, block, NULL);
|
|
|
|
|
|
|
|
UI_block_bounds_set_centered(block, 10);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wm_test_autorun_warning(bContext *C)
|
|
|
|
{
|
|
|
|
/* Test if any auto-execution of scripts failed. */
|
2019-02-02 13:39:51 +11:00
|
|
|
if ((G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL) == 0) {
|
2018-11-01 18:32:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only show the warning once. */
|
2019-02-02 13:39:51 +11:00
|
|
|
if (G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET) {
|
2018-11-01 18:32:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:39:51 +11:00
|
|
|
G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET;
|
2018-11-01 18:32:37 +01:00
|
|
|
|
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
wmWindow *win = (wm->winactive) ? wm->winactive : wm->windows.first;
|
|
|
|
|
|
|
|
if (win) {
|
|
|
|
wmWindow *prevwin = CTX_wm_window(C);
|
|
|
|
CTX_wm_window_set(C, win);
|
|
|
|
UI_popup_block_invoke(C, block_create_autorun_warning, NULL);
|
|
|
|
CTX_wm_window_set(C, prevwin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|