]> git.saurik.com Git - wxWidgets.git/blame - samples/widgets/itemcontainer.cpp
Use template class instead of template function in wxVectorSort().
[wxWidgets.git] / samples / widgets / itemcontainer.cpp
CommitLineData
a236aa20
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Program: wxWidgets Widgets Sample
3// Name: itemcontainer.cpp
4// Purpose: Part of the widgets sample showing wxComboBox
5// Created: 20.07.07
6// Id: $Id$
7// License: wxWindows license
8/////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
18// for compilers that support precompilation, includes "wx/wx.h".
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
22 #pragma hdrstop
23#endif
24
25// for all others, include the necessary headers
26#ifndef WX_PRECOMP
27 #include "wx/log.h"
28
29 #include "wx/event.h"
30#endif
31
32#include "wx/ctrlsub.h"
33#include "itemcontainer.h"
34
35
36// Help track client data objects in wxItemContainer instances.
37class TrackedClientData : public wxClientData
38{
39public:
40
41 TrackedClientData(ItemContainerWidgetsPage* tracker, int value)
42 : m_tracker(tracker),
43 m_value(value)
44 {
45 m_tracker->StartTrackingData();
46 }
47
48 virtual ~TrackedClientData()
49 {
50 m_tracker->StopTrackingData();
51 }
52
53 int GetValue() const
54 {
55 return m_value;
56 }
57
58private:
59 ItemContainerWidgetsPage *m_tracker;
60 int m_value;
61
c0c133e1 62 wxDECLARE_NO_COPY_CLASS(TrackedClientData);
a236aa20
VZ
63};
64
65// ============================================================================
66// implementation
67// ============================================================================
68
69ItemContainerWidgetsPage::ItemContainerWidgetsPage(WidgetsBookCtrl *book,
70 wxImageList *image_list,
747d7d7c 71 const char *const icon[])
a236aa20
VZ
72: WidgetsPage(book, image_list, icon), m_trackedDataObjects(0)
73{
9a83f860
VZ
74 m_items.Add(wxT("This"));
75 m_items.Add(wxT("is"));
76 m_items.Add(wxT("a"));
77 m_items.Add(wxT("List"));
78 m_items.Add(wxT("of"));
79 m_items.Add(wxT("strings"));
a236aa20
VZ
80 m_itemsSorted = m_items;
81}
82
83ItemContainerWidgetsPage::~ItemContainerWidgetsPage()
84{
85}
86
87wxClientData* ItemContainerWidgetsPage::CreateClientData(int value)
88{
89 return new TrackedClientData(this, value);
90}
91
92void ItemContainerWidgetsPage::StartTrackingData()
93{
94 ++m_trackedDataObjects;
95}
96
97void ItemContainerWidgetsPage::StopTrackingData()
98{
99 --m_trackedDataObjects;
100}
101
102bool ItemContainerWidgetsPage::VerifyAllClientDataDestroyed()
103{
104 if ( m_trackedDataObjects )
105 {
9a83f860 106 wxString message = wxT("Bug in managing wxClientData: ");
a236aa20 107 if ( m_trackedDataObjects > 0 )
9a83f860 108 message << m_trackedDataObjects << wxT(" lost objects");
a236aa20 109 else
9a83f860 110 message << (-m_trackedDataObjects) << wxT(" extra deletes");
a236aa20
VZ
111 wxFAIL_MSG(message);
112 return false;
113 }
114
115 return true;
116}
117
118void ItemContainerWidgetsPage::StartTest(const wxString& label)
119{
120 m_container->Clear();
9a83f860 121 wxLogMessage(wxT("Test - %s:"), label.c_str());
a236aa20
VZ
122}
123
2549484f 124void ItemContainerWidgetsPage::EndTest(const wxArrayString& items)
a236aa20
VZ
125{
126 const unsigned count = m_container->GetCount();
127
128 bool ok = count == items.GetCount();
129 if ( !ok )
130 {
9a83f860 131 wxFAIL_MSG(wxT("Item count does not match."));
a236aa20
VZ
132 }
133 else
134 {
135 for ( unsigned i = 0; i < count; ++i )
136 {
137 wxString str = m_container->GetString(i);
138 if ( str != items[i] )
139 {
140 wxFAIL_MSG(wxString::Format(
9a83f860 141 wxT("Wrong string \"%s\" at position %d (expected \"%s\")"),
a236aa20
VZ
142 str.c_str(), i, items[i].c_str()));
143 ok = false;
144 break;
145 }
146
147 if ( m_container->HasClientUntypedData() )
148 {
149 void *data = m_container->GetClientData(i);
150 if ( data && !VerifyClientData((wxUIntPtr)data, str) )
151 {
152 ok = false;
153 break;
154 }
155 }
156 else if ( m_container->HasClientObjectData() )
157 {
158 TrackedClientData* obj = (TrackedClientData*)m_container->GetClientObject(i);
159 if ( obj && !VerifyClientData(obj->GetValue(), str) )
160 {
161 ok = false;
162 break;
163 }
164 }
165 }
166
167 if ( !ok )
168 {
169 wxLogMessage(DumpContainerData(items));
170 }
171 }
172
173 m_container->Clear();
174 ok &= VerifyAllClientDataDestroyed();
175
9a83f860 176 wxLogMessage(wxT("...%s"), ok ? wxT("passed") : wxT("failed"));
a236aa20
VZ
177}
178
179wxString
2549484f 180ItemContainerWidgetsPage::DumpContainerData(const wxArrayString& expected) const
a236aa20
VZ
181{
182 wxString str;
9a83f860 183 str << wxT("Current content:\n");
a236aa20
VZ
184
185 unsigned i;
186 for ( i = 0; i < m_container->GetCount(); ++i )
187 {
9a83f860 188 str << wxT(" - ") << m_container->GetString(i) << wxT(" [");
a236aa20
VZ
189 if ( m_container->HasClientObjectData() )
190 {
191 TrackedClientData *
192 obj = (TrackedClientData*)m_container->GetClientObject(i);
193 if ( obj )
194 str << obj->GetValue();
195 }
196 else if ( m_container->HasClientUntypedData() )
197 {
198 void *data = m_container->GetClientData(i);
199 if ( data )
200 str << (wxUIntPtr)data;
201 }
9a83f860 202 str << wxT("]\n");
a236aa20
VZ
203 }
204
9a83f860 205 str << wxT("Expected content:\n");
a236aa20
VZ
206 for ( i = 0; i < expected.GetCount(); ++i )
207 {
208 const wxString& item = expected[i];
9a83f860 209 str << wxT(" - ") << item << wxT("[");
a236aa20
VZ
210 for( unsigned j = 0; j < m_items.GetCount(); ++j )
211 {
212 if ( m_items[j] == item )
213 str << j;
214 }
9a83f860 215 str << wxT("]\n");
a236aa20
VZ
216 }
217
218 return str;
219}
220
221bool ItemContainerWidgetsPage::VerifyClientData(wxUIntPtr i, const wxString& str)
222{
223 if ( i > m_items.GetCount() || m_items[i] != str )
224 {
9a83f860 225 wxLogMessage(wxT("Client data for '%s' does not match."), str.c_str());
a236aa20
VZ
226 return false;
227 }
228
229 return true;
230}
231
2549484f
VZ
232/* static */
233wxArrayString
234ItemContainerWidgetsPage::MakeArray(const wxSortedArrayString& sorted)
235{
236 wxArrayString a;
237
238 const size_t count = sorted.size();
239 a.reserve(count);
240 for ( size_t n = 0; n < count; n++ )
241 a.push_back(sorted[n]);
242
243 return a;
244}
245
a236aa20
VZ
246void ItemContainerWidgetsPage::OnButtonTestItemContainer(wxCommandEvent&)
247{
248 m_container = GetContainer();
9a83f860 249 wxASSERT_MSG(m_container, wxT("Widget must have a test widget"));
a236aa20 250
9a83f860 251 wxLogMessage(wxT("wxItemContainer test for %s, %s:"),
a236aa20
VZ
252 GetWidget()->GetClassInfo()->GetClassName(),
253 (m_container->IsSorted() ? "Sorted" : "Unsorted"));
254
2549484f
VZ
255 const wxArrayString
256 expected_result = m_container->IsSorted() ? MakeArray(m_itemsSorted)
257 : m_items;
a236aa20 258
9a83f860 259 StartTest(wxT("Append one item"));
a236aa20
VZ
260 wxString item = m_items[0];
261 m_container->Append(item);
262 EndTest(wxArrayString(1, &item));
263
9a83f860 264 StartTest(wxT("Append some items"));
a236aa20
VZ
265 m_container->Append(m_items);
266 EndTest(expected_result);
267
9a83f860 268 StartTest(wxT("Append some items with data objects"));
a236aa20 269 wxClientData **objects = new wxClientData *[m_items.GetCount()];
e081b01f
JS
270 unsigned i;
271 for ( i = 0; i < m_items.GetCount(); ++i )
a236aa20
VZ
272 objects[i] = CreateClientData(i);
273 m_container->Append(m_items, objects);
274 EndTest(expected_result);
275 delete[] objects;
276
9a83f860 277 StartTest(wxT("Append some items with data"));
a236aa20 278 void **data = new void *[m_items.GetCount()];
e081b01f 279 for ( i = 0; i < m_items.GetCount(); ++i )
567d9d70 280 data[i] = wxUIntToPtr(i);
a236aa20
VZ
281 m_container->Append(m_items, data);
282 EndTest(expected_result);
283 delete[] data;
284
9a83f860 285 StartTest(wxT("Append some items with data, one by one"));
e081b01f 286 for ( i = 0; i < m_items.GetCount(); ++i )
567d9d70 287 m_container->Append(m_items[i], wxUIntToPtr(i));
a236aa20
VZ
288 EndTest(expected_result);
289
9a83f860 290 StartTest(wxT("Append some items with data objects, one by one"));
e081b01f 291 for ( i = 0; i < m_items.GetCount(); ++i )
a236aa20
VZ
292 m_container->Append(m_items[i], CreateClientData(i));
293 EndTest(expected_result);
294
295 if ( !m_container->IsSorted() )
296 {
9a83f860 297 StartTest(wxT("Insert in reverse order with data, one by one"));
a236aa20 298 for ( unsigned i = m_items.GetCount(); i; --i )
567d9d70 299 m_container->Insert(m_items[i - 1], 0, wxUIntToPtr(i - 1));
a236aa20
VZ
300 EndTest(expected_result);
301 }
302}
303