diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index 720cb5fd6..d2b7bfd9d 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -200,44 +200,38 @@ void ControlToolBar::Populate() void ControlToolBar::RegenerateToolsTooltips() { #if wxUSE_TOOLTIPS + std::vector commands; for (long iWinID = ID_PLAY_BUTTON; iWinID < BUTTON_COUNT; iWinID++) { - wxWindow* pCtrl = this->FindWindow(iWinID); - wxString strToolTip = pCtrl->GetLabel(); - AudacityProject* pProj = GetActiveProject(); - CommandManager* pCmdMgr = (pProj) ? pProj->GetCommandManager() : NULL; - if (pCmdMgr) + commands.clear(); + auto pCtrl = static_cast(this->FindWindow(iWinID)); + commands.push_back(pCtrl->GetLabel()); + switch (iWinID) { - wxString strKey(wxT(" (")); - switch (iWinID) - { - case ID_PLAY_BUTTON: - strKey += pCmdMgr->GetKeyFromName(wxT("Play")); - strKey += _(") / Loop Play ("); - strKey += pCmdMgr->GetKeyFromName(wxT("PlayLooped")); - break; - case ID_RECORD_BUTTON: - strKey += pCmdMgr->GetKeyFromName(wxT("Record")); - strKey += _(") / Append Record ("); - strKey += pCmdMgr->GetKeyFromName(wxT("RecordAppend")); - break; - case ID_PAUSE_BUTTON: - strKey += pCmdMgr->GetKeyFromName(wxT("Pause")); - break; - case ID_STOP_BUTTON: - strKey += pCmdMgr->GetKeyFromName(wxT("Stop")); - break; - case ID_FF_BUTTON: - strKey += pCmdMgr->GetKeyFromName(wxT("SkipEnd")); - break; - case ID_REW_BUTTON: - strKey += pCmdMgr->GetKeyFromName(wxT("SkipStart")); - break; - } - strKey += wxT(")"); - strToolTip += strKey; + case ID_PLAY_BUTTON: + commands.push_back(wxT("Play")); + commands.push_back(_("Loop Play")); + commands.push_back(wxT("PlayLooped")); + break; + case ID_RECORD_BUTTON: + commands.push_back(wxT("Record")); + commands.push_back(_("Append Record")); + commands.push_back(wxT("RecordAppend")); + break; + case ID_PAUSE_BUTTON: + commands.push_back(wxT("Pause")); + break; + case ID_STOP_BUTTON: + commands.push_back(wxT("Stop")); + break; + case ID_FF_BUTTON: + commands.push_back(wxT("SkipEnd")); + break; + case ID_REW_BUTTON: + commands.push_back(wxT("SkipStart")); + break; } - pCtrl->SetToolTip(strToolTip); + ToolBar::SetButtonToolTip(*pCtrl, commands); } #endif } diff --git a/src/toolbars/ToolBar.cpp b/src/toolbars/ToolBar.cpp index 433d7c851..b949dcfd6 100644 --- a/src/toolbars/ToolBar.cpp +++ b/src/toolbars/ToolBar.cpp @@ -48,6 +48,7 @@ in which buttons can be placed. #include "../ImageManipulation.h" #include "../Project.h" #include "../Theme.h" +#include "../commands/Keyboard.h" #include "../widgets/AButton.h" #include "../widgets/Grabber.h" @@ -761,6 +762,33 @@ void ToolBar::MakeAlternateImages(AButton &button, int idx, button.SetAlternateImages(idx, *up, *hilite, *down, *disable); } +void ToolBar::SetButtonToolTip +(AButton &button, const std::vector &commands, const wxString &separator) +{ + const auto project = GetActiveProject(); + const auto commandManager = project ? project->GetCommandManager() : nullptr; + wxString result; + auto iter = commands.begin(), end = commands.end(); + while (iter != end) { + result += *iter++; + if (iter != end) { + if (!iter->empty()) { + if (commandManager) { + auto keyStr = commandManager->GetKeyFromName(*iter); + if (keyStr.empty()) + keyStr = _("no key"); + result += wxT(" "); + result += Internat::Parenthesize(KeyStringDisplay(keyStr, true)); + } + } + ++iter; + } + if (iter != end) + result += separator; + } + button.SetToolTip(result); +} + // // This changes the state a button (from up to down or vice versa) // diff --git a/src/toolbars/ToolBar.h b/src/toolbars/ToolBar.h index 1e6d28575..2392bc675 100644 --- a/src/toolbars/ToolBar.h +++ b/src/toolbars/ToolBar.h @@ -15,6 +15,7 @@ #include "../Experimental.h" +#include #include #include #include @@ -149,7 +150,18 @@ class ToolBar /* not final */ : public wxPanel teBmps eStandardDown, teBmps eDisabled, wxSize size); - + + static + void SetButtonToolTip + (AButton &button, + // An array, alternating user-visible strings, and + // 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(" / ")); + protected: void SetButton(bool down, AButton *button);