Page MenuHome

UI: Add Preset should preseve case
ClosedPublic

Authored by Ankur Deria (DAnkur) on Jan 27 2021, 2:16 PM.

Details

Summary

This addresses T79822 : Add Preset should preseve case

Problem :

Adding new presets converted the preset name to title case.

Solution

Prevent the strings from being converted to lower case. As a result the .py preset files are also save with the exact same case as the preset name but all the preset names are shown exactly as the input string.

Note - There exists a bug in import operator preset where the preset name is not shown if you you select a user preset from the drop down menu. This bug is not due to this fix.

Diff Detail

Repository
rB Blender

Event Timeline

Ankur Deria (DAnkur) requested review of this revision.Jan 27 2021, 2:16 PM
Ankur Deria (DAnkur) created this revision.
Ankur Deria (DAnkur) edited the summary of this revision. (Show Details)
Nathan Craddock (natecraddock) requested changes to this revision.Jan 27 2021, 3:02 PM

Thanks for working on this!

There is one case that isn't handled yet that I think would make sense to support. If the preset name that the user types is entirely lowercase, it will be converted to title case when loaded from disk and displayed in the menu.

release/scripts/startup/bl_operators/presets.py
254

The extension should be converted to lowercase. The extension is loaded from disk, and if for some reason the file extension was changed from .py to .PY then the preset would fail to load.

This revision now requires changes to proceed.Jan 27 2021, 3:02 PM
Ankur Deria (DAnkur) updated this revision to Diff 33264.EditedJan 28 2021, 7:22 PM

Made changes to consider title case in the case where user inputs all small letters for preset name. Instead of saving the file as all small case, I am converting the string to title case before saving it to disk.

Note - I tried changing the ".py" extension to ".PY" in the folder where render presets are saved. Blender fails to load the preset even when the extension gets converted ".py".

Sorry @Ankur Deria (DAnkur), I wasn't clear in my previous comment.

What I intended to say, is that if the user types a string in all lowercase, then that intention should be preserved. So typing my preset should be displayed in the list as my preset.

The code that reads the filenames from disk and displays is in release/scripts/modules/bpy/path/py

Ankur Deria (DAnkur) marked an inline comment as done.

Made changes to keep the file name exactly same as the user input string. In Path.py, I check for ".xml" and ".py" extensions because those are the only two extensions I found in the saved preset files and do not perform title case conversion on those file names.

Thank you for helping me and sorry if I am bothering you, I am a complete newbie to open source contribution.

Thank you for helping me and sorry if I am bothering you, I am a complete newbie to open source contribution.

No worries! We are all new at some point, and I'm happy to help.

The behavior is good now, but I think the implementation could be made a bit simpler and more flexible. Currently the function makes things title case unless it's an xml or py file. How about making display_name take an optional argument for title case that defaults to True. Then it wouldn't be dependent on file extensions, but on the caller deciding to use title case or not.

Then when draw_preset in bpy_types.py calls self.path_menu it can specify to use display name without title case.

Ankur Deria (DAnkur) updated this revision to Diff 33341.EditedJan 30 2021, 11:40 AM

Added title_case as parameter which defaults to true. In case of draw preset and preset find, title_case is set to false.

Overall looks good now! There's a few small things now that you could change if you want, or I could make a few small tweaks before committing it for you.

release/scripts/modules/bpy/path.py
211

Try not to change unnecessary whitespace

release/scripts/modules/bpy_types.py
931

Here the first display_name function might not have a title_case argument because it is a callback function passed in, so that should be removed.

985

This comment isn't critical, but a simpler way would be to pass in a lambda for display_name (like for filter_ext) that calls bpy.path.display_name with title_case=True. Then you don't even need to add an extra argument to path_menu.

Ankur Deria (DAnkur) marked 2 inline comments as done.Jan 31 2021, 8:10 PM

Removed extra arguement in path_menu and passed in a lambda for display_name while calling path_menu from draw_preset.

Looks good to me! I'll try to get this committed soon. Thanks again for working on it :)

This revision is now accepted and ready to land.Feb 1 2021, 3:46 PM

Thank you for all the help :)

This patch seems fine.

Although, if we're changing how preset names are stored/displayed, we could move to URL quoting, see: urllib.parse.quote, urllib.parse.unquote.

Examples:

>>> urllib.parse.quote("My/Preset: High/Quality!", safe="")
'My%2FPreset%3A%20High%2FQuality%21'

>>> urllib.parse.unquote("My%2FPreset%3A%20High%2FQuality%21")
'My/Preset: High/Quality!'

This has the advantage of using a standardized way of storing characters that can't be written in path names, other (non-python) libraries support this too, so we could display them without Python - if that's ever needed.

Suggest to commit this to a branch, look into using URL quoting too. If this is a straightforward change, we could make this in one go. If it's more involved (for example, if existing presets cause errors loading)... this could be handled as a separate task - and this patch could go into master directly.

Also think URL quoting would be a good general solution to support unusual/reserved chars

Brecht Van Lommel (brecht) requested changes to this revision.Feb 3 2021, 2:13 PM
In D10224#256557, @Zachman wrote:

What I intended to say, is that if the user types a string in all lowercase, then that intention should be preserved. So typing my preset should be displayed in the list as my preset.

This breaks compatibility with existing preset names, now all bundled or user saved presets display in lower case. Bundled presets could be updated, but user saved ones can't.

Although, if we're changing how preset names are stored/displayed, we could move to URL quoting, see: urllib.parse.quote, urllib.parse.unquote.

I've never encountered software that saves filenames like this, it seems quite strange to me.

If we want to fix both compatibility and avoid such quoting in filenames we could save the name inside the preset file somehow, like # Name: on the first line.

This revision now requires changes to proceed.Feb 3 2021, 2:13 PM

@Brecht Van Lommel (brecht) I do have the fixes for bundled preset names in P1940.

I see two issues here. 1 is the incompatibility problems introduced by allowing full lowercase versions of the presets. 2 is support of special characters in the file names.

For the first, I think the simplest solution would be to commit @Ankur Deria (DAnkur)'s first version of this patch, which only removes saving user presets as lowercase, which wouldn't break compatibility with anything.

Then if we want URL encoding to support special characters in the names, that could be done later, but wouldn't be dependent on this patch.

If we want to fix both compatibility and avoid such quoting in filenames we could save the name inside the preset file somehow, like # Name: on the first line.

If Ankur's patch is committed in the simple form, then this could work as an alternative to URL encoding

That can work. I'll leave review and decisions here to other developers though. I just wanted to point out the compatibility issue and suggest a solution.

This revision is now accepted and ready to land.Feb 3 2021, 3:44 PM
This comment was removed by Ankur Deria (DAnkur).
Campbell Barton (campbellbarton) accepted this revision.EditedFeb 3 2021, 9:01 PM
In D10224#256557, @Zachman wrote:

What I intended to say, is that if the user types a string in all lowercase, then that intention should be preserved. So typing my preset should be displayed in the list as my preset.

This breaks compatibility with existing preset names, now all bundled or user saved presets display in lower case. Bundled presets could be updated, but user saved ones can't.

The existing preset names are mostly plain-text, I didn't think this would be an issue if some user presets don't show exactly as they did before this patch.

Although, if we're changing how preset names are stored/displayed, we could move to URL quoting, see: urllib.parse.quote, urllib.parse.unquote.

I've never encountered software that saves filenames like this, it seems quite strange to me.

I've seen a few programs use this, checking my cache rtags & gnome-tracker use this.

If we want to fix both compatibility and avoid such quoting in filenames we could save the name inside the preset file somehow, like # Name: on the first line.

This gets a bit more involved with XML presets, display names are used for app-templates too IIRC (although these are directories).

Approving this patch, as quoting may need some more discussion.

The following tests FAILED:
	 47 - script_load_addons (Failed)

@Ankit Meel (ankitm) thanks for catching that, it should be fixed now. rBA35d5df9bf4