diff --git a/src/Internat.cpp b/src/Internat.cpp index 5d91b48bf..48efbbfbf 100644 --- a/src/Internat.cpp +++ b/src/Internat.cpp @@ -298,12 +298,3 @@ wxString Internat::StripAccelerators(const wxString &s) } return result; } - -wxString Internat::Parenthesize(const wxString &str) -{ - /* i18n-hint: An opening parenthesis, in some languages a right parenthesis */ - auto open = _("("); - /* i18n-hint: A closing parenthesis, in some languages a left parenthesis */ - auto close = _(")"); - return open + str + close; -} diff --git a/src/Internat.h b/src/Internat.h index 6cb005010..e6c2e2a9a 100644 --- a/src/Internat.h +++ b/src/Internat.h @@ -76,8 +76,6 @@ public: * when they aren't, saving translators effort. */ static wxString StripAccelerators(const wxString& str); - static wxString Parenthesize(const wxString &str); - static const wxArrayString &GetExcludedCharacters() { return exclude; } diff --git a/src/commands/CommandManager.cpp b/src/commands/CommandManager.cpp index 1924d89e5..b1bd2b298 100644 --- a/src/commands/CommandManager.cpp +++ b/src/commands/CommandManager.cpp @@ -1287,24 +1287,51 @@ void CommandManager::TellUserWhyDisallowed( const wxString & Name, CommandFlag f } wxString CommandManager::DescribeCommandsAndShortcuts -(const std::vector &commands, const wxString &separator) const +(const std::vector &commands) const { + wxString mark; + // This depends on the language setting and may change in-session after + // change of preferences: + bool rtl = (wxLayout_RightToLeft == wxTheApp->GetLayoutDirection()); + if (rtl) + mark = wxT("\u200f"); + + static const wxString &separatorFormat = wxT("%s / %s"); wxString result; auto iter = commands.begin(), end = commands.end(); while (iter != end) { - result += *iter++; + // If RTL, then the control character forces right-to-left sequencing of + // "/" -separated command names, and puts any "(...)" shortcuts to the + // left, consistently with accelerators in menus (assuming matching + // operating system prefernces for language), even if the command name + // was missing from the translation file and defaulted to the English. + auto piece = wxString::Format(wxT("%s%s"), mark, *iter++); + if (iter != end) { if (!iter->empty()) { auto keyStr = GetKeyFromName(*iter); if (!keyStr.empty()){ - result += wxT(" "); - result += Internat::Parenthesize(KeyStringDisplay(keyStr, true)); + auto keyString = KeyStringDisplay(keyStr, true); + auto format = wxT("%s %s(%s)"); +#ifdef __WXMAC__ + // The unicode controls push and pop left-to-right embedding. + // This keeps the directionally weak characters, such as uparrow + // for Shift, left of the key name, + // consistently with how menu accelerators appear, even when the + // system language is RTL. + format = wxT("%s %s(\u202a%s\u202c)"); +#endif + // The mark makes correctly placed parentheses for RTL, even + // in the case that the piece is untranslated. + piece = wxString::Format(format, piece, mark, keyString); } } ++iter; } - if (iter != end) - result += separator; + if (result.empty()) + result = piece; + else + result = wxString::Format(separatorFormat, result, piece); } return result; } diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index c6e0579a7..0b3fad11d 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -270,9 +270,7 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler // non-user-visible command names. If a shortcut key is defined // for the command, then it is appended, parenthesized, after the // user-visible string. - const std::vector &commands, - // If more than one pair of strings is given, then use this separator. - const wxString &separator = wxT(" / ")) const; + const std::vector &commands) const; protected: diff --git a/src/toolbars/ToolBar.cpp b/src/toolbars/ToolBar.cpp index 38bd0612b..d34babd62 100644 --- a/src/toolbars/ToolBar.cpp +++ b/src/toolbars/ToolBar.cpp @@ -832,7 +832,7 @@ void ToolBar::MakeAlternateImages(AButton &button, int idx, } void ToolBar::SetButtonToolTip -(AButton &button, const std::vector &commands, const wxString &separator) +(AButton &button, const std::vector &commands) { wxString result; const auto project = GetActiveProject(); @@ -840,7 +840,7 @@ void ToolBar::SetButtonToolTip project ? project->GetCommandManager() : nullptr; if (commandManager) result = - commandManager->DescribeCommandsAndShortcuts(commands, separator); + commandManager->DescribeCommandsAndShortcuts(commands); button.SetToolTip(result); } diff --git a/src/toolbars/ToolBar.h b/src/toolbars/ToolBar.h index 79ace9a3b..ba6cd5bcd 100644 --- a/src/toolbars/ToolBar.h +++ b/src/toolbars/ToolBar.h @@ -161,9 +161,7 @@ class ToolBar /* not final */ : public wxPanelWrapper // non-user-visible command names. If a shortcut key is defined // for the command, then it is appended, parenthesized, after the // user-visible string. - const std::vector &commands, - // If more than one pair of strings is given, then use this separator. - const wxString &separator = wxT(" / ")); + const std::vector &commands); protected: void SetButton(bool down, AButton *button);