The rounded corners look really dumb at this size.
[wxWidgets.git] / src / generic / accel.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/accel.cpp
3 // Purpose: generic implementation of wxAcceleratorTable class
4 // Author: Robert Roebling
5 // Modified: VZ pn 31.05.01: use typed lists, Unicode cleanup, Add/Remove
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_ACCEL
26
27 #ifndef WX_PRECOMP
28 #include "wx/list.h"
29 #include "wx/event.h"
30 #endif // WX_PRECOMP
31
32 #include "wx/accel.h"
33
34 #include <ctype.h>
35
36 // ----------------------------------------------------------------------------
37 // wxAccelList: a list of wxAcceleratorEntries
38 // ----------------------------------------------------------------------------
39
40 WX_DECLARE_LIST(wxAcceleratorEntry, wxAccelList);
41 #include "wx/listimpl.cpp"
42 WX_DEFINE_LIST(wxAccelList)
43
44 // ----------------------------------------------------------------------------
45 // wxAccelRefData: the data used by wxAcceleratorTable
46 // ----------------------------------------------------------------------------
47
48 class wxAccelRefData : public wxObjectRefData
49 {
50 public:
51 wxAccelRefData()
52 {
53 }
54
55 wxAccelRefData(const wxAccelRefData& data)
56 : wxObjectRefData()
57 {
58 m_accels = data.m_accels;
59 }
60
61 virtual ~wxAccelRefData()
62 {
63 WX_CLEAR_LIST(wxAccelList, m_accels);
64 }
65
66 wxAccelList m_accels;
67 };
68
69 // macro which can be used to access wxAccelRefData from wxAcceleratorTable
70 #define M_ACCELDATA ((wxAccelRefData *)m_refData)
71
72
73 // ============================================================================
74 // implementation
75 // ============================================================================
76
77 // ----------------------------------------------------------------------------
78 // wxAcceleratorTable ctors
79 // ----------------------------------------------------------------------------
80
81 IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject)
82
83 wxAcceleratorTable::wxAcceleratorTable()
84 {
85 }
86
87 wxAcceleratorTable::wxAcceleratorTable(int n, const wxAcceleratorEntry entries[])
88 {
89 m_refData = new wxAccelRefData;
90
91 for ( int i = 0; i < n; i++ )
92 {
93 const wxAcceleratorEntry& entry = entries[i];
94
95 int keycode = entry.GetKeyCode();
96 if ( wxIsascii(keycode) )
97 keycode = wxToupper(keycode);
98
99 M_ACCELDATA->m_accels.Append(new wxAcceleratorEntry(entry.GetFlags(),
100 keycode,
101 entry.GetCommand()));
102 }
103 }
104
105 wxAcceleratorTable::~wxAcceleratorTable()
106 {
107 }
108
109 bool wxAcceleratorTable::IsOk() const
110 {
111 return m_refData != NULL;
112 }
113
114 // ----------------------------------------------------------------------------
115 // wxAcceleratorTable updating
116 // ----------------------------------------------------------------------------
117
118 void wxAcceleratorTable::Add(const wxAcceleratorEntry& entry)
119 {
120 AllocExclusive();
121
122 if ( !m_refData )
123 {
124 m_refData = new wxAccelRefData;
125 }
126
127 M_ACCELDATA->m_accels.Append(new wxAcceleratorEntry(entry));
128 }
129
130 void wxAcceleratorTable::Remove(const wxAcceleratorEntry& entry)
131 {
132 AllocExclusive();
133
134 wxAccelList::compatibility_iterator node = M_ACCELDATA->m_accels.GetFirst();
135 while ( node )
136 {
137 const wxAcceleratorEntry *entryCur = node->GetData();
138
139 // given entry contains only the information of the accelerator key
140 // because it was set that way during creation so do not use the
141 // comparison operator which also checks the command field
142 if ((entryCur->GetKeyCode() == entry.GetKeyCode()) &&
143 (entryCur->GetFlags() == entry.GetFlags()))
144 {
145 delete node->GetData();
146 M_ACCELDATA->m_accels.Erase(node);
147
148 return;
149 }
150
151 node = node->GetNext();
152 }
153
154 wxFAIL_MSG(wxT("deleting inexistent accel from wxAcceleratorTable"));
155 }
156
157 // ----------------------------------------------------------------------------
158 // wxAcceleratorTable: find a command for the given key press
159 // ----------------------------------------------------------------------------
160
161 const wxAcceleratorEntry *
162 wxAcceleratorTable::GetEntry(const wxKeyEvent& event) const
163 {
164 if ( !IsOk() )
165 {
166 // not an error, the accel table is just empty
167 return NULL;
168 }
169
170 wxAccelList::compatibility_iterator node = M_ACCELDATA->m_accels.GetFirst();
171 while ( node )
172 {
173 const wxAcceleratorEntry *entry = node->GetData();
174
175 // is the key the same?
176 if ( event.m_keyCode == entry->GetKeyCode() )
177 {
178 int flags = entry->GetFlags();
179
180 // now check flags
181 if ( (((flags & wxACCEL_CTRL) != 0) == event.ControlDown()) &&
182 (((flags & wxACCEL_SHIFT) != 0) == event.ShiftDown()) &&
183 (((flags & wxACCEL_ALT) != 0) == event.AltDown()) )
184 {
185 return entry;
186 }
187 }
188
189 node = node->GetNext();
190 }
191
192 return NULL;
193 }
194
195 wxMenuItem *wxAcceleratorTable::GetMenuItem(const wxKeyEvent& event) const
196 {
197 const wxAcceleratorEntry *entry = GetEntry(event);
198
199 return entry ? entry->GetMenuItem() : NULL;
200 }
201
202 int wxAcceleratorTable::GetCommand(const wxKeyEvent& event) const
203 {
204 const wxAcceleratorEntry *entry = GetEntry(event);
205
206 return entry ? entry->GetCommand() : -1;
207 }
208
209 wxObjectRefData *wxAcceleratorTable::CreateRefData() const
210 {
211 return new wxAccelRefData;
212 }
213
214 wxObjectRefData *wxAcceleratorTable::CloneRefData(const wxObjectRefData *data) const
215 {
216 return new wxAccelRefData(*(wxAccelRefData *)data);
217 }
218
219 #endif // wxUSE_ACCEL