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

11565 confirmation dialog for reset preferences and fixes #25400

Conversation

krasko78
Copy link
Contributor

@krasko78 krasko78 commented Nov 1, 2024

Resolves: #11565

  1. Added a confirmation dialog for when the Reset preferences button on the Preferences dialog is clicked
  2. All preference pages update all of their settings to match the reset preferences after resetting the preferences.

I've added some comments below (in this PR) with more info and observations.

  • I signed the CLA
  • The title of the PR describes the problem it addresses
  • Each commit's message describes its purpose and effects, and references the issue it resolves
  • If changes are extensive, there is a sequence of easily reviewable commits
  • The code in the PR follows the coding rules
  • There are no unnecessary changes
  • The code compiles and runs on my machine, preferably after each commit individually
  • I created a unit test or vtest to verify the changes I made (if applicable)

@krasko78
Copy link
Contributor Author

krasko78 commented Nov 1, 2024

Observations:

  • The confirmation dialog is in preferencesmodel.cpp and is pretty straight-forward. The Cancel button is the default button. Here is a screenshot:
    image

  • The changes to update each page after the reset is complete are in separate commits (much easier to review I guess). The Appearance, Folders and Shortcuts page already worked as expected so no changes were needed for them.

  • There is inconsistency in the use of .onReceive(nullptr, vs. .onReceive(this,.

  • There is also inconsistent use of ValCh vs. ValNt vs. separate channel/notification.

  • I've added a few comments to some files to explain why I had to make a specific change that might not be obvious.

@krasko78 krasko78 marked this pull request as draft November 1, 2024 19:58
//! NOTE To change the language at the moment, a restart is required
m_needRestartToApplyLanguageChange = true;
m_needRestartToApplyLanguageChange = newLanguageCode != m_activeLanguageCode;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is needed to make the "Restart required" text go away if the user restores the language explicitly or via Reset preferences to the currently active language. Currently, once this text appears, it won't go away.

Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't the new m_activeLanguageCode field duplicate info from m_currentLanguage.code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not exactly. If the language code is "system", m_currentLanguageCode will hold the effective language code, e.g. "en-us" so choosing another language and going back to "system" will not make "Restart required" go away if we use m_currentLanguageCode here. I am changing m_activeLanguageCode to be a local variable in this method since it is not used anywhere else.

@@ -95,6 +95,13 @@ void Settings::reset(bool keepDefaultSettings, bool notifyAboutChanges)
m_settings->clear();

m_isTransactionStarted = false;

std::vector<Settings::Key> locallyAddedKeys;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made these changes because it turned out that some settings without a value are not present in m_items. If the user opens the Preferences dialog, all settings are switched to m_localSettings. If the user sets a value of a missing setting, it will be created in m_localSettings. Then, if the user resets the preferences without closing the dialog, change notifications will be sent out for the settings in m_items, i.e. any settings added in m_localSettings will be missed and thefore not updated on the dialog. Two examples of such settings are: Score -> Style for part (PART_STYLE_FILE_PATH in the code) and Import -> Style file (STYLE_FILE_IMPORT_PATH_KEY in the code).

@@ -41,7 +41,12 @@ BaseSection {
QtObject {
id: prv

property bool useStyleFile: root.styleFileImportPath !== ""
property bool useStyleFileExplicitlySet: root.styleFileImportPath !== ""
Copy link
Contributor Author

@krasko78 krasko78 Nov 1, 2024

Choose a reason for hiding this comment

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

These changes were needed to properly update the Styles used for import controls on the Import page and fix these two bugs:
1. Open the Preferences dialog and navigate to the Import page.
2. Change Style used for import from Built-in style to Use style file.
3. Type a file if you want or skip this step.
4. Click Reset Preferences without closing the dialog.
Result: the Use style file radiobutton remains selected.

AND:
1. Open the Preferences dialog and navigate to the Import page.
2. Change Style used for import from Built-in style to Use style file.
3. Type something in the file textbox.
4. Delete the text in the file textbox.
Result: the Built-in style radiobutton becomes selected.

@krasko78 krasko78 force-pushed the 11565-ConfirmationDialogForResetPreferencesAndFixes branch 2 times, most recently from 8f244fd to a23448e Compare November 1, 2024 23:14
@krasko78 krasko78 force-pushed the 11565-ConfirmationDialogForResetPreferencesAndFixes branch from a23448e to 628dfa7 Compare November 1, 2024 23:18
@krasko78 krasko78 marked this pull request as ready for review November 1, 2024 23:53
@@ -96,28 +96,46 @@ void AdvancedPreferencesModel::load()
for (auto it = items.cbegin(); it != items.cend(); ++it) {
if (it->second.canBeManuallyEdited) {
m_items << it->second;

muse::Settings::Key key = it->second.key;
settings()->valueChanged(key).onReceive(this, [this, key](const Val& val) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe each subsequent call to settings()->valueChanged(key).onReceive(this (with emphasis on the latter this) either overrides the previously registered callback or does nothing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you elaborate? Each subsequent call is for a different setting (key) => different notification channel.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah sorry, you're definitely right!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No worries. Comments are always welcome. :)

Copy link
Contributor

@mathesoncalum mathesoncalum left a comment

Choose a reason for hiding this comment

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

Thanks for this @krasko78, Ieft some comments.

Also looks like quite a hefty rebase is required, apologies for not reviewing this sooner (we're all very busy at the moment). Before updating this though, I think it might be wise to wait for @avvvvve to get back to us with their design considerations so you don't end up doing double-work.

Cheers!

@@ -34,7 +34,7 @@ using namespace winrt;
using namespace muse;
using namespace muse::audio;

static constexpr char DEFAULT_DEVICE_ID[] = "default";
static constexpr char DEFAULT_DEVICE_ID[] = "default"; // Must match DEFAULT_DEVICE_ID in audioconfiguration.cpp and possibly others!
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should define DEFAULT_DEVICE_ID in audiotypes.h to avoid duplication.

This of course means we'll need to tweak the other audio driver classes (jackaudiodriver.cpp, linuxaudiodriver.cpp, osxaudiodriver.mm)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, I'll see what I can do, thanks!

Comment on lines +208 to +212
{
std::string title = muse::trc("appshell", "Are you sure you want to reset preferences?");
std::string question = muse::trc("appshell", "This action will reset all your app preferences and delete all custom palettes and custom shortcuts.\n\n"
"This action will not delete any of your scores.\n\n"
"This action cannot be undone.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably need a quick copy pass here.

@avvvvve pressing the reset preferences button in the preferences dialog will show a dialog with this text (screenshot here). Any thoughts on this (or the new dialog flow generally)?

Comment on lines +58 to +59
static async::Notification ch;
return ch;
Copy link
Contributor

Choose a reason for hiding this comment

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

Extreme nitpick (sorry) - why the change? It's still a Notification (n).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most likely my intension was to rename the other one indeed. :)

Comment on lines +88 to +89
static async::Channel<bool> n;
return n;
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, perhaps you intended to rename this to ch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe so, thanks! I have fixed both.

@avvvvve
Copy link

avvvvve commented Dec 12, 2024

@krasko78 Thanks for taking this one on!

I understand the thought to make "Cancel" the default action here, but reordering the buttons tripped me up. I would imagine most users (including me) are used to "Cancel" being the left button in a group of two buttons in MuseScore. So if you accidentally click "Reset preferences" and instinctively move your mouse to the left button to "Cancel" the dialog without reading, you might inadvertently reset your preferences.

I would leave the order/coloration of buttons as they are in the revert to factory settings dialog (Cancel in grey on left, Reset in accent color on right).

However, we should make "Cancel" the first button that is focused if you open this dialog via keyboard navigation (rather than "Reset"). I also think we can delete the extra line breaks before "This action will note delete any of your scores", like so:

image

Just curious—while you're working on this, are you willing to tackle this issue that would make it so the startup wizard doesn't appear after you reset preferences and reopen the app? #13299

@krasko78
Copy link
Contributor Author

Thanks for the feedback, @mathesoncalum and @avvvvve! I'll look at your comments in detail shortly.
The Cancel button is on the right because my screenshot is from Windows (I am a Windows user). On Windows the Cancel button is on the right otherwise it would trip Windows users up :) So I believe on MacOS and Linux it will actually appear on the left. The code itself takes care of this automatically. Or is it that when we have a destructive action it is supposed to be to the right of the Cancel button even on Windows?

@avvvvve
Copy link

avvvvve commented Dec 12, 2024

On Mac, the Cancel is showing up on the right (see screenshot), so something must be up with the auto-handling of that ordering. Fine to leave it like that for Windows then, but on Mac it should stick to the Mac defaults. I think "Reset" should still be the accented button on both OSs though.

image

@cbjeukendrup
Copy link
Contributor

cbjeukendrup commented Dec 13, 2024

The code added by this PR looks fine in itself, but the order needs to be fixed in buttonboxmodel.h. Looks like we should move RejectRole almost to the front of the list, for macOS (and I guess Linux too), like this:

        // MacLayout
        std::vector <ButtonRole> { CustomRole, HelpRole, RejectRole, ResetRole, RetryRole, DestructiveRole, BackRole, AcceptRole,
                                   ApplyRole, ContinueRole },

Would be good to make sure that this has no undesired effects on other dialogs.

(FWIW, this is what Apple says about the topic: https://developer.apple.com/design/human-interface-guidelines/alerts#Buttons
So, Cancel should indeed always be on the left; they advise against making Cancel the default button, and suggest having no default at all for destructive dialogs. But we don't necessarily need to follow that of course.)

@krasko78
Copy link
Contributor Author

@avvvvve @cbjeukendrup Ah, yeah, I didn't check the button layouts in the code and automatically assumed they would be correct. I do not feel like moving RejectRole that much to the left of the list because as Casper said this would require review of the other dialogs which goes out of the scope of this PR. Instead I could give the Reset button either the ApplyRole (in fact this is what "Revert to factory settings" uses) or the ContinueRole. Another possibility is to see where the ResetRole is used and if it can be moved to the right of RejectRole.

@krasko78
Copy link
Contributor Author

I am closing this PR in favor of PR 25872 due to inability to rebase. apologies for any inconvenience.

@krasko78 krasko78 closed this Dec 17, 2024
@krasko78 krasko78 deleted the 11565-ConfirmationDialogForResetPreferencesAndFixes branch December 19, 2024 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[MU4 Issue] "Reset preferences" doesn't reset all preferences (e.g. advanced), no confirmation
4 participants