This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/space_file/file_ops.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

2985 lines
89 KiB
C
Raw Normal View History

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
2010-02-12 13:34:04 +00:00
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup spfile
2011-02-27 20:29:51 +00:00
*/
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
2011-02-27 20:29:51 +00:00
#include "BLO_readfile.h"
#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
Asset System: New Asset Browser editor This introduces the User Interface part of the Asset Browser, based on the design in T54642. Additions: * New Asset Browser (internally a sub-editor of the File Browser). * Navigation region showing asset categories. * Main region showing the assets of the selected asset library with previews. The assets may be stored over multiple .blends in the directory that's "mounted" as asset library in the Preferences. They will all be shown in this list. * Header with an asset library dropdown, allowing to choose the active asset library to show. Options are the "Current File" as asset library and all custom libraries. * Display popover, filter popover and search box (partially dummies, see T82680). * Sidebar showing the metadata of the currently active file (name, preview, description and tags), which can be edited for assets in the "Current File" asset library. (For others it will reset on reload.) * The sidebar includes a button to load a custom preview image from a file. * Make asset files draggable (with preview image). * If a library with invalid path is selected, a message is drawn in the main region to help the user understand what's wrong. * Operators to add and remove asset tags. Exposed in the sidebar. * "Only Assets" option for Link/Append. * Internal utilities for asset UI scripts. For screenshots or demo videos, please see D9725. Or the 2.92 release notes. Note that there are many things to be tweaked and polished in the Asset Browser UI still. For example, the filter and display popovers are mostly dummies. See T82680. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9725 Reviewed by: Brecht Van Lommel, Hans Goudey
2020-12-14 14:07:42 +01:00
#include "ED_asset.h"
#include "ED_fileselect.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "UI_view2d.h"
#include "WM_api.h"
#include "WM_types.h"
#include "file_intern.h"
#include "filelist.h"
#include "fsmenu.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2020-03-25 21:24:59 +11:00
/* -------------------------------------------------------------------- */
/** \name File Selection Utilities
* \{ */
static FileSelection find_file_mouse_rect(SpaceFile *sfile,
ARegion *region,
const rcti *rect_region)
{
FileSelection sel;
View2D *v2d = &region->v2d;
rcti rect_view;
rctf rect_view_fl;
rctf rect_region_fl;
BLI_rctf_rcti_copy(&rect_region_fl, rect_region);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
/* Okay, manipulating v2d rects here is hacky... */
v2d->mask.ymax -= sfile->layout->offset_top;
v2d->cur.ymax -= sfile->layout->offset_top;
UI_view2d_region_to_view_rctf(v2d, &rect_region_fl, &rect_view_fl);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
v2d->mask.ymax += sfile->layout->offset_top;
v2d->cur.ymax += sfile->layout->offset_top;
BLI_rcti_init(&rect_view,
(int)(v2d->tot.xmin + rect_view_fl.xmin),
(int)(v2d->tot.xmin + rect_view_fl.xmax),
(int)(v2d->tot.ymax - rect_view_fl.ymin),
(int)(v2d->tot.ymax - rect_view_fl.ymax));
sel = ED_fileselect_layout_offset_rect(sfile->layout, &rect_view);
return sel;
}
static void file_deselect_all(SpaceFile *sfile, uint flag)
{
FileSelection sel;
sel.first = 0;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
sel.last = filelist_files_ensure(sfile->files) - 1;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
}
typedef enum FileSelect {
FILE_SELECT_NOTHING = 0,
FILE_SELECT_DIR = 1,
FILE_SELECT_FILE = 2,
} FileSelect;
2012-06-18 13:01:24 +00:00
static void clamp_to_filelist(int numfiles, FileSelection *sel)
{
/* box select before the first file */
2012-06-18 13:01:24 +00:00
if ((sel->first < 0) && (sel->last >= 0)) {
sel->first = 0;
}
/* don't select if everything is outside filelist */
if ((sel->first >= numfiles) && ((sel->last < 0) || (sel->last >= numfiles))) {
sel->first = -1;
sel->last = -1;
}
/* fix if last file invalid */
2019-04-22 09:19:45 +10:00
if ((sel->first > 0) && (sel->last < 0)) {
2012-06-18 13:01:24 +00:00
sel->last = numfiles - 1;
2019-04-22 09:19:45 +10:00
}
/* clamp */
if ((sel->first >= numfiles)) {
2012-06-18 13:01:24 +00:00
sel->first = numfiles - 1;
}
if ((sel->last >= numfiles)) {
2012-06-18 13:01:24 +00:00
sel->last = numfiles - 1;
}
}
2014-04-11 11:25:41 +10:00
static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill)
{
ARegion *region = CTX_wm_region(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
int numfiles = filelist_files_ensure(sfile->files);
FileSelection sel;
sel = find_file_mouse_rect(sfile, region, rect);
2012-06-18 13:01:24 +00:00
if (!((sel.first == -1) && (sel.last == -1))) {
clamp_to_filelist(numfiles, &sel);
}
/* if desired, fill the selection up from the last selected file to the current one */
if (fill && (sel.last >= 0) && (sel.last < numfiles)) {
int f;
/* Try to find a smaller-index selected item. */
for (f = sel.last; f >= 0; f--) {
2019-04-22 09:19:45 +10:00
if (filelist_entry_select_index_get(sfile->files, f, CHECK_ALL)) {
break;
2019-04-22 09:19:45 +10:00
}
}
if (f >= 0) {
2012-06-18 13:01:24 +00:00
sel.first = f + 1;
}
/* If none found, try to find a higher-index selected item. */
else {
for (f = sel.first; f < numfiles; f++) {
2019-04-22 09:19:45 +10:00
if (filelist_entry_select_index_get(sfile->files, f, CHECK_ALL)) {
break;
2019-04-22 09:19:45 +10:00
}
}
if (f < numfiles) {
sel.last = f - 1;
}
}
}
return sel;
}
2014-04-11 11:25:41 +10:00
static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
{
Main *bmain = CTX_data_main(C);
FileSelect retval = FILE_SELECT_NOTHING;
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
int numfiles = filelist_files_ensure(sfile->files);
const FileDirEntry *file;
/* make the selected file active */
2012-06-18 13:01:24 +00:00
if ((selected_idx >= 0) && (selected_idx < numfiles) &&
(file = filelist_file(sfile->files, selected_idx))) {
params->highlight_file = selected_idx;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
params->active_file = selected_idx;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (file->typeflag & FILE_TYPE_DIR) {
const bool is_parent_dir = FILENAME_IS_PARENT(file->relpath);
if (do_diropen == false) {
retval = FILE_SELECT_DIR;
}
/* the path is too long and we are not going up! */
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
else if (!is_parent_dir && strlen(params->dir) + strlen(file->relpath) >= FILE_MAX) {
// XXX error("Path too long, cannot enter this directory");
}
else {
if (is_parent_dir) {
/* avoids /../../ */
BLI_path_parent_dir(params->dir);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
params->recursion_level = 0;
filelist_setrecursion(sfile->files, params->recursion_level);
}
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
}
else {
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
strcat(params->dir, file->relpath);
BLI_path_slash_ensure(params->dir);
}
ED_file_change_dir(C);
retval = FILE_SELECT_DIR;
}
}
2012-04-21 12:51:47 +00:00
else {
retval = FILE_SELECT_FILE;
}
fileselect_file_set(sfile, selected_idx);
}
return retval;
}
/**
* \warning: loops over all files so better use cautiously
*/
static bool file_is_any_selected(struct FileList *files)
{
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
const int numfiles = filelist_files_ensure(files);
int i;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
/* Is any file selected ? */
for (i = 0; i < numfiles; i++) {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (filelist_entry_select_index_get(files, i, CHECK_ALL)) {
return true;
}
}
return false;
}
static FileSelection file_current_selection_range_get(struct FileList *files)
{
const int numfiles = filelist_files_ensure(files);
FileSelection selection = {-1, -1};
/* Iterate over the files once but in two loops, one to find the first selected file, and the
* other to find the last. */
int file_index;
for (file_index = 0; file_index < numfiles; file_index++) {
if (filelist_entry_is_selected(files, file_index)) {
/* First selected entry found. */
selection.first = file_index;
break;
}
}
for (; file_index < numfiles; file_index++) {
if (filelist_entry_is_selected(files, file_index)) {
selection.last = file_index;
/* Keep looping, we may find more selected files. */
}
}
return selection;
}
/**
* If \a file is outside viewbounds, this adjusts view to make sure it's inside
*/
static void file_ensure_inside_viewbounds(ARegion *region, SpaceFile *sfile, const int file)
{
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
rctf *cur = &region->v2d.cur;
rcti rect;
bool changed = true;
file_tile_boundbox(region, layout, file, &rect);
/* down - also use if tile is higher than viewbounds so view is aligned to file name */
if (cur->ymin > rect.ymin || layout->tile_h > region->winy) {
cur->ymin = rect.ymin - (2 * layout->tile_border_y);
cur->ymax = cur->ymin + region->winy;
}
/* up */
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
else if ((cur->ymax - layout->offset_top) < rect.ymax) {
cur->ymax = rect.ymax + layout->tile_border_y + layout->offset_top;
cur->ymin = cur->ymax - region->winy;
}
/* left - also use if tile is wider than viewbounds so view is aligned to file name */
else if (cur->xmin > rect.xmin || layout->tile_w > region->winx) {
cur->xmin = rect.xmin - layout->tile_border_x;
cur->xmax = cur->xmin + region->winx;
}
/* right */
else if (cur->xmax < rect.xmax) {
cur->xmax = rect.xmax + (2 * layout->tile_border_x);
cur->xmin = cur->xmax - region->winx;
}
else {
BLI_assert(cur->xmin <= rect.xmin && cur->xmax >= rect.xmax && cur->ymin <= rect.ymin &&
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
(cur->ymax - layout->offset_top) >= rect.ymax);
changed = false;
}
if (changed) {
UI_view2d_curRect_validate(&region->v2d);
}
}
static void file_ensure_selection_inside_viewbounds(ARegion *region,
SpaceFile *sfile,
FileSelection *sel)
{
const FileLayout *layout = ED_fileselect_get_layout(sfile, region);
if (((layout->flag & FILE_LAYOUT_HOR) && region->winx <= (1.2f * layout->tile_w)) &&
((layout->flag & FILE_LAYOUT_VER) && region->winy <= (2.0f * layout->tile_h))) {
return;
}
/* Adjust view to display selection. Doing iterations for first and last
* selected item makes view showing as much of the selection possible.
* Not really useful if tiles are (almost) bigger than viewbounds though. */
file_ensure_inside_viewbounds(region, sfile, sel->last);
file_ensure_inside_viewbounds(region, sfile, sel->first);
}
2014-04-11 11:25:41 +10:00
static FileSelect file_select(
bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen)
{
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelect retval = FILE_SELECT_NOTHING;
2012-06-18 13:01:24 +00:00
FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */
const FileCheckType check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
/* flag the files as selected in the filelist */
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entries_select_index_range_set(
sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
/* Don't act on multiple selected files */
2019-04-22 09:19:45 +10:00
if (sel.first != sel.last) {
select = 0;
2019-04-22 09:19:45 +10:00
}
/* Do we have a valid selection and are we actually selecting */
if ((sel.last >= 0) && (select != FILE_SEL_REMOVE)) {
/* Check last selection, if selected, act on the file or dir */
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (filelist_entry_select_index_get(sfile->files, sel.last, check_type)) {
retval = file_select_do(C, sel.last, do_diropen);
}
}
if (select != FILE_SEL_ADD && !file_is_any_selected(sfile->files)) {
params->active_file = -1;
}
else if (sel.last >= 0) {
ARegion *region = CTX_wm_region(C);
file_ensure_selection_inside_viewbounds(region, sfile, &sel);
}
/* update operator for name change event */
file_draw_check(C);
return retval;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Box Select Operator
* \{ */
static int file_box_select_find_last_selected(SpaceFile *sfile,
ARegion *region,
const FileSelection *sel,
const int mouse_xy[2])
{
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
rcti bounds_first, bounds_last;
int dist_first, dist_last;
float mouseco_view[2];
UI_view2d_region_to_view(&region->v2d, UNPACK2(mouse_xy), &mouseco_view[0], &mouseco_view[1]);
file_tile_boundbox(region, layout, sel->first, &bounds_first);
file_tile_boundbox(region, layout, sel->last, &bounds_last);
/* are first and last in the same column (horizontal layout)/row (vertical layout)? */
if ((layout->flag & FILE_LAYOUT_HOR && bounds_first.xmin == bounds_last.xmin) ||
(layout->flag & FILE_LAYOUT_VER && bounds_first.ymin != bounds_last.ymin)) {
/* use vertical distance */
const int my_loc = (int)mouseco_view[1];
dist_first = BLI_rcti_length_y(&bounds_first, my_loc);
dist_last = BLI_rcti_length_y(&bounds_last, my_loc);
}
else {
/* use horizontal distance */
const int mx_loc = (int)mouseco_view[0];
dist_first = BLI_rcti_length_x(&bounds_first, mx_loc);
dist_last = BLI_rcti_length_x(&bounds_last, mx_loc);
}
return (dist_first < dist_last) ? sel->first : sel->last;
}
static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelection sel;
rcti rect;
int result;
result = WM_gesture_box_modal(C, op, event);
2012-05-19 13:55:54 +00:00
if (result == OPERATOR_RUNNING_MODAL) {
WM_operator_properties_border_to_rcti(op, &rect);
ED_fileselect_layout_isect_rect(sfile->layout, &region->v2d, &rect, &rect);
sel = file_selection_get(C, &rect, 0);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if ((sel.first != params->sel_first) || (sel.last != params->sel_last)) {
int idx;
file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entries_select_index_range_set(
sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
for (idx = sel.last; idx >= 0; idx--) {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
const FileDirEntry *file = filelist_file(sfile->files, idx);
2021-03-18 09:35:12 +11:00
/* Don't highlight read-only file (".." or ".") on box select. */
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (FILENAME_IS_CURRPAR(file->relpath)) {
filelist_entry_select_set(
sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
}
/* make sure highlight_file is no readonly file */
if (sel.last == idx) {
params->highlight_file = idx;
}
}
}
params->sel_first = sel.first;
params->sel_last = sel.last;
params->active_file = file_box_select_find_last_selected(sfile, region, &sel, event->mval);
}
else {
params->highlight_file = -1;
params->sel_first = params->sel_last = -1;
fileselect_file_set(sfile, params->active_file);
file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
return result;
}
static int file_box_select_exec(bContext *C, wmOperator *op)
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
rcti rect;
FileSelect ret;
WM_operator_properties_border_to_rcti(op, &rect);
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
const bool select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
file_deselect_all(sfile, FILE_SEL_SELECTED);
}
ED_fileselect_layout_isect_rect(sfile->layout, &region->v2d, &rect, &rect);
ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, false, false);
/* unselect '..' parent entry - it's not supposed to be selected if more than
* one file is selected */
filelist_entry_parent_select_set(sfile->files, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
if (FILE_SELECT_DIR == ret) {
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
else if (FILE_SELECT_FILE == ret) {
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
return OPERATOR_FINISHED;
}
void FILE_OT_select_box(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Box Select";
ot->description = "Activate/select the file(s) contained in the border";
ot->idname = "FILE_OT_select_box";
/* api callbacks */
ot->invoke = WM_gesture_box_invoke;
ot->exec = file_box_select_exec;
ot->modal = file_box_select_modal;
ot->poll = ED_operator_file_active;
ot->cancel = WM_gesture_box_cancel;
/* properties */
WM_operator_properties_gesture_box(ot);
WM_operator_properties_select_operation_simple(ot);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Select Pick Operator
* \{ */
static rcti file_select_mval_to_select_rect(const int mval[2])
{
rcti rect;
rect.xmin = rect.xmax = mval[0];
rect.ymin = rect.ymax = mval[1];
return rect;
}
static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelect ret;
rcti rect;
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool fill = RNA_boolean_get(op->ptr, "fill");
const bool do_diropen = RNA_boolean_get(op->ptr, "open");
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
if (region->regiontype != RGN_TYPE_WINDOW) {
return OPERATOR_CANCELLED;
2019-04-22 09:19:45 +10:00
}
rect = file_select_mval_to_select_rect(event->mval);
if (!ED_fileselect_layout_is_inside_pt(sfile->layout, &region->v2d, rect.xmin, rect.ymin)) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
2019-04-22 09:19:45 +10:00
}
const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (sfile && params) {
int idx = params->highlight_file;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
int numfiles = filelist_files_ensure(sfile->files);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if ((idx >= 0) && (idx < numfiles)) {
/* single select, deselect all selected first */
if (!extend) {
file_deselect_all(sfile, FILE_SEL_SELECTED);
}
}
}
ret = file_select(C, &rect, extend ? FILE_SEL_TOGGLE : FILE_SEL_ADD, fill, do_diropen);
if (extend) {
/* unselect '..' parent entry - it's not supposed to be selected if more
* than one file is selected */
filelist_entry_parent_select_set(sfile->files, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
}
if (ret == FILE_SELECT_NOTHING) {
if (deselect_all) {
file_deselect_all(sfile, FILE_SEL_SELECTED);
}
}
else if (ret == FILE_SELECT_DIR) {
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
2019-04-22 09:19:45 +10:00
}
else if (ret == FILE_SELECT_FILE) {
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
2019-04-22 09:19:45 +10:00
}
WM_event_add_mousemove(CTX_wm_window(C)); /* for directory changes */
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
return OPERATOR_FINISHED;
}
void FILE_OT_select(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Select";
ot->idname = "FILE_OT_select";
ot->description = "Handle mouse clicks to select and activate items";
/* api callbacks */
ot->invoke = file_select_invoke;
ot->poll = ED_operator_file_active;
/* properties */
prop = RNA_def_boolean(ot->srna,
"extend",
false,
"Extend",
"Extend selection instead of deselecting everything first");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(
ot->srna, "fill", false, "Fill", "Select everything beginning with the last selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "open", true, "Open", "Open a directory when selecting it");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna,
"deselect_all",
false,
"Deselect On Nothing",
"Deselect all when nothing under the cursor");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Select Walk Operator
* \{ */
/**
* \returns true if selection has changed
*/
static bool file_walk_select_selection_set(wmWindow *win,
ARegion *region,
SpaceFile *sfile,
const int direction,
const int numfiles,
const int active_old,
const int active_new,
const int other_site,
const bool has_selection,
const bool extend,
const bool fill)
{
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
struct FileList *files = sfile->files;
const int last_sel = params->active_file; /* store old value */
int active = active_old; /* could use active_old instead, just for readability */
bool deselect = false;
BLI_assert(params);
if (numfiles == 0) {
/* No files visible, nothing to do. */
return false;
}
if (has_selection) {
if (extend && filelist_entry_select_index_get(files, active_old, CHECK_ALL) &&
filelist_entry_select_index_get(files, active_new, CHECK_ALL)) {
2015-06-16 10:18:45 +10:00
/* conditions for deselecting: initial file is selected, new file is
* selected and either other_side isn't selected/found or we use fill */
2015-08-20 08:51:35 +10:00
deselect = (fill || other_site == -1 ||
!filelist_entry_select_index_get(files, other_site, CHECK_ALL));
/* don't change highlight_file here since we either want to deselect active or we want
* to walk through a block of selected files without selecting/deselecting anything */
2015-06-16 10:18:45 +10:00
params->active_file = active_new;
/* but we want to change active if we use fill
* (needed to get correct selection bounds) */
2015-06-16 10:18:45 +10:00
if (deselect && fill) {
active = active_new;
}
}
else {
/* regular selection change */
params->active_file = active = active_new;
}
}
else {
/* select last file */
if (ELEM(direction, UI_SELECT_WALK_UP, UI_SELECT_WALK_LEFT)) {
params->active_file = active = numfiles - 1;
}
/* select first file */
else if (ELEM(direction, UI_SELECT_WALK_DOWN, UI_SELECT_WALK_RIGHT)) {
params->active_file = active = 0;
}
else {
BLI_assert(0);
}
}
if (active < 0) {
return false;
}
if (extend) {
/* highlight the active walker file for extended selection for better visual feedback */
params->highlight_file = params->active_file;
/* unselect '..' parent entry - it's not supposed to be selected if more
* than one file is selected */
filelist_entry_parent_select_set(files, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
}
else {
/* deselect all first */
file_deselect_all(sfile, FILE_SEL_SELECTED);
/* highlight file under mouse pos */
params->highlight_file = -1;
WM_event_add_mousemove(win);
}
/* do the actual selection */
if (fill) {
FileSelection sel = {MIN2(active, last_sel), MAX2(active, last_sel)};
/* fill selection between last and first selected file */
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entries_select_index_range_set(
files, &sel, deselect ? FILE_SEL_REMOVE : FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
/* entire sel is cleared here, so select active again */
if (deselect) {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entry_select_index_set(files, active, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
}
/* unselect '..' parent entry - it's not supposed to be selected if more
* than one file is selected */
if ((sel.last - sel.first) > 1) {
filelist_entry_parent_select_set(files, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
}
}
else {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entry_select_index_set(
files, active, deselect ? FILE_SEL_REMOVE : FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
}
BLI_assert(IN_RANGE(active, -1, numfiles));
fileselect_file_set(sfile, params->active_file);
/* ensure newly selected file is inside viewbounds */
file_ensure_inside_viewbounds(region, sfile, params->active_file);
/* selection changed */
return true;
}
/**
* \returns true if selection has changed
*/
static bool file_walk_select_do(bContext *C,
SpaceFile *sfile,
FileSelectParams *params,
const int direction,
const bool extend,
const bool fill)
{
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
struct FileList *files = sfile->files;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
const int numfiles = filelist_files_ensure(files);
const bool has_selection = file_is_any_selected(files);
const int active_old = params->active_file;
int active_new = -1;
int other_site = -1; /* file on the other site of active_old */
/* *** get all needed files for handling selection *** */
if (numfiles == 0) {
/* No files visible, nothing to do. */
return false;
}
if (has_selection) {
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
const int idx_shift = (layout->flag & FILE_LAYOUT_HOR) ? layout->rows : layout->flow_columns;
if ((layout->flag & FILE_LAYOUT_HOR && direction == UI_SELECT_WALK_UP) ||
(layout->flag & FILE_LAYOUT_VER && direction == UI_SELECT_WALK_LEFT)) {
active_new = active_old - 1;
other_site = active_old + 1;
}
else if ((layout->flag & FILE_LAYOUT_HOR && direction == UI_SELECT_WALK_DOWN) ||
(layout->flag & FILE_LAYOUT_VER && direction == UI_SELECT_WALK_RIGHT)) {
active_new = active_old + 1;
other_site = active_old - 1;
}
else if ((layout->flag & FILE_LAYOUT_HOR && direction == UI_SELECT_WALK_LEFT) ||
(layout->flag & FILE_LAYOUT_VER && direction == UI_SELECT_WALK_UP)) {
active_new = active_old - idx_shift;
other_site = active_old + idx_shift;
}
else if ((layout->flag & FILE_LAYOUT_HOR && direction == UI_SELECT_WALK_RIGHT) ||
(layout->flag & FILE_LAYOUT_VER && direction == UI_SELECT_WALK_DOWN)) {
active_new = active_old + idx_shift;
other_site = active_old - idx_shift;
}
else {
BLI_assert(0);
}
if (!IN_RANGE(active_new, -1, numfiles)) {
if (extend) {
/* extend to invalid file -> abort */
return false;
}
/* if we don't extend, selecting '..' (index == 0) is allowed so
* using key selection to go to parent directory is possible */
if (active_new != 0) {
/* select initial file */
active_new = active_old;
}
}
if (!IN_RANGE(other_site, 0, numfiles)) {
other_site = -1;
}
}
return file_walk_select_selection_set(win,
region,
sfile,
direction,
numfiles,
active_old,
active_new,
other_site,
has_selection,
extend,
fill);
}
static int file_walk_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
const int direction = RNA_enum_get(op->ptr, "direction");
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool fill = RNA_boolean_get(op->ptr, "fill");
if (file_walk_select_do(C, sfile, params, direction, extend, fill)) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void FILE_OT_select_walk(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Walk Select/Deselect File";
ot->description = "Select/Deselect files by walking through them";
ot->idname = "FILE_OT_select_walk";
/* api callbacks */
ot->invoke = file_walk_select_invoke;
ot->poll = ED_operator_file_active;
/* properties */
WM_operator_properties_select_walk_direction(ot);
prop = RNA_def_boolean(ot->srna,
"extend",
false,
"Extend",
"Extend selection instead of deselecting everything first");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(
ot->srna, "fill", false, "Fill", "Select everything beginning with the last selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Select All Operator
* \{ */
static int file_select_all_exec(bContext *C, wmOperator *op)
{
ScrArea *area = CTX_wm_area(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelection sel;
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
const int numfiles = filelist_files_ensure(sfile->files);
int action = RNA_enum_get(op->ptr, "action");
if (action == SEL_TOGGLE) {
action = file_is_any_selected(sfile->files) ? SEL_DESELECT : SEL_SELECT;
}
sel.first = 0;
2012-06-18 13:01:24 +00:00
sel.last = numfiles - 1;
FileCheckType check_type;
FileSelType filesel_type;
switch (action) {
case SEL_SELECT:
case SEL_INVERT: {
check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES;
filesel_type = (action == SEL_INVERT) ? FILE_SEL_TOGGLE : FILE_SEL_ADD;
break;
}
case SEL_DESELECT: {
check_type = CHECK_ALL;
filesel_type = FILE_SEL_REMOVE;
break;
}
default: {
BLI_assert(0);
return OPERATOR_CANCELLED;
}
}
filelist_entries_select_index_range_set(
sfile->files, &sel, filesel_type, FILE_SEL_SELECTED, check_type);
params->active_file = -1;
if (action != SEL_DESELECT) {
for (int i = 0; i < numfiles; i++) {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (filelist_entry_select_index_get(sfile->files, i, check_type)) {
params->active_file = i;
break;
}
}
}
file_draw_check(C);
WM_event_add_mousemove(CTX_wm_window(C));
ED_area_tag_redraw(area);
return OPERATOR_FINISHED;
}
void FILE_OT_select_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "(De)select All Files";
ot->description = "Select or deselect all files";
ot->idname = "FILE_OT_select_all";
/* api callbacks */
ot->exec = file_select_all_exec;
ot->poll = ED_operator_file_active;
/* properties */
WM_operator_properties_select_all(ot);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name View Selected Operator
* \{ */
static int file_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelection sel = file_current_selection_range_get(sfile->files);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (sel.first == -1 && sel.last == -1 && params->active_file == -1) {
/* Nothing was selected. */
return OPERATOR_CANCELLED;
}
/* Extend the selection area with the active file, as it may not be selected but still is
* important to have in view. */
if (sel.first == -1 || params->active_file < sel.first) {
sel.first = params->active_file;
}
if (sel.last == -1 || params->active_file > sel.last) {
sel.last = params->active_file;
}
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
file_ensure_selection_inside_viewbounds(region, sfile, &sel);
file_draw_check(C);
WM_event_add_mousemove(CTX_wm_window(C));
ED_area_tag_redraw(area);
return OPERATOR_FINISHED;
}
void FILE_OT_view_selected(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Frame Selected";
ot->description = "Scroll the selected files into view";
ot->idname = "FILE_OT_view_selected";
/* api callbacks */
ot->exec = file_view_selected_exec;
ot->poll = ED_operator_file_active;
}
/** \} */
2020-03-25 21:24:59 +11:00
/* -------------------------------------------------------------------- */
/** \name Select Bookmark Operator
* \{ */
/* Note we could get rid of this one, but it's used by some addon so...
* Does not hurt keeping it around for now. */
Asset System: Prepare File Browser backend for the Asset Browser The Asset Browser will be a sub-editor of the File Browser. This prepares the File Browser code for that. **File-Lists** * Support loading assets with metadata read from external files into the file-list. * New main based file-list type, for the "Current File" asset library. * Refresh file-list when switching between browse modes or asset libraries. * Support empty file-lists (asset library with no assets). * Store file previews as icons, so scripts can reference them via icon-id. See previous commit. **Space Data** * Introduce "browse mode" to differeniate between file and asset browsing. * Add `FileAssetSelectParams` to `SpaceFile`, with `FileSelectParams` as base. Makes sure data is separated between asset and file browsing when switching between them. The active params can be obtained through `ED_fileselect_get_active_params()`. * `FileAssetSelectParams` stores the currently visible asset library ID. * Introduce file history abstraction so file and asset browsing can keep a separate history (previous and next directories). **General** * Option to only show asset data-blocks while file browsing (not exposed here). * Add "active_file" context member, so scripts can get and display info about the active file. * Add "active_id" context member, so `ED_OT_lib_id_load_custom_preview` can set a custom ID preview. (Only for "Current File" asset library) * Expose some of `FileDirEntry` in RNA as (non-editable). That way scripts can obtain name, preview icon and asset-data. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9724 Reviewed by: Bastien Montagne
2020-12-14 13:50:36 +01:00
/* TODO disallow bookmark editing in assets mode? */
static int bookmark_select_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
2015-02-17 13:09:21 +11:00
PropertyRNA *prop;
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "dir"))) {
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
char entry[256];
2015-02-17 13:09:21 +11:00
RNA_property_string_get(op->ptr, prop, entry);
BLI_strncpy(params->dir, entry, sizeof(params->dir));
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
ED_file_change_dir(C);
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
return OPERATOR_FINISHED;
}
void FILE_OT_select_bookmark(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Select Directory";
ot->description = "Select a bookmarked directory";
ot->idname = "FILE_OT_select_bookmark";
/* api callbacks */
ot->exec = bookmark_select_exec;
ot->poll = ED_operator_file_active;
/* properties */
prop = RNA_def_string(ot->srna, "dir", NULL, FILE_MAXDIR, "Directory", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Add Bookmark Operator
* \{ */
static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
struct FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params->dir[0] != '\0') {
char name[FILE_MAX];
fsmenu_insert_entry(
fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, NULL, ICON_FILE_FOLDER, FS_INSERT_SAVE);
BLI_join_dirfile(name,
sizeof(name),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
}
ED_area_tag_refresh(area);
ED_area_tag_redraw(area);
return OPERATOR_FINISHED;
}
operator renaming for more consistent word ordering (_add/_remmove shold be last, ACT_OT_* --> ACTION_OT_*) ACT_OT_clean --> ACTION_OT_clean ACT_OT_clickselect --> ACTION_OT_clickselect ACT_OT_copy --> ACTION_OT_copy ACT_OT_delete --> ACTION_OT_delete ACT_OT_duplicate --> ACTION_OT_duplicate ACT_OT_extrapolation_type --> ACTION_OT_extrapolation_type ACT_OT_frame_jump --> ACTION_OT_frame_jump ACT_OT_handle_type --> ACTION_OT_handle_type ACT_OT_insert_keyframe --> ACTION_OT_insert_keyframe ACT_OT_insert_keyframe --> ACT_OT_keyframe_insert ACT_OT_interpolation_type --> ACTION_OT_interpolation_type ACT_OT_keyframe_type --> ACTION_OT_keyframe_type ACT_OT_mirror --> ACTION_OT_mirror ACT_OT_new --> ACTION_OT_new ACT_OT_paste --> ACTION_OT_paste ACT_OT_previewrange_set --> ACTION_OT_previewrange_set ACT_OT_properties --> ACTION_OT_properties ACT_OT_sample --> ACTION_OT_sample ACT_OT_select_all_toggle --> ACTION_OT_select_all_toggle ACT_OT_select_border --> ACTION_OT_select_border ACT_OT_select_column --> ACTION_OT_select_column ACT_OT_snap --> ACTION_OT_snap ACT_OT_test --> ACTION_OT_test ACT_OT_unlink --> ACTION_OT_unlink ACT_OT_view_all --> ACTION_OT_view_all ANIM_OT_add_driver_button --> ANIM_OT_driver_button_add ANIM_OT_add_keyingset_button --> ANIM_OT_keyingset_button_add ANIM_OT_delete_keyframe --> ANIM_OT_keyframe_delete ANIM_OT_delete_keyframe_button --> ANIM_OT_keyframe_delete_button ANIM_OT_delete_keyframe_v3d --> ANIM_OT_keyframe_delete_v3d ANIM_OT_insert_keyframe --> ANIM_OT_keyframe_insert ANIM_OT_insert_keyframe_button --> ANIM_OT_keyframe_insert_button ANIM_OT_insert_keyframe_menu --> ANIM_OT_keyframe_insert_menu ANIM_OT_remove_driver_button --> ANIM_OT_driver_button_remove ANIM_OT_remove_keyingset_button --> ANIM_OT_keyingset_button_remove FILE_OT_add_bookmark --> FILE_OT_bookmark_add GRAPH_OT_insert_keyframe --> GRAPH_OT_keyframe_insert NLA_OT_add_actionclip --> NLA_OT_actionclip_add NLA_OT_add_meta --> NLA_OT_meta_add NLA_OT_add_tracks --> NLA_OT_tracks_add NLA_OT_add_transition --> NLA_OT_transition_add NLA_OT_remove_meta --> NLA_OT_meta_remove PARTICLE_OT_remove_target --> PARTICLE_OT_target_remove PTCACHE_OT_add_new --> PTCACHE_OT_add
2009-11-28 14:37:21 +00:00
void FILE_OT_bookmark_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Bookmark";
ot->description = "Add a bookmark for the selected/active directory";
ot->idname = "FILE_OT_bookmark_add";
/* api callbacks */
ot->exec = bookmark_add_exec;
ot->poll = ED_operator_file_active;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Delete Bookmark Operator
* \{ */
static int bookmark_delete_exec(bContext *C, wmOperator *op)
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
int nentries = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "index");
if (prop) {
int index;
if (RNA_property_is_set(op->ptr, prop)) {
index = RNA_property_int_get(op->ptr, prop);
}
else { /* if index unset, use active bookmark... */
index = sfile->bookmarknr;
}
2014-03-17 21:48:13 +11:00
if ((index > -1) && (index < nentries)) {
char name[FILE_MAX];
fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
BLI_join_dirfile(name,
sizeof(name),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
ED_area_tag_refresh(area);
ED_area_tag_redraw(area);
}
}
return OPERATOR_FINISHED;
}
void FILE_OT_bookmark_delete(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Delete Bookmark";
ot->description = "Delete selected bookmark";
ot->idname = "FILE_OT_bookmark_delete";
/* api callbacks */
ot->exec = bookmark_delete_exec;
ot->poll = ED_operator_file_active;
/* properties */
prop = RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Cleanup Bookmark Operator
* \{ */
static int bookmark_cleanup_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
struct FSMenuEntry *fsme_next, *fsme = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS);
int index;
bool changed = false;
for (index = 0; fsme; fsme = fsme_next) {
fsme_next = fsme->next;
if (!BLI_is_dir(fsme->path)) {
fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
changed = true;
}
else {
index++;
}
}
if (changed) {
char name[FILE_MAX];
BLI_join_dirfile(name,
sizeof(name),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
fsmenu_refresh_bookmarks_status(CTX_wm_manager(C), fsmenu);
ED_area_tag_refresh(area);
ED_area_tag_redraw(area);
}
return OPERATOR_FINISHED;
}
void FILE_OT_bookmark_cleanup(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Cleanup Bookmarks";
ot->description = "Delete all invalid bookmarks";
ot->idname = "FILE_OT_bookmark_cleanup";
/* api callbacks */
ot->exec = bookmark_cleanup_exec;
ot->poll = ED_operator_file_active;
/* properties */
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Reorder Bookmark Operator
* \{ */
enum {
FILE_BOOKMARK_MOVE_TOP = -2,
FILE_BOOKMARK_MOVE_UP = -1,
FILE_BOOKMARK_MOVE_DOWN = 1,
FILE_BOOKMARK_MOVE_BOTTOM = 2,
};
static int bookmark_move_exec(bContext *C, wmOperator *op)
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS);
const struct FSMenuEntry *fsmentry_org = fsmentry;
char fname[FILE_MAX];
const int direction = RNA_enum_get(op->ptr, "direction");
const int totitems = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
const int act_index = sfile->bookmarknr;
int new_index;
if (totitems < 2) {
return OPERATOR_CANCELLED;
}
switch (direction) {
case FILE_BOOKMARK_MOVE_TOP:
new_index = 0;
break;
case FILE_BOOKMARK_MOVE_BOTTOM:
new_index = totitems - 1;
break;
case FILE_BOOKMARK_MOVE_UP:
case FILE_BOOKMARK_MOVE_DOWN:
default:
new_index = (totitems + act_index + direction) % totitems;
break;
}
if (new_index == act_index) {
return OPERATOR_CANCELLED;
}
BLI_linklist_move_item((LinkNode **)&fsmentry, act_index, new_index);
if (fsmentry != fsmentry_org) {
ED_fsmenu_set_category(fsmenu, FS_CATEGORY_BOOKMARKS, fsmentry);
}
/* Need to update active bookmark number. */
sfile->bookmarknr = new_index;
BLI_join_dirfile(fname,
sizeof(fname),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, fname);
ED_area_tag_redraw(area);
return OPERATOR_FINISHED;
}
void FILE_OT_bookmark_move(wmOperatorType *ot)
{
static const EnumPropertyItem slot_move[] = {
2016-01-21 09:05:52 +11:00
{FILE_BOOKMARK_MOVE_TOP, "TOP", 0, "Top", "Top of the list"},
{FILE_BOOKMARK_MOVE_UP, "UP", 0, "Up", ""},
{FILE_BOOKMARK_MOVE_DOWN, "DOWN", 0, "Down", ""},
{FILE_BOOKMARK_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"},
{0, NULL, 0, NULL, NULL}};
/* identifiers */
ot->name = "Move Bookmark";
ot->idname = "FILE_OT_bookmark_move";
ot->description = "Move the active bookmark up/down in the list";
/* api callbacks */
ot->poll = ED_operator_file_active;
ot->exec = bookmark_move_exec;
/* flags */
ot->flag = OPTYPE_REGISTER; /* No undo! */
RNA_def_enum(ot->srna,
"direction",
slot_move,
0,
"Direction",
"Direction to move the active bookmark towards");
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Reset Recent Blend Files Operator
* \{ */
2012-09-17 22:34:42 +00:00
static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
char name[FILE_MAX];
struct FSMenu *fsmenu = ED_fsmenu_get();
while (ED_fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) {
fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0);
}
BLI_join_dirfile(name,
sizeof(name),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
ED_area_tag_redraw(area);
return OPERATOR_FINISHED;
}
void FILE_OT_reset_recent(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Reset Recent";
ot->description = "Reset recent files";
ot->idname = "FILE_OT_reset_recent";
/* api callbacks */
ot->exec = reset_recent_exec;
ot->poll = ED_operator_file_active;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Highlight File Operator
* \{ */
int file_highlight_set(SpaceFile *sfile, ARegion *region, int mx, int my)
{
View2D *v2d = &region->v2d;
2012-06-18 13:01:24 +00:00
FileSelectParams *params;
int numfiles, origfile;
2019-04-22 09:19:45 +10:00
if (sfile == NULL || sfile->files == NULL) {
2012-06-18 13:01:24 +00:00
return 0;
2019-04-22 09:19:45 +10:00
}
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
numfiles = filelist_files_ensure(sfile->files);
params = ED_fileselect_get_active_params(sfile);
origfile = params->highlight_file;
mx -= region->winrct.xmin;
my -= region->winrct.ymin;
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
if (ED_fileselect_layout_is_inside_pt(sfile->layout, v2d, mx, my)) {
float fx, fy;
int highlight_file;
UI_view2d_region_to_view(v2d, mx, my, &fx, &fy);
highlight_file = ED_fileselect_layout_offset(
sfile->layout, (int)(v2d->tot.xmin + fx), (int)(v2d->tot.ymax - fy));
2019-04-22 09:19:45 +10:00
if ((highlight_file >= 0) && (highlight_file < numfiles)) {
params->highlight_file = highlight_file;
2019-04-22 09:19:45 +10:00
}
else {
params->highlight_file = -1;
2019-04-22 09:19:45 +10:00
}
}
2019-04-22 09:19:45 +10:00
else {
params->highlight_file = -1;
2019-04-22 09:19:45 +10:00
}
return (params->highlight_file != origfile);
}
static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
if (!file_highlight_set(sfile, region, event->x, event->y)) {
return OPERATOR_PASS_THROUGH;
2019-04-22 09:19:45 +10:00
}
ED_area_tag_redraw(CTX_wm_area(C));
return OPERATOR_PASS_THROUGH;
}
void FILE_OT_highlight(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Highlight File";
ot->description = "Highlight selected file(s)";
ot->idname = "FILE_OT_highlight";
/* api callbacks */
ot->invoke = file_highlight_invoke;
ot->poll = ED_operator_file_active;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Sort from Column Operator
* \{ */
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
static int file_column_sort_ui_context_invoke(bContext *C,
wmOperator *UNUSED(op),
const wmEvent *event)
{
const ARegion *region = CTX_wm_region(C);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
SpaceFile *sfile = CTX_wm_space_file(C);
if (file_attribute_column_header_is_inside(
&region->v2d, sfile->layout, event->mval[0], event->mval[1])) {
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
const FileAttributeColumnType column_type = file_attribute_column_type_find_isect(
&region->v2d, params, sfile->layout, event->mval[0]);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
if (column_type != COLUMN_NONE) {
const FileAttributeColumn *column = &sfile->layout->attribute_columns[column_type];
BLI_assert(column->sort_type != FILE_SORT_DEFAULT);
if (params->sort == column->sort_type) {
/* Already sorting by selected column -> toggle sort invert (three state logic). */
params->flag ^= FILE_SORT_INVERT;
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
}
else {
params->sort = column->sort_type;
params->flag &= ~FILE_SORT_INVERT;
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
}
}
return OPERATOR_PASS_THROUGH;
}
void FILE_OT_sort_column_ui_context(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Sort from Column";
ot->description = "Change sorting to use column under cursor";
ot->idname = "FILE_OT_sort_column_ui_context";
/* api callbacks */
ot->invoke = file_column_sort_ui_context_invoke;
ot->poll = ED_operator_file_active;
ot->flag = OPTYPE_INTERNAL;
}
2020-03-25 21:24:59 +11:00
/** \} */
2020-03-25 21:24:59 +11:00
/* -------------------------------------------------------------------- */
/** \name Cancel File Selector Operator
* \{ */
2018-07-02 11:47:00 +02:00
static bool file_operator_poll(bContext *C)
{
2018-07-02 11:47:00 +02:00
bool poll = ED_operator_file_active(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
2019-04-22 09:19:45 +10:00
if (!sfile || !sfile->op) {
2012-06-18 13:01:24 +00:00
poll = 0;
2019-04-22 09:19:45 +10:00
}
return poll;
}
2020-03-25 21:24:59 +11:00
static int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
sfile->op = NULL;
WM_event_fileselect_event(wm, op, EVT_FILESELECT_CANCEL);
return OPERATOR_FINISHED;
}
void FILE_OT_cancel(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Cancel File Load";
ot->description = "Cancel loading of selected file";
ot->idname = "FILE_OT_cancel";
/* api callbacks */
ot->exec = file_cancel_exec;
ot->poll = file_operator_poll;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Operator Utilities
* \{ */
void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath)
{
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
2015-02-17 13:09:21 +11:00
PropertyRNA *prop;
/* XXX, not real length */
BLI_join_dirfile(filepath, FILE_MAX, params->dir, params->file);
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
BLI_path_rel(filepath, BKE_main_blendfile_path(bmain));
}
}
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
RNA_property_string_set(op->ptr, prop, params->file);
}
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
RNA_property_string_set(op->ptr, prop, params->dir);
}
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
RNA_property_string_set(op->ptr, prop, filepath);
}
/* some ops have multiple files to select */
/* this is called on operators check() so clear collections first since
* they may be already set. */
{
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
int i, numfiles = filelist_files_ensure(sfile->files);
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
PointerRNA itemptr;
int num_files = 0;
2015-02-17 13:09:21 +11:00
RNA_property_collection_clear(op->ptr, prop);
2012-06-18 13:01:24 +00:00
for (i = 0; i < numfiles; i++) {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
FileDirEntry *file = filelist_file(sfile->files, i);
/* Cannot (currently) mix regular items and alias/shortcuts in multiple selection. */
if (!file->redirection_path) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", file->relpath);
num_files++;
}
}
}
/* make sure the file specified in the filename button is added even if no
* files selected */
if (0 == num_files) {
2015-02-17 13:09:21 +11:00
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", params->file);
}
}
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "dirs"))) {
PointerRNA itemptr;
int num_dirs = 0;
2015-02-17 13:09:21 +11:00
RNA_property_collection_clear(op->ptr, prop);
2012-06-18 13:01:24 +00:00
for (i = 0; i < numfiles; i++) {
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (filelist_entry_select_index_get(sfile->files, i, CHECK_DIRS)) {
FileDirEntry *file = filelist_file(sfile->files, i);
2015-02-17 13:09:21 +11:00
RNA_property_collection_add(op->ptr, prop, &itemptr);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
RNA_string_set(&itemptr, "name", file->relpath);
num_dirs++;
}
}
/* make sure the directory specified in the button is added even if no
* directory selected */
if (0 == num_dirs) {
2015-02-17 13:09:21 +11:00
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", params->dir);
}
}
}
}
void file_sfile_to_operator(Main *bmain, wmOperator *op, SpaceFile *sfile)
{
char filepath_dummy[FILE_MAX];
file_sfile_to_operator_ex(bmain, op, sfile, filepath_dummy);
}
void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op)
{
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
PropertyRNA *prop;
/* If neither of the above are set, split the filepath back */
2012-06-18 13:01:24 +00:00
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
char filepath[FILE_MAX];
RNA_property_string_get(op->ptr, prop, filepath);
BLI_split_dirfile(
filepath, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
else {
2012-06-18 13:01:24 +00:00
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
RNA_property_string_get(op->ptr, prop, params->file);
}
2012-06-18 13:01:24 +00:00
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
RNA_property_string_get(op->ptr, prop, params->dir);
}
}
/* we could check for relative_path property which is used when converting
* in the other direction but doesn't hurt to do this every time */
BLI_path_abs(params->dir, BKE_main_blendfile_path(bmain));
/* 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)
{
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
BLI_assert(BLI_exists(filepath));
if (BLI_is_dir(filepath)) {
BLI_strncpy(params->dir, filepath, sizeof(params->dir));
}
else {
if ((params->flag & FILE_DIRSEL_ONLY) == 0) {
BLI_split_dirfile(
filepath, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
2015-11-06 05:09:14 +11:00
else {
BLI_split_dir_part(filepath, params->dir, sizeof(params->dir));
}
}
}
void file_draw_check_ex(bContext *C, ScrArea *area)
{
/* May happen when manipulating non-active spaces. */
if (UNLIKELY(area->spacetype != SPACE_FILE)) {
return;
}
SpaceFile *sfile = area->spacedata.first;
2012-06-18 13:01:24 +00:00
wmOperator *op = sfile->op;
if (op) { /* fail on reload */
if (op->type->check) {
Main *bmain = CTX_data_main(C);
file_sfile_to_operator(bmain, op, sfile);
/* redraw */
if (op->type->check(C, op)) {
file_operator_to_sfile(bmain, sfile, op);
/* redraw, else the changed settings wont get updated */
ED_area_tag_redraw(area);
}
}
}
}
void file_draw_check(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
file_draw_check_ex(C, area);
}
/* for use with; UI_block_func_set */
void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
{
file_draw_check(C);
}
2014-02-03 18:55:59 +11:00
bool file_draw_check_exists(SpaceFile *sfile)
{
if (sfile->op) { /* fails on reload */
const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params && (params->flag & FILE_CHECK_EXISTING)) {
char filepath[FILE_MAX];
BLI_join_dirfile(filepath, sizeof(filepath), params->dir, params->file);
if (BLI_is_file(filepath)) {
return true;
}
}
}
return false;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Execute File Window Operator
* \{ */
/**
* Execute the active file, as set in the file select params.
*/
static bool file_execute(bContext *C, SpaceFile *sfile)
{
Main *bmain = CTX_data_main(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileDirEntry *file = filelist_file(sfile->files, params->active_file);
if (file && file->redirection_path) {
/* redirection_path is an absolute path that takes precedence
* over using params->dir + params->file. */
BLI_split_dirfile(file->redirection_path,
params->dir,
params->file,
sizeof(params->dir),
sizeof(params->file));
/* Update relpath with redirected filename as well so that the alternative
* combination of params->dir + relpath remains valid as well. */
MEM_freeN(file->relpath);
file->relpath = BLI_strdup(params->file);
}
/* directory change */
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (file && (file->typeflag & FILE_TYPE_DIR)) {
if (!file->relpath) {
return false;
}
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
if (FILENAME_IS_PARENT(file->relpath)) {
BLI_path_parent_dir(params->dir);
}
else {
BLI_path_normalize(BKE_main_blendfile_path(bmain), params->dir);
BLI_path_append(params->dir, sizeof(params->dir) - 1, file->relpath);
BLI_path_slash_ensure(params->dir);
}
ED_file_change_dir(C);
}
/* opening file - sends events now, so things get handled on windowqueue level */
else if (sfile->op) {
2012-06-18 13:01:24 +00:00
wmOperator *op = sfile->op;
char filepath[FILE_MAX];
sfile->op = NULL;
file_sfile_to_operator_ex(bmain, op, sfile, filepath);
if (BLI_exists(params->dir)) {
fsmenu_insert_entry(ED_fsmenu_get(),
FS_CATEGORY_RECENT,
params->dir,
NULL,
ICON_FILE_FOLDER,
FS_INSERT_SAVE | FS_INSERT_FIRST);
}
BLI_join_dirfile(filepath,
sizeof(filepath),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), filepath);
WM_event_fileselect_event(CTX_wm_manager(C), op, EVT_FILESELECT_EXEC);
}
return true;
}
static int file_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceFile *sfile = CTX_wm_space_file(C);
if (!file_execute(C, sfile)) {
return OPERATOR_CANCELLED;
}
return OPERATOR_FINISHED;
}
void FILE_OT_execute(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Execute File Window";
ot->description = "Execute selected file";
ot->idname = "FILE_OT_execute";
/* api callbacks */
ot->exec = file_exec;
/* Important since handler is on window level.
*
* Avoid using #file_operator_poll since this is also used for entering directories
* which is used even when the file manager doesn't have an operator. */
ot->poll = ED_operator_file_active;
}
/**
* \returns false if the mouse doesn't hover a selectable item.
*/
static bool file_ensure_hovered_is_active(bContext *C, const wmEvent *event)
{
rcti rect = file_select_mval_to_select_rect(event->mval);
if (file_select(C, &rect, FILE_SEL_ADD, false, false) == FILE_SELECT_NOTHING) {
return false;
}
return true;
}
static int file_execute_mouse_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (!ED_fileselect_layout_is_inside_pt(
sfile->layout, &region->v2d, event->mval[0], event->mval[1])) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
/* Note that this isn't needed practically, because the keymap already activates the hovered item
* on mouse-press. This execute operator is called afterwards on the double-click event then.
* However relying on this would be fragile and could break with keymap changes, so better to
* have this mouse-execute operator that makes sure once more that the hovered file is active. */
if (!file_ensure_hovered_is_active(C, event)) {
return OPERATOR_CANCELLED;
}
if (!file_execute(C, sfile)) {
return OPERATOR_CANCELLED;
}
return OPERATOR_FINISHED;
}
/**
* Variation of #FILE_OT_execute that accounts for some mouse specific handling. Otherwise calls
* the same logic.
*/
void FILE_OT_mouse_execute(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Execute File";
ot->description =
"Perform the current execute action for the file under the cursor (e.g. open the file)";
ot->idname = "FILE_OT_mouse_execute";
/* api callbacks */
ot->invoke = file_execute_mouse_invoke;
ot->poll = ED_operator_file_active;
ot->flag = OPTYPE_INTERNAL;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Refresh File List Operator
* \{ */
static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
/* refresh system directory menu */
fsmenu_refresh_system_category(fsmenu);
/* Update bookmarks 'valid' state. */
fsmenu_refresh_bookmarks_status(wm, fsmenu);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
}
void FILE_OT_refresh(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Refresh File List";
2020-03-25 21:24:59 +11:00
ot->description = "Refresh the file list";
ot->idname = "FILE_OT_refresh";
/* api callbacks */
ot->exec = file_refresh_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Navigate Parent Operator
* \{ */
static int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
{
Main *bmain = CTX_data_main(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
if (BLI_path_parent_dir(params->dir)) {
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
ED_file_change_dir(C);
if (params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
params->recursion_level = 0;
filelist_setrecursion(sfile->files, params->recursion_level);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
}
return OPERATOR_FINISHED;
}
void FILE_OT_parent(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Parent File";
ot->description = "Move to parent directory";
ot->idname = "FILE_OT_parent";
/* api callbacks */
ot->exec = file_parent_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Navigate Previous Operator
* \{ */
static int file_previous_exec(bContext *C, wmOperator *UNUSED(op))
{
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
folderlist_pushdir(sfile->folders_next, params->dir);
folderlist_popdir(sfile->folders_prev, params->dir);
folderlist_pushdir(sfile->folders_next, params->dir);
2020-03-25 21:24:59 +11:00
ED_file_change_dir(C);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
}
void FILE_OT_previous(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Previous Folder";
ot->description = "Move to previous folder";
ot->idname = "FILE_OT_previous";
/* api callbacks */
ot->exec = file_previous_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Navigate Next Operator
* \{ */
static int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
{
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
folderlist_pushdir(sfile->folders_prev, params->dir);
folderlist_popdir(sfile->folders_next, params->dir);
2020-03-25 21:24:59 +11:00
/* update folders_prev so we can check for it in #folderlist_clear_next() */
folderlist_pushdir(sfile->folders_prev, params->dir);
ED_file_change_dir(C);
}
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
}
void FILE_OT_next(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Next Folder";
ot->description = "Move to next folder";
ot->idname = "FILE_OT_next";
/* api callbacks */
ot->exec = file_next_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
2020-03-25 21:24:59 +11:00
/** \} */
2020-03-25 21:24:59 +11:00
/* -------------------------------------------------------------------- */
/** \name Smooth Scroll Operator
* \{ */
/* only meant for timer usage */
static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ScrArea *area = CTX_wm_area(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
ARegion *region, *region_ctx = CTX_wm_region(C);
const bool is_horizontal = (sfile->layout->flag & FILE_LAYOUT_HOR) != 0;
int i;
/* escape if not our timer */
2019-04-22 09:19:45 +10:00
if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata) {
return OPERATOR_PASS_THROUGH;
2019-04-22 09:19:45 +10:00
}
const int numfiles = filelist_files_ensure(sfile->files);
/* Due to async nature of file listing, we may execute this code before `file_refresh()`
* editing entry is available in our listing,
* so we also have to handle switching to rename mode here. */
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if ((params->rename_flag &
(FILE_PARAMS_RENAME_PENDING | FILE_PARAMS_RENAME_POSTSCROLL_PENDING)) != 0) {
file_params_renamefile_activate(sfile, params);
}
/* check if we are editing a name */
int edit_idx = -1;
for (i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL) &
(FILE_SEL_EDITING | FILE_SEL_HIGHLIGHTED)) {
2012-06-18 13:01:24 +00:00
edit_idx = i;
break;
}
}
/* if we are not editing, we are done */
if (edit_idx == -1) {
/* Do not invalidate timer if filerename is still pending,
* we might still be building the filelist and yet have to find edited entry. */
if (params->rename_flag == 0) {
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
sfile->smoothscroll_timer = NULL;
}
return OPERATOR_PASS_THROUGH;
}
/* we need the correct area for scrolling */
region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
if (!region || region->regiontype != RGN_TYPE_WINDOW) {
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
2012-06-18 13:01:24 +00:00
sfile->smoothscroll_timer = NULL;
return OPERATOR_PASS_THROUGH;
}
/* Number of items in a block (i.e. lines in a column in horizontal layout, or columns in a line
* in vertical layout).
*/
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
const int items_block_size = is_horizontal ? sfile->layout->rows : sfile->layout->flow_columns;
/* Scroll offset is the first file in the row/column we are editing in. */
if (sfile->scroll_offset == 0) {
sfile->scroll_offset = (edit_idx / items_block_size) * items_block_size;
}
const int numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, region);
const int first_visible_item = ED_fileselect_layout_offset(
sfile->layout, (int)region->v2d.cur.xmin, (int)-region->v2d.cur.ymax);
const int last_visible_item = first_visible_item + numfiles_layout + 1;
/* Note: the special case for vertical layout is because filename is at the bottom of items then,
* so we artificially move current row back one step, to ensure we show bottom of
* active item rather than its top (important in case visible height is low). */
const int middle_offset = max_ii(
0, (first_visible_item + last_visible_item) / 2 - (is_horizontal ? 0 : items_block_size));
const int min_middle_offset = numfiles_layout / 2;
const int max_middle_offset = ((numfiles / items_block_size) * items_block_size +
((numfiles % items_block_size) != 0 ? items_block_size : 0)) -
(numfiles_layout / 2);
/* Actual (physical) scrolling info, in pixels, used to detect whether we are fully at the
2019-07-07 15:38:41 +10:00
* beginning/end of the view. */
/* Note that there is a weird glitch, that sometimes tot rctf is smaller than cur rctf...
* that is why we still need to keep the min/max_middle_offset checks too. :( */
const float min_tot_scroll = is_horizontal ? region->v2d.tot.xmin : -region->v2d.tot.ymax;
const float max_tot_scroll = is_horizontal ? region->v2d.tot.xmax : -region->v2d.tot.ymin;
const float min_curr_scroll = is_horizontal ? region->v2d.cur.xmin : -region->v2d.cur.ymax;
const float max_curr_scroll = is_horizontal ? region->v2d.cur.xmax : -region->v2d.cur.ymin;
/* Check if we have reached our final scroll position. */
/* Filelist has to be ready, otherwise it makes no sense to stop scrolling yet. */
const bool is_ready = filelist_is_ready(sfile->files);
2019-07-07 15:38:41 +10:00
/* Edited item must be in the 'middle' of shown area (kind of approximated).
* Note that we have to do the check in 'block space', not in 'item space' here. */
const bool is_centered = (abs(middle_offset / items_block_size -
sfile->scroll_offset / items_block_size) == 0);
2019-07-07 15:38:41 +10:00
/* OR edited item must be towards the beginning, and we are scrolled fully to the start. */
const bool is_full_start = ((sfile->scroll_offset < min_middle_offset) &&
(min_curr_scroll - min_tot_scroll < 1.0f) &&
(middle_offset - min_middle_offset < items_block_size));
/* OR edited item must be towards the end, and we are scrolled fully to the end.
2019-07-07 15:38:41 +10:00
* This one is crucial (unlike the one for the beginning), because without it we won't scroll
* fully to the end, and last column or row will end up only partially drawn. */
const bool is_full_end = ((sfile->scroll_offset > max_middle_offset) &&
(max_tot_scroll - max_curr_scroll < 1.0f) &&
(max_middle_offset - middle_offset < items_block_size));
if (is_ready && (is_centered || is_full_start || is_full_end)) {
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
2012-06-18 13:01:24 +00:00
sfile->smoothscroll_timer = NULL;
2019-04-29 14:14:14 +10:00
/* Post-scroll (after rename has been validated by user) is done,
* rename process is totally finished, cleanup. */
if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE) != 0) {
params->renamefile[0] = '\0';
params->rename_flag = 0;
}
return OPERATOR_FINISHED;
}
/* Temporarily set context to the main window region,
* so that the pan operator works. */
CTX_wm_region_set(C, region);
/* scroll one step in the desired direction */
PointerRNA op_ptr;
int deltax = 0;
int deltay = 0;
/* We adjust speed of scrolling to avoid tens of seconds of it in e.g. directories with tens of
* thousands of folders... See T65782. */
/* This will slow down scrolling when approaching final goal, also avoids going too far and
* having to bounce back... */
/* Number of blocks (columns in horizontal layout, rows otherwise) between current middle of
* screen, and final goal position. */
const int diff_offset = sfile->scroll_offset / items_block_size -
middle_offset / items_block_size;
/* convert diff_offset into pixels. */
const int diff_offset_delta = abs(diff_offset) *
(is_horizontal ?
sfile->layout->tile_w + 2 * sfile->layout->tile_border_x :
sfile->layout->tile_h + 2 * sfile->layout->tile_border_y);
const int scroll_delta = max_ii(2, diff_offset_delta / 15);
if (diff_offset < 0) {
if (is_horizontal) {
deltax = -scroll_delta;
}
else {
deltay = scroll_delta;
}
}
else {
if (is_horizontal) {
deltax = scroll_delta;
}
else {
deltay = -scroll_delta;
}
}
WM_operator_properties_create(&op_ptr, "VIEW2D_OT_pan");
RNA_int_set(&op_ptr, "deltax", deltax);
RNA_int_set(&op_ptr, "deltay", deltay);
WM_operator_name_call(C, "VIEW2D_OT_pan", WM_OP_EXEC_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
ED_region_tag_redraw(region);
/* and restore context */
CTX_wm_region_set(C, region_ctx);
return OPERATOR_FINISHED;
}
void FILE_OT_smoothscroll(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Smooth Scroll";
ot->idname = "FILE_OT_smoothscroll";
ot->description = "Smooth scroll to make editable file visible";
/* api callbacks */
ot->invoke = file_smoothscroll_invoke;
ot->poll = ED_operator_file_active;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name File Selector Drop Operator
* \{ */
static int filepath_drop_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
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(bmain, 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->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, "", "");
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name New Directory Operator
* \{ */
/**
* Create a new, non-existing folder name, returns true if successful,
* false if name couldn't be created.
* The actual name is returned in 'name', 'folder' contains the complete path,
* including the new folder name.
*/
static bool new_folder_path(const char *parent, char folder[FILE_MAX], char name[FILE_MAXFILE])
{
int i = 1;
int len = 0;
BLI_strncpy(name, "New Folder", FILE_MAXFILE);
BLI_join_dirfile(folder, FILE_MAX, parent, name);
/* check whether folder with the name already exists, in this case
* add number to the name. Check length of generated name to avoid
* crazy case of huge number of folders each named 'New Folder (x)' */
2012-06-18 13:01:24 +00:00
while (BLI_exists(folder) && (len < FILE_MAXFILE)) {
len = BLI_snprintf(name, FILE_MAXFILE, "New Folder(%d)", i);
BLI_join_dirfile(folder, FILE_MAX, parent, name);
i++;
}
2012-06-18 13:01:24 +00:00
return (len < FILE_MAXFILE);
}
2020-03-25 21:24:59 +11:00
static int file_directory_new_exec(bContext *C, wmOperator *op)
{
char name[FILE_MAXFILE];
char path[FILE_MAX];
bool generate_name = true;
2015-02-17 13:09:21 +11:00
PropertyRNA *prop;
wmWindowManager *wm = CTX_wm_manager(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
const bool do_diropen = RNA_boolean_get(op->ptr, "open");
if (!params) {
2012-04-29 15:47:02 +00:00
BKE_report(op->reports, RPT_WARNING, "No parent directory given");
return OPERATOR_CANCELLED;
}
path[0] = '\0';
2015-02-17 13:09:21 +11:00
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
RNA_property_string_get(op->ptr, prop, path);
if (path[0] != '\0') {
generate_name = false;
}
}
if (generate_name) {
/* create a new, non-existing folder name */
if (!new_folder_path(params->dir, path, name)) {
BKE_report(op->reports, RPT_ERROR, "Could not create new folder name");
return OPERATOR_CANCELLED;
}
}
else { /* We assume we are able to generate a valid name! */
char org_path[FILE_MAX];
BLI_strncpy(org_path, path, sizeof(org_path));
if (BLI_path_make_safe(path)) {
BKE_reportf(op->reports,
RPT_WARNING,
"'%s' given path is OS-invalid, creating '%s' path instead",
org_path,
path);
}
}
/* create the file */
errno = 0;
if (!BLI_dir_create_recursive(path) ||
/* Should no more be needed,
* now that BLI_dir_create_recursive returns a success state - but kept just in case. */
!BLI_exists(path)) {
BKE_reportf(op->reports,
RPT_ERROR,
"Could not create new folder: %s",
errno ? strerror(errno) : "unknown error");
return OPERATOR_CANCELLED;
}
/* If we don't enter the directory directly, remember file to jump into editing. */
if (do_diropen == false) {
BLI_strncpy(params->renamefile, name, FILE_MAXFILE);
params->rename_flag = FILE_PARAMS_RENAME_PENDING;
}
2021-02-16 21:15:45 +11:00
/* Set timer to smoothly view newly generated file. */
if (sfile->smoothscroll_timer != NULL) {
WM_event_remove_timer(wm, CTX_wm_window(C), sfile->smoothscroll_timer);
}
sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0);
2012-06-18 13:01:24 +00:00
sfile->scroll_offset = 0;
/* reload dir to make sure we're seeing what's in the directory */
ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
if (do_diropen) {
BLI_strncpy(params->dir, path, sizeof(params->dir));
ED_file_change_dir(C);
}
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
}
void FILE_OT_directory_new(struct wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Create New Directory";
ot->description = "Create a new directory";
ot->idname = "FILE_OT_directory_new";
/* api callbacks */
ot->invoke = WM_operator_confirm_or_exec;
ot->exec = file_directory_new_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
prop = RNA_def_string_dir_path(
ot->srna, "directory", NULL, FILE_MAX, "Directory", "Name of new directory");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "open", false, "Open", "Open new directory");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
WM_operator_properties_confirm_or_exec(ot);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Refresh File List Operator
* \{ */
/* TODO This should go to BLI_path_utils. */
static void file_expand_directory(bContext *C)
{
Main *bmain = CTX_data_main(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
if (BLI_path_is_rel(params->dir)) {
/* Use of 'default' folder here is just to avoid an error message on '//' prefix. */
BLI_path_abs(params->dir,
G.relbase_valid ? BKE_main_blendfile_path(bmain) : BKE_appdir_folder_default());
}
else if (params->dir[0] == '~') {
char tmpstr[sizeof(params->dir) - 1];
BLI_strncpy(tmpstr, params->dir + 1, sizeof(tmpstr));
BLI_join_dirfile(params->dir, sizeof(params->dir), BKE_appdir_folder_default(), tmpstr);
}
else if (params->dir[0] == '\0')
#ifndef WIN32
{
params->dir[0] = '/';
params->dir[1] = '\0';
}
#else
{
BLI_windows_get_default_root_dir(params->dir);
}
/* change "C:" --> "C:\", T28102. */
else if ((isalpha(params->dir[0]) && (params->dir[1] == ':')) && (params->dir[2] == '\0')) {
params->dir[2] = '\\';
params->dir[3] = '\0';
}
else if (BLI_path_is_unc(params->dir)) {
BLI_path_normalize_unc(params->dir, FILE_MAX_LIBEXTRA);
}
#endif
}
}
/* TODO check we still need this, it's annoying to have OS-specific code here... :/ */
#if defined(WIN32)
static bool can_create_dir(const char *dir)
{
/* for UNC paths we need to check whether the parent of the new
* directory is a proper directory itself and not a share or the
* UNC root (server name) itself. Calling BLI_is_dir does this
*/
if (BLI_path_is_unc(dir)) {
char parent[PATH_MAX];
BLI_strncpy(parent, dir, PATH_MAX);
BLI_path_parent_dir(parent);
return BLI_is_dir(parent);
}
return true;
}
#endif
void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UNUSED(arg_but))
{
Main *bmain = CTX_data_main(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
char old_dir[sizeof(params->dir)];
BLI_strncpy(old_dir, params->dir, sizeof(old_dir));
file_expand_directory(C);
/* special case, user may have pasted a filepath into the directory */
if (!filelist_is_dir(sfile->files, params->dir)) {
char tdir[FILE_MAX_LIBEXTRA];
char *group, *name;
if (BLI_is_file(params->dir)) {
char path[sizeof(params->dir)];
BLI_strncpy(path, params->dir, sizeof(path));
BLI_split_dirfile(
path, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
else if (BLO_library_path_explode(params->dir, tdir, &group, &name)) {
if (group) {
BLI_path_append(tdir, sizeof(tdir), group);
}
BLI_strncpy(params->dir, tdir, sizeof(params->dir));
if (name) {
BLI_strncpy(params->file, name, sizeof(params->file));
}
else {
params->file[0] = '\0';
}
}
}
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
if (filelist_is_dir(sfile->files, params->dir)) {
if (!STREQ(params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */
/* if directory exists, enter it immediately */
ED_file_change_dir(C);
}
/* don't do for now because it selects entire text instead of
* placing cursor at the end */
/* UI_textbutton_activate_but(C, but); */
}
#if defined(WIN32)
else if (!can_create_dir(params->dir)) {
const char *lastdir = folderlist_peeklastdir(sfile->folders_prev);
2019-04-22 09:19:45 +10:00
if (lastdir) {
BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
2019-04-22 09:19:45 +10:00
}
}
#endif
else {
const char *lastdir = folderlist_peeklastdir(sfile->folders_prev);
char tdir[FILE_MAX_LIBEXTRA];
/* If we are 'inside' a blend library, we cannot do anything... */
if (lastdir && BLO_library_path_explode(lastdir, tdir, NULL, NULL)) {
BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
}
else {
/* if not, ask to create it and enter if confirmed */
wmOperatorType *ot = WM_operatortype_find("FILE_OT_directory_new", false);
PointerRNA ptr;
WM_operator_properties_create_ptr(&ptr, ot);
RNA_string_set(&ptr, "directory", params->dir);
RNA_boolean_set(&ptr, "open", true);
2020-10-22 17:08:37 -04:00
/* Enable confirmation prompt, else it's too easy
* to accidentally create new directories. */
RNA_boolean_set(&ptr, "confirm", true);
2019-04-22 09:19:45 +10:00
if (lastdir) {
BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
2019-04-22 09:19:45 +10:00
}
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
WM_operator_properties_free(&ptr);
}
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
}
void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg_but)
{
Main *bmain = CTX_data_main(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
2013-12-10 13:44:46 +11:00
uiBut *but = arg_but;
char matched_file[FILE_MAX];
if (params) {
char filepath[sizeof(params->dir)];
int matches;
matched_file[0] = '\0';
filepath[0] = '\0';
file_expand_directory(C);
matches = file_select_match(sfile, params->file, matched_file);
/* *After* file_select_match! */
BLI_filename_make_safe(params->file);
if (matches) {
/* replace the pattern (or filename that the user typed in,
* with the first selected file of the match */
BLI_strncpy(params->file, matched_file, sizeof(params->file));
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
if (matches == 1) {
BLI_join_dirfile(filepath, sizeof(params->dir), params->dir, params->file);
/* if directory, open it and empty filename field */
if (filelist_is_dir(sfile->files, filepath)) {
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), filepath);
BLI_strncpy(params->dir, filepath, sizeof(params->dir));
params->file[0] = '\0';
ED_file_change_dir(C);
UI_textbutton_activate_but(C, but);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
}
else if (matches > 1) {
file_draw_check(C);
}
}
}
2020-03-25 21:24:59 +11:00
/** \} */
2020-03-25 21:24:59 +11:00
/* -------------------------------------------------------------------- */
/** \name Toggle Show Hidden Files Operator
* \{ */
static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
{
wmWindowManager *wm = CTX_wm_manager(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
params->flag ^= FILE_HIDE_DOT;
ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
return OPERATOR_FINISHED;
}
void FILE_OT_hidedot(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Toggle Hide Dot Files";
ot->description = "Toggle hide hidden dot files";
ot->idname = "FILE_OT_hidedot";
/* api callbacks */
ot->exec = file_hidedot_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Associate File Type Operator (Windows only)
* \{ */
static int associate_blend_exec(bContext *UNUSED(C), wmOperator *op)
{
#ifdef WIN32
WM_cursor_wait(true);
if (BLI_windows_register_blend_extension(true)) {
BKE_report(op->reports, RPT_INFO, "File association registered");
WM_cursor_wait(false);
return OPERATOR_FINISHED;
}
else {
BKE_report(op->reports, RPT_ERROR, "Unable to register file association");
WM_cursor_wait(false);
return OPERATOR_CANCELLED;
}
#else
BKE_report(op->reports, RPT_WARNING, "Operator Not supported");
return OPERATOR_CANCELLED;
#endif
}
void FILE_OT_associate_blend(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Register File Association";
ot->description = "Use this installation for .blend files and to display thumbnails";
ot->idname = "FILE_OT_associate_blend";
/* api callbacks */
ot->exec = associate_blend_exec;
}
/** \} */
2020-03-25 21:24:59 +11:00
/* -------------------------------------------------------------------- */
/** \name Increment Filename Operator
* \{ */
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
static bool file_filenum_poll(bContext *C)
{
SpaceFile *sfile = CTX_wm_space_file(C);
if (!ED_operator_file_active(C)) {
return false;
}
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
return params && (params->flag & FILE_CHECK_EXISTING);
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
}
/**
* Looks for a string of digits within name (using BLI_path_sequence_decode) and adjusts it by add.
*/
static void filenum_newname(char *name, size_t name_size, int add)
{
char head[FILE_MAXFILE], tail[FILE_MAXFILE];
char name_temp[FILE_MAXFILE];
int pic;
ushort digits;
pic = BLI_path_sequence_decode(name, head, tail, &digits);
/* are we going from 100 -> 99 or from 10 -> 9 */
if (add < 0 && digits > 0) {
int i, exp;
exp = 1;
for (i = digits; i > 1; i--) {
exp *= 10;
}
if (pic >= exp && (pic + add) < exp) {
digits--;
}
}
pic += add;
2019-04-22 09:19:45 +10:00
if (pic < 0) {
pic = 0;
2019-04-22 09:19:45 +10:00
}
BLI_path_sequence_encode(name_temp, head, tail, digits, pic);
BLI_strncpy(name, name_temp, name_size);
}
static int file_filenum_exec(bContext *C, wmOperator *op)
{
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
ScrArea *area = CTX_wm_area(C);
int inc = RNA_int_get(op->ptr, "increment");
if (params && (inc != 0)) {
filenum_newname(params->file, sizeof(params->file), inc);
ED_area_tag_redraw(area);
file_draw_check(C);
// WM_event_add_notifier(C, NC_WINDOW, NULL);
}
return OPERATOR_FINISHED;
}
void FILE_OT_filenum(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Increment Number in Filename";
ot->description = "Increment number in filename";
ot->idname = "FILE_OT_filenum";
/* api callbacks */
ot->exec = file_filenum_exec;
UI: File Browser Design Overhaul This is a general redesign of the File Browser GUI and interaction methods. For screenshots, check patch D5601. Main changes in short: * File Browser as floating window * New layout of regions * Popovers for view and filter options * Vertical list view with interactive column header * New and updated icons * Keymap consistency fixes * Many tweaks and fixes to the drawing of views ---- General: * The file browser now opens as temporary floating window. It closes on Esc. The header is hidden then. * When the file browser is opened as regular editor, the header remains visible. * All file browser regions are now defined in Python (the button layout). * Adjusted related operator UI names. Keymap: Keymap is now consistent with other list-based views in Blender, such as the Outliner. * Left click to select, double-click to open * Right-click context menus * Shift-click to fill selection * Ctrl-click to extend selection Operator options: These previously overlapped with the source list, which caused numerous issues with resizing and presenting many settings in a small panel area. It was also generally inconsistent with Blender. * Moved to new sidebar, which can easily be shown or hidden using a prominent Options toggle. * IO operators have new layouts to match this new sidebar, using sub-panels. This will have to be committed separately (Add-on repository). * If operators want to show the options by default, they have the option to do so (see `WM_FILESEL_SHOW_PROPS`, `hide_props_region`), otherwise they are hidden by default. General Layout: The layout has been changed to be simpler, more standard, and fits better in with Blender 2.8. * More conventional layout (file path at top, file name at the bottom, execute/cancel buttons in bottom right). * Use of popovers to group controls, and allow for more descriptive naming. * Search box is always live now, just like Outliner. Views: * Date Modified column combines both date and time, also uses user friendly strings for recent dates (i.e. "Yesterday", "Today"). * Details columns (file size, modification date/time) are now toggleable for all display types, they are not hardcoded per display type. * File sizes now show as B, KB, MB, ... rather than B, KiB, MiB, … They are now also calculated using base 10 of course. * Option to sort in inverse order. Vertical List View: * This view now used a much simpler single vertical list with columns for information. * Users can click on the headers of these columns to order by that category, and click again to reverse the ordering. Icons: * Updated icons by Jendrzych, with better centering. * Files and folders have new icons in Icon view. * Both files and folders have reworked superimposed icons that show users the file/folder type. * 3D file documents correctly use the 3d file icon, which was unused previously. * Workspaces now show their icon on Link/Append - also when listed in the Outliner. Minor Python-API breakage: * `bpy.types.FileSelectParams.display_type`: `LIST_SHORT` and `LIST_LONG` are replaced by `LIST_VERTICAL` and `LIST_HORIZONTAL`. Removes the feature where directories would automatically be created if they are entered into the file path text button, but don't exist. We were not sure if users use it enough to keep it. We can definitely bring it back. ---- //Combined effort by @billreynish, @harley, @jendrzych, my university colleague Brian Meisenheimer and myself.// Differential Revision: https://developer.blender.org/D5601 Reviewers: Brecht, Bastien
2019-09-03 15:43:38 +02:00
ot->poll = file_filenum_poll;
/* props */
2012-04-29 15:47:02 +00:00
RNA_def_int(ot->srna, "increment", 1, -100, 100, "Increment", "", -100, 100);
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Rename File/Directory Operator
* \{ */
static void file_rename_state_activate(SpaceFile *sfile, int file_idx, bool require_selected)
{
const int numfiles = filelist_files_ensure(sfile->files);
if ((file_idx >= 0) && (file_idx < numfiles)) {
FileDirEntry *file = filelist_file(sfile->files, file_idx);
if ((require_selected == false) ||
(filelist_entry_select_get(sfile->files, file, CHECK_ALL) & FILE_SEL_SELECTED)) {
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
filelist_entry_select_index_set(
sfile->files, file_idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
BLI_strncpy(params->renamefile, file->relpath, FILE_MAXFILE);
/* We can skip the pending state,
* as we can directly set FILE_SEL_EDITING on the expected entry here. */
params->rename_flag = FILE_PARAMS_RENAME_ACTIVE;
}
}
}
static int file_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
file_rename_state_activate(sfile, params->active_file, true);
ED_area_tag_redraw(area);
}
return OPERATOR_FINISHED;
}
static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
file_rename_state_activate(sfile, params->highlight_file, false);
ED_area_tag_redraw(area);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
}
return OPERATOR_FINISHED;
}
void FILE_OT_rename(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Rename File or Directory";
ot->description = "Rename file or file directory";
ot->idname = "FILE_OT_rename";
/* api callbacks */
ot->invoke = file_rename_invoke;
ot->exec = file_rename_exec;
ot->poll = ED_operator_file_active;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Delete File Operator
* \{ */
2018-07-02 11:47:00 +02:00
static bool file_delete_poll(bContext *C)
{
2018-07-02 11:47:00 +02:00
bool poll = ED_operator_file_active(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (sfile && params) {
char dir[FILE_MAX_LIBEXTRA];
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
int numfiles = filelist_files_ensure(sfile->files);
int i;
int num_selected = 0;
2019-04-22 09:19:45 +10:00
if (filelist_islibrary(sfile->files, dir, NULL)) {
poll = 0;
2019-04-22 09:19:45 +10:00
}
for (i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
num_selected++;
}
}
if (num_selected <= 0) {
poll = 0;
}
}
2019-04-22 09:19:45 +10:00
else {
2012-06-18 13:01:24 +00:00
poll = 0;
2019-04-22 09:19:45 +10:00
}
return poll;
}
Asset System: New Asset Browser editor This introduces the User Interface part of the Asset Browser, based on the design in T54642. Additions: * New Asset Browser (internally a sub-editor of the File Browser). * Navigation region showing asset categories. * Main region showing the assets of the selected asset library with previews. The assets may be stored over multiple .blends in the directory that's "mounted" as asset library in the Preferences. They will all be shown in this list. * Header with an asset library dropdown, allowing to choose the active asset library to show. Options are the "Current File" as asset library and all custom libraries. * Display popover, filter popover and search box (partially dummies, see T82680). * Sidebar showing the metadata of the currently active file (name, preview, description and tags), which can be edited for assets in the "Current File" asset library. (For others it will reset on reload.) * The sidebar includes a button to load a custom preview image from a file. * Make asset files draggable (with preview image). * If a library with invalid path is selected, a message is drawn in the main region to help the user understand what's wrong. * Operators to add and remove asset tags. Exposed in the sidebar. * "Only Assets" option for Link/Append. * Internal utilities for asset UI scripts. For screenshots or demo videos, please see D9725. Or the 2.92 release notes. Note that there are many things to be tweaked and polished in the Asset Browser UI still. For example, the filter and display popovers are mostly dummies. See T82680. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9725 Reviewed by: Brecht Van Lommel, Hans Goudey
2020-12-14 14:07:42 +01:00
static bool file_delete_single(const FileSelectParams *params,
FileDirEntry *file,
const char **r_error_message)
{
if (file->typeflag & FILE_TYPE_ASSET) {
ID *id = filelist_file_get_id(file);
if (!id) {
*r_error_message = "File is not a local data-block asset.";
return false;
}
ED_asset_clear_id(id);
}
else {
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath);
if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) {
return false;
}
}
return true;
}
2020-03-25 21:24:59 +11:00
static int file_delete_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
2012-06-18 13:01:24 +00:00
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
Final 'FileBrowser First Stage' merge. It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser. From user perspective, it: * Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender! * Makes short/long display 'fixed' size (among four choices, like thumbnails mode). * Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories). * Consequently, adds datablocks types filtering. * Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared). * Generates thumbnails way faster. From code perspective, it: * Is ready for asset engine needs (on data structure level in filebrowser's listing). * Simplifies and makes 'generic' file listing much lighter. * Separates file listing in three different aspects: ** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct. ** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.). ** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one. * Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items. * Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs). * Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too). Revision: https://developer.blender.org/D1316 Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
int numfiles = filelist_files_ensure(sfile->files);
const char *error_message = NULL;
bool report_error = false;
errno = 0;
for (int i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
FileDirEntry *file = filelist_file(sfile->files, i);
Asset System: New Asset Browser editor This introduces the User Interface part of the Asset Browser, based on the design in T54642. Additions: * New Asset Browser (internally a sub-editor of the File Browser). * Navigation region showing asset categories. * Main region showing the assets of the selected asset library with previews. The assets may be stored over multiple .blends in the directory that's "mounted" as asset library in the Preferences. They will all be shown in this list. * Header with an asset library dropdown, allowing to choose the active asset library to show. Options are the "Current File" as asset library and all custom libraries. * Display popover, filter popover and search box (partially dummies, see T82680). * Sidebar showing the metadata of the currently active file (name, preview, description and tags), which can be edited for assets in the "Current File" asset library. (For others it will reset on reload.) * The sidebar includes a button to load a custom preview image from a file. * Make asset files draggable (with preview image). * If a library with invalid path is selected, a message is drawn in the main region to help the user understand what's wrong. * Operators to add and remove asset tags. Exposed in the sidebar. * "Only Assets" option for Link/Append. * Internal utilities for asset UI scripts. For screenshots or demo videos, please see D9725. Or the 2.92 release notes. Note that there are many things to be tweaked and polished in the Asset Browser UI still. For example, the filter and display popovers are mostly dummies. See T82680. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9725 Reviewed by: Brecht Van Lommel, Hans Goudey
2020-12-14 14:07:42 +01:00
if (!file_delete_single(params, file, &error_message)) {
report_error = true;
}
}
}
if (report_error) {
if (error_message != NULL) {
BKE_reportf(op->reports, RPT_ERROR, "Could not delete file or directory: %s", error_message);
}
else {
BKE_reportf(op->reports,
RPT_ERROR,
"Could not delete file or directory: %s",
errno ? strerror(errno) : "unknown error");
}
}
ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
2012-06-18 13:01:24 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
}
void FILE_OT_delete(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Selected Files";
ot->description = "Move selected files to the trash or recycle bin";
ot->idname = "FILE_OT_delete";
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = file_delete_exec;
ot->poll = file_delete_poll; /* <- important, handler is on window level */
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Enter Filter Text Operator
* \{ */
static int file_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
ARegion *region_ctx = CTX_wm_region(C);
if (area) {
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
CTX_wm_region_set(C, region);
if (UI_textbutton_activate_rna(C, region, params, "filter_search")) {
break;
}
}
}
CTX_wm_region_set(C, region_ctx);
return OPERATOR_FINISHED;
}
void FILE_OT_start_filter(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Filter";
ot->description = "Start entering filter text";
ot->idname = "FILE_OT_start_filter";
/* api callbacks */
ot->exec = file_start_filter_exec;
ot->poll = ED_operator_file_active;
}
2020-03-25 21:24:59 +11:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Macro Operators
* \{ */
void ED_operatormacros_file(void)
{
// wmOperatorType *ot;
// wmOperatorTypeMacro *otmacro;
/* future macros */
}
2020-03-25 21:24:59 +11:00
/** \} */