]> git.saurik.com Git - wxWidgets.git/blob - src/univ/checklst.cpp
fix memory leak (coverity checker CID 53)
[wxWidgets.git] / src / univ / checklst.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: univ/checklst.cpp
3 // Purpose: wxCheckListBox implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 12.09.00
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_CHECKLISTBOX
27
28 #ifndef WX_PRECOMP
29 #include "wx/log.h"
30
31 #include "wx/dcclient.h"
32 #include "wx/checklst.h"
33 #include "wx/validate.h"
34 #endif
35
36 #include "wx/univ/renderer.h"
37 #include "wx/univ/inphand.h"
38 #include "wx/univ/theme.h"
39
40 // ============================================================================
41 // implementation of wxCheckListBox
42 // ============================================================================
43
44 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
45
46 // ----------------------------------------------------------------------------
47 // creation
48 // ----------------------------------------------------------------------------
49
50 void wxCheckListBox::Init()
51 {
52 }
53
54 wxCheckListBox::wxCheckListBox(wxWindow *parent,
55 wxWindowID id,
56 const wxPoint &pos,
57 const wxSize &size,
58 const wxArrayString& choices,
59 long style,
60 const wxValidator& validator,
61 const wxString &name)
62 {
63 Init();
64
65 Create(parent, id, pos, size, choices, style, validator, name);
66 }
67
68 bool wxCheckListBox::Create(wxWindow *parent,
69 wxWindowID id,
70 const wxPoint &pos,
71 const wxSize &size,
72 const wxArrayString& choices,
73 long style,
74 const wxValidator& validator,
75 const wxString &name)
76 {
77 wxCArrayString chs(choices);
78
79 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
80 style, validator, name);
81 }
82
83 bool wxCheckListBox::Create(wxWindow *parent,
84 wxWindowID id,
85 const wxPoint &pos,
86 const wxSize &size,
87 int n,
88 const wxString choices[],
89 long style,
90 const wxValidator& validator,
91 const wxString &name)
92 {
93 if ( !wxListBox::Create(parent, id, pos, size,
94 n, choices, style, validator, name) )
95 return false;
96
97 CreateInputHandler(wxINP_HANDLER_CHECKLISTBOX);
98
99 return true;
100 }
101
102 // ----------------------------------------------------------------------------
103 // wxCheckListBox functions
104 // ----------------------------------------------------------------------------
105
106 bool wxCheckListBox::IsChecked(size_t item) const
107 {
108 wxCHECK_MSG( item < m_checks.GetCount(), false,
109 _T("invalid index in wxCheckListBox::IsChecked") );
110
111 return m_checks[item] != 0;
112 }
113
114 void wxCheckListBox::Check(size_t item, bool check)
115 {
116 wxCHECK_RET( item < m_checks.GetCount(),
117 _T("invalid index in wxCheckListBox::Check") );
118
119 // intermediate var is needed to avoid compiler warning with VC++
120 bool isChecked = m_checks[item] != 0;
121 if ( check != isChecked )
122 {
123 m_checks[item] = check;
124
125 RefreshItem(item);
126 }
127 }
128
129 // ----------------------------------------------------------------------------
130 // methods forwarded to wxListBox
131 // ----------------------------------------------------------------------------
132
133 void wxCheckListBox::Delete(int n)
134 {
135 wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
136
137 wxListBox::Delete(n);
138
139 m_checks.RemoveAt(n);
140 }
141
142 int wxCheckListBox::DoAppend(const wxString& item)
143 {
144 int pos = wxListBox::DoAppend(item);
145
146 // the item is initially unchecked
147 m_checks.Insert(false, pos);
148
149 return pos;
150 }
151
152 void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos)
153 {
154 wxListBox::DoInsertItems(items, pos);
155
156 size_t count = items.GetCount();
157 for ( size_t n = 0; n < count; n++ )
158 {
159 m_checks.Insert(false, pos + n);
160 }
161 }
162
163 void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData)
164 {
165 // call it first as it does DoClear()
166 wxListBox::DoSetItems(items, clientData);
167
168 size_t count = items.GetCount();
169 for ( size_t n = 0; n < count; n++ )
170 {
171 m_checks.Add(false);
172 }
173 }
174
175 void wxCheckListBox::DoClear()
176 {
177 m_checks.Empty();
178 }
179
180 // ----------------------------------------------------------------------------
181 // drawing
182 // ----------------------------------------------------------------------------
183
184 wxSize wxCheckListBox::DoGetBestClientSize() const
185 {
186 wxSize size = wxListBox::DoGetBestClientSize();
187 size.x += GetRenderer()->GetCheckBitmapSize().x;
188
189 return size;
190 }
191
192 void wxCheckListBox::DoDrawRange(wxControlRenderer *renderer,
193 int itemFirst, int itemLast)
194 {
195 renderer->DrawCheckItems(this, itemFirst, itemLast);
196 }
197
198 // ----------------------------------------------------------------------------
199 // actions
200 // ----------------------------------------------------------------------------
201
202 bool wxCheckListBox::PerformAction(const wxControlAction& action,
203 long numArg,
204 const wxString& strArg)
205 {
206 if ( action == wxACTION_CHECKLISTBOX_TOGGLE )
207 {
208 int sel = (int)numArg;
209 if ( sel == -1 )
210 {
211 sel = GetSelection();
212 }
213
214 if ( sel != -1 )
215 {
216 Check(sel, !IsChecked(sel));
217
218 SendEvent(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, sel);
219 }
220 }
221 else
222 {
223 return wxListBox::PerformAction(action, numArg, strArg);
224 }
225
226 return true;
227 }
228
229 // ----------------------------------------------------------------------------
230 // wxStdCheckListboxInputHandler
231 // ----------------------------------------------------------------------------
232
233 wxStdCheckListboxInputHandler::
234 wxStdCheckListboxInputHandler(wxInputHandler *inphand)
235 : wxStdListboxInputHandler(inphand)
236 {
237 }
238
239 bool wxStdCheckListboxInputHandler::HandleKey(wxInputConsumer *consumer,
240 const wxKeyEvent& event,
241 bool pressed)
242 {
243 if ( pressed && (event.GetKeyCode() == WXK_SPACE) )
244 consumer->PerformAction(wxACTION_CHECKLISTBOX_TOGGLE);
245
246 return wxStdListboxInputHandler::HandleKey(consumer, event, pressed);
247 }
248
249 bool wxStdCheckListboxInputHandler::HandleMouse(wxInputConsumer *consumer,
250 const wxMouseEvent& event)
251 {
252 if ( event.LeftDown() || event.LeftDClick() )
253 {
254 wxCheckListBox *lbox = wxStaticCast(consumer->GetInputWindow(), wxCheckListBox);
255 int x, y;
256
257 wxPoint pt = event.GetPosition();
258 pt -= consumer->GetInputWindow()->GetClientAreaOrigin();
259 lbox->CalcUnscrolledPosition(pt.x, pt.y, &x, &y);
260
261 wxRenderer *renderer = lbox->GetRenderer();
262 x -= renderer->GetCheckItemMargin();
263
264 int item = y / lbox->GetLineHeight();
265 if ( x >= 0 &&
266 x < renderer->GetCheckBitmapSize().x &&
267 item >= 0 &&
268 item < lbox->GetCount() )
269 {
270 lbox->PerformAction(wxACTION_CHECKLISTBOX_TOGGLE, item);
271
272 return true;
273 }
274 }
275
276 return wxStdListboxInputHandler::HandleMouse(consumer, event);
277 }
278
279 #endif // wxUSE_CHECKLISTBOX