]> git.saurik.com Git - wxWidgets.git/blame - samples/xti/classlist.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / samples / xti / classlist.cpp
CommitLineData
cc3977bf
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: classlist.cpp
3// Purpose: ClassListDialog implementation
4// Author: Francesco Montorsi
5// Modified by:
6// Created: 03/06/2007 14:49:55
cc3977bf 7// Copyright: (c) 2007 Francesco Montorsi
3fdcd5d5 8// Licence: wxWindows licence
cc3977bf
SC
9/////////////////////////////////////////////////////////////////////////////
10
11
12// ----------------------------------------------------------------------------
13// headers
14// ----------------------------------------------------------------------------
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25#endif
26
27#include "classlist.h"
28
29#if !wxUSE_EXTENDED_RTTI
30 #error This sample requires XTI (eXtended RTTI) enabled
31#endif
32
33// IMPLEMENT_DYNAMIC_CLASS( ClassListDialog, wxDialog ) -- see the header
34BEGIN_EVENT_TABLE( ClassListDialog, wxDialog )
35 EVT_LISTBOX( ID_LISTBOX, ClassListDialog::OnListboxSelected )
36 EVT_TREE_SEL_CHANGED( ID_TREECTRL, ClassListDialog::OnTreectrlSelChanged )
37 EVT_CHOICEBOOK_PAGE_CHANGED( ID_LISTMODE, ClassListDialog::OnChoiceBookPageChange )
38
39 EVT_CHECKBOX( ID_SHOW_ONLY_XTI, ClassListDialog::OnShowOnlyXTICheckbox )
40 EVT_CHECKBOX( ID_SHOW_PROPERTIES_RECURSIVELY, ClassListDialog::OnShowRecursiveInfoCheckbox )
41END_EVENT_TABLE()
42
43// defined later
44wxString DumpClassInfo(const wxClassInfo*, bool recursive);
45
46
47// ----------------------------------------------------------------------------
48// ClassListDialog
49// ----------------------------------------------------------------------------
50
51ClassListDialog::ClassListDialog()
52{
53 Init();
54}
55
56ClassListDialog::ClassListDialog( wxWindow* parent, wxWindowID id,
57 const wxString& caption, const wxPoint& pos,
58 const wxSize& size, long style )
59{
60 Init();
61 Create(parent, id, caption, pos, size, style);
62}
63
64bool ClassListDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption,
65 const wxPoint& pos, const wxSize& size, long style )
66{
67 SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
68 wxDialog::Create( parent, id, caption, pos, size, style );
69
70 CreateControls();
71 if (GetSizer())
72 {
73 GetSizer()->SetSizeHints(this);
74 }
75 Centre();
76
77 return true;
78}
79
80ClassListDialog::~ClassListDialog()
81{
82}
83
84void ClassListDialog::Init()
85{
86 m_pClassCountText = NULL;
87 m_pRawListBox = NULL;
88 m_pParentTreeCtrl = NULL;
89 m_pSizeListBox = NULL;
90 m_pTextCtrl = NULL;
91}
92
93void ClassListDialog::CreateControls()
94{
95 wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
96 this->SetSizer(itemBoxSizer2);
97
98 wxStaticText* itemStaticText3 = new wxStaticText( this, wxID_STATIC, _("This is the list of wxWidgets classes registered in the XTI system.\nNote that not all wxWidgets classes are registered nor all registered classes are completely _described_ using XTI metadata."), wxDefaultPosition, wxDefaultSize, 0 );
99 itemBoxSizer2->Add(itemStaticText3, 0, wxALIGN_LEFT|wxALL, 5);
100
101 // filters
102 wxBoxSizer* filters = new wxBoxSizer(wxHORIZONTAL);
103 itemBoxSizer2->Add(filters, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5);
104 filters->Add(new wxCheckBox(this, ID_SHOW_ONLY_XTI,
105 wxT("Show only classes with eXtended infos")));
106 filters->AddSpacer(10);
107 filters->Add(new wxCheckBox(this, ID_SHOW_PROPERTIES_RECURSIVELY,
108 wxT("Show properties of parent classes")));
109
110 // show how many have we filtered out
111 m_pClassCountText = new wxStaticText( this, wxID_STATIC,
112 wxT("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
113 wxDefaultPosition, wxDefaultSize, 0 );
114 m_pClassCountText->SetFont(wxFont(8, wxSWISS, wxNORMAL, wxBOLD, false, wxT("Tahoma")));
115 itemBoxSizer2->Add(m_pClassCountText, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxBOTTOM, 5);
116
117 wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
118 itemBoxSizer2->Add(itemBoxSizer5, 1, wxGROW, 5);
119
120 m_pChoiceBook = new wxChoicebook( this, ID_LISTMODE, wxDefaultPosition, wxDefaultSize, wxCHB_DEFAULT );
121
122 // raw-list page
123 wxPanel* itemPanel7 = new wxPanel( m_pChoiceBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
124 wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL);
125 itemPanel7->SetSizer(itemBoxSizer8);
126
127 wxArrayString m_pRawListBoxStrings;
128 m_pRawListBox = new wxListBox( itemPanel7, ID_LISTBOX, wxDefaultPosition, wxDefaultSize, m_pRawListBoxStrings, wxLB_SINGLE );
129 itemBoxSizer8->Add(m_pRawListBox, 1, wxGROW, 5);
130
131 m_pChoiceBook->AddPage(itemPanel7, _("Raw list"));
132
133 // by-size page
134 wxPanel* itemPanel13 = new wxPanel( m_pChoiceBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
135 wxBoxSizer* itemBoxSizer14 = new wxBoxSizer(wxHORIZONTAL);
136 itemPanel13->SetSizer(itemBoxSizer14);
137
138 wxArrayString m_pSizeListBoxStrings;
139 m_pSizeListBox = new wxListBox( itemPanel13, ID_LISTBOX, wxDefaultPosition, wxDefaultSize, m_pSizeListBoxStrings, wxLB_SINGLE );
140 itemBoxSizer14->Add(m_pSizeListBox, 1, wxGROW, 5);
141
142 m_pChoiceBook->AddPage(itemPanel13, _("Classes by size"));
143
144 // tree page
145 wxPanel* itemPanel10 = new wxPanel( m_pChoiceBook, ID_PANEL, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
146 wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxVERTICAL);
147 itemPanel10->SetSizer(itemBoxSizer11);
148
149 m_pParentTreeCtrl = new wxTreeCtrl( itemPanel10, ID_TREECTRL, wxDefaultPosition, wxSize(100, 100), wxTR_HAS_BUTTONS |wxTR_SINGLE );
150 itemBoxSizer11->Add(m_pParentTreeCtrl, 1, wxGROW, 5);
151
152 m_pChoiceBook->AddPage(itemPanel10, _("Classes by parent"));
153
154
155 itemBoxSizer5->Add(m_pChoiceBook, 0, wxGROW|wxALL, 5);
156
ebfe373e 157 m_pTextCtrl = new wxTextCtrl( this, ID_TEXTCTRL, wxT(""), wxDefaultPosition, wxSize(500, -1), wxTE_MULTILINE|wxTE_READONLY );
cc3977bf
SC
158 itemBoxSizer5->Add(m_pTextCtrl, 3, wxGROW|wxALL, 5);
159
160 wxStdDialogButtonSizer* itemStdDialogButtonSizer17 = new wxStdDialogButtonSizer;
161
162 itemBoxSizer2->Add(itemStdDialogButtonSizer17, 0, wxGROW|wxALL, 5);
163 wxButton* itemButton18 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
164 itemStdDialogButtonSizer17->AddButton(itemButton18);
165
166 wxButton* itemButton19 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
167 itemStdDialogButtonSizer17->AddButton(itemButton19);
168
169 itemStdDialogButtonSizer17->Realize();
170
171 InitControls();
172}
173
174int ClassListDialog::AddClassesWithParent(const wxClassInfo *parent, const wxTreeItemId &id)
175{
176 const wxClassInfo *ci = wxClassInfo::GetFirst();
177 int count = 0;
178 while (ci)
179 {
180 // is this class derived from the given parent?
181 if (wxString(ci->GetBaseClassName1()) == parent->GetClassName() ||
182 wxString(ci->GetBaseClassName2()) == parent->GetClassName())
183 {
184 wxTreeItemId child = m_pParentTreeCtrl->AppendItem(id, ci->GetClassName());
185
186 // update the name of this child with the count of the children classes
187 int ret = AddClassesWithParent(ci, child);
188 m_pParentTreeCtrl->SetItemText(child,
189 m_pParentTreeCtrl->GetItemText(child) +
190 wxString::Format(wxT(" [%d]"), ret));
191 count += ret+1;
192 }
193
194 ci = ci->GetNext();
195 }
196
197 // reorder all the children we've just added
198 m_pParentTreeCtrl->SortChildren(id);
199
200 return count;
201}
202
203int GetSizeOfClass(const wxString &cn)
204{
205 const wxClassInfo *ci = wxClassInfo::FindClass(cn);
206 if (ci)
207 return ci->GetSize();
208 return 0;
209}
210
211int CompareClassSizes(const wxString &class1, const wxString &class2)
212{
213 return GetSizeOfClass(class1) - GetSizeOfClass(class2);
214}
215
216void ClassListDialog::InitControls()
217{
218 // create a wxArrayString with the names of all classes:
219 const wxClassInfo *ci = wxClassInfo::GetFirst();
220 wxArrayString arr;
221 while (ci)
222 {
223 arr.Add(ci->GetClassName());
224 ci = ci->GetNext();
225 }
226
227 arr.Sort(); // sort alphabetically
228
229 // now add it to the raw-mode listbox
230 for (unsigned int i=0; i<arr.GetCount(); i++)
231 if (!IsToDiscard(arr[i]))
232 m_pRawListBox->Append(arr[i]);
233 m_nCount = m_pRawListBox->GetCount();
234
235 // sort again using size as sortkey
236 arr.Sort((wxArrayString::CompareFunction)CompareClassSizes);
237
238 // now add it to the size-mode listbox
239 for (unsigned int i=0; i<arr.GetCount(); i++)
240 if (!IsToDiscard(arr[i]))
241 m_pSizeListBox->Append(arr[i]);
242
243 // add root item to parent-mode treectrl
ebfe373e 244 wxTreeItemId id = m_pParentTreeCtrl->AddRoot(wxT("wxObject"));
cc3977bf
SC
245
246 // recursively add all leaves to the treectrl
247 int count = AddClassesWithParent(CLASSINFO(wxObject), id);
248 m_pParentTreeCtrl->SetItemText(id, m_pParentTreeCtrl->GetItemText(id) +
249 wxString::Format(wxT(" [%d]"), count));
250
251 // initially expand the root item
252 m_pParentTreeCtrl->Expand(id);
253
254 m_nTotalCount = arr.GetCount();
255 UpdateFilterText();
256
257 // don't leave blank the XTI info display
258 m_pChoiceBook->ChangeSelection(0);
259 m_pRawListBox->Select(0);
260 UpdateClassInfo(m_pRawListBox->GetStringSelection());
261}
262
263bool ClassListDialog::IsToDiscard(const wxString &classname) const
264{
265 wxCheckBox *cb = wx_static_cast(wxCheckBox*, FindWindow(ID_SHOW_ONLY_XTI));
266 if (!cb || !cb->IsChecked())
267 return false;
268
269 // check if this class has XTI infos
270 wxClassInfo *info = wxClassInfo::FindClass(classname);
271 if (!info)
272 return false;
273 if (info->GetFirstProperty() != NULL || info->GetFirstHandler() != NULL)
274 return false; // has XTI info
275 return true; // no XTI info
276}
277
278void ClassListDialog::UpdateFilterText()
279{
280 // tell the user how many registered classes are present and
281 // how many are we showing
282 m_pClassCountText->SetLabel(
283 wxString::Format(
284 wxT("Showing %d classes on a total of %d registered classes in wxXTI."),
285 m_nCount, m_nTotalCount));
286}
287
288void ClassListDialog::UpdateClassInfo(const wxString &itemName)
289{
ebfe373e 290 wxString classname = itemName.BeforeFirst(wxT(' '));
cc3977bf
SC
291 wxCheckBox *cb = wx_static_cast(wxCheckBox*, FindWindow(ID_SHOW_PROPERTIES_RECURSIVELY));
292
293 m_pTextCtrl->SetValue(
294 DumpClassInfo(wxClassInfo::FindClass(classname), cb->IsChecked()));
295}
296
297
298// ----------------------------------------------------------------------------
299// ClassListDialog - event handlers
300// ----------------------------------------------------------------------------
301
302void ClassListDialog::OnShowOnlyXTICheckbox( wxCommandEvent& WXUNUSED(event) )
303{
304 m_pRawListBox->Clear();
305 m_pParentTreeCtrl->DeleteAllItems();
306 m_pSizeListBox->Clear();
307
308 InitControls();
309}
310
311void ClassListDialog::OnShowRecursiveInfoCheckbox( wxCommandEvent& WXUNUSED(event) )
312{
313 m_pRawListBox->Clear();
314 m_pParentTreeCtrl->DeleteAllItems();
315 m_pSizeListBox->Clear();
316
317 InitControls();
318}
319
320void ClassListDialog::OnListboxSelected( wxCommandEvent& event )
321{
322 UpdateClassInfo(event.GetString());
323}
324
325void ClassListDialog::OnTreectrlSelChanged( wxTreeEvent& event )
326{
327 UpdateClassInfo(m_pParentTreeCtrl->GetItemText(event.GetItem()));
328}
329
330void ClassListDialog::OnChoiceBookPageChange( wxChoicebookEvent& event )
331{
332 switch (event.GetSelection())
333 {
334 case 0:
335 if (m_pRawListBox->GetCount())
336 {
337 m_pRawListBox->Select(0);
338 UpdateClassInfo(m_pRawListBox->GetStringSelection());
339 }
340 break;
341 case 1:
342 if (m_pSizeListBox->GetCount())
343 {
344 m_pSizeListBox->Select(0);
345 UpdateClassInfo(m_pSizeListBox->GetStringSelection());
346 }
347 break;
348 case 2:
349 {
350 wxTreeItemId root = m_pParentTreeCtrl->GetRootItem();
351 if (root.IsOk())
352 {
353 m_pParentTreeCtrl->SelectItem(root);
354 UpdateClassInfo(m_pParentTreeCtrl->GetItemText(root));
355 }
356 }
357 break;
358 }
359}
360
361
362
363// ----------------------------------------------------------------------------
364// dump functions
365// ----------------------------------------------------------------------------
366
367wxString DumpStr(const wxString &str)
368{
369 if (str.empty())
370 return wxT("none");
371 return str;
372}
373
374wxString DumpTypeInfo(const wxTypeInfo *ti)
375{
376 if (!ti)
ebfe373e 377 return wxT("none");
cc3977bf
SC
378
379 return DumpStr(ti->GetTypeName());
380}
381
382wxString DumpPropertyAccessor(const wxPropertyAccessor *acc, int indent)
383{
ebfe373e 384 wxString ind = wxT("\n") + wxString(indent, wxT(' '));
cc3977bf
SC
385 wxString infostr;
386
387 if (!acc)
ebfe373e 388 return ind + wxT("no property accessors");
cc3977bf
SC
389
390 if (acc->HasSetter())
ebfe373e 391 infostr << ind << wxT("setter name: ") << acc->GetSetterName();
cc3977bf 392 if (acc->HasCollectionGetter())
ebfe373e 393 infostr << ind << wxT("collection getter name: ") << acc->GetCollectionGetterName();
cc3977bf 394 if (acc->HasGetter())
ebfe373e 395 infostr << ind << wxT("getter name: ") << acc->GetGetterName();
cc3977bf 396 if (acc->HasAdder())
ebfe373e 397 infostr << ind << wxT("adder name: ") << acc->GetAdderName();
cc3977bf
SC
398
399 return infostr;
400}
401
402wxString DumpPropertyInfo(const wxPropertyInfo *prop, int indent)
403{
ebfe373e 404 wxString ind = wxT("\n") + wxString(indent, wxT(' '));
cc3977bf
SC
405 wxString infostr;
406
407 if (!prop)
ebfe373e 408 return ind + wxT("none");
cc3977bf 409
ebfe373e 410 infostr << ind << wxT("flags: ");
cc3977bf 411 if (prop->GetFlags() & wxPROP_DEPRECATED)
ebfe373e 412 infostr << wxT("wxPROP_DEPRECATED,");
cc3977bf 413 if (prop->GetFlags() & wxPROP_OBJECT_GRAPH)
ebfe373e 414 infostr << wxT("wxPROP_OBJECT_GRAPH,");
cc3977bf 415 if (prop->GetFlags() & wxPROP_ENUM_STORE_LONG)
ebfe373e 416 infostr << wxT("wxPROP_ENUM_STORE_LONG,");
cc3977bf 417 if (prop->GetFlags() & wxPROP_DONT_STREAM)
ebfe373e 418 infostr << wxT("wxPROP_DONT_STREAM,");
cc3977bf
SC
419
420 if (prop->GetFlags() == 0)
ebfe373e 421 infostr << wxT("none");
cc3977bf
SC
422 else
423 infostr.RemoveLast(); // remove last comma
424
ebfe373e
DS
425 infostr << ind << wxT("help string: ") << DumpStr(prop->GetHelpString());
426 infostr << ind << wxT("group string: ") << DumpStr(prop->GetGroupString());
cc3977bf 427
ebfe373e
DS
428 infostr << ind << wxT("collection element type: ") << DumpTypeInfo(prop->GetCollectionElementTypeInfo());
429 infostr << ind << wxT("type: ") << DumpTypeInfo(prop->GetTypeInfo());
cc3977bf 430
ebfe373e 431 infostr << ind << wxT("default value: ") << DumpStr(wxAnyGetAsString(prop->GetDefaultValue()));
cc3977bf
SC
432 infostr << DumpPropertyAccessor(prop->GetAccessor(), indent+1);
433
434 return infostr;
435}
436
437wxString DumpHandlerInfo(const wxHandlerInfo *phdlr, int indent)
438{
ebfe373e 439 wxString ind = wxT("\n") + wxString(indent, wxT(' '));
cc3977bf
SC
440 wxString infostr;
441
442 if (!phdlr)
ebfe373e 443 return ind + wxT("none");
cc3977bf 444
ebfe373e 445 infostr << ind << wxT("event class: ") <<
cc3977bf
SC
446 (phdlr->GetEventClassInfo() ? phdlr->GetEventClassInfo()->GetClassName() : wxT("none"));
447
448 return infostr;
449}
450
451int DumpProperties(const wxClassInfo *info, wxString& infostr, bool recursive)
452{
453 const wxPropertyInfo *prop;
454 int pcount;
455 for (prop = info->GetFirstProperty(), pcount = 0;
456 prop;
457 prop = prop->GetNext(), pcount++)
458 {
ebfe373e 459 infostr << wxT("\n\n [") << pcount+1 << wxT("] Property: ") << prop->GetName();
cc3977bf
SC
460 infostr << DumpPropertyInfo(prop, 4);
461 }
462
463 if (pcount == 0)
ebfe373e 464 infostr << wxT("\n None");
cc3977bf
SC
465
466 if (recursive)
467 {
468 const wxClassInfo **parent = info->GetParents();
469 wxString str;
470
471 for (int i=0; parent[i] != NULL; i++)
472 {
473 int ppcount = DumpProperties(parent[i], str, recursive);
474 if (ppcount)
475 {
476 pcount += ppcount;
ebfe373e 477 infostr << wxT("\n\n ") << parent[i]->GetClassName() << wxT(" PARENT'S PROPERTIES:");
cc3977bf
SC
478 infostr << str;
479 }
480 }
481 }
482
483 return pcount;
484}
485
486int DumpHandlers(const wxClassInfo *info, wxString& infostr, bool recursive)
487{
488 const wxHandlerInfo *h;
489 int hcount;
490 for (h = info->GetFirstHandler(), hcount = 0;
491 h;
492 h = h->GetNext(), hcount++)
493 {
ebfe373e 494 infostr << wxT("\n\n [") << hcount+1 << wxT("] Handler: ") << h->GetName();
cc3977bf
SC
495 infostr << DumpHandlerInfo(h, 4);
496 }
497
498 if (hcount == 0)
ebfe373e 499 infostr << wxT("\n None");
cc3977bf
SC
500
501 if (recursive)
502 {
503 const wxClassInfo **parent = info->GetParents();
504 wxString str;
505
506 for (int i=0; parent[i] != NULL; i++)
507 {
508 int hhcount = DumpHandlers(parent[i], str, recursive);
509 if (hhcount)
510 {
511 hcount += hhcount;
ebfe373e 512 infostr << wxT("\n\n ") << parent[i]->GetClassName() << wxT(" PARENT'S HANDLERS:");
cc3977bf
SC
513 infostr << str;
514 }
515 }
516 }
517
518 return hcount;
519}
520
521wxString DumpClassInfo(const wxClassInfo *info, bool recursive)
522{
523 wxString infostr;
524
525 if (!info)
526 return wxEmptyString;
527
528 // basic stuff:
529
ebfe373e
DS
530 infostr << wxT("\n BASIC RTTI INFO ABOUT ") << info->GetClassName();
531 infostr << wxT("\n =================================================");
532 infostr << wxT("\n Base class #1: ") << DumpStr(info->GetBaseClassName1());
533 infostr << wxT("\n Base class #2: ") << DumpStr(info->GetBaseClassName2());
534 infostr << wxT("\n Include file: ") << DumpStr(info->GetIncludeName());
535 infostr << wxT("\n Size: ") << info->GetSize();
536 infostr << wxT("\n Dynamic: ") << (info->IsDynamic() ? wxT("true") : wxT("false"));
cc3977bf
SC
537
538
539 // advanced stuff:
540
ebfe373e
DS
541 infostr << wxT("\n\n\n ADVANCED RTTI INFO ABOUT ") << info->GetClassName();
542 infostr << wxT("\n =================================================\n");
543 infostr << wxT("\n PROPERTIES");
544 infostr << wxT("\n -----------------------------------------");
cc3977bf 545 int pcount = DumpProperties(info, infostr, recursive);
ebfe373e
DS
546 infostr << wxT("\n\n HANDLERS");
547 infostr << wxT("\n -----------------------------------------");
cc3977bf
SC
548 int hcount = DumpHandlers(info, infostr, recursive);
549
550 if (pcount+hcount == 0)
ebfe373e 551 infostr << wxT("\n\n no advanced info\n");
cc3977bf
SC
552 else
553 {
ebfe373e
DS
554 infostr << wxT("\n\n Total count of properties: ") << pcount;
555 infostr << wxT("\n Total count of handlers: ") << hcount << wxT("\n");
cc3977bf
SC
556 }
557
558 return infostr;
559}