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

[GUI] Add Preference Pack support #4787

Merged
merged 22 commits into from Oct 14, 2021
Merged

Conversation

chennes
Copy link
Member

@chennes chennes commented May 12, 2021

Summary

This PR adds a system for storing and applying sets of user preferences called "Preference Packs". These are intended to give users the ability to make bulk modifications to their FreeCAD setup by applying one or more of these packs. The packs are designed to be distributable, and to that end this PR introduces a new type of metadata file, "package.xml". Anything that can be stored in the user.cfg file can be stored in a Preference Pack. More details can be found in the "Details" section below.

Testing

The main questions to be addressed in testing are:

  • Does this PR compile on your system?
  • Does FreeCAD run?
  • When you load the Preferences dialog, does the new Preference Packs area look OK?
  • Does it work correctly? (see suggested tests below)

Before testing, please back up your user.cfg file. If the tests fail it is likely that your preferences will be corrupted. Although the system makes backups, if there is a problem with that code, you may lose your settings!

Suggested Test A - Stylesheet change

  1. Apply a stylesheet using the Stylesheet setting in Preferences
  2. Apply the "FreeCAD Classic Colors" Preferences Pack

Expected results: the stylesheet is reverted to "None".

Suggested Test B - Color change

  1. Change the color of something in Preferences that you have previous left at the system default color
  2. Apply the "FreeCAD Classic Colors" Preferences Pack

Expected results: the color change is reverted to the original default.

Suggested Test C - Un-reverted change

  1. Change a preference that is not related to colors
  2. Apply the "FreeCAD Classic Colors" Preferences Pack

Expected results: your change is not affected by the pack.

Suggested Test D - New appearance preference pack

  1. Make some color changes
  2. In Preferences, in the Preference Pack area, choose Save
  3. Ensure that the checkboxes next to the colors options are checked
  4. Uncheck the checkbox next to the behaviors options
  5. Give your new pack a name and click save
  6. Make another change to the colors you modified in the first step
  7. Apply your preference pack

Expected result: the change you just made is reverted to the color you stored in the preference pack. Your preference pack is listed as an "appearance" pack in the GUI.

Suggested Test E - New behavior preference pack

(Only a few behaviors are encoded into the preference pack template files in this PR: it is expected that more will be added in later PRs in consultation with testers and users)

  1. Save a new preference pack, checking the box next to "Main window layout" and unchecking all of the other template options
  2. Change which Dock Windows are showing (e.g. Selection View, Combo View, PythonView, TreeView, etc.)
  3. Apply the preference pack you just created

Expected result: the shown/hidden state of the Dock windows is restored to that which was stored in the preference pack.

Details

This PR comprises three main additions to FreeCAD:

App::Metadata

C++ and Python support for reading and writing the new metadata format. That format is based on REP 149, with minor modifications to accommodate use within FreeCAD. The format is documented at https://wiki.freecadweb.org/Package_Metadata.

Preference Packs require this file to be present and to describe the pack, and the long-term goal is that this metadata file can be added to other types of Add-Ons, facilitating a more powerful add-on manager, and eliminating the need to compile in external workbench icons, etc.

Gui::PreferencePack

This class manages a single preference pack, which itself is made of a number of separate files, grouped together into a folder with the same name as the preference pack (as described by its package.xml metadata file).

A preference pack consists of the following files (all technically optional):

  • pre.FCMacro -- run prior to applying the pack. If it raises an exception, application of the pack is aborted.
  • Package Name.cfg -- The core of a preference pack, a well-formatted user.cfg file containing only those elements that the preference pack sets. Anything that can be in a user.cfg file is allowed.
  • post.FCMacro -- run after applying the pack. If it raises an exception, the application of the pack is rolled back.
  • Auxiliary files referenced by the .cfg file -- most commonly a QSS stylesheet, but in the future might include icons, etc.

Preference Packs provide an additional piece of guidance to end users, describing whether the pack is intended to change FreeCAD's appearance, behavior, or both. This is purely GUI guidance, and is not enforced by the code in any way. It is set via the "type" element in the package.xml metadata file.

Because of the sensitivity of user preferences, and the possibility that a pack will make a change the user does not like that is not discovered immediately, when applying a pack two separate backups are taken. One is used to roll back the most recent change in the event that post.FCMacro raises an exception, and the other is a set of backups managed by the PreferencePackManager (described next) and retained for one week. There is currently no user interface for rolling those back, they must be manually copied by the user.

Gui::PreferencePackManager

This class manages a list of all available preference packs, and also provides the ability to save the user's current settings as a new pack.

