Attributes: Integrate implicit sharing with the attribute API #107059
|
@ -335,18 +335,6 @@ if(WITH_CYCLES AND (WITH_CYCLES_DEVICE_ONEAPI OR (WITH_CYCLES_EMBREE AND EMBREE_
|
|||
unset(_sycl_runtime_libraries)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES AND WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if(WITH_CYCLES_ONEAPI_BINARIES)
|
||||
set(cycles_kernel_oneapi_lib_suffix "_aot")
|
||||
else()
|
||||
set(cycles_kernel_oneapi_lib_suffix "_jit")
|
||||
endif()
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/intern/cycles/kernel/libcycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.so
|
||||
)
|
||||
unset(cycles_kernel_oneapi_lib_suffix)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
find_package(OpenVDB)
|
||||
set_and_warn_library_found("OpenVDB" OPENVDB_FOUND WITH_OPENVDB)
|
||||
|
|
|
@ -1105,18 +1105,6 @@ if(WITH_CYCLES AND (WITH_CYCLES_DEVICE_ONEAPI OR (WITH_CYCLES_EMBREE AND EMBREE_
|
|||
set(SYCL_LIBRARIES optimized ${SYCL_LIBRARY} debug ${SYCL_LIBRARY_DEBUG})
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES AND WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if(WITH_CYCLES_ONEAPI_BINARIES)
|
||||
set(cycles_kernel_oneapi_lib_suffix "_aot")
|
||||
else()
|
||||
set(cycles_kernel_oneapi_lib_suffix "_jit")
|
||||
endif()
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/intern/cycles/kernel/cycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.dll
|
||||
)
|
||||
unset(cycles_kernel_oneapi_lib_suffix)
|
||||
endif()
|
||||
|
||||
|
||||
# Environment variables to run precompiled executables that needed libraries.
|
||||
list(JOIN PLATFORM_BUNDLED_LIBRARY_DIRS ";" _library_paths)
|
||||
|
|
|
@ -907,13 +907,22 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
endif()
|
||||
|
||||
# For the Cycles standalone put libraries next to the Cycles application.
|
||||
if(NOT WITH_BLENDER)
|
||||
if(WIN32)
|
||||
delayed_install("" "${cycles_kernel_oneapi_lib}" ${CYCLES_INSTALL_PATH})
|
||||
else()
|
||||
delayed_install("" "${cycles_kernel_oneapi_lib}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
endif()
|
||||
# For the Cycles standalone put libraries next to the Cycles application.
|
||||
set(cycles_oneapi_target_path ${CYCLES_INSTALL_PATH})
|
||||
else()
|
||||
# For Blender put the libraries next to the Blender executable.
|
||||
#
|
||||
# Note that the installation path in the delayed_install is relative to the versioned folder,
|
||||
# which means we need to go one level up.
|
||||
set(cycles_oneapi_target_path "../")
|
||||
endif()
|
||||
|
||||
# install dynamic libraries required at runtime
|
||||
if(WIN32)
|
||||
delayed_install("" "${cycles_kernel_oneapi_lib}" ${cycles_oneapi_target_path})
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
delayed_install("" "${cycles_kernel_oneapi_lib}" ${cycles_oneapi_target_path}/lib)
|
||||
endif()
|
||||
|
||||
add_custom_target(cycles_kernel_oneapi ALL DEPENDS ${cycles_kernel_oneapi_lib})
|
||||
|
|
|
@ -538,6 +538,7 @@ class FILEBROWSER_MT_context_menu(FileBrowserMenu, Menu):
|
|||
layout.operator("file.next", text="Forward")
|
||||
layout.operator("file.parent", text="Go to Parent")
|
||||
layout.operator("file.refresh", text="Refresh")
|
||||
layout.menu("FILEBROWSER_MT_operations_menu")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -171,7 +171,6 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider {
|
|||
* if the stored type is the same as the attribute type.
|
||||
*/
|
||||
class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
|
||||
using UpdateOnRead = void (*)(const void *owner);
|
||||
using UpdateOnChange = void (*)(void *owner);
|
||||
const eCustomDataType stored_type_;
|
||||
const CustomDataAccessInfo custom_data_access_;
|
||||
|
|
|
@ -113,6 +113,33 @@ ENUM_OPERATORS(eFileAttributes, FILE_ATTR_HARDLINK);
|
|||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name External File Operations
|
||||
* \{ */
|
||||
|
||||
typedef enum FileExternalOperation {
|
||||
FILE_EXTERNAL_OPERATION_OPEN = 0,
|
||||
FILE_EXTERNAL_OPERATION_FOLDER_OPEN,
|
||||
/* Following are Windows-only: */
|
||||
FILE_EXTERNAL_OPERATION_EDIT,
|
||||
FILE_EXTERNAL_OPERATION_NEW,
|
||||
FILE_EXTERNAL_OPERATION_FIND,
|
||||
FILE_EXTERNAL_OPERATION_SHOW,
|
||||
FILE_EXTERNAL_OPERATION_PLAY,
|
||||
FILE_EXTERNAL_OPERATION_BROWSE,
|
||||
FILE_EXTERNAL_OPERATION_PREVIEW,
|
||||
FILE_EXTERNAL_OPERATION_PRINT,
|
||||
FILE_EXTERNAL_OPERATION_INSTALL,
|
||||
FILE_EXTERNAL_OPERATION_RUNAS,
|
||||
FILE_EXTERNAL_OPERATION_PROPERTIES,
|
||||
FILE_EXTERNAL_OPERATION_FOLDER_FIND,
|
||||
FILE_EXTERNAL_OPERATION_FOLDER_CMD,
|
||||
} FileExternalOperation;
|
||||
|
||||
bool BLI_file_external_operation_supported(const char *filepath, FileExternalOperation operation);
|
||||
bool BLI_file_external_operation_execute(const char *filepath, FileExternalOperation operation);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Directories
|
||||
* \{ */
|
||||
|
|
|
@ -89,6 +89,11 @@ bool BLI_windows_register_blend_extension(bool background);
|
|||
void BLI_windows_get_default_root_dir(char root_dir[4]);
|
||||
int BLI_windows_get_executable_dir(char *str);
|
||||
|
||||
/* ShellExecute Helpers. */
|
||||
|
||||
bool BLI_windows_external_operation_supported(const char *filepath, const char *operation);
|
||||
bool BLI_windows_external_operation_execute(const char *filepath, const char *operation);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,71 @@
|
|||
#include "BLI_sys_types.h" /* for intptr_t support */
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef WIN32
|
||||
/* Text string used as the "verb" for Windows shell operations. */
|
||||
static char *windows_operation_string(FileExternalOperation operation)
|
||||
{
|
||||
switch (operation) {
|
||||
case FILE_EXTERNAL_OPERATION_OPEN:
|
||||
return "open";
|
||||
case FILE_EXTERNAL_OPERATION_FOLDER_OPEN:
|
||||
return "open";
|
||||
case FILE_EXTERNAL_OPERATION_EDIT:
|
||||
return "edit";
|
||||
case FILE_EXTERNAL_OPERATION_NEW:
|
||||
return "new";
|
||||
case FILE_EXTERNAL_OPERATION_FIND:
|
||||
return "find";
|
||||
case FILE_EXTERNAL_OPERATION_SHOW:
|
||||
return "show";
|
||||
case FILE_EXTERNAL_OPERATION_PLAY:
|
||||
return "play";
|
||||
case FILE_EXTERNAL_OPERATION_BROWSE:
|
||||
return "browse";
|
||||
case FILE_EXTERNAL_OPERATION_PREVIEW:
|
||||
return "preview";
|
||||
case FILE_EXTERNAL_OPERATION_PRINT:
|
||||
return "print";
|
||||
case FILE_EXTERNAL_OPERATION_INSTALL:
|
||||
return "install";
|
||||
case FILE_EXTERNAL_OPERATION_RUNAS:
|
||||
return "runas";
|
||||
case FILE_EXTERNAL_OPERATION_PROPERTIES:
|
||||
return "properties";
|
||||
case FILE_EXTERNAL_OPERATION_FOLDER_FIND:
|
||||
return "find";
|
||||
case FILE_EXTERNAL_OPERATION_FOLDER_CMD:
|
||||
return "cmd";
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
bool BLI_file_external_operation_supported(const char *filepath, FileExternalOperation operation)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *opstring = windows_operation_string(operation);
|
||||
return BLI_windows_external_operation_supported(filepath, opstring);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool BLI_file_external_operation_execute(const char *filepath, FileExternalOperation operation)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *opstring = windows_operation_string(operation);
|
||||
if (BLI_windows_external_operation_supported(filepath, opstring) &&
|
||||
BLI_windows_external_operation_execute(filepath, opstring)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t BLI_file_zstd_from_mem_at_pos(
|
||||
void *buf, size_t len, FILE *file, size_t file_offset, int compression_level)
|
||||
{
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
# include <conio.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <shlwapi.h>
|
||||
|
||||
# include "MEM_guardedalloc.h"
|
||||
|
||||
# define WIN32_SKIP_HKEY_PROTECTION /* Need to use HKEY. */
|
||||
# include "BLI_fileops.h"
|
||||
# include "BLI_path_util.h"
|
||||
# include "BLI_string.h"
|
||||
# include "BLI_utildefines.h"
|
||||
|
@ -178,6 +180,62 @@ bool BLI_windows_register_blend_extension(const bool background)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Check the registry to see if there is an operation association to a file
|
||||
* extension. Extension *should almost always contain a dot like ".txt",
|
||||
* but this does allow querying non - extensions *like "Directory", "Drive",
|
||||
* "AllProtocols", etc - anything in Classes with a "shell" branch.
|
||||
*/
|
||||
static bool BLI_windows_file_operation_is_registered(const char *extension, const char *operation)
|
||||
{
|
||||
HKEY hKey;
|
||||
HRESULT hr = AssocQueryKey(ASSOCF_INIT_IGNOREUNKNOWN,
|
||||
ASSOCKEY_SHELLEXECCLASS,
|
||||
(LPCTSTR)extension,
|
||||
(LPCTSTR)operation,
|
||||
&hKey);
|
||||
if (SUCCEEDED(hr)) {
|
||||
RegCloseKey(hKey);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BLI_windows_external_operation_supported(const char *filepath, const char *operation)
|
||||
{
|
||||
if (STREQ(operation, "open") || STREQ(operation, "properties")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (BLI_is_dir(filepath)) {
|
||||
return BLI_windows_file_operation_is_registered("Directory", operation);
|
||||
}
|
||||
|
||||
const char *extension = BLI_path_extension(filepath);
|
||||
return BLI_windows_file_operation_is_registered(extension, operation);
|
||||
}
|
||||
|
||||
bool BLI_windows_external_operation_execute(const char *filepath, char *operation)
|
||||
{
|
||||
WCHAR wpath[FILE_MAX];
|
||||
if (conv_utf_8_to_16(filepath, wpath, ARRAY_SIZE(wpath)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WCHAR woperation[FILE_MAX];
|
||||
if (conv_utf_8_to_16(operation, woperation, ARRAY_SIZE(woperation)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SHELLEXECUTEINFOW shellinfo = {0};
|
||||
shellinfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
shellinfo.fMask = SEE_MASK_INVOKEIDLIST;
|
||||
shellinfo.lpVerb = woperation;
|
||||
shellinfo.lpFile = wpath;
|
||||
shellinfo.nShow = SW_SHOW;
|
||||
|
||||
return ShellExecuteExW(&shellinfo);
|
||||
}
|
||||
|
||||
void BLI_windows_get_default_root_dir(char root[4])
|
||||
{
|
||||
char str[MAX_PATH + 1];
|
||||
|
|
|
@ -256,43 +256,21 @@ static void curves_batch_cache_ensure_edit_points_pos(const bke::CurvesGeometry
|
|||
}
|
||||
|
||||
static void curves_batch_cache_ensure_edit_points_selection(const bke::CurvesGeometry &curves,
|
||||
const eAttrDomain selection_domain,
|
||||
CurvesBatchCache &cache)
|
||||
{
|
||||
static GPUVertFormat format_data = {0};
|
||||
static uint selection_id;
|
||||
if (format_data.attr_len == 0) {
|
||||
selection_id = GPU_vertformat_attr_add(
|
||||
&format_data, "selection", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
GPU_vertformat_attr_add(&format_data, "selection", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPU_vertbuf_init_with_format(cache.edit_points_selection, &format_data);
|
||||
GPU_vertbuf_data_alloc(cache.edit_points_selection, curves.points_num());
|
||||
MutableSpan<float> data(static_cast<float *>(GPU_vertbuf_get_data(cache.edit_points_selection)),
|
||||
curves.points_num());
|
||||
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
|
||||
const VArray<bool> selection = *curves.attributes().lookup_or_default<bool>(
|
||||
".selection", selection_domain, true);
|
||||
switch (selection_domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
for (const int point_i : selection.index_range()) {
|
||||
const float point_selection = selection[point_i] ? 1.0f : 0.0f;
|
||||
GPU_vertbuf_attr_set(cache.edit_points_selection, selection_id, point_i, &point_selection);
|
||||
}
|
||||
break;
|
||||
case ATTR_DOMAIN_CURVE:
|
||||
for (const int curve_i : curves.curves_range()) {
|
||||
const float curve_selection = selection[curve_i] ? 1.0f : 0.0f;
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
for (const int point_i : points) {
|
||||
GPU_vertbuf_attr_set(
|
||||
cache.edit_points_selection, selection_id, point_i, &curve_selection);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const VArray<float> attribute = *curves.attributes().lookup_or_default<float>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
attribute.materialize(data);
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_edit_lines(const bke::CurvesGeometry &curves,
|
||||
|
@ -773,8 +751,7 @@ void DRW_curves_batch_cache_create_requested(Object *ob)
|
|||
curves_batch_cache_ensure_edit_points_pos(curves_orig, deformation.positions, cache);
|
||||
}
|
||||
if (DRW_vbo_requested(cache.edit_points_selection)) {
|
||||
curves_batch_cache_ensure_edit_points_selection(
|
||||
curves_orig, eAttrDomain(curves_id->selection_domain), cache);
|
||||
curves_batch_cache_ensure_edit_points_selection(curves_orig, cache);
|
||||
}
|
||||
if (DRW_ibo_requested(cache.edit_lines_ibo)) {
|
||||
curves_batch_cache_ensure_edit_lines(curves_orig, cache);
|
||||
|
|
|
@ -66,6 +66,10 @@ void FILE_OT_bookmark_move(struct wmOperatorType *ot);
|
|||
void FILE_OT_reset_recent(wmOperatorType *ot);
|
||||
void FILE_OT_hidedot(struct wmOperatorType *ot);
|
||||
void FILE_OT_execute(struct wmOperatorType *ot);
|
||||
|
||||
void FILE_OT_external_operation(struct wmOperatorType *ot);
|
||||
void file_external_operations_menu_register(void);
|
||||
|
||||
/**
|
||||
* Variation of #FILE_OT_execute that accounts for some mouse specific handling.
|
||||
* Otherwise calls the same logic.
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
@ -1768,6 +1770,258 @@ bool file_draw_check_exists(SpaceFile *sfile)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name External operations that can performed on files.
|
||||
* \{ */
|
||||
|
||||
static const EnumPropertyItem file_external_operation[] = {
|
||||
{FILE_EXTERNAL_OPERATION_OPEN, "OPEN", 0, "Open", "Open the file"},
|
||||
{FILE_EXTERNAL_OPERATION_FOLDER_OPEN, "FOLDER_OPEN", 0, "Open Folder", "Open the folder"},
|
||||
{FILE_EXTERNAL_OPERATION_EDIT, "EDIT", 0, "Edit", "Edit the file"},
|
||||
{FILE_EXTERNAL_OPERATION_NEW, "NEW", 0, "New", "Create a new file of this type"},
|
||||
{FILE_EXTERNAL_OPERATION_FIND, "FIND", 0, "Find File", "Search for files of this type"},
|
||||
{FILE_EXTERNAL_OPERATION_SHOW, "SHOW", 0, "Show", "Show this file"},
|
||||
{FILE_EXTERNAL_OPERATION_PLAY, "PLAY", 0, "Play", "Play this file"},
|
||||
{FILE_EXTERNAL_OPERATION_BROWSE, "BROWSE", 0, "Browse", "Browse this file"},
|
||||
{FILE_EXTERNAL_OPERATION_PREVIEW, "PREVIEW", 0, "Preview", "Preview this file"},
|
||||
{FILE_EXTERNAL_OPERATION_PRINT, "PRINT", 0, "Print", "Print this file"},
|
||||
{FILE_EXTERNAL_OPERATION_INSTALL, "INSTALL", 0, "Install", "Install this file"},
|
||||
{FILE_EXTERNAL_OPERATION_RUNAS, "RUNAS", 0, "Run As User", "Run as specific user"},
|
||||
{FILE_EXTERNAL_OPERATION_PROPERTIES,
|
||||
"PROPERTIES",
|
||||
0,
|
||||
"Properties",
|
||||
"Show OS Properties for this item"},
|
||||
{FILE_EXTERNAL_OPERATION_FOLDER_FIND,
|
||||
"FOLDER_FIND",
|
||||
0,
|
||||
"Find in Folder",
|
||||
"Search for items in this folder"},
|
||||
{FILE_EXTERNAL_OPERATION_FOLDER_CMD,
|
||||
"CMD",
|
||||
0,
|
||||
"Command Prompt Here",
|
||||
"Open a command prompt here"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static int file_external_operation_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
|
||||
char filepath[FILE_MAX];
|
||||
RNA_property_string_get(op->ptr, prop, filepath);
|
||||
|
||||
const FileExternalOperation operation = (FileExternalOperation)RNA_enum_get(op->ptr,
|
||||
"operation");
|
||||
WM_cursor_set(CTX_wm_window(C), WM_CURSOR_WAIT);
|
||||
|
||||
#ifdef WIN32
|
||||
if (BLI_file_external_operation_execute(filepath, operation)) {
|
||||
WM_cursor_set(CTX_wm_window(C), WM_CURSOR_DEFAULT);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
#else
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
|
||||
PointerRNA op_props;
|
||||
WM_operator_properties_create_ptr(&op_props, ot);
|
||||
RNA_string_set(&op_props, "filepath", filepath);
|
||||
if (WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_props, NULL) ==
|
||||
OPERATOR_FINISHED) {
|
||||
WM_cursor_set(CTX_wm_window(C), WM_CURSOR_DEFAULT);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
#endif
|
||||
|
||||
BKE_reportf(
|
||||
op->reports, RPT_ERROR, "Failure to perform exernal file operation on \"%s\"", filepath);
|
||||
WM_cursor_set(CTX_wm_window(C), WM_CURSOR_DEFAULT);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static char *file_external_operation_description(bContext *UNUSED(C),
|
||||
wmOperatorType *UNUSED(ot),
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
const char *description = "";
|
||||
RNA_enum_description(file_external_operation, RNA_enum_get(ptr, "operation"), &description);
|
||||
return BLI_strdup(description);
|
||||
}
|
||||
|
||||
void FILE_OT_external_operation(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "External File Operation";
|
||||
ot->idname = "FILE_OT_external_operation";
|
||||
ot->description = "Perform external operation on a file or folder";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = file_external_operation_exec;
|
||||
ot->get_description = file_external_operation_description;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER; /* No undo! */
|
||||
|
||||
/* properties */
|
||||
prop = RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "File or folder path", "");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"operation",
|
||||
file_external_operation,
|
||||
0,
|
||||
"Operation",
|
||||
"Operation to perform on the file or path");
|
||||
}
|
||||
|
||||
static void file_os_operations_menu_item(uiLayout *layout,
|
||||
wmOperatorType *ot,
|
||||
const char *path,
|
||||
FileExternalOperation operation)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (!BLI_file_external_operation_supported(path, operation)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (!ELEM(operation, FILE_EXTERNAL_OPERATION_OPEN, FILE_EXTERNAL_OPERATION_FOLDER_OPEN)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *title = "";
|
||||
RNA_enum_name(file_external_operation, operation, &title);
|
||||
|
||||
PointerRNA props_ptr;
|
||||
uiItemFullO_ptr(layout, ot, title, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
|
||||
RNA_string_set(&props_ptr, "filepath", path);
|
||||
if (operation) {
|
||||
RNA_enum_set(&props_ptr, "operation", operation);
|
||||
}
|
||||
}
|
||||
|
||||
static void file_os_operations_menu_draw(const bContext *C_const, Menu *menu)
|
||||
{
|
||||
bContext *C = (bContext *)C_const;
|
||||
|
||||
/* File browsing only operator (not asset browsing). */
|
||||
if (!ED_operator_file_browsing_active(C)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
if (!sfile || !params) {
|
||||
return;
|
||||
}
|
||||
|
||||
char dir[FILE_MAX_LIBEXTRA];
|
||||
if (filelist_islibrary(sfile->files, dir, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int numfiles = filelist_files_ensure(sfile->files);
|
||||
FileDirEntry *fileentry = NULL;
|
||||
int num_selected = 0;
|
||||
|
||||
for (int i = 0; i < numfiles; i++) {
|
||||
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
|
||||
fileentry = filelist_file(sfile->files, i);
|
||||
num_selected++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileentry || num_selected > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
char path[FILE_MAX_LIBEXTRA];
|
||||
filelist_file_get_full_path(sfile->files, fileentry, path);
|
||||
const char *root = filelist_dir(sfile->files);
|
||||
|
||||
uiLayout *layout = menu->layout;
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||
wmOperatorType *ot = WM_operatortype_find("FILE_OT_external_operation", true);
|
||||
|
||||
if (fileentry->typeflag & FILE_TYPE_DIR) {
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_FOLDER_OPEN);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_FOLDER_CMD);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_PROPERTIES);
|
||||
}
|
||||
else {
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_OPEN);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_EDIT);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_NEW);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_FIND);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_SHOW);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_PLAY);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_BROWSE);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_PREVIEW);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_PRINT);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_INSTALL);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_RUNAS);
|
||||
file_os_operations_menu_item(layout, ot, root, FILE_EXTERNAL_OPERATION_FOLDER_OPEN);
|
||||
file_os_operations_menu_item(layout, ot, root, FILE_EXTERNAL_OPERATION_FOLDER_CMD);
|
||||
file_os_operations_menu_item(layout, ot, path, FILE_EXTERNAL_OPERATION_PROPERTIES);
|
||||
}
|
||||
}
|
||||
|
||||
static bool file_os_operations_menu_poll(const bContext *C_const, MenuType *UNUSED(mt))
|
||||
{
|
||||
bContext *C = (bContext *)C_const;
|
||||
|
||||
/* File browsing only operator (not asset browsing). */
|
||||
if (!ED_operator_file_browsing_active(C)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
|
||||
if (sfile && params) {
|
||||
char dir[FILE_MAX_LIBEXTRA];
|
||||
if (filelist_islibrary(sfile->files, dir, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int numfiles = filelist_files_ensure(sfile->files);
|
||||
int num_selected = 0;
|
||||
for (int i = 0; i < numfiles; i++) {
|
||||
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
|
||||
num_selected++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_selected > 1) {
|
||||
CTX_wm_operator_poll_msg_set(C, "More than one item is selected");
|
||||
}
|
||||
else if (num_selected < 1) {
|
||||
CTX_wm_operator_poll_msg_set(C, "No items are selected");
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void file_external_operations_menu_register(void)
|
||||
{
|
||||
MenuType *mt;
|
||||
|
||||
mt = MEM_callocN(sizeof(MenuType), "spacetype file menu file operations");
|
||||
strcpy(mt->idname, "FILEBROWSER_MT_operations_menu");
|
||||
strcpy(mt->label, N_("External"));
|
||||
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
mt->draw = file_os_operations_menu_draw;
|
||||
mt->poll = file_os_operations_menu_poll;
|
||||
WM_menutype_add(mt);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Execute File Window Operator
|
||||
* \{ */
|
||||
|
|
|
@ -613,6 +613,7 @@ static void file_operatortypes(void)
|
|||
WM_operatortype_append(FILE_OT_start_filter);
|
||||
WM_operatortype_append(FILE_OT_edit_directory_path);
|
||||
WM_operatortype_append(FILE_OT_view_selected);
|
||||
WM_operatortype_append(FILE_OT_external_operation);
|
||||
}
|
||||
|
||||
/* NOTE: do not add .blend file reading on this level */
|
||||
|
@ -1063,6 +1064,7 @@ void ED_spacetype_file(void)
|
|||
art->draw = file_tools_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
file_tool_props_region_panels_register(art);
|
||||
file_external_operations_menu_register();
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
}
|
||||
|
|
|
@ -2371,6 +2371,13 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
|
|||
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
|
||||
for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
|
||||
PropertyRNA *nameprop = RNA_struct_name_property(iter.ptr.type);
|
||||
BLI_assert_msg(
|
||||
nameprop,
|
||||
"Attempted to use a string to index into a collection of items with no 'nameproperty'.");
|
||||
if (nameprop == NULL) {
|
||||
/* For non-debug builds, bail if there's no 'nameproperty' to check. */
|
||||
break;
|
||||
}
|
||||
char *nameptr = RNA_property_string_get_alloc(
|
||||
&iter.ptr, nameprop, name, sizeof(name), &namelen);
|
||||
if ((keylen == namelen) && STREQ(nameptr, keyname)) {
|
||||
|
|
Loading…
Reference in New Issue