Audacity  3.0.3
JournalWindowPaths.cpp
Go to the documentation of this file.
1 /*!********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  @file JournalWindowPaths.cpp
6 
7  Paul Licameli
8 
9 *********************************************************************/
10 
11 #include "JournalWindowPaths.h"
12 
13 #include <wx/stattext.h>
14 #include <wx/toplevel.h>
15 #include "Identifier.h"
16 #include "Theme.h"
17 #include "wxArrayStringEx.h"
18 #include "widgets/auStaticText.h"
19 
20 
21 namespace Journal {
22 
23 namespace WindowPaths {
24 
25 namespace {
26 
27 constexpr auto PathSeparator = ':';
28 constexpr auto EscapeCharacter = '\\';
29 
33 inline auto HasName( const wxString &name )
34 {
35  return [name](const wxWindow *pWindow2){
36  return pWindow2 &&
37  // Ignore wxStaticText windows, which ShuttleGui may assign the same
38  // name as the related control. Those windows are non-interactive so
39  // don't interest us for journalling.
40  !dynamic_cast<const wxStaticText *>( pWindow2 ) &&
41  // Also excluse this special window type defined in Audacity.
42  !dynamic_cast<const auStaticText *>( pWindow2 ) &&
43  pWindow2->GetName() == name; };
44 }
45 
49 inline auto SameName( const wxWindow &window )
50 {
51  return HasName( window.GetName() );
52 }
53 
55 template< typename Pred >
57  const wxWindowList &list, const Pred &pred )
58 {
59  const auto begin = list.begin(), end = list.end();
60  auto iter1 = std::find_if(begin, end, pred);
61  if (iter1 == end)
62  return nullptr;
63  auto next = iter1, iter2 = std::find_if(++next, end, pred);
64  if (iter2 != end)
65  return nullptr;
66  return *iter1;
67 }
68 
70 bool HasUniqueNameAmongPeers( const wxWindow &window, const wxWindowList &list )
71 {
72  return &window == UniqueWindowAmongPeers(list, SameName(window));
73 }
74 
75 // Find the unique window in the list for the given name, if there is such
77  const wxString &name, const wxWindowList &list )
78 {
79  return UniqueWindowAmongPeers(list, HasName(name));
80 }
81 
82 // Find array of window names, starting with a top-level window and ending
83 // with the given window, or an empty array if the conditions fail for
84 // uniqueness of names.
85 void PathComponents( const wxWindow &window, wxArrayStringEx &components )
86 {
87  if ( dynamic_cast<const wxTopLevelWindow*>( &window ) ) {
88  if ( HasUniqueNameAmongPeers( window, wxTopLevelWindows ) ) {
89  components.push_back( window.GetName() );
90  return;
91  }
92  }
93  else if ( auto pParent = window.GetParent() ) {
94  // Recur
95  PathComponents( *pParent, components );
96  if ( !components.empty() &&
97  HasUniqueNameAmongPeers( window, pParent->GetChildren() ) ) {
98  components.push_back( window.GetName() );
99  return;
100  }
101  }
102 
103  // Failure
104  components.clear();
105 }
106 
107 }
108 
109 Path FindPath( const wxWindow &window )
110 {
111  wxArrayStringEx components;
112  PathComponents( window, components );
113  return wxJoin( components, PathSeparator, EscapeCharacter );
114 }
115 
116 wxWindow *FindByPath( const Path &path )
117 {
118  auto components = wxSplit( path.GET(), PathSeparator, EscapeCharacter );
119  if ( !components.empty() ) {
120  auto iter = components.begin(), end = components.end();
121  auto pWindow = FindByNameAmongPeers( *iter++, wxTopLevelWindows );
122  while ( pWindow && iter != end )
123  pWindow = FindByNameAmongPeers( *iter++, pWindow->GetChildren() );
124  return pWindow;
125  }
126  return nullptr;
127 }
128 
129 }
130 
131 }
Journal
Facilities for recording and playback of sequences of user interaction.
Journal::WindowPaths::FindByPath
wxWindow * FindByPath(const Path &path)
Definition: JournalWindowPaths.cpp:116
Journal::WindowPaths::FindPath
Path FindPath(const wxWindow &window)
Definition: JournalWindowPaths.cpp:109
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::UniqueWindowAmongPeers
wxWindow * UniqueWindowAmongPeers(const wxWindowList &list, const Pred &pred)
Definition: JournalWindowPaths.cpp:56
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::HasName
auto HasName(const wxString &name)
Definition: JournalWindowPaths.cpp:33
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::HasUniqueNameAmongPeers
bool HasUniqueNameAmongPeers(const wxWindow &window, const wxWindowList &list)
Definition: JournalWindowPaths.cpp:70
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
Identifier
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
Theme.h
name
const TranslatableString name
Definition: Distortion.cpp:98
Identifier.h
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::FindByNameAmongPeers
wxWindow * FindByNameAmongPeers(const wxString &name, const wxWindowList &list)
Definition: JournalWindowPaths.cpp:76
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::SameName
auto SameName(const wxWindow &window)
Definition: JournalWindowPaths.cpp:49
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::PathSeparator
constexpr auto PathSeparator
Definition: JournalWindowPaths.cpp:27
Identifier::GET
const wxString & GET() const
Explicit conversion to wxString, meant to be ugly-looking and demanding of a comment why it's correct...
Definition: Identifier.h:66
wxArrayStringEx.h
auStaticText
is like wxStaticText, except it can be themed. wxStaticText can't be.
Definition: auStaticText.h:20
Journal::WindowPaths::anonymous_namespace{JournalWindowPaths.cpp}::PathComponents
void PathComponents(const wxWindow &window, wxArrayStringEx &components)
Definition: JournalWindowPaths.cpp:85
Journal::EscapeCharacter
constexpr auto EscapeCharacter
Definition: JournalOutput.h:23
auStaticText.h
JournalWindowPaths.h