| 151 | } }; |
| 152 | |
| 153 | void ReplayPopup( wxMenu *theMenu ) |
| 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 | } |
| 206 | |
| 207 | } |
| 208 |
no test coverage detected