Audacity 3.2.0
Classes | Typedefs | Functions | Variables
BasicMenu::anonymous_namespace{BasicMenu.cpp} Namespace Reference

Classes

struct  Watcher
 Singleton object listens to global wxEvent stream. More...
 

Typedefs

using Menus = std::vector< wxWeakRef< wxMenu > >
 

Functions

Menus FindDescendants (wxMenu &menu)
 
bool ContainsMenu (const Menus &menus, void *pObj)
 
std::optional< wxArrayStringExFindPathName (wxMenu &theMenu, int id)
 
void Watch ()
 
void ReplayPopup (wxMenu *theMenu)
 

Variables

const auto JournalCode = L"PopupMenu"
 
std::vector< MenussMenuStack
 
bool sHandledEvent = false
 
Journal::RegisteredInitializer initializer
 

Typedef Documentation

◆ Menus

using BasicMenu::anonymous_namespace{BasicMenu.cpp}::Menus = typedef std::vector< wxWeakRef< wxMenu > >

Definition at line 31 of file BasicMenu.cpp.

Function Documentation

◆ ContainsMenu()

bool BasicMenu::anonymous_namespace{BasicMenu.cpp}::ContainsMenu ( const Menus menus,
void *  pObj 
)
inline

Definition at line 52 of file BasicMenu.cpp.

53{
54 return std::count( menus.begin(), menus.end(), pObj );
55}

Referenced by BasicMenu::anonymous_namespace{BasicMenu.cpp}::Watcher::FilterEvent().

Here is the caller graph for this function:

◆ FindDescendants()

Menus BasicMenu::anonymous_namespace{BasicMenu.cpp}::FindDescendants ( wxMenu &  menu)

Definition at line 37 of file BasicMenu.cpp.

38{
39 Menus result{ &menu };
40 // We can discover them breadth-first
41 for ( size_t ii = 0; ii < result.size(); ++ii ) {
42 if ( auto pMenu = result[ii] ) {
43 for ( const auto &pItem : pMenu->GetMenuItems() ) {
44 if ( const auto pSubMenu = pItem->GetSubMenu() )
45 result.push_back( pSubMenu );
46 }
47 }
48 }
49 return result;
50}
std::vector< wxWeakRef< wxMenu > > Menus
Definition: BasicMenu.cpp:31

Referenced by BasicMenu::Handle::Popup().

Here is the caller graph for this function:

◆ FindPathName()

std::optional< wxArrayStringEx > BasicMenu::anonymous_namespace{BasicMenu.cpp}::FindPathName ( wxMenu &  theMenu,
int  id 
)

Definition at line 59 of file BasicMenu.cpp.

60{
61 wxMenuItem *pItem = nullptr;
62 wxMenu *pSubMenu = nullptr;
63 if ( !( pItem = theMenu.FindItem( id, &pSubMenu ) ) )
64 return std::nullopt;
65
66 // Gather path components, checking uniqueness at each level
68 for ( ; pSubMenu; pSubMenu = pSubMenu->GetParent() ) {
69 const auto &items = pSubMenu->GetMenuItems();
70 const auto begin = items.begin(), end = items.end();
71 if ( !names.empty() ) {
72 // Update pItem on second and later passes
73 if ( const auto iter = std::find_if( begin, end,
74 [&]( auto pNewItem ){
75 return pNewItem->GetSubMenu() == pItem->GetMenu(); } );
76 iter == end )
77 return std::nullopt;
78 else
79 pItem = *iter;
80 }
81 auto name = pItem->GetItemLabelText();
82 if ( 1 != std::count_if( begin, end, [&](auto item){
83 return item->GetItemLabelText() == name; } ) )
84 // nonuniqueness
85 return std::nullopt;
86 names.push_back( name );
87 }
88 std::reverse( names.begin(), names.end() );
89 return { names };
90}
const TranslatableString name
Definition: Distortion.cpp:74
static TranslatableStrings names
Definition: TagsEditor.cpp:152
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150

