UI: show blocking popup when auto execution of scripts is disabled.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 1 Nov 2018 17:32:37 +0000 (18:32 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 1 Nov 2018 18:44:03 +0000 (19:44 +0100)
This is important information, and it was easily missed at the top/bottom of
the screen.

Ref T57197.

release/scripts/startup/bl_ui/space_statusbar.py
source/blender/editors/space_script/script_edit.c
source/blender/editors/space_script/script_intern.h
source/blender/editors/space_script/script_ops.c
source/blender/python/intern/bpy_app.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/wm_window.h

index 2cc5bd94bd7a79e8a1a10e3e2b5ed423cb07bfca..87085e4ceea3fdb748920c32497e967a6ad28079 100644 (file)
@@ -34,19 +34,6 @@ class STATUSBAR_HT_header(Header):
 
         # messages
         layout.template_reports_banner()
-
-        row = layout.row(align=True)
-        if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False:
-            row.label(text="Auto-run disabled", icon='ERROR')
-            if bpy.data.is_saved:
-                props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
-                props.use_scripts = True
-
-            row.operator("script.autoexec_warn_clear", text="Ignore")
-
-            # include last so text doesn't push buttons out of the header
-            row.label(text=bpy.app.autoexec_fail_message)
-
         layout.template_running_jobs()
 
         layout.separator_spacer()
index 6bfb51d07c62dd9a397d5b28014554571febe5da..beff7c8211d958b7ed1225c6dca79bf9a0fe1049 100644 (file)
@@ -145,23 +145,3 @@ void SCRIPT_OT_reload(wmOperatorType *ot)
        /* api callbacks */
        ot->exec = script_reload_exec;
 }
-
-static int script_autoexec_warn_clear_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
-{
-       G.f |= G_SCRIPT_AUTOEXEC_FAIL_QUIET;
-       return OPERATOR_FINISHED;
-}
-
-void SCRIPT_OT_autoexec_warn_clear(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name = "Continue Untrusted";
-       ot->description = "Ignore autoexec warning";
-       ot->idname = "SCRIPT_OT_autoexec_warn_clear";
-
-       /* flags */
-       ot->flag = OPTYPE_INTERNAL;
-
-       /* api callbacks */
-       ot->exec = script_autoexec_warn_clear_exec;
-}
index 0e0936cf082f08c2ba452df4b3458c141555527d..649992fec4f11c8f65fd4fcd4db9e112a703d68b 100644 (file)
@@ -40,6 +40,5 @@ void script_keymap(struct wmKeyConfig *keyconf);
 /* script_edit.c */
 void SCRIPT_OT_reload(struct wmOperatorType *ot);
 void SCRIPT_OT_python_file_run(struct wmOperatorType *ot);
-void SCRIPT_OT_autoexec_warn_clear(struct wmOperatorType *ot);
 
 #endif /* __SCRIPT_INTERN_H__ */
index 41c07596a3b788034adc097a26bf20c0ad113fee..90eb38db7f7c996cb9d2cc32d59a8943d89c8c32 100644 (file)
@@ -44,7 +44,6 @@ void script_operatortypes(void)
 {
        WM_operatortype_append(SCRIPT_OT_python_file_run);
        WM_operatortype_append(SCRIPT_OT_reload);
-       WM_operatortype_append(SCRIPT_OT_autoexec_warn_clear);
 }
 
 void script_keymap(wmKeyConfig *UNUSED(keyconf))
index d8c74bdf565a6fe6c0ec952876ce7f410bc6b209..97ac975c95857e8e6df9f43d5ac724eba1756d5c 100644 (file)
@@ -316,12 +316,6 @@ static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void
        return 0;
 }
 
-static PyObject *bpy_app_global_flag_get(PyObject *UNUSED(self), void *closure)
-{
-       const int flag = POINTER_AS_INT(closure);
-       return PyBool_FromLong(G.f & flag);
-}
-
 PyDoc_STRVAR(bpy_app_tempdir_doc,
 "String, the temp directory used by blender (read-only)"
 );
