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