yet another file I added on the wxUniv branch and forgot to merge
[wxWidgets.git] / src / generic / accel.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #ifdef __GNUG__
20 #pragma implementation "accel.h"
21 #endif
22
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #if wxUSE_ACCEL
31
32 #ifndef WX_PRECOMP
33 #include "wx/event.h"
34 #include "wx/list.h"
35 #endif // WX_PRECOMP
36
37 #include "wx/accel.h"
38
39 #include <ctype.h>
40
41 // ----------------------------------------------------------------------------
42 // wxAccelList: a list of wxAcceleratorEntries
43 // ----------------------------------------------------------------------------
44
45 WX_DECLARE_LIST(wxAcceleratorEntry, wxAccelList);
46 #include "wx/listimpl.cpp"
47 WX_DEFINE_LIST(wxAccelList);
48
49 // ----------------------------------------------------------------------------
50 // wxAccelRefData: the data used by wxAcceleratorTable
51 // ----------------------------------------------------------------------------
52
53 class wxAccelRefData : public wxObjectRefData
54 {
55 public:
56 wxAccelRefData() { m_accels.DeleteContents(TRUE); }
57
58 wxAccelList m_accels;
59 };
60
61 // macro which can be used to access wxAccelRefData from wxAcceleratorTable
62 #define M_ACCELDATA ((wxAccelRefData *)m_refData)
63
64 // ============================================================================
65 // implementation
66 // ============================================================================
67
68 // ----------------------------------------------------------------------------
69 // wxAcceleratorTable ctors
70 // ----------------------------------------------------------------------------
71
72 IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject)
73
74 wxAcceleratorTable::wxAcceleratorTable()
75 {
76 }
77
78 wxAcceleratorTable::wxAcceleratorTable(int n, wxAcceleratorEntry entries[])
79 {
80 m_refData = new wxAccelRefData;
81
82 for ( int i = 0; i < n; i++ )
83 {
84 const wxAcceleratorEntry& entry = entries[i];
85
86 int keycode = entry.GetKeyCode();
87 if ( wxIslower(keycode) )
88 keycode = wxToupper(keycode);
89
90 M_ACCELDATA->m_accels.Append(new wxAcceleratorEntry(entry.GetFlags(),
91 keycode,
92 entry.GetCommand()));
93 }
94 }
95
96 wxAcceleratorTable::~wxAcceleratorTable()
97 {
98 }
99
100 bool wxAcceleratorTable::Ok() const
101 {
102 return m_refData != NULL;
103 }
104
105 // ----------------------------------------------------------------------------
106 // wxAcceleratorTable updating
107 // ----------------------------------------------------------------------------
108
109 void wxAcceleratorTable::Add(const wxAcceleratorEntry& entry)
110 {
111 if ( !m_refData )
112 {
113 m_refData = new wxAccelRefData;
114 }
115
116 M_ACCELDATA->m_accels.Append(new wxAcceleratorEntry(entry));
117 }
118
119 void wxAcceleratorTable::Remove(const wxAcceleratorEntry& entry)
120 {
121 wxAccelList::Node *node = M_ACCELDATA->m_accels.GetFirst();
122 while ( node )
123 {
124 const wxAcceleratorEntry *entryCur = node->GetData();
125
126 if ( *entryCur == entry )
127 {
128 M_ACCELDATA->m_accels.DeleteNode(node);
129
130 return;
131 }
132
133 node = node->GetNext();
134 }
135
136 wxFAIL_MSG(_T("deleting inexistent accel from wxAcceleratorTable"));
137 }
138
139 // ----------------------------------------------------------------------------
140 // wxAcceleratorTable: find a command for the given key press
141 // ----------------------------------------------------------------------------
142
143 const wxAcceleratorEntry *
144 wxAcceleratorTable::GetEntry(const wxKeyEvent& event) const
145 {
146 if ( !Ok() )
147 {
148 // not an error, the accel table is just empty
149 return NULL;
150 }
151
152 wxAccelList::Node *node = M_ACCELDATA->m_accels.GetFirst();
153 while ( node )
154 {
155 const wxAcceleratorEntry *entry = node->GetData();
156
157 // is the key the same?
158 if ( event.m_keyCode == entry->GetKeyCode() )
159 {
160 int flags = entry->GetFlags();
161
162 // now check flags
163 if ( (((flags & wxACCEL_CTRL) != 0) == event.ControlDown()) &&
164 (((flags & wxACCEL_SHIFT) != 0) == event.ShiftDown()) &&
165 (((flags & wxACCEL_ALT) != 0) ==
166 (event.AltDown() || event.MetaDown())) )
167 {
168 return entry;
169 }
170 }
171
172 node = node->GetNext();
173 }
174
175 return NULL;
176 }
177
178 wxMenuItem *wxAcceleratorTable::GetMenuItem(const wxKeyEvent& event) const
179 {
180 const wxAcceleratorEntry *entry = GetEntry(event);
181
182 return entry ? entry->GetMenuItem() : NULL;
183 }
184
185 int wxAcceleratorTable::GetCommand(const wxKeyEvent& event) const
186 {
187 const wxAcceleratorEntry *entry = GetEntry(event);
188
189 return entry ? entry->GetCommand() : -1;
190 }
191
192 #endif // wxUSE_ACCEL
193