@@ -353,12 +347,6 @@ static PyObject *bpy_app_preview_render_size_get(PyObject *UNUSED(self), void *c
        return PyLong_FromLong((long)UI_preview_render_size(POINTER_AS_INT(closure)));
 }
 
-static PyObject *bpy_app_autoexec_fail_message_get(PyObject *UNUSED(self), void *UNUSED(closure))
-{
-       return PyC_UnicodeFromByte(G.autoexec_fail);
-}
-
-
 PyDoc_STRVAR(bpy_app_use_static_override_doc,
 "Boolean, whether static override is exposed in UI or not."
 );
@@ -410,12 +398,6 @@ static PyGetSetDef bpy_app_getsets[] = {
 
        {(char *)"render_icon_size", bpy_app_preview_render_size_get, NULL, (char *)bpy_app_preview_render_size_doc, (void *)ICON_SIZE_ICON},
        {(char *)"render_preview_size", bpy_app_preview_render_size_get, NULL, (char *)bpy_app_preview_render_size_doc, (void *)ICON_SIZE_PREVIEW},
-
-       /* security */
-       {(char *)"autoexec_fail", bpy_app_global_flag_get, NULL, NULL, (void *)G_SCRIPT_AUTOEXEC_FAIL},
-       {(char *)"autoexec_fail_quiet", bpy_app_global_flag_get, NULL, NULL, (void *)G_SCRIPT_AUTOEXEC_FAIL_QUIET},
-       {(char *)"autoexec_fail_message", bpy_app_autoexec_fail_message_get, NULL, NULL, NULL},
-       {NULL, NULL, NULL, NULL, NULL}
 };
 
 static void py_struct_seq_getset_init(void)
index e562053b62ccf0c28a0aade0c6e9ac22852cac30..c829dd9b5896a80a6d4fafd3b164d16b634f2a4c 100644 (file)
@@ -521,6 +521,9 @@ void wm_event_do_notifiers(bContext *C)
                WM_window_cursor_keymap_status_refresh(C, win);
                CTX_wm_window_set(C, NULL);
        }
+
+       /* Autorun warning */
+       wm_test_autorun_warning(C);
 }
 
 static int wm_event_always_pass(const wmEvent *event)
index 2283ae0118bd329e8d6401deffbd87a56e0d1307..05f139858a5022d93a37a2d368397a85d29d1b7c 100644 (file)
@@ -2322,3 +2322,110 @@ void WM_OT_save_mainfile(wmOperatorType *ot)
 }
 
 /** \} */
+
+/** \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);
+
+       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);
+       uiItemL(col, IFACE_("This may lead to unexpected behavior."), ICON_BLANK1);
+
+       uiItemS(layout);
+       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(
+                               block, UI_BTYPE_BUT, 0, ICON_NONE, IFACE_("Allow Executon"), 0, 0, 50, UI_UNIT_Y,
+                               NULL, 0, 0, 0, 0, TIP_("Reload file with execution of Python scripts enabled"));
+               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. */
+       if ((G.f & G_SCRIPT_AUTOEXEC_FAIL) == 0) {
+               return;
+       }
+
+       /* Only show the warning once. */
+       if (G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET) {
+               return;
+       }
+
+       G.f |= G_SCRIPT_AUTOEXEC_FAIL_QUIET;
+
+       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);
+       }
+}
+
+/** \} */
index 4fd5d66fb4374be7587684a020af44c5dc244502..5988c8dab1713779abeeefa6a59274248f5daa01 100644 (file)
@@ -88,6 +88,8 @@ void          wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win) ATTR
 int                    wm_window_new_exec(bContext *C, struct wmOperator *op);
 int                    wm_window_new_main_exec(bContext *C, struct wmOperator *op);
 
+void           wm_test_autorun_warning(bContext *C);
+
 /* Initial (unmaximized) size to start with for
  * systems that can't find it for themselves (X11).
  * Clamped by real desktop limits */