Preference Packs are searched for in three locations:

  • $USER_APP_DATA_DIR/Mod/* (for packs distributed as add-ons)
  • $USER_APP_DATA_DIR/SavedPreferencePacks/ (for packs the user has saved locally)
  • $RESOURCE_DIR/Gui/PreferencePacks/ (for packs distributed with FreeCAD)

To locate the packs, files named "package.xml" are searched for in the above locations. If found, that metadata is read in and examined for "preferencepack" content items. These items must all have unique names (as specified by the metadata), and their files must be located in a subdirectory of the same name as the preference pack.

Saving preference packs

To ease the development of distributable preference packs, the ability to save a subset of the user's current preferences into a preference pack is also provided. However, this facility requires some additional complication due to the way FreeCAD handles default preferences.

The ability to save to a preference pack is provided by including a set of "Preference Pack Template" files. These are needed to support saving of preferences that the user has not explicitly set, and are using their hardcoded default values -- in that case, the user.cfg file does not have any information about the current setting, which is only currently available in the code that accesses that setting.

To overcome this obstacle, Preference Pack Templates are intended to provide a complete "user.cfg"-formatted set of preferences set to their default values. When a user selects "Save as new" in the GUI, several locations are scanned for these template files:

  • $USER_APP_DATA_DIR/Mod/*/PreferencePackTemplates (for templates distributed with add-ons)
  • $RESOURCE_DIR/Gui/PreferencePackTemplates/ (for templates distributed with FreeCAD)

(the alternate directory name "preference_pack_templates" is also supported, for those mod authors who prefer to use snake case). Within these directories, two subdirectories are searched, "Appearance" and "Behavior". Template files should be grouped into preferences that affect only the appearance of FreeCAD, and those that change its behavior.

The user is presented with a set of checkboxes to select which of these templates they would like used to determine which preferences are stored. This feature is mainly intended to provide "Theme" authors with an easy way of creating new preference packs with UI color information in them. To that end, a relatively complete set of templates is provided for UI color information, and only a single "demonstration" template is included in this PR with other preference information in it. In the long term it is expected that a robust set of templates will be developed and included with FreeCAD covering the most-requested Preference Pack settings.

Future Work

A separate PR will provide an extension to the Add-on Manager to support the new package.xml data, and to add "Preference Pack" as a new type of add-on. For now, packs can be managed as a standard add-on, as long as they provide a package.xml file and follow the appropriate folder structure and naming convention. This includes manual installation into the Mod directory.

Forums discussions


  • Your pull request is confined strictly to a single module.
  • Discussed in forums
  • Your branch is rebased on latest master
  • All FreeCAD unit tests are confirmed to pass
  • All commit messages are well-written
  • Your pull request is well written and has a good description
  • No tracker ticket

src/App/Metadata.cpp Outdated Show resolved Hide resolved
src/App/Metadata.cpp Outdated Show resolved Hide resolved
src/App/Metadata.cpp Show resolved Hide resolved
src/App/Metadata.cpp Show resolved Hide resolved
src/Gui/DlgCreateNewPreferencePackImp.cpp Outdated Show resolved Hide resolved
<FCBool Name="Std_SelectionView" Value="0"/>
<FCBool Name="Std_ComboView" Value="1"/>
<FCBool Name="Std_ReportView" Value="0"/>
<FCBool Name="Std_PythonView" Value="0"/>
Copy link
Contributor

Choose a reason for hiding this comment

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

Worth listing 'Tree View', 'Property View' and 'DAG View' ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, probably. Right now that file is purely a skeleton for testing, I'd love some help fleshing it it, and creating other Behavior templates.

Copy link
Member Author

Choose a reason for hiding this comment

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

I have added those three, but will leave this conversation open in case other additions come up.

Copy link
Member Author

Choose a reason for hiding this comment

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

At the suggestion of Forum member jnxd I have added Editor font information into a template file.

Preference Packs are collections of preferences that can be applied en
mass to the user's current setup. Any preference that can be stored in
user.cfg can be stored in a preference pack, and they are designed to be
easy to distribute.

Support is also added for saving a subset of current preferences into a
new preference pack in order to facilitate easy creation of new
"themes", etc.
@luzpaz luzpaz added the Missing: confirmation Missing confirmation from other testers label Jul 20, 2021
@berndhahnebach berndhahnebach added the Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD label Aug 1, 2021
@luzpaz
Copy link
Contributor

luzpaz commented Aug 1, 2021

@chennes would mpetrikas's VerticalUI be a good usecase for this ?

@chennes
Copy link
Member Author

chennes commented Aug 2, 2021

@chennes would mpetrikas's VerticalUI be a good usecase for this ?

Fo some of mpetrika's suggestions, yes: the ones that are just preference-driven, or are part of the Qt Theme system. But other suggestions in that post are not things that are (currently) stored as user preferences, and do require code modifications.

@balrobs
Copy link
Contributor

