Move file execute region back to C, fixing bugs
authorJulian Eisel <eiseljulian@gmail.com>
Wed, 4 Sep 2019 14:21:42 +0000 (16:21 +0200)
committerJulian Eisel <eiseljulian@gmail.com>
Wed, 4 Sep 2019 14:30:09 +0000 (16:30 +0200)
We moved this to Python too quickly, causing the following regressions:
* No auto completion for file names
* Additional handling not applied on changes, like automatic extension
  appending (see file_filename_enter_handle)
* Red highlight missing when the file name already exists

Note that earlier (before the file browser redesign), this didn't use
the panel and layout code at all. So even if it's still not in Python,
at least it's integrated into regular panel management now.
OS-specific ordering of the open and cancel button is kept.

Fixes T69457.

release/scripts/startup/bl_ui/space_filebrowser.py
source/blender/editors/space_file/file_intern.h
source/blender/editors/space_file/file_panels.c
source/blender/editors/space_file/space_file.c

index 7a80390636996b3891ac8b2c4d4b6356c4cc933c..92eae7a4de9345876213493709691930d9a5ea52 100644 (file)
@@ -414,46 +414,6 @@ class FILEBROWSER_PT_directory_path(Panel):
         )
 
 
-class FILEBROWSER_PT_file_operation(Panel):
-    bl_space_type = 'FILE_BROWSER'
-    bl_region_type = 'EXECUTE'
-    bl_label = "Execute File Operation"
-    bl_options = {'HIDE_HEADER'}
-
-    @classmethod
-    def poll(cls, context):
-        return context.space_data.active_operator
-
-    def draw(self, context):
-        import sys
-
-        layout = self.layout
-        space = context.space_data
-        params = space.params
-
-        layout.scale_x = 1.3
-        layout.scale_y = 1.3
-
-        row = layout.row()
-        sub = row.row()
-        sub.prop(params, "filename", text="")
-        sub = row.row()
-        sub.ui_units_x = 5
-
-        # subsub = sub.row(align=True)
-        # subsub.operator("file.filenum", text="", icon='ADD').increment = 1
-        # subsub.operator("file.filenum", text="", icon='REMOVE').increment = -1
-
-        # organize buttons according to the OS standard
-        if sys.platform[:3] != "win":
-            sub.operator("FILE_OT_cancel", text="Cancel")
-        subsub = sub.row()
-        subsub.active_default = True
-        subsub.operator("FILE_OT_execute", text=params.title)
-        if sys.platform[:3] == "win":
-            sub.operator("FILE_OT_cancel", text="Cancel")
-
-
 class FILEBROWSER_MT_view(Menu):
     bl_label = "View"
 
@@ -523,7 +483,6 @@ classes = (
     FILEBROWSER_PT_bookmarks_recents,
     FILEBROWSER_PT_advanced_filter,
     FILEBROWSER_PT_directory_path,
-    FILEBROWSER_PT_file_operation,
     FILEBROWSER_PT_options_toggle,
     FILEBROWSER_MT_view,
     FILEBROWSER_MT_context_menu,
index 61f13098783f45c6e532a5a806612e91a64b1087..4b86f38f8e468b3d5a5365df86f1f53c31dbcbd7 100644 (file)
@@ -136,7 +136,8 @@ int autocomplete_file(struct bContext *C, char *str, void *arg_v);
 void file_params_renamefile_activate(struct SpaceFile *sfile, struct FileSelectParams *params);
 
 /* file_panels.c */
-void file_panels_register(struct ARegionType *art);
+void file_tool_props_region_panels_register(struct ARegionType *art);
+void file_execute_region_panels_register(struct ARegionType *art);
 
 /* file_utils.c */
 void file_tile_boundbox(const ARegion *ar, FileLayout *layout, const int file, rcti *r_bounds);
index b41358f575fdeaf7e6e89c5f284f5b62f27466c6..290b5385bf7e915fa2accea6e7925978e2a7c374 100644 (file)
@@ -95,7 +95,7 @@ static void file_panel_operator(const bContext *C, Panel *pa)
   UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
 }
 
-void file_panels_register(ARegionType *art)
+void file_tool_props_region_panels_register(ARegionType *art)
 {
   PanelType *pt;
 
@@ -109,3 +109,111 @@ void file_panels_register(ARegionType *art)
   pt->draw = file_panel_operator;
   BLI_addtail(&art->paneltypes, pt);
 }
+
+static void file_panel_execution_cancel_button(uiBlock *block)
+{
+  uiDefButO(block,
+            UI_BTYPE_BUT,
+            "FILE_OT_cancel",
+            WM_OP_EXEC_REGION_WIN,
+            IFACE_("Cancel"),
+            0,
+            0,
+            UI_UNIT_X,
+            UI_UNIT_Y,
+            "");
+}
+
+static void file_panel_execution_buttons_draw(const bContext *C, Panel *pa)
+{
+  bScreen *screen = CTX_wm_screen(C);
+  SpaceFile *sfile = CTX_wm_space_file(C);
+  FileSelectParams *params = ED_fileselect_get_params(sfile);
+  uiBlock *block = uiLayoutGetBlock(pa->layout);
+  uiBut *but;
+  uiLayout *row;
+  PointerRNA params_rna_ptr;
+
+  const bool overwrite_alert = file_draw_check_exists(sfile);
+  const bool windows_layout =
+#ifdef _WIN32
+      true;
+#else
+      false;
+#endif
+
+  RNA_pointer_create(&screen->id, &RNA_FileSelectParams, params, &params_rna_ptr);
+
+  row = uiLayoutRow(pa->layout, false);
+  uiLayoutSetScaleX(row, 1.3f);
+  uiLayoutSetScaleY(row, 1.3f);
+
+  /* callbacks for operator check functions */
+  UI_block_func_set(block, file_draw_check_cb, NULL, NULL);
+
+  but = uiDefButR(block,
+                  UI_BTYPE_TEXT,
+                  -1,
+                  "",
+                  0,
+                  0,
+                  UI_UNIT_X * 5,
+                  UI_UNIT_Y,
+                  &params_rna_ptr,
+                  "filename",
+                  0,
+                  0.0f,
+                  (float)FILE_MAXFILE,
+                  0,
+                  0,
+                  TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name")));
+
+  BLI_assert(!UI_but_flag_is_set(but, UI_BUT_UNDO));
+  BLI_assert(!UI_but_is_utf8(but));
+
+  UI_but_func_complete_set(but, autocomplete_file, NULL);
+  /* silly workaround calling NFunc to ensure this does not get called
+   * immediate ui_apply_but_func but only after button deactivates */
+  UI_but_funcN_set(but, file_filename_enter_handle, NULL, but);
+
+  /* check if this overrides a file and if the operator option is used */
+  if (overwrite_alert) {
+    UI_but_flag_enable(but, UI_BUT_REDALERT);
+  }
+  UI_block_func_set(block, NULL, NULL, NULL);
+
+  {
+    if (windows_layout == false) {
+      file_panel_execution_cancel_button(block);
+    }
+    but = uiDefButO(block,
+                    UI_BTYPE_BUT,
+                    "FILE_OT_execute",
+                    WM_OP_EXEC_REGION_WIN,
+                    params->title,
+                    0,
+                    0,
+                    UI_UNIT_X,
+                    UI_UNIT_Y,
+                    "");
+    /* Just a display hint. */
+    UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
+    if (windows_layout) {
+      file_panel_execution_cancel_button(block);
+    }
+  }
+}
+
+void file_execute_region_panels_register(ARegionType *art)
+{
+  PanelType *pt;
+
+  pt = MEM_callocN(sizeof(PanelType), "spacetype file execution buttons");
+  strcpy(pt->idname, "FILE_PT_execution_buttons");
+  strcpy(pt->label, N_("Execute Buttons"));
+  strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+  pt->flag = PNL_NO_HEADER;
+  pt->poll = file_panel_operator_poll;
+  pt->draw = file_panel_execution_buttons_draw;
+  BLI_addtail(&art->paneltypes, pt);
+}
index 1befdd52d7d3d70528920370ba65d302bd9f84e2..7525ac5b70547958b92acc20b00ad22d6941336a 100644 (file)
@@ -704,6 +704,7 @@ void ED_spacetype_file(void)
   art->init = file_execution_region_init;
   art->draw = file_execution_region_draw;
   BLI_addhead(&st->regiontypes, art);
+  file_execute_region_panels_register(art);
 
   /* regions: channels (directories) */
   art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
@@ -726,7 +727,7 @@ void ED_spacetype_file(void)
   art->init = file_tools_region_init;
   art->draw = file_tools_region_draw;
   BLI_addhead(&st->regiontypes, art);
-  file_panels_register(art);
+  file_tool_props_region_panels_register(art);
 
   BKE_spacetype_register(st);
 }