]>
Commit | Line | Data |
---|---|---|
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. | |
37 | class TrackedClientData : public wxClientData | |
38 | { | |
39 | public: | |
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 | ||
58 | private: | |
59 | ItemContainerWidgetsPage *m_tracker; | |
60 | int m_value; | |
61 | ||
62 | DECLARE_NO_COPY_CLASS(TrackedClientData) | |
63 | }; | |
64 | ||
65 | // ============================================================================ | |
66 | // implementation | |
67 | // ============================================================================ | |
68 | ||
69 | ItemContainerWidgetsPage::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 | { | |
74 | m_items.Add(_T("This")); | |
75 | m_items.Add(_T("is")); | |
76 | m_items.Add(_T("a")); | |
77 | m_items.Add(_T("List")); | |
78 | m_items.Add(_T("of")); | |
79 | m_items.Add(_T("strings")); | |
80 | m_itemsSorted = m_items; | |
81 | } | |
82 | ||
83 | ItemContainerWidgetsPage::~ItemContainerWidgetsPage() | |
84 | { | |
85 | } | |
86 | ||
87 | wxClientData* ItemContainerWidgetsPage::CreateClientData(int value) | |
88 | { | |
89 | return new TrackedClientData(this, value); | |
90 | } | |
91 | ||
92 | void ItemContainerWidgetsPage::StartTrackingData() | |
93 | { | |
94 | ++m_trackedDataObjects; | |
95 | } | |
96 | ||
97 | void ItemContainerWidgetsPage::StopTrackingData() | |
98 | { | |
99 | --m_trackedDataObjects; | |
100 | } | |
101 | ||
102 | bool ItemContainerWidgetsPage::VerifyAllClientDataDestroyed() | |
103 | { | |
104 | if ( m_trackedDataObjects ) | |
105 | { | |
106 | wxString message = _T("Bug in managing wxClientData: "); | |
107 | if ( m_trackedDataObjects > 0 ) | |
108 | message << m_trackedDataObjects << _T(" lost objects"); | |
109 | else | |
110 | message << (-m_trackedDataObjects) << _T(" extra deletes"); | |
111 | wxFAIL_MSG(message); | |
112 | return false; | |
113 | } | |
114 | ||
115 | return true; | |
116 | } | |
117 | ||
118 | void ItemContainerWidgetsPage::StartTest(const wxString& label) | |
119 | { | |
120 | m_container->Clear(); | |
121 | wxLogMessage(_T("Test - %s:"), label.c_str()); | |
122 | } | |
123 | ||
c1daf252 | 124 | void ItemContainerWidgetsPage::EndTest(const wxMaybeSortedArrayString& items) |
a236aa20 VZ |
125 | { |
126 | const unsigned count = m_container->GetCount(); | |
127 | ||
128 | bool ok = count == items.GetCount(); | |
129 | if ( !ok ) | |
130 | { | |
131 | wxFAIL_MSG(_T("Item count does not match.")); | |
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( | |
141 | _T("Wrong string \"%s\" at position %d (expected \"%s\")"), | |
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 | ||
176 | wxLogMessage(_T("...%s"), ok ? _T("passed") : _T("failed")); | |
177 | } | |
178 | ||
179 | wxString | |
c1daf252 | 180 | ItemContainerWidgetsPage::DumpContainerData(const wxMaybeSortedArrayString& expected) const |
a236aa20 VZ |
181 | { |
182 | wxString str; | |
183 | str << _T("Current content:\n"); | |
184 | ||
185 | unsigned i; | |
186 | for ( i = 0; i < m_container->GetCount(); ++i ) | |
187 | { | |
188 | str << _T(" - ") << m_container->GetString(i) << _T(" ["); | |
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 | } | |
202 | str << _T("]\n"); | |
203 | } | |
204 | ||
205 | str << _T("Expected content:\n"); | |
206 | for ( i = 0; i < expected.GetCount(); ++i ) | |
207 | { | |
208 | const wxString& item = expected[i]; | |
209 | str << _T(" - ") << item << _T("["); | |
210 | for( unsigned j = 0; j < m_items.GetCount(); ++j ) | |
211 | { | |
212 | if ( m_items[j] == item ) | |
213 | str << j; | |
214 | } | |
215 | str << _T("]\n"); | |
216 | } | |
217 | ||
218 | return str; | |
219 | } | |
220 | ||
221 | bool ItemContainerWidgetsPage::VerifyClientData(wxUIntPtr i, const wxString& str) | |
222 | { | |
223 | if ( i > m_items.GetCount() || m_items[i] != str ) | |
224 | { | |
225 | wxLogMessage(_T("Client data for '%s' does not match."), str.c_str()); | |
226 | return false; | |
227 | } | |
228 | ||
229 | return true; | |
230 | } | |
231 | ||
232 | void ItemContainerWidgetsPage::OnButtonTestItemContainer(wxCommandEvent&) | |
233 | { | |
234 | m_container = GetContainer(); | |
235 | wxASSERT_MSG(m_container, _T("Widget must have a test widget")); | |
236 | ||
237 | wxLogMessage(_T("wxItemContainer test for %s, %s:"), | |
238 | GetWidget()->GetClassInfo()->GetClassName(), | |
239 | (m_container->IsSorted() ? "Sorted" : "Unsorted")); | |
240 | ||
c1daf252 VZ |
241 | const wxMaybeSortedArrayString& |
242 | expected_result = m_container->IsSorted() ? m_itemsSorted | |
243 | : m_items; | |
a236aa20 VZ |
244 | |
245 | StartTest(_T("Append one item")); | |
246 | wxString item = m_items[0]; | |
247 | m_container->Append(item); | |
248 | EndTest(wxArrayString(1, &item)); | |
249 | ||
250 | StartTest(_T("Append some items")); | |
251 | m_container->Append(m_items); | |
252 | EndTest(expected_result); | |
253 | ||
254 | StartTest(_T("Append some items with data objects")); | |
255 | wxClientData **objects = new wxClientData *[m_items.GetCount()]; | |
e081b01f JS |
256 | unsigned i; |
257 | for ( i = 0; i < m_items.GetCount(); ++i ) | |
a236aa20 VZ |
258 | objects[i] = CreateClientData(i); |
259 | m_container->Append(m_items, objects); | |
260 | EndTest(expected_result); | |
261 | delete[] objects; | |
262 | ||
263 | StartTest(_T("Append some items with data")); | |
264 | void **data = new void *[m_items.GetCount()]; | |
e081b01f | 265 | for ( i = 0; i < m_items.GetCount(); ++i ) |
567d9d70 | 266 | data[i] = wxUIntToPtr(i); |
a236aa20 VZ |
267 | m_container->Append(m_items, data); |
268 | EndTest(expected_result); | |
269 | delete[] data; | |
270 | ||
271 | StartTest(_T("Append some items with data, one by one")); | |
e081b01f | 272 | for ( i = 0; i < m_items.GetCount(); ++i ) |
567d9d70 | 273 | m_container->Append(m_items[i], wxUIntToPtr(i)); |
a236aa20 VZ |
274 | EndTest(expected_result); |
275 | ||
276 | StartTest(_T("Append some items with data objects, one by one")); | |
e081b01f | 277 | for ( i = 0; i < m_items.GetCount(); ++i ) |
a236aa20 VZ |
278 | m_container->Append(m_items[i], CreateClientData(i)); |
279 | EndTest(expected_result); | |
280 | ||
281 | if ( !m_container->IsSorted() ) | |
282 | { | |
283 | StartTest(_T("Insert in reverse order with data, one by one")); | |
284 | for ( unsigned i = m_items.GetCount(); i; --i ) | |
567d9d70 | 285 | m_container->Insert(m_items[i - 1], 0, wxUIntToPtr(i - 1)); |
a236aa20 VZ |
286 | EndTest(expected_result); |
287 | } | |
288 | } | |
289 |