balrobs commented Aug 23, 2021

@chennes here is my test report:
https://forum.freecadweb.org/viewtopic.php?p=526323#p526323
I had some troble with Test E. Maybe I missunderstood something ;-)

@yorikvanhavre
Copy link
Member

This looks like a mastery addition... Will test too ASAP!

Just changing the preference for hiding or showing a dock window does
not actually trigger a state change. To enable that, the preferences
pack manager must manually instruct the DockWindowManager to save its
state into the preferences before storing a preference pack, and must
instruct the DockWindowManager to load its new state from the
preferences after loading a pack.
@chennes
Copy link
Member Author

chennes commented Aug 24, 2021

I had some troble with Test E. Maybe I missunderstood something ;-)

Thanks again for testing: I've pushed a fix to the bug you discovered.

@balrobs
Copy link
Contributor

balrobs commented Aug 24, 2021

Thank you for the fix. Now everything is fine ... only one minor issue remaining? See https://forum.freecadweb.org/viewtopic.php?f=8&t=58210&start=40#p526935

@ghost
Copy link

ghost commented Aug 29, 2021

"Preference Packs" ... package.xml

Why not just use "Preferences Preset" and store in preferences.xml?

@chennes
Copy link
Member Author

chennes commented Aug 29, 2021

Why not just use "Preferences Preset" and store in preferences.xml?

No particular reason for "Preference Pack" - we discussed it in the forum and that was the consensus. Basically the same for the xml file, though also note that that file is not specific to Preference Packs, the intention is that in the long term all mods are distributed with that file, so we stuck with the "standard" filename as used in that ROS specification.

@berndhahnebach
Copy link
Contributor

Following a link to the branch on the CI-repository:

https://gitlab.com/berndhahnebach/FreeCAD/-/commits/PR_5060

The CI-status is available on the latest commit of the branch.
If there is no status available the PR should be rebased on latest master.
Check pipeline branches to see if your PR has been run by the CI.

https://gitlab.com/berndhahnebach/FreeCAD/-/pipelines?scope=branches

@berndhahnebach
Copy link
Contributor

@yorikvanhavre yorikvanhavre self-requested a review October 9, 2021 09:15
Copy link
Member

@yorikvanhavre yorikvanhavre left a comment

Choose a reason for hiding this comment

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

This is pretty cool! I tested on Debian testing and everything seems to work as expected, no regression or bug noted.
Observations (generic suggestions, don't consider these as needed for this PR, I let you choose if you consider this PR ready or not):

  • The "preferences pack" section uses quite a lot of the "General" preferences page. I wonder if it wouldn't be better in its own tab
  • It is unclear what the "Manage" button is for. It opens a file selection dialog without explanation
  • The template type in the available pref packs seems to me rather unuseful info.... I'd rather see maybe a description text, ie what will happen if I press "apply"

@chennes
Copy link
Member Author

chennes commented Oct 11, 2021

Thanks, @yorikvanhavre .

  1. I decided to put it on the general tab for two reasons: first, because otherwise that tab had a lot of unused space on it, and this can expand to fit, or contract as needed. And second, because when you apply a pack the window has to get closed and reopened, this way it appears to be reopening where you left off! Even though actually it just opens to the first page all the time.
  2. Eventually that will be connected to the add-on manager, but I didn't want to do that until I'd actually written the new Add-on manager code to handle the metadata and preference packs. I'll hide that button for now unless the user has saved some preference packs, and add a tooltip to it.
  3. Agreed. It made sense at the time, I think, but several months later I agree that it's pretty worthless. I'll look into what else could be displayed instead. Maybe a list of "tags"? The pack description will be too long, I think.

@yorikvanhavre
Copy link
Member

ok! the description could be in a tooltip maybe..

In display, show the "tags" instead.
@chennes
Copy link
Member Author

chennes commented Oct 11, 2021

OK, I've addressed your comments above: I removed the "type" thing and replaced it with a display of the tags assigned to the pack (those are set in the metadata file). Eventually it would be good for a user to be able to edit those from the GUI, but that can be later work I think. From my perspective then this is ready for merge.

@freecadci
Copy link

pipeline status for feature branch PR_4787. Pipeline #386440257 was triggered at 1076ba0. All CI branch pipelines.

@yorikvanhavre
Copy link
Member

Ok let's do it then! Thanks for the very clean coding BTW, even I can find myself in it ;)

@yorikvanhavre yorikvanhavre merged commit d95f085 into FreeCAD:master Oct 14, 2021
@chennes
Copy link
Member Author

chennes commented Oct 14, 2021

Thanks, I was too much a coward to press the button myself 😄

@yorikvanhavre
Copy link
Member

So far so good 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD Missing: confirmation Missing confirmation from other testers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants