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