Python: Support multiple custom script directories in Preferences #104876

Merged
Julian Eisel merged 9 commits from JulianEisel/blender:temp-multiple-script-dirs into main 2023-04-11 15:21:06 +02:00
5 changed files with 20 additions and 20 deletions
Showing only changes of commit 2663599d78 - Show all commits

View File

@ -802,10 +802,10 @@ void blo_do_versions_userdef(UserDef *userdef)
if (!USER_VERSION_ATLEAST(306, 5)) {
if (userdef->pythondir_legacy[0]) {
NamedDirectoryPathEntry *script_path = MEM_callocN(sizeof(*script_path),
"Versioning user script path");
STRNCPY(script_path->dir_path, userdef->pythondir_legacy);
BLI_addhead(&userdef->script_directories, script_path);
bUserScriptDirectory *script_dir = MEM_callocN(sizeof(*script_dir),
JulianEisel marked this conversation as resolved Outdated

The name should be initialized (suggest "Untitled" ?) - otherwise no strong preference, just don't leave it blank.

The name should be initialized (suggest "Untitled" ?) - otherwise no strong preference, just don't leave it blank.

Good catch, missed that when introducing the name option.

Good catch, missed that when introducing the name option.
"Versioning user script path");
STRNCPY(script_dir->dir_path, userdef->pythondir_legacy);
BLI_addhead(&userdef->script_directories, script_dir);
}
}

View File

@ -922,8 +922,8 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef)
BLO_write_struct(writer, bPathCompare, path_cmp);
}
LISTBASE_FOREACH (const NamedDirectoryPathEntry *, python_dir, &userdef->script_directories) {
BLO_write_struct(writer, NamedDirectoryPathEntry, python_dir);
LISTBASE_FOREACH (const bUserScriptDirectory *, script_dir, &userdef->script_directories) {
BLO_write_struct(writer, bUserScriptDirectory, script_dir);
}
LISTBASE_FOREACH (const bUserAssetLibrary *, asset_library_ref, &userdef->asset_libraries) {

View File

@ -1033,11 +1033,11 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
FS_UDIR_PATH(U.fontdir, ICON_FILE_FONT)
FS_UDIR_PATH(U.textudir, ICON_FILE_IMAGE)
LISTBASE_FOREACH (NamedDirectoryPathEntry *, pythondir, &U.script_directories) {
LISTBASE_FOREACH (bUserScriptDirectory *, script_dir, &U.script_directories) {
fsmenu_insert_entry(fsmenu,
FS_CATEGORY_OTHER,
pythondir->dir_path,
pythondir->name,
script_dir->dir_path,
script_dir->name,
ICON_FILE_SCRIPT,
FS_INSERT_LAST);
}

View File

@ -682,13 +682,13 @@ typedef struct UserDef_Experimental {
/**
* Container to store multiple directory paths and a name for each as a #ListBase.
*/
typedef struct NamedDirectoryPathEntry {
struct NamedDirectoryPathEntry *next, *prev;
typedef struct bUserScriptDirectory {
struct bUserScriptDirectory *next, *prev;
/** Depending on the use case of this struct, this should probably be a unique name. */
/** Name must be unique. */
char name[64]; /* MAX_NAME */
char dir_path[768]; /* FILE_MAXDIR */
} NamedDirectoryPathEntry;
} bUserScriptDirectory;
typedef struct UserDef {
DNA_DEFINE_CXX_METHODS(UserDef)
@ -802,7 +802,7 @@ typedef struct UserDef {
* launch with a new version of Blender. In this case setting the script path on top of
* factory settings will work without problems.
*/
ListBase script_directories; /* #NamedDirectoryPathEntry */
ListBase script_directories; /* #bUserScriptDirectory */
/** #bUserMenu. */
struct ListBase user_menus;
/** #bUserAssetLibrary */

View File

@ -347,7 +347,7 @@ static void rna_userdef_script_autoexec_update(Main *UNUSED(bmain),
static void rna_userdef_script_directory_name_set(PointerRNA *ptr, const char *value)
JulianEisel marked this conversation as resolved
Review

If DEFAULT or an empty string is passed in, use a fallback name such as "Untitled" or "Path", this avoids having to account for unlikely corner cases - maybe the user has a points to a script dir called DEFAULT and gets an error in the operator.

Disallowing empty strings is just a convention from data-block naming, which I think would be good to enforce here too since it's not expected and means the enum identifier for e.g. would be an empty string - probably it works for the most-part but could cause issues (empty strings have a special meaning for enum separators .. for e.g.). Python scripts may do truth checks on a value without realizing an empty string is a valid value... so we can avoid all this with a default name.

If `DEFAULT` or an empty string is passed in, use a fallback name such as "Untitled" or "Path", this avoids having to account for unlikely corner cases - maybe the user has a points to a script dir called `DEFAULT` and gets an error in the operator. Disallowing empty strings is just a convention from data-block naming, which I think would be good to enforce here too since it's not expected and means the enum identifier for e.g. would be an empty string - probably it works for the most-part but could cause issues (empty strings have a special meaning for enum separators .. for e.g.). Python scripts may do truth checks on a value without realizing an empty string is a valid value... so we can avoid all this with a default name.
{
NamedDirectoryPathEntry *script_dir = ptr->data;
bUserScriptDirectory *script_dir = ptr->data;
bool value_invalid = false;
if (!value[0]) {
@ -368,13 +368,13 @@ static void rna_userdef_script_directory_name_set(PointerRNA *ptr, const char *v
script_dir,
value,
'.',
offsetof(NamedDirectoryPathEntry, name),
offsetof(bUserScriptDirectory, name),
sizeof(script_dir->name));
}
static NamedDirectoryPathEntry *rna_userdef_script_directory_new(void)
static bUserScriptDirectory *rna_userdef_script_directory_new(void)
{
NamedDirectoryPathEntry *script_dir = MEM_callocN(sizeof(*script_dir), __func__);
bUserScriptDirectory *script_dir = MEM_callocN(sizeof(*script_dir), __func__);
BLI_addtail(&U.script_directories, script_dir);
USERDEF_TAG_DIRTY;
return script_dir;
@ -382,7 +382,7 @@ static NamedDirectoryPathEntry *rna_userdef_script_directory_new(void)
static void rna_userdef_script_directory_remove(ReportList *reports, PointerRNA *ptr)
{
NamedDirectoryPathEntry *script_dir = ptr->data;
bUserScriptDirectory *script_dir = ptr->data;
if (BLI_findindex(&U.script_directories, script_dir) == -1) {
BKE_report(reports, RPT_ERROR, "Script directory not found");
return;
@ -6264,7 +6264,7 @@ static void rna_def_userdef_filepaths_asset_library(BlenderRNA *brna)
static void rna_def_userdef_script_directory(BlenderRNA *brna)
{
StructRNA *srna = RNA_def_struct(brna, "ScriptDirectory", NULL);
RNA_def_struct_sdna(srna, "NamedDirectoryPathEntry");
RNA_def_struct_sdna(srna, "bUserScriptDirectory");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Python Scripts Directory", "");