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:
authorCampbell Barton <ideasman42@gmail.com>2018-03-21 18:00:18 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-03-21 18:04:01 +0300
commit5ba5254ec1ebba6c1e89b663592d716b92e13165 (patch)
treeb8f74acaf2ec5ba374235bbf811f412ad8b1f7e3 /source
parent23ffd4ec394011cec26879cba946501b245020fd (diff)
UI: Optional prompt to quit for non win32 systems
D566 by @januz Use Blender native dialog when OS dialog's aren't supported.
Diffstat (limited to 'source')
-rw-r--r--source/blender/windowmanager/intern/wm_files.c8
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c15
-rw-r--r--source/blender/windowmanager/intern/wm_window.c136
-rw-r--r--source/blender/windowmanager/wm_window.h1
4 files changed, 149 insertions, 11 deletions
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 16cc1d44923..551b17302fe 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -2075,6 +2075,10 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL);
+ if (RNA_boolean_get(op->ptr, "exit")) {
+ WM_exit(C);
+ }
+
return OPERATOR_FINISHED;
}
@@ -2174,12 +2178,16 @@ void WM_OT_save_mainfile(wmOperatorType *ot)
ot->check = blend_save_check;
/* omit window poll so this can work in background mode */
+ PropertyRNA *prop;
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");
+
+ prop = RNA_def_boolean(ot->srna, "exit", false, "Exit", "Exit Blender after saving");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/** \} */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 2a50de62dda..363b8e61763 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2162,10 +2162,16 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
static int wm_exit_blender_exec(bContext *C, wmOperator *op)
{
- WM_operator_free(op);
-
- WM_exit(C);
-
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) {
+ wm_confirm_quit(C);
+ }
+ else {
+ WM_operator_free(op);
+ WM_exit(C);
+ }
+
return OPERATOR_FINISHED;
}
@@ -2175,7 +2181,6 @@ static void WM_OT_quit_blender(wmOperatorType *ot)
ot->idname = "WM_OT_quit_blender";
ot->description = "Quit Blender";
- ot->invoke = WM_operator_confirm;
ot->exec = wm_exit_blender_exec;
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index cbf06e8c6e9..2e12ceab5b3 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -70,6 +70,7 @@
#include "ED_fileselect.h"
#include "UI_interface.h"
+#include "UI_resources.h"
#include "PIL_time.h"
@@ -295,6 +296,124 @@ wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src)
}
}
+
+/* -------------------------------------------------------------------- */
+/** \name Quit Confirmation Dialog
+ * \{ */
+
+/** Cancel quitting and close the dialog */
+static void wm_block_confirm_quit_cancel(bContext *C, void *arg_block, void *UNUSED(arg))
+{
+ wmWindow *win = CTX_wm_window(C);
+ UI_popup_block_close(C, win, arg_block);
+}
+
+/** Discard the file changes and quit */
+static void wm_block_confirm_quit_discard(bContext *C, void *arg_block, void *UNUSED(arg))
+{
+ wmWindow *win = CTX_wm_window(C);
+ UI_popup_block_close(C, win, arg_block);
+ WM_exit(C);
+}
+
+/* Save changes and quit */
+static void wm_block_confirm_quit_save(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);
+
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_save_mainfile", false);
+
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+ RNA_boolean_set(&props_ptr, "exit", true);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+ WM_operator_properties_free(&props_ptr);
+}
+
+
+/* Build the confirm dialog UI */
+static uiBlock *block_create_confirm_quit(struct bContext *C, struct ARegion *ar, void *UNUSED(arg1))
+{
+
+ uiStyle *style = UI_style_get();
+ uiBlock *block = UI_block_begin(C, ar, "confirm_quit_popup", UI_EMBOSS);
+
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP );
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ uiLayout *layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
+
+ /* Text and some vertical space */
+ {
+ char *message;
+ if (G.main->name[0] == '\0') {
+ message = BLI_strdup(IFACE_("This file has not been saved yet. Save before closing?"));
+ }
+ else {
+ const char *basename = BLI_path_basename(G.main->name);
+ message = BLI_sprintfN(IFACE_("Save changes to \"%s\" before closing?"), basename);
+ }
+ uiItemL(layout, message, ICON_ERROR);
+ MEM_freeN(message);
+ }
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+
+ /* Buttons */
+ uiBut *but;
+
+ uiLayout *split = uiLayoutSplit(layout, 0.0f, true);
+
+ uiLayout *col = uiLayoutColumn(split, false);
+
+ but = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_SCREEN_BACK, IFACE_("Cancel"), 0, 0, 0, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Do not quit"));
+ UI_but_func_set(but, wm_block_confirm_quit_cancel, block, NULL);
+
+ /* empty space between buttons */
+ col = uiLayoutColumn(split, false);
+ uiItemS(col);
+
+ col = uiLayoutColumn(split, 1);
+ but = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_CANCEL, IFACE_("Discard Changes"), 0, 0, 50, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Discard changes and quit"));
+ UI_but_func_set(but, wm_block_confirm_quit_discard, block, NULL);
+
+ col = uiLayoutColumn(split, 1);
+ but = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_FILE_TICK, IFACE_("Save & Quit"), 0, 0, 50, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Save and quit"));
+ UI_but_func_set(but, wm_block_confirm_quit_save, block, NULL);
+
+ UI_block_bounds_set_centered(block, 10);
+
+ return block;
+}
+
+
+/** Call the confirm dialog on quitting. */
+void wm_confirm_quit(bContext *C)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ /* The popup needs to have a window set in context to show up since
+ * it's being called outside the normal operator event handling loop */
+ if (wm->winactive) {
+ CTX_wm_window_set(C, wm->winactive);
+ }
+
+ UI_popup_block_invoke(C, block_create_confirm_quit, NULL);
+}
+
+/** \} */
+
/* this is event from ghost, or exit-blender op */
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
@@ -311,19 +430,24 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
if (tmpwin == NULL)
do_exit = 1;
-
- if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved && !G.background) {
- if (do_exit) {
+
+ if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved && !G.background && do_exit) {
+ /* We have unsaved changes and we're quitting */
+ if(GHOST_SupportsNativeDialogs() == 0) {
+ wm_confirm_quit(C);
+ }
+ else {
if (!GHOST_confirmQuit(win->ghostwin))
return;
}
}
-
- /* let WM_exit do all freeing, for correct quit.blend save */
- if (do_exit) {
+ else if (do_exit) {
+ /* No changes but we're quitting */
+ /* let WM_exit do all freeing, for correct quit.blend save */
WM_exit(C);
}
else {
+ /* We're just closing a window */
bScreen *screen = win->screen;
BLI_remlink(&wm->windows, win);
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index f70ec6b47f6..4313c978ef4 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -78,6 +78,7 @@ void wm_window_IME_end (wmWindow *win);
int wm_window_close_exec(bContext *C, struct wmOperator *op);
int wm_window_duplicate_exec(bContext *C, struct wmOperator *op);
int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
+void wm_confirm_quit(bContext *C);
/* Initial (unmaximized) size to start with for
* systems that can't find it for themselves (X11).