27#include <wx/listbox.h>
29#include <wx/listbook.h>
31#include <wx/treebook.h>
32#include <wx/treectrl.h>
38#include "../commands/CommandManager.h"
44#if wxUSE_ACCESSIBILITY
49#if wxUSE_ACCESSIBILITY
60 template<
typename Result,
typename Fn >
64 std::vector< wxTreeItemId > stack;
65 stack.push_back( ctrl.GetRootItem() );
66 unsigned position = 0;
67 while ( !stack.empty() ) {
68 auto itemId = stack.back();
69 auto pair =
fn( itemId, position );
73 wxTreeItemIdValue cookie;
74 auto childId = ctrl.GetFirstChild( itemId, cookie );
76 stack.push_back( childId );
78 auto &
id = stack.back();
79 if ( !!(
id = ctrl.GetNextSibling(
id ) ) )
81 }
while ( stack.pop_back(), !stack.empty() );
88 unsigned FindItemPosition(
const wxTreeCtrl &ctrl, wxTreeItemId
id )
93 return VisitItems<unsigned>( ctrl,
94 [=]( wxTreeItemId itemId,
unsigned position ){
95 return std::make_pair( itemId ==
id, position ); } );
98 wxTreeItemId FindItem(
const wxTreeCtrl &ctrl,
int nn )
101 return VisitItems<wxTreeItemId>( ctrl,
102 [=]( wxTreeItemId itemId,
unsigned position ){
103 return std::make_pair( nn == position, itemId ); } );
108class TreeCtrlAx final
112 TreeCtrlAx(wxTreeCtrl * ctrl);
113 virtual ~ TreeCtrlAx();
115 wxAccStatus GetChild(
int childId, wxAccessible** child)
override;
117 wxAccStatus GetChildCount(
int* childCount)
override;
119 wxAccStatus GetDefaultAction(
int childId, wxString *actionName)
override;
122 wxAccStatus GetDescription(
int childId, wxString *description)
override;
128 wxAccStatus GetFocus(
int *childId, wxAccessible **child)
override;
131 wxAccStatus GetHelpText(
int childId, wxString *helpText)
override;
135 wxAccStatus GetKeyboardShortcut(
int childId, wxString *shortcut)
override;
139 wxAccStatus GetLocation(wxRect& rect,
int elementId)
override;
142 wxAccStatus GetName(
int childId, wxString *
name)
override;
145 wxAccStatus GetRole(
int childId, wxAccRole *role)
override;
159 wxAccStatus GetState(
int childId,
long* state)
override;
163 wxAccStatus GetValue(
int childId, wxString* strValue)
override;
169 wxAccStatus Select(
int childId, wxAccSelectionFlags selectFlags)
override;
172 wxTreeCtrl *GetCtrl() {
return static_cast<wxTreeCtrl*
>( GetWindow() ); }
175TreeCtrlAx::TreeCtrlAx( wxTreeCtrl *ctrl )
180TreeCtrlAx::~TreeCtrlAx() =
default;
182wxAccStatus TreeCtrlAx::GetChild(
int childId, wxAccessible** child )
184 if( childId == wxACC_SELF )
196wxAccStatus TreeCtrlAx::GetChildCount(
int* childCount)
198 auto ctrl = GetCtrl();
202 *childCount = ctrl->GetCount();
206wxAccStatus TreeCtrlAx::GetDefaultAction(
int WXUNUSED(childId), wxString* actionName)
214wxAccStatus TreeCtrlAx::GetDescription(
int WXUNUSED(childId), wxString *description )
216 description->clear();
224wxAccStatus TreeCtrlAx::GetFocus(
int *childId, wxAccessible **child )
226 auto ctrl = GetCtrl();
230 auto item = ctrl->GetFocusedItem();
231 auto id = FindItemPosition( *ctrl, item );
238wxAccStatus TreeCtrlAx::GetHelpText(
int WXUNUSED(childId), wxString *helpText )
247wxAccStatus TreeCtrlAx::GetKeyboardShortcut(
int WXUNUSED(childId), wxString *shortcut )
254wxAccStatus TreeCtrlAx::GetLocation( wxRect& rect,
int elementId )
256 auto ctrl = GetCtrl();
260 if (elementId == wxACC_SELF)
261 rect = ctrl->GetRect();
263 auto item = FindItem( *ctrl, elementId );
264 if ( !( item && ctrl->GetBoundingRect( item, rect ) ) )
265 return wxACC_INVALID_ARG;
267 rect.SetPosition( ctrl->GetParent()->ClientToScreen( rect.GetPosition() ) );
271wxAccStatus TreeCtrlAx::GetName(
int childId, wxString*
name)
273 if ( childId == wxACC_SELF )
274 return WindowAccessible::GetName( childId,
name );
276 auto ctrl = GetCtrl();
280 auto item = FindItem( *ctrl, childId );
282 *
name = ctrl->GetItemText( item );
286 return wxACC_INVALID_ARG;
290wxAccStatus TreeCtrlAx::GetRole(
int childId, wxAccRole* role )
295 childId == wxACC_SELF ? wxROLE_SYSTEM_PANE : wxROLE_SYSTEM_STATICTEXT;
300wxAccStatus TreeCtrlAx::GetState(
int childId,
long* state)
302 auto ctrl = GetCtrl();
306 *state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
308 if ( childId != wxACC_SELF ) {
309 auto item = FindItem( *ctrl, childId );
311 if( item == ctrl->GetFocusedItem() )
312 *state |= wxACC_STATE_SYSTEM_FOCUSED;
314 if( item == ctrl->GetSelection() )
315 *state |= wxACC_STATE_SYSTEM_SELECTED;
324wxAccStatus TreeCtrlAx::GetValue(
int childId, wxString* strValue)
326 *strValue = wxString{};
337wxAccStatus TreeCtrlAx::Select(
int childId, wxAccSelectionFlags selectFlags)
339 auto ctrl = GetCtrl();
343 if (childId != wxACC_SELF) {
345 GetChildCount( &childCount );
346 if (childId > childCount)
349 auto item = FindItem( *ctrl, childId );
351 if (selectFlags == wxACC_SEL_TAKEFOCUS)
352 ctrl->SetFocusedItem( item );
353 else if (selectFlags == wxACC_SEL_TAKESELECTION)
354 ctrl->SelectItem( item );
356 return wxACC_NOT_IMPLEMENTED;
361 return wxACC_NOT_IMPLEMENTED;
381 wxTreebookExt( wxWindow *parent,
384 , mTitlePrefix(titlePrefix)
387 int ChangeSelection(
size_t n)
override;
388 int SetSelection(
size_t n)
override;
393int wxTreebookExt::ChangeSelection(
size_t n) {
394 int i = wxTreebook::ChangeSelection(n);
395 wxString Temp = GetPageText( n );
396 static_cast<wxDialog*
>(GetParent())->SetTitle( Temp );
397 static_cast<wxDialog*
>(GetParent())->SetName( Temp );
401int wxTreebookExt::SetSelection(
size_t n)
403 int i = wxTreebook::SetSelection(n);
404 auto Temp = mTitlePrefix.Translation() +
wxT(
" ") + GetPageText( n );
405 static_cast<wxDialog*
>(GetParent())->SetTitle( Temp );
406 static_cast<wxDialog*
>(GetParent())->SetName( Temp );
411 wxWindow *
const helpButton = wxWindow::FindWindowById(wxID_HELP, GetParent());
412 wxWindow *
const previewButton = wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
417#if defined(__WXMAC__)
420 entries[0].Set(wxACCEL_NORMAL, (
int) WXK_F1, wxID_HELP);
422 wxAcceleratorTable accel(1,
entries);
423 this->SetAcceleratorTable(accel);
426 this->SetAcceleratorTable(wxNullAcceleratorTable);
429 const bool changed = helpButton->Show(showHelp);
431 GetParent()->Layout();
435 const bool changed = previewButton->Show(showPreview);
437 GetParent()->Layout();
450 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
451, mFactories(factories)
452, mTitlePrefix(titlePrefix)
454 wxASSERT(factories.size() > 0);
455 const bool uniquePage = (factories.size() == 1);
456 SetLayoutDirection(wxLayout_LeftToRight);
460 S.StartVerticalLay(
true);
462 wxASSERT(factories.size() > 0);
465#if wxUSE_ACCESSIBILITY
472 S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND,
true);
479 typedef std::pair<int, int> IntPair;
480 std::vector<IntPair> stack;
482 for (
auto it = factories.begin(),
end = factories.end();
483 it !=
end; ++it, ++iPage)
485 const auto &node = *it;
486 const auto &
factory = node.factory;
488 node.enabled = (w !=
nullptr);
495 IntPair &top = *stack.rbegin();
498 w, w->GetName(),
false, 0);
499 if (--top.second == 0) {
505 if (node.nChildren > 0)
506 stack.push_back(IntPair(iPage, node.nChildren));
510 S.EndHorizontalLay();
518 const auto &node = factories[0];
519 const auto &
factory = node.factory;
523 wxWindow * uniquePageWindow =
S.Prop(1)
528#if defined(__WXMAC__)
531 entries[0].Set(wxACCEL_NORMAL, (
int) WXK_F1, wxID_HELP);
533 wxAcceleratorTable accel(1,
entries);
534 uniquePageWindow->SetAcceleratorTable(accel);
543 wxWindow *
const previewButton =
544 wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
545 previewButton->Show(
false);
548#if defined(__WXGTK__)
556 wxSize sz = GetSize();
562 for (
auto it = factories.begin(),
end = factories.end();
576 wxRect screenRect(wxGetClientDisplayRect());
577 wxASSERT_MSG(sz.x <= screenRect.width && sz.y <= screenRect.height,
wxT(
"Preferences dialog exceeds max size"));
579 sz.DecTo(screenRect.GetSize());
582 int prefWidth, prefHeight;
583 gPrefs->Read(
wxT(
"/Prefs/Width"), &prefWidth, sz.x);
584 gPrefs->Read(
wxT(
"/Prefs/Height"), &prefHeight, wxMax(480,sz.y));
586 wxSize prefSize = wxSize(prefWidth, prefHeight);
587 prefSize.DecTo(screenRect.GetSize());
589 InvalidateBestSize();
598 mTransaction = std::make_unique< SettingTransaction >();
614 if (selected < 0 ||
size_t(selected) >=
mCategories->GetPageCount())
625 return wxDialogWrapper::ShowModal();
633 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
642 wxSize sz = GetSize();
643 gPrefs->Write(
wxT(
"/Prefs/Width"), sz.x);
644 gPrefs->Write(
wxT(
"/Prefs/Height"), sz.y);
668 const auto &page = pPanel->HelpPageName();
677 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
693 if(event.GetKeyCode() == WXK_RETURN)
705 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
709 if (!panel->Validate()) {
726 for (
int i = (
int)
mCategories->GetPageCount()-1; i>= 0; i--) {
739 wxSize sz = GetSize();
740 gPrefs->Write(
wxT(
"/Prefs/Width"), sz.x);
741 gPrefs->Write(
wxT(
"/Prefs/Height"), sz.y);
763 if (gAudioIO->IsMonitoring())
765 gAudioIO->StopStream();
766 while (gAudioIO->IsBusy()) {
767 using namespace std::chrono;
768 std::this_thread::sleep_for(100ms);
771 gAudioIO->HandleDeviceChange();
797 for (
size_t i = 0; i < n; i++) {
822 :
PrefsDialog(parent, pProject,
XO(
"Preferences:"), factories)
832 long prefscat =
gPrefs->Read(
wxT(
"/Prefs/PrefsCategory"), 0L);
851 it->expanded =
mCategories->IsNodeExpanded(iPage++);
880#if defined(__WXGTK__)
888 wxRect r = window.GetRect();
889 window.SetSize(wxSize(1,1));
890 window.SetSize(r.GetSize());
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
void DoReloadPreferences(AudacityProject &project)
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
GlobalPrefsDialog(wxWindow *parent, AudacityProject *pProject, PrefsPanel::Factories &factories=PrefsPanel::DefaultFactories())
virtual ~GlobalPrefsDialog()
void SavePreferredPage() override
long GetPreferredPage() override
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Dialog that shows the current PrefsPanel in a tabbed divider.
void OnPreview(wxCommandEvent &e)
void ShuttleAll(ShuttleGui &S)
void RecordExpansionState()
void OnHelp(wxCommandEvent &e)
int GetSelectedPage() const
const TranslatableString mTitlePrefix
PrefsPanel * GetCurrentPanel()
void OnTreeKeyDown(wxTreeEvent &e)
void OnCancel(wxCommandEvent &e)
virtual void SavePreferredPage()=0
std::unique_ptr< SettingTransaction > mTransaction
PrefsDialog(wxWindow *parent, AudacityProject *pProject, const TranslatableString &titlePrefix=XO("Preferences:"), PrefsPanel::Factories &factories=PrefsPanel::DefaultFactories())
virtual long GetPreferredPage()=0
void OnOK(wxCommandEvent &e)
void SelectPageByName(const wxString &pageName)
PrefsPanel::Factories & mFactories
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
Base class for a panel in the PrefsDialog. Classes derived from this class include BatchPrefs,...
virtual ManualPageID HelpPageName()
If not empty string, the Help button is added below the panel.
virtual bool ShowsPreviewButton()
virtual void PopulateOrExchange(ShuttleGui &WXUNUSED(S))
std::vector< PrefsPanel::PrefsNode > Factories
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Holds a msgid for the translation catalog; may also bind format arguments.
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void SetTitle(const TranslatableString &title)
A wxTreebook is a class like wxNotebook, but not yet supported by wxWidgets 2.6.3.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
void VisitItems(Registry::Visitor &visitor, CollectedItems &collection, Path &path, GroupItemBase *pGroup, const GroupItemBase *pToMerge, const OrderingHint &hint, bool &doFlush)
static RegisteredToolbarFactory factory
static void ReinitializeAll()