Python: Support multiple custom script directories in Preferences #104876
|
@ -354,8 +354,8 @@ def script_paths_pref():
|
|||
"""returns the user preference script directory paths or None"""
|
||||
JulianEisel marked this conversation as resolved
Outdated
|
||||
paths = []
|
||||
for script_directory in _preferences.filepaths.script_directories:
|
||||
if script_directory.path:
|
||||
paths.append(_os.path.normpath(script_directory.path))
|
||||
if script_directory.directory:
|
||||
JulianEisel marked this conversation as resolved
Outdated
Campbell Barton
commented
picky assign a value and avoid accessing *picky* assign a value and avoid accessing `script_directory.directory` twice.
|
||||
paths.append(_os.path.normpath(script_directory.directory))
|
||||
return paths
|
||||
|
||||
|
||||
|
|
|
@ -593,7 +593,7 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||
return (
|
||||
('DEFAULT', "Default", ""),
|
||||
None,
|
||||
*[(item.name, item.name, "") for index, item in enumerate(paths.script_directories) if item.path],
|
||||
*[(item.name, item.name, "") for index, item in enumerate(paths.script_directories) if item.directory],
|
||||
)
|
||||
|
||||
target: EnumProperty(
|
||||
|
@ -635,7 +635,7 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||
paths = context.preferences.filepaths
|
||||
for script_directory in paths.script_directories:
|
||||
if script_directory.name == self.target:
|
||||
path_addons = os.path.join(script_directory.path, "addons")
|
||||
path_addons = os.path.join(script_directory.directory, "addons")
|
||||
break
|
||||
|
||||
if not path_addons:
|
||||
|
@ -1161,14 +1161,14 @@ class PREFERENCES_OT_script_directory_new(Operator):
|
|||
)
|
||||
|
||||
def execute(self, context):
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
script_directories = context.preferences.filepaths.script_directories
|
||||
|
||||
new_dir = script_directories.new()
|
||||
# Assign path selected via file browser.
|
||||
new_dir.path = self.directory
|
||||
new_dir.name = Path(self.directory).name
|
||||
new_dir.directory = self.directory
|
||||
new_dir.name = os.path.basename(self.directory.rstrip(os.sep))
|
||||
|
||||
assert(context.preferences.is_dirty == True)
|
||||
JulianEisel marked this conversation as resolved
Outdated
Campbell Barton
commented
newer autopep8 removes parenthesis after assert (they're not needed), so prefer not to add them. newer autopep8 removes parenthesis after assert (they're not needed), so prefer not to add them.
|
||||
|
||||
|
|
|
@ -1336,16 +1336,16 @@ class USERPREF_PT_file_paths_data(FilePathsPanel, Panel):
|
|||
|
||||
class USERPREF_PT_file_paths_script_directories(FilePathsPanel, Panel):
|
||||
bl_label = "Script Directories"
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
|
||||
paths = context.preferences.filepaths
|
||||
|
||||
|
||||
if len(paths.script_directories) == 0:
|
||||
layout.operator("preferences.script_directory_add", text="Add", icon='ADD')
|
||||
return
|
||||
|
||||
|
||||
layout.use_property_split = False
|
||||
layout.use_property_decorate = False
|
||||
|
||||
|
@ -1353,26 +1353,26 @@ class USERPREF_PT_file_paths_script_directories(FilePathsPanel, Panel):
|
|||
split = box.split(factor=0.35)
|
||||
name_col = split.column()
|
||||
path_col = split.column()
|
||||
|
||||
|
||||
row = name_col.row(align=True) # Padding
|
||||
row.separator()
|
||||
row.label(text="Name")
|
||||
|
||||
|
||||
row = path_col.row(align=True) # Padding
|
||||
row.separator()
|
||||
row.label(text="Path")
|
||||
|
||||
|
||||
row.operator("preferences.script_directory_add", text="", icon='ADD', emboss=False)
|
||||
|
||||
|
||||
for i, script_directory in enumerate(paths.script_directories):
|
||||
row = name_col.row()
|
||||
row.alert = not script_directory.name
|
||||
row.prop(script_directory, "name", text="")
|
||||
|
||||
|
||||
row = path_col.row()
|
||||
subrow = row.row()
|
||||
subrow.alert = not script_directory.path
|
||||
subrow.prop(script_directory, "path", text="")
|
||||
subrow.alert = not script_directory.directory
|
||||
subrow.prop(script_directory, "directory", text="")
|
||||
row.operator("preferences.script_directory_remove", text="", icon='X', emboss=False).index = i
|
||||
|
||||
|
||||
|
|
|
@ -782,10 +782,10 @@ void blo_do_versions_userdef(UserDef *userdef)
|
|||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(306, 1)) {
|
||||
if (userdef->pythondir[0]) {
|
||||
if (userdef->pythondir_legacy[0]) {
|
||||
NamedDirectoryPathEntry *script_path = MEM_callocN(sizeof(*script_path),
|
||||
"Versioning user script path");
|
||||
STRNCPY(script_path->dir_path, userdef->pythondir);
|
||||
STRNCPY(script_path->dir_path, userdef->pythondir_legacy);
|
||||
BLI_addhead(&userdef->script_directories, script_path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -700,7 +700,7 @@ typedef struct UserDef {
|
|||
char render_cachedir[768];
|
||||
char textudir[768];
|
||||
/* Deprecated, use #UserDef.script_directories instead. */
|
||||
char pythondir[768] DNA_DEPRECATED;
|
||||
char pythondir_legacy[768] DNA_DEPRECATED;
|
||||
char sounddir[768];
|
||||
char i18ndir[768];
|
||||
/** 1024 = FILE_MAX. */
|
||||
|
|
|
@ -139,6 +139,7 @@ DNA_STRUCT_RENAME_ELEM(ThemeSpace, scrubbing_background, time_scrub_background)
|
|||
DNA_STRUCT_RENAME_ELEM(ThemeSpace, show_back_grad, background_type)
|
||||
DNA_STRUCT_RENAME_ELEM(UVProjectModifierData, num_projectors, projectors_num)
|
||||
DNA_STRUCT_RENAME_ELEM(UserDef, gp_manhattendist, gp_manhattandist)
|
||||
DNA_STRUCT_RENAME_ELEM(UserDef, pythondir, pythondir_legacy)
|
||||
DNA_STRUCT_RENAME_ELEM(VFont, name, filepath)
|
||||
DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end)
|
||||
DNA_STRUCT_RENAME_ELEM(View3D, near, clip_start)
|
||||
|
|
|
@ -349,6 +349,11 @@ static void rna_userdef_script_directory_name_set(PointerRNA *ptr, const char *v
|
|||
{
|
||||
NamedDirectoryPathEntry *script_dir = ptr->data;
|
||||
|
||||
if (STREQ(value, "DEFAULT")) {
|
||||
BKE_report(NULL, RPT_ERROR, "Name 'DEFAULT' is reserved for internal use and cannot be used");
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_strncpy_utf8(script_dir->name, value, sizeof(script_dir->name));
|
||||
BLI_uniquename(&U.script_directories,
|
||||
JulianEisel marked this conversation as resolved
Campbell Barton
commented
Rather not warn as in the rare case a user runs into this - it's not as if there is anything to "fix", besides the script author adding explicit checks for "DEFAULT" which isn't useful. Over long names will also be clipped for e.g. which doesn't warn. In general it's possible the name requested in Blender is manipulated. It can't be assumed a string literal will be used verbatim. Rather not warn as in the rare case a user runs into this - it's not as if there is anything to "fix", besides the script author adding explicit checks for "DEFAULT" which isn't useful.
Over long names will also be clipped for e.g. which doesn't warn. In general it's possible the name requested in Blender is manipulated. It can't be assumed a string literal will be used verbatim.
|
||||
script_dir,
|
||||
|
@ -6211,7 +6216,7 @@ static void rna_def_userdef_script_directory(BlenderRNA *brna)
|
|||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH);
|
||||
prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
|
||||
RNA_def_property_string_sdna(prop, NULL, "dir_path");
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
|
|
Loading…
Reference in New Issue
Should read
"Returns a list of user preference script directories."
or similar.