Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PICARD-9: Add support for user profiles #1851

Merged
merged 31 commits into from
Jun 28, 2021

Conversation

rdswift
Copy link
Collaborator

@rdswift rdswift commented Jun 21, 2021

Summary

  • This is a…
    • Bug fix
    • Feature addition
    • Refactoring
    • Minor / simple change (like a typo)
    • Other
  • Describe this change in 1-2 sentences: Add support for user profiles.

Problem

There has been a long-standing request to allow for different user settings profiles, with a quick and easy method for switching between profiles. The plan for implementing user profiles involves maintaining a stack of profiles that would be applied sequentially (for active profiles in the stack). See the discussion on the JIRA ticket.

Solution

Implement a new subclass of ConfigSection to use for user settings that applies the user profile stack automatically to all config.setting assignments and retrievals. Add new keys to store the user profiles list and settings (overrides) for each profile in a new config.profiles section. Add a new dialog accessed from the main screen menu to manage the user profiles and settings.

Action

Additional work to be completed when this is finalized:

picard/config.py Outdated Show resolved Hide resolved
picard/config.py Outdated Show resolved Hide resolved
picard/profile.py Outdated Show resolved Hide resolved
@zas zas requested a review from phw June 21, 2021 15:45
picard/config.py Outdated Show resolved Hide resolved
picard/profile.py Outdated Show resolved Hide resolved
picard/profile.py Outdated Show resolved Hide resolved
picard/config.py Outdated Show resolved Hide resolved
picard/profile.py Outdated Show resolved Hide resolved
picard/config.py Outdated Show resolved Hide resolved
picard/config.py Outdated Show resolved Hide resolved
picard/config.py Outdated Show resolved Hide resolved
picard/config.py Outdated Show resolved Hide resolved
@rdswift
Copy link
Collaborator Author

rdswift commented Jun 24, 2021

I added a working version of the profile editor dialog, which I've been using for local testing. Once we firm up structures and such, I'll see about adding some tests as well.

EDIT: I suppose the dialog should have been in a separate PR, but I thought it might prove useful for any testing that you might want to do.

EDIT 2: I think the system now works as described by @zas in https://tickets.metabrainz.org/browse/PICARD-9

@rdswift rdswift force-pushed the add_user_profiles branch 2 times, most recently from c2e5a8d to 2b0f0f1 Compare June 24, 2021 21:10
@zas
Copy link
Collaborator

zas commented Jun 24, 2021

I did a quick test, it works well.
I'm a bit bothered by the fact profile-modified options are stored in an option, rather than in their own config sub-section.
Also we'll need to handle config upgrades (when an option name is modified, we'll need to propagate the change to profiles).

That's a good improvement already. Good job!

@rdswift
Copy link
Collaborator Author

rdswift commented Jun 24, 2021

I'm a bit bothered by the fact profile-modified options are stored in an option, rather than in their own config sub-section.

It should be fairly easy to store the profile settings dictionaries by profile id under a new config.profiles section, or were you thinking about having separate ConfigSection objects for each profile?

@rdswift
Copy link
Collaborator Author

rdswift commented Jun 25, 2021

After moving the profile settings to a new config.profiles group, it seems that it broke all of the tests that use the config.setting, even though it seems to work perfectly when running Picard. The tests all seem to be failing because config.setting can't see config.profiles and fail with a KeyError. I suspect there's something that needs to be fixed in the PicardTestCase module, but I'm not finding it.

@zas
Copy link
Collaborator

zas commented Jun 25, 2021

After moving the profile settings to a new config.profiles group, it seems that it broke all of the tests that use the config.setting, even though it seems to work perfectly when running Picard. The tests all seem to be failing because config.setting can't see config.profiles and fail with a KeyError. I suspect there's something that needs to be fixed in the PicardTestCase module, but I'm not finding it.

I think that's due to the use of global config in SettingConfigSection.

self.__qt_config = config

Use self.__qt_config instead of config:

profiles = config.profiles[self.PROFILES_KEY]

profile_settings = config.profiles[self.SETTINGS_KEY][id]

all_settings = config.profiles[self.SETTINGS_KEY]

config.profiles[self.SETTINGS_KEY] = all_settings

@rdswift
Copy link
Collaborator Author

rdswift commented Jun 25, 2021

I think that's due to the use of global config in SettingConfigSection.

That was exactly the problem. THANK-YOU!

@rdswift rdswift changed the title Create subclass of ConfigSection to support user profiles PICARD-9: Add support for user profiles Jun 25, 2021
@rdswift rdswift marked this pull request as ready for review June 25, 2021 15:37
Copy link
Collaborator

@zas zas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just (few more) stylistic remarks, but the patch is very good ;)

picard/ui/profileeditor.py Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Show resolved Hide resolved
picard/ui/profileeditor.py Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
test/test_profiles.py Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
Named tuple profile settings
In `picard/ui/profileeditor.py`:
- Remove unnecessary `deepcopy()`.
- Use `set.difference()` for comparing key sets.
- Add explanation for creating missing key in
`get_settings_for_profile()` method.
- Move `settings` declaration into `if` section where it is used.
- Remove unnecessary `.keys()` call when creating set of profile IDs.
- Use `set.difference()` for comparing setting sets.
- Remove unnecessary `self.loading` check.
- Add class constant for which QTreeWidgetItem column to use.

In test/test_profiles.py:
- Use keys defined in `SettingConfigSection` class.
zas
zas previously approved these changes Jun 26, 2021
Copy link
Collaborator

@zas zas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

zas
zas previously approved these changes Jun 26, 2021
picard/config.py Outdated Show resolved Hide resolved
zas
zas previously approved these changes Jun 27, 2021
Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work. This works really well, and I am especially glad that this was possible with rather small and clean changes to the config module itself.

From a user perspective I find the settings concept rather difficult to grasp, but it is very flexible. Before deep diving into the code itself I tried this functionality from a user's perspective. But I definitely had to read the documentation to fully understand it (even though I had kind of suspected how this works based on our previous discussions).

I have a few notes about the profile editor dialog itself:

  • The buttons should be placed in QDialogButtonBox and should be added with appropriate roles. This ensures the buttons render consistent with other dialogs and platform dependent.
  • I find the separate "Save" and "Make it so!" buttons really confusing and not easy to use. I'd favor having this behave like options themselves: Have a "Cancel" button and a single "Make it so!" button to save and close
  • I would consider moving the "New", "Copy" and "Delete" buttons below the widget, next to the ordering buttons. That would make it consistent with other widgets we use in options where the buttons to control a list of things (e.g. scripts) are next to the widget presenting this list. It would also make the main dialog buttons look less cluttered

I would also add a keyboard shortcut to open the profile editor. Ctrl+Shift+P maybe? That would allow the user to quickly change profiles without the menu.

For a future refinement to make the behavior of profiles more clear I think it would be beneficial to indicate in the profile editor which settings actually have distinct values. Maybe even show the value itself (which would probably require that we have a useful rendering depending on the option type, e.g. show BoolOption as "Yes" / "No" or something.

But we can do this in a follow up PR.

ui/profileeditor.ui Outdated Show resolved Hide resolved
picard/ui/profileeditor.py Outdated Show resolved Hide resolved
@rdswift
Copy link
Collaborator Author

rdswift commented Jun 28, 2021

I have a few notes about the profile editor dialog itself:

  • The buttons should be placed in QDialogButtonBox and should be added with appropriate roles. This ensures the buttons render consistent with other dialogs and platform dependent.

Most were in the buttonbox, except "Make It So!". Now are all in buttonboxes with the appropriate roles assigned.

  • I find the separate "Save" and "Make it so!" buttons really confusing and not easy to use. I'd favor having this behave like options themselves: Have a "Cancel" button and a single "Make it so!" button to save and close

I actually simplified it by removing the "Save" button and auto-save the changes locally (within the dialog) as they are made. Do we still need a "Reset" button?

  • I would consider moving the "New", "Copy" and "Delete" buttons below the widget, next to the ordering buttons. That would make it consistent with other widgets we use in options where the buttons to control a list of things (e.g. scripts) are next to the widget presenting this list. It would also make the main dialog buttons look less cluttered

Done. I agree that they look better there.

I would also add a keyboard shortcut to open the profile editor. Ctrl+Shift+P maybe? That would allow the user to quickly change profiles without the menu.

Done. At the same time I also added one for the file naming script editor to be consistent. I hope that's okay.

zas
zas previously approved these changes Jun 28, 2021
zas
zas previously approved these changes Jun 28, 2021
Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dialog now looks much clearer with re-arranged buttons.

LGTM

@phw phw merged commit 75f8d93 into metabrainz:master Jun 28, 2021
@rdswift rdswift deleted the add_user_profiles branch June 28, 2021 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants