File Selector, support filepath dropping
authorGaia Clary <gaia.clary@machinimatrix.org>
Wed, 4 Nov 2015 13:24:46 +0000 (14:24 +0100)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 4 Nov 2015 14:33:50 +0000 (01:33 +1100)
This adds support for dropping a filepath on an open file-selector to set that path.

release/datafiles/locale
release/scripts/addons
release/scripts/addons_contrib
source/blender/editors/space_file/file_intern.h
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/space_file.c

index e4d4a560cafb21d74dd4db13473a2d1d7ee73161..9628dc1922be2fb6281bc66f5f7512c2a57c294a 160000 (submodule)
@@ -1 +1 @@
-Subproject commit e4d4a560cafb21d74dd4db13473a2d1d7ee73161
+Subproject commit 9628dc1922be2fb6281bc66f5f7512c2a57c294a
index ecdc7c03ec14e6ed70dea808b61049017f46ad97..407d0ea752b3af73d3f13ba072671bd09eefecb1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ecdc7c03ec14e6ed70dea808b61049017f46ad97
+Subproject commit 407d0ea752b3af73d3f13ba072671bd09eefecb1
index c63ada6ae2569864be891ff308cda6b39d8368f1..9f29e18707917ec5be262431d2e09dbb85332f41 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c63ada6ae2569864be891ff308cda6b39d8368f1
+Subproject commit 9f29e18707917ec5be262431d2e09dbb85332f41
index baafefab1f61821141c9f525482b44efa561a23e..71e38f72a7acf2676d8d39a972cac2b008034b5d 100644 (file)
@@ -93,6 +93,7 @@ void FILE_OT_filenum(struct wmOperatorType *ot);
 void FILE_OT_delete(struct wmOperatorType *ot);
 void FILE_OT_rename(struct wmOperatorType *ot);
 void FILE_OT_smoothscroll(struct wmOperatorType *ot);
+void FILE_OT_filepath_drop(struct wmOperatorType *ot);
 
 int file_exec(bContext *C, struct wmOperator *exec_op);
 int file_cancel_exec(bContext *C, struct wmOperator *unused);
@@ -107,7 +108,9 @@ void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
 
 int file_highlight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
 
-void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
+void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath);
+void file_sfile_to_operator_ex(struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
+void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile);
 void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op);
 
 
index 36572d6469dd0a4b77c0d8602fda648038ac8ed0..feea40443faecd4ce789f37e823112e364d6d1d3 100644 (file)
@@ -1188,7 +1188,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
 }
 
 
-void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
+void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath)
 {
        PropertyRNA *prop;
 
@@ -1258,6 +1258,12 @@ void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
 
        }
 }
+void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile)
+{
+       char filepath[FILE_MAX];
+
+       file_sfile_to_operator_ex(op, sfile, filepath);
+}
 
 void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
 {
@@ -1285,14 +1291,35 @@ void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
        /* XXX, files and dirs updates missing, not really so important though */
 }
 
+/**
+ * Use to set the file selector path from some arbitrary source.
+ */
+void file_sfile_filepath_set(SpaceFile *sfile, const char *filepath)
+{
+       BLI_assert(BLI_exists(filepath));
+
+       if (BLI_is_dir(filepath)) {
+               BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
+               sfile->params->file[0] = '\0';
+       }
+       else {
+               if ((sfile->params->flag & FILE_DIRSEL_ONLY) == 0) {
+                       BLI_split_dirfile(filepath, sfile->params->dir, sfile->params->file,
+                                         sizeof(sfile->params->dir), sizeof(sfile->params->file));
+               }
+               else{
+                       BLI_split_dir_part(filepath, sfile->params->dir, sizeof(sfile->params->dir));
+               }
+       }
+}
+
 void file_draw_check(bContext *C)
 {
        SpaceFile *sfile = CTX_wm_space_file(C);
        wmOperator *op = sfile->op;
        if (op) { /* fail on reload */
                if (op->type->check) {
-                       char filepath[FILE_MAX];
-                       file_sfile_to_operator(op, sfile, filepath);
+                       file_sfile_to_operator(op, sfile);
                        
                        /* redraw */
                        if (op->type->check(C, op)) {
@@ -1375,7 +1402,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
                
                sfile->op = NULL;
 
-               file_sfile_to_operator(op, sfile, filepath);
+               file_sfile_to_operator_ex(op, sfile, filepath);
 
                if (BLI_exists(sfile->params->dir)) {
                        fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL,
@@ -1652,6 +1679,45 @@ void FILE_OT_smoothscroll(wmOperatorType *ot)
 }
 
 
+static int filepath_drop_exec(bContext *C, wmOperator *op)
+{
+       SpaceFile *sfile = CTX_wm_space_file(C);
+
+       if (sfile) {
+               char filepath[FILE_MAX];
+
+               RNA_string_get(op->ptr, "filepath", filepath);
+               if (!BLI_exists(filepath)) {
+                       BKE_report(op->reports, RPT_ERROR, "File does not exist");
+                       return OPERATOR_CANCELLED;
+               }
+
+               file_sfile_filepath_set(sfile, filepath);
+
+               if (sfile->op) {
+                       file_sfile_to_operator(sfile->op, sfile);
+                       file_draw_check(C);
+               }
+
+               WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
+               return OPERATOR_FINISHED;
+       }
+
+       return OPERATOR_CANCELLED;
+}
+
+void FILE_OT_filepath_drop(wmOperatorType *ot)
+{
+       ot->name = "File Selector Drop";
+       ot->description = "";
+       ot->idname = "FILE_OT_filepath_drop";
+
+       ot->exec = filepath_drop_exec;
+       ot->poll = WM_operator_winactive;
+
+       RNA_def_string_file_path(ot->srna, "filepath", "Path", FILE_MAX, "", "");
+}
+
 /* create a new, non-existing folder name, returns 1 if successful, 0 if name couldn't be created.
  * The actual name is returned in 'name', 'folder' contains the complete path, including the new folder name.
  */
index 97c2d75e46938b3476c9734a3d52790a502ac69f..3202164edbd0e7f0ce57911eee528f3a3383658e 100644 (file)
@@ -441,6 +441,7 @@ static void file_operatortypes(void)
        WM_operatortype_append(FILE_OT_delete);
        WM_operatortype_append(FILE_OT_rename);
        WM_operatortype_append(FILE_OT_smoothscroll);
+       WM_operatortype_append(FILE_OT_filepath_drop);
 }
 
 /* NOTE: do not add .blend file reading on this level */
@@ -661,6 +662,30 @@ static void file_ui_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg
        }
 }
 
+static int filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+{
+       if (drag->type == WM_DRAG_PATH) {
+               SpaceFile *sfile = CTX_wm_space_file(C);
+               if (sfile) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static void filepath_drop_copy(wmDrag *drag, wmDropBox *drop)
+{
+       RNA_string_set(drop->ptr, "filepath", drag->path);
+}
+
+/* region dropbox definition */
+static void file_dropboxes(void)
+{
+       ListBase *lb = WM_dropboxmap_find("Window", SPACE_EMPTY, RGN_TYPE_WINDOW);
+
+       WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy);
+}
+
 /* only called once, from space/spacetypes.c */
 void ED_spacetype_file(void)
 {
@@ -679,7 +704,8 @@ void ED_spacetype_file(void)
        st->listener = file_listener;
        st->operatortypes = file_operatortypes;
        st->keymap = file_keymap;
-       
+       st->dropboxes = file_dropboxes;
+
        /* regions: main window */
        art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
        art->regionid = RGN_TYPE_WINDOW;