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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-08-28 16:12:14 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-09-18 20:38:20 +0300
commit84f21c170dda9e503de440c20bc2753002987901 (patch)
treeba079a1930ed2d0d6217679ec0e63ba02ebdfa6f /source
parentb08d9f036e05dd3546514239b5e3501b88cbf053 (diff)
Application Templates: make templates more prominent in the UI.
The goal here is to make app templates usable for default templates that we can ship with Blender. These only have a custom startup.blend currently and so are quite limited compared to app templates that fully customize Blender. But still it seems like the same kind of concept where we should be sharing the code and UI. It is useful to be able to save a startup.blend per template, and I can imagine some scripting being useful in the future as well. Changes made: * File > New and Ctrl+N now list the templates, replacing a separate Application Templates menu that was not as easy to discover. * File menu now shows name of active template above Save Startup File and Load Factory Settings to indicate these are saved/loaded per template. * The "Default" template was renamed to "General". * Workspaces can now be added from any of the template startup.blend files when clicking the (+) button in the topbar. * User preferences are now fully shared between app templates, unless the template includes a custom userpref.blend. I think this will be useful in general, not all app templates need their own keymaps for example. * Previously Save User Preferences would save the current app template and then Blender would start using that template by default. I've disabled this, to me it seems it was unintentional, or at least not clear at all that saving user preferences also makes the current Differential Revision: https://developer.blender.org/D3690
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_appdir.h2
-rw-r--r--source/blender/blenkernel/intern/appdir.c30
-rw-r--r--source/blender/blenlib/BLI_path_util.h2
-rw-r--r--source/blender/blenlib/intern/path_util.c42
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface_templates.c10
-rw-r--r--source/blender/editors/screen/workspace_edit.c121
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c1
-rw-r--r--source/blender/windowmanager/intern/wm_files.c51
10 files changed, 196 insertions, 68 deletions
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index ac8f861fa56..6162c7b6bf6 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -23,6 +23,7 @@
/** \file BKE_appdir.h
* \ingroup bli
*/
+struct ListBase;
/* note on naming: typical _get() suffix is omitted here,
* since its the main purpose of the API. */
@@ -35,6 +36,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, con
bool BKE_appdir_app_template_any(void);
bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len);
+void BKE_appdir_app_templates(struct ListBase *templates);
/* Initialize path to program executable */
void BKE_appdir_program_path_init(const char *argv0);
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 46f25815481..2848c245553 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -28,9 +28,11 @@
#include <stdio.h>
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BLI_fileops.h"
+#include "BLI_fileops_types.h"
+#include "BLI_listbase.h"
#include "BLI_path_util.h"
+#include "BLI_string.h"
#include "BKE_blender_version.h"
#include "BKE_appdir.h" /* own include */
@@ -738,6 +740,32 @@ bool BKE_appdir_app_template_id_search(const char *app_template, char *path, siz
return false;
}
+void BKE_appdir_app_templates(ListBase *templates)
+{
+ BLI_listbase_clear(templates);
+
+ for (int i = 0; i < 2; i++) {
+ char subdir[FILE_MAX];
+ if (!BKE_appdir_folder_id_ex(
+ app_template_directory_id[i], app_template_directory_search[i],
+ subdir, sizeof(subdir)))
+ {
+ continue;
+ }
+
+ struct direntry *dir;
+ uint totfile = BLI_filelist_dir_contents(subdir, &dir);
+ for (int f = 0; f < totfile; f++) {
+ if (!FILENAME_IS_CURRPAR(dir[f].relname) && S_ISDIR(dir[f].type)) {
+ char *template = BLI_strdup(dir[f].relname);
+ BLI_addtail(templates, BLI_genericNodeN(template));
+ }
+ }
+
+ BLI_filelist_free(dir, totfile);
+ }
+}
+
/**
* Gets the temp directory when blender first runs.
* If the default path is not found, use try $TEMP
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index e434e83416b..dcfb2c9cbc9 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -108,6 +108,8 @@ void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL();
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
bool BLI_path_is_unc(const char *path);
+void BLI_path_to_display_name(char *display_name, int maxlen, const char *name) ATTR_NONNULL();
+
#if defined(WIN32)
void BLI_cleanup_unc_16(wchar_t *path_16);
void BLI_cleanup_unc(char *path_16, int maxlen);
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 10ca0fa6cbf..b3ab33312ba 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -928,6 +928,48 @@ bool BLI_path_frame_check_chars(const char *path)
}
/**
+ * Creates a display string from path to be used menus and the user interface.
+ * Like bpy.path.display_name().
+ */
+void BLI_path_to_display_name(char *display_name, int maxlen, const char *name)
+{
+ /* Strip leading underscores and spaces. */
+ int strip_offset = 0;
+ while (ELEM(name[strip_offset], '_', ' ')) {
+ strip_offset++;
+ }
+
+ BLI_strncpy(display_name, name + strip_offset, maxlen);
+
+ /* Replace underscores with spaces. */
+ BLI_str_replace_char(display_name, '_', ' ');
+
+ /* Strip extension. */
+ BLI_path_extension_replace(display_name, maxlen, "");
+
+ /* Test if string has any upper case characters. */
+ bool all_lower = true;
+ for (int i = 0; display_name[i]; i++) {
+ if (isupper(display_name[i])) {
+ all_lower = false;
+ break;
+ }
+ }
+
+ if (all_lower) {
+ /* For full lowercase string, use title case. */
+ bool prevspace = true;
+ for (int i = 0; display_name[i]; i++) {
+ if (prevspace) {
+ display_name[i] = toupper(display_name[i]);
+ }
+
+ prevspace = isspace(display_name[i]);
+ }
+ }
+}
+
+/**
* If path begins with "//", strips that and replaces it with basepath directory.
*
* \note Also converts drive-letter prefix to something more sensible
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index db6dacd2064..04896eacb43 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8938,6 +8938,9 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->uistyles);
+ /* Don't read the active app template, use the default one. */
+ user->app_template[0] = '\0';
+
/* free fd->datamap again */
oldnewmap_free_unused(fd->datamap);
oldnewmap_clear(fd->datamap);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 0fe4b63763f..4e0a0711473 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1039,7 +1039,7 @@ void uiTemplateIDPreview(
void uiTemplateIDTabs(
uiLayout *layout, struct bContext *C,
PointerRNA *ptr, const char *propname,
- const char *newop, const char *openop, const char *menu,
+ const char *newop, const char *menu,
int filter);
void uiTemplateAnyID(
uiLayout *layout, struct PointerRNA *ptr, const char *propname,
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index a5762b8566f..b7a553d1bd5 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -838,7 +838,7 @@ ID *UI_context_active_but_get_tab_ID(bContext *C)
static void template_ID_tabs(
bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag,
- const char *newop, const char *UNUSED(openop), const char *menu)
+ const char *newop, const char *menu)
{
const ARegion *region = CTX_wm_region(C);
const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop);
@@ -934,7 +934,7 @@ static void ui_template_id(
if (template_ui->idlb) {
if (use_tabs) {
uiLayoutRow(layout, true);
- template_ID_tabs(C, layout, template_ui, type, flag, newop, openop, unlinkop);
+ template_ID_tabs(C, layout, template_ui, type, flag, newop, unlinkop);
}
else {
uiLayoutRow(layout, true);
@@ -996,13 +996,13 @@ void uiTemplateGpencilColorPreview(
void uiTemplateIDTabs(
uiLayout *layout, bContext *C,
PointerRNA *ptr, const char *propname,
- const char *newop, const char *openop, const char *unlinkop,
+ const char *newop, const char *unlinkop,
int filter)
{
ui_template_id(
layout, C, ptr, propname,
- newop, openop, unlinkop,
- UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE,
+ newop, NULL, unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME,
0, 0, filter, true, 1.0f, false);
}
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index db60bfc9fb6..a6a85a0f201 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -349,20 +349,23 @@ static int workspace_append(bContext *C, const char *directory, const char *idna
static int workspace_append_activate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- char idname[MAX_ID_NAME - 2], directory[FILE_MAX];
+ char idname[MAX_ID_NAME - 2], filepath[FILE_MAX];
if (!RNA_struct_property_is_set(op->ptr, "idname") ||
- !RNA_struct_property_is_set(op->ptr, "directory"))
+ !RNA_struct_property_is_set(op->ptr, "filepath"))
{
return OPERATOR_CANCELLED;
}
RNA_string_get(op->ptr, "idname", idname);
- RNA_string_get(op->ptr, "directory", directory);
+ RNA_string_get(op->ptr, "filepath", filepath);
- if (workspace_append(C, directory, idname) != OPERATOR_CANCELLED) {
+ if (workspace_append(C, filepath, idname) != OPERATOR_CANCELLED) {
WorkSpace *appended_workspace = BLI_findstring(&bmain->workspaces, idname, offsetof(ID, name) + 2);
-
BLI_assert(appended_workspace != NULL);
+
+ /* Reorder to last position. */
+ BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
+
/* Changing workspace changes context. Do delayed! */
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
@@ -385,37 +388,39 @@ static void WORKSPACE_OT_append_activate(wmOperatorType *ot)
RNA_def_string(ot->srna, "idname", NULL, MAX_ID_NAME - 2, "Identifier",
"Name of the workspace to append and activate");
- RNA_def_string(ot->srna, "directory", NULL, FILE_MAX, "Directory",
+ RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath",
"Path to the library");
}
-static void workspace_config_file_path_from_folder_id(
- const Main *bmain, int folder_id, char *r_path)
+static WorkspaceConfigFileData *workspace_config_file_read(const char *app_template)
{
- const char *app_template = U.app_template[0] ? U.app_template : NULL;
- const char * const cfgdir = BKE_appdir_folder_id(folder_id, app_template);
+ const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template);
+ char startup_file_path[FILE_MAX] = {0};
if (cfgdir) {
- BLI_make_file_string(bmain->name, r_path, cfgdir, BLENDER_STARTUP_FILE);
- }
- else {
- r_path[0] = '\0';
+ BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE);
}
+
+ bool has_path = BLI_exists(startup_file_path);
+ return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
}
-ATTR_NONNULL(1)
-static WorkspaceConfigFileData *workspace_config_file_read(
- const Main *bmain, ReportList *reports)
+static WorkspaceConfigFileData *workspace_system_file_read(const char *app_template)
{
- char workspace_config_path[FILE_MAX];
- bool has_path = false;
+ if (app_template == NULL) {
+ return BKE_blendfile_workspace_config_read(NULL, datatoc_startup_blend, datatoc_startup_blend_size, NULL);
+ }
- workspace_config_file_path_from_folder_id(bmain, BLENDER_USER_CONFIG, workspace_config_path);
- if (BLI_exists(workspace_config_path)) {
- has_path = true;
+ char template_dir[FILE_MAX];
+ if (!BKE_appdir_app_template_id_search(app_template, template_dir, sizeof(template_dir))) {
+ return NULL;
}
- return (has_path) ? BKE_blendfile_workspace_config_read(workspace_config_path, NULL, 0, reports) : NULL;
+ char startup_file_path[FILE_MAX];
+ BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE);
+
+ bool has_path = BLI_exists(startup_file_path);
+ return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
}
static void workspace_append_button(
@@ -438,32 +443,28 @@ static void workspace_append_button(
layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL,
WM_OP_EXEC_DEFAULT, 0, &opptr);
RNA_string_set(&opptr, "idname", id->name + 2);
- RNA_string_set(&opptr, "directory", lib_path);
+ RNA_string_set(&opptr, "filepath", lib_path);
}
-ATTR_NONNULL(1, 2)
-static void workspace_config_file_append_buttons(
- uiLayout *layout, const Main *bmain, ReportList *reports)
+static void workspace_add_menu(bContext *C, uiLayout *layout, void *template_v)
{
+ Main *bmain = CTX_data_main(C);
+ const char *app_template = template_v;
+ bool has_startup_items = false;
+
wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true);
- WorkspaceConfigFileData *startup_config = workspace_config_file_read(bmain, reports);
- WorkspaceConfigFileData *builtin_config = BKE_blendfile_workspace_config_read(NULL, datatoc_startup_blend, datatoc_startup_blend_size, reports);
+ WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
+ WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
if (startup_config) {
- bool has_title = false;
-
for (WorkSpace *workspace = startup_config->workspaces.first; workspace; workspace = workspace->id.next) {
+ uiLayout *row = uiLayoutRow(layout, false);
if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
- continue;
- }
-
- if (!has_title) {
- uiItemS(layout);
- uiItemL(layout, IFACE_("Startup File"), ICON_NONE);
- has_title = true;
+ uiLayoutSetActive(row, false);
}
- workspace_append_button(layout, ot_append, workspace, startup_config->main);
+ workspace_append_button(row, ot_append, workspace, startup_config->main);
+ has_startup_items = true;
}
}
@@ -471,22 +472,23 @@ static void workspace_config_file_append_buttons(
bool has_title = false;
for (WorkSpace *workspace = builtin_config->workspaces.first; workspace; workspace = workspace->id.next) {
- if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
- continue;
- }
if (startup_config && BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) {
continue;
}
if (!has_title) {
- uiItemS(layout);
- uiItemL(layout, IFACE_("Builtin"), ICON_NONE);
+ if (has_startup_items) {
+ uiItemS(layout);
+ }
has_title = true;
}
- if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name)) == NULL) {
- workspace_append_button(layout, ot_append, workspace, builtin_config->main);
+ uiLayout *row = uiLayoutRow(layout, false);
+ if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
+ uiLayoutSetActive(row, false);
}
+
+ workspace_append_button(row, ot_append, workspace, builtin_config->main);
}
}
@@ -500,26 +502,41 @@ static void workspace_config_file_append_buttons(
static int workspace_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- const Main *bmain = CTX_data_main(C);
-
uiPopupMenu *pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
+ uiItemMenuF(layout, IFACE_("General"), ICON_NONE, workspace_add_menu, NULL);
+
+ ListBase templates;
+ BKE_appdir_app_templates(&templates);
+
+ for (LinkData *link = templates.first; link; link = link->next) {
+ char *template = link->data;
+ char display_name[FILE_MAX];
+
+ BLI_path_to_display_name(display_name, sizeof(display_name), template);
+
+ /* Steals ownership of link data string. */
+ uiItemMenuF(layout, display_name, ICON_NONE, workspace_add_menu, template);
+ }
+
+ BLI_freelistN(&templates);
+
+ uiItemS(layout);
uiItemO(layout, "Duplicate Current", ICON_NONE, "WORKSPACE_OT_duplicate");
- workspace_config_file_append_buttons(layout, bmain, op->reports);
UI_popup_menu_end(C, pup);
return OPERATOR_INTERFACE;
}
-static void WORKSPACE_OT_add_menu(wmOperatorType *ot)
+static void WORKSPACE_OT_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Workspace";
ot->description = "Add a new workspace by duplicating the current one or appending one "
"from the user configuration";
- ot->idname = "WORKSPACE_OT_add_menu";
+ ot->idname = "WORKSPACE_OT_add";
/* api callbacks */
ot->invoke = workspace_add_invoke;
@@ -575,7 +592,7 @@ void ED_operatortypes_workspace(void)
{
WM_operatortype_append(WORKSPACE_OT_duplicate);
WM_operatortype_append(WORKSPACE_OT_delete);
- WM_operatortype_append(WORKSPACE_OT_add_menu);
+ WM_operatortype_append(WORKSPACE_OT_add);
WM_operatortype_append(WORKSPACE_OT_append_activate);
WM_operatortype_append(WORKSPACE_OT_reorder_to_back);
WM_operatortype_append(WORKSPACE_OT_reorder_to_front);
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index bafc7dc69c1..694d44a87e8 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -791,7 +791,6 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new ID block");
- RNA_def_string(func, "open", NULL, 0, "", "Operator identifier to open a file for creating a new ID block");
RNA_def_string(func, "menu", NULL, 0, "", "Context menu identifier");
RNA_def_enum(func, "filter", id_template_filter_items, UI_TEMPLATE_ID_FILTER_ALL,
"", "Optionally limit the items which can be selected");
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 65f4823464a..7883b2aded6 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -696,6 +696,25 @@ const char *WM_init_state_app_template_get(void)
return wm_init_state_app_template.override ? wm_init_state_app_template.app_template : NULL;
}
+
+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);
+}
+
/**
* Called on startup, (context entirely filled with NULLs)
* or called for 'New File' both startup.blend and userpref.blend are checked.
@@ -1489,7 +1508,7 @@ void WM_OT_save_homefile(wmOperatorType *ot)
{
ot->name = "Save Startup File";
ot->idname = "WM_OT_save_homefile";
- ot->description = "Make the current file the default .blend file, includes preferences";
+ ot->description = "Make the current file the default .blend file";
ot->invoke = WM_operator_confirm;
ot->exec = wm_homefile_write_exec;
@@ -1543,6 +1562,7 @@ static int wm_userpref_write_exec(bContext *C, wmOperator *op)
char filepath[FILE_MAX];
const char *cfgdir;
bool ok = true;
+ bool use_template_userpref = wm_app_template_has_userpref(U.app_template);
/* update keymaps in user preferences */
WM_keyconfig_update(wm);
@@ -1550,9 +1570,8 @@ static int wm_userpref_write_exec(bContext *C, wmOperator *op)
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
bool ok_write;
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
- printf("trying to save userpref at %s ", filepath);
- if (U.app_template[0]) {
+ if (use_template_userpref) {
ok_write = BKE_blendfile_userdef_write_app_template(filepath, op->reports);
}
else {
@@ -1571,11 +1590,10 @@ static int wm_userpref_write_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Unable to create userpref path");
}
- if (U.app_template[0]) {
+ if (use_template_userpref) {
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);
- printf("trying to save app-template userpref at %s ", filepath);
if (BKE_blendfile_userdef_write(filepath, op->reports) != 0) {
printf("ok\n");
}
@@ -1664,8 +1682,9 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
RNA_property_string_get(op->ptr, prop_app_template, app_template_buf);
app_template = app_template_buf;
- /* Always load preferences when switching templates. */
- use_userdef = true;
+ /* 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);
/* Turn override off, since we're explicitly loading a different app-template. */
WM_init_state_app_template_set(NULL);
@@ -1686,6 +1705,22 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
}
}
+static int wm_homefile_read_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
+{
+ /* Draw menu which includes default startup and application templates. */
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("New File"), ICON_NEW);
+ 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;
+}
+
void WM_OT_read_homefile(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1693,7 +1728,7 @@ void WM_OT_read_homefile(wmOperatorType *ot)
ot->idname = "WM_OT_read_homefile";
ot->description = "Open the default file (doesn't save the current file)";
- ot->invoke = WM_operator_confirm;
+ ot->invoke = wm_homefile_read_invoke;
ot->exec = wm_homefile_read_exec;
prop = RNA_def_string_file_path(ot->srna, "filepath", NULL,