References PackedArray::begin(), PackedArray::end(), name, and names.

Referenced by BasicMenu::anonymous_namespace{BasicMenu.cpp}::Watcher::FilterEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReplayPopup()

void BasicMenu::anonymous_namespace{BasicMenu.cpp}::ReplayPopup ( wxMenu *  theMenu)

Definition at line 153 of file BasicMenu.cpp.

154{
155 // Expect JournalCode and maybe a path.
156 const auto fields = Journal::GetTokens();
157 if ( fields[0] == JournalCode ) {
158 if ( fields.size() == 1)
159 // No command, so just eat the journal line
160 return;
161
162 // Locate the menu item by name in the current popup menu or descendant.
163 auto found = [&]() -> std::pair<wxMenuItem *, wxMenu*> {
164 wxMenuItem *pItem = nullptr;
165 auto pMenu = theMenu;
166 for ( auto pField = fields.begin() + 1, endFields = fields.end();
167 pMenu && pField != endFields; ++pField ) {
168 auto &name = *pField;
169 const auto &list = pMenu->GetMenuItems();
170 const auto pred = [&name](auto &pItem){
171 return pItem->GetItemLabelText() == name; };
172 const auto begin = list.begin(), end = list.end(),
173 iter = std::find_if(begin, end, pred);
174
175 // Check existence and uniqueness
176 if ( auto next = iter;
177 end == next || end != std::find_if(++next, end, pred) )
178 return { nullptr, nullptr };
179
180 pItem = *iter;
181 if ( pField + 1 != endFields )
182 pMenu = pItem->GetSubMenu();
183 }
184 return { pItem, pMenu };
185 }();
186
187 if ( auto [pItem, pMenu] = found; pItem && pMenu ) {
188 // Don't really pop up the menu, which uses native event handling
189 // that we can't filter. Simulate an event instead.
190 // Require that some event is bound to the item, so it is
191 // handled, or else the journal fails replay.
192 wxCommandEvent event{ wxEVT_MENU, pItem->GetId() };
193 event.SetEventObject( pMenu );
194 if ( pMenu->ProcessEvent( event ) ) {
195 sHandledEvent = true;
196 return;
197 }
198 }
199 }
200
201 // Replay did not find all as expected
202 throw Journal::SyncException(wxString::Format(
203 "PopupMenu has failed to invoke %s",
204 wxJoin(fields, ',').ToStdString().c_str()));
205}
wxArrayStringEx GetTokens()
Definition: Journal.cpp:281

References PackedArray::begin(), PackedArray::end(), Journal::GetTokens(), JournalCode, name, and sHandledEvent.

Referenced by BasicMenu::Handle::Popup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Watch()

void BasicMenu::anonymous_namespace{BasicMenu.cpp}::Watch ( )

Definition at line 137 of file BasicMenu.cpp.

138{
139 static Watcher instance;
140}
Singleton object listens to global wxEvent stream.
Definition: BasicMenu.cpp:94

Variable Documentation

◆ initializer

Journal::RegisteredInitializer BasicMenu::anonymous_namespace{BasicMenu.cpp}::initializer
Initial value:
{ []{
using namespace Journal;
if ( !GetError() && IsRecording() )
Watch();
return true;
} }
Facilities for recording and playback of sequences of user interaction.
bool IsRecording()
bool GetError()

Definition at line 143 of file BasicMenu.cpp.

◆ JournalCode

const auto BasicMenu::anonymous_namespace{BasicMenu.cpp}::JournalCode = L"PopupMenu"

◆ sHandledEvent

bool BasicMenu::anonymous_namespace{BasicMenu.cpp}::sHandledEvent = false

◆ sMenuStack

std::vector< Menus > BasicMenu::anonymous_namespace{BasicMenu.cpp}::sMenuStack