1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: ClassListDialog implementation
4 // Author: Francesco Montorsi
6 // Created: 03/06/2007 14:49:55
7 // RCS-ID: $Id: classlist.cpp 48186 2007-08-19 19:59:54Z FM $
8 // Copyright: (c) 2007 Francesco Montorsi
9 // Licence: wxWidgets license
10 /////////////////////////////////////////////////////////////////////////////
13 // ----------------------------------------------------------------------------
15 // ----------------------------------------------------------------------------
17 // For compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
28 #include "classlist.h"
30 #if !wxUSE_EXTENDED_RTTI
31 #error This sample requires XTI (eXtended RTTI) enabled
34 // IMPLEMENT_DYNAMIC_CLASS( ClassListDialog, wxDialog ) -- see the header
35 BEGIN_EVENT_TABLE( ClassListDialog
, wxDialog
)
36 EVT_LISTBOX( ID_LISTBOX
, ClassListDialog::OnListboxSelected
)
37 EVT_TREE_SEL_CHANGED( ID_TREECTRL
, ClassListDialog::OnTreectrlSelChanged
)
38 EVT_CHOICEBOOK_PAGE_CHANGED( ID_LISTMODE
, ClassListDialog::OnChoiceBookPageChange
)
40 EVT_CHECKBOX( ID_SHOW_ONLY_XTI
, ClassListDialog::OnShowOnlyXTICheckbox
)
41 EVT_CHECKBOX( ID_SHOW_PROPERTIES_RECURSIVELY
, ClassListDialog::OnShowRecursiveInfoCheckbox
)
45 wxString
DumpClassInfo(const wxClassInfo
*, bool recursive
);
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 ClassListDialog::ClassListDialog()
57 ClassListDialog::ClassListDialog( wxWindow
* parent
, wxWindowID id
,
58 const wxString
& caption
, const wxPoint
& pos
,
59 const wxSize
& size
, long style
)
62 Create(parent
, id
, caption
, pos
, size
, style
);
65 bool ClassListDialog::Create( wxWindow
* parent
, wxWindowID id
, const wxString
& caption
,
66 const wxPoint
& pos
, const wxSize
& size
, long style
)
68 SetExtraStyle(wxWS_EX_BLOCK_EVENTS
);
69 wxDialog::Create( parent
, id
, caption
, pos
, size
, style
);
74 GetSizer()->SetSizeHints(this);
81 ClassListDialog::~ClassListDialog()
85 void ClassListDialog::Init()
87 m_pClassCountText
= NULL
;
89 m_pParentTreeCtrl
= NULL
;
90 m_pSizeListBox
= NULL
;
94 void ClassListDialog::CreateControls()
96 wxBoxSizer
* itemBoxSizer2
= new wxBoxSizer(wxVERTICAL
);
97 this->SetSizer(itemBoxSizer2
);
99 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 );
100 itemBoxSizer2
->Add(itemStaticText3
, 0, wxALIGN_LEFT
|wxALL
, 5);
103 wxBoxSizer
* filters
= new wxBoxSizer(wxHORIZONTAL
);
104 itemBoxSizer2
->Add(filters
, 0, wxGROW
|wxLEFT
|wxRIGHT
|wxBOTTOM
, 5);
105 filters
->Add(new wxCheckBox(this, ID_SHOW_ONLY_XTI
,
106 wxT("Show only classes with eXtended infos")));
107 filters
->AddSpacer(10);
108 filters
->Add(new wxCheckBox(this, ID_SHOW_PROPERTIES_RECURSIVELY
,
109 wxT("Show properties of parent classes")));
111 // show how many have we filtered out
112 m_pClassCountText
= new wxStaticText( this, wxID_STATIC
,
113 wxT("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
114 wxDefaultPosition
, wxDefaultSize
, 0 );
115 m_pClassCountText
->SetFont(wxFont(8, wxSWISS
, wxNORMAL
, wxBOLD
, false, wxT("Tahoma")));
116 itemBoxSizer2
->Add(m_pClassCountText
, 0, wxALIGN_LEFT
|wxLEFT
|wxRIGHT
|wxBOTTOM
, 5);
118 wxBoxSizer
* itemBoxSizer5
= new wxBoxSizer(wxHORIZONTAL
);
119 itemBoxSizer2
->Add(itemBoxSizer5
, 1, wxGROW
, 5);
121 m_pChoiceBook
= new wxChoicebook( this, ID_LISTMODE
, wxDefaultPosition
, wxDefaultSize
, wxCHB_DEFAULT
);
124 wxPanel
* itemPanel7
= new wxPanel( m_pChoiceBook
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxTAB_TRAVERSAL
);
125 wxBoxSizer
* itemBoxSizer8
= new wxBoxSizer(wxHORIZONTAL
);
126 itemPanel7
->SetSizer(itemBoxSizer8
);
128 wxArrayString m_pRawListBoxStrings
;
129 m_pRawListBox
= new wxListBox( itemPanel7
, ID_LISTBOX
, wxDefaultPosition
, wxDefaultSize
, m_pRawListBoxStrings
, wxLB_SINGLE
);
130 itemBoxSizer8
->Add(m_pRawListBox
, 1, wxGROW
, 5);
132 m_pChoiceBook
->AddPage(itemPanel7
, _("Raw list"));
135 wxPanel
* itemPanel13
= new wxPanel( m_pChoiceBook
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxSUNKEN_BORDER
|wxTAB_TRAVERSAL
);
136 wxBoxSizer
* itemBoxSizer14
= new wxBoxSizer(wxHORIZONTAL
);
137 itemPanel13
->SetSizer(itemBoxSizer14
);
139 wxArrayString m_pSizeListBoxStrings
;
140 m_pSizeListBox
= new wxListBox( itemPanel13
, ID_LISTBOX
, wxDefaultPosition
, wxDefaultSize
, m_pSizeListBoxStrings
, wxLB_SINGLE
);
141 itemBoxSizer14
->Add(m_pSizeListBox
, 1, wxGROW
, 5);
143 m_pChoiceBook
->AddPage(itemPanel13
, _("Classes by size"));
146 wxPanel
* itemPanel10
= new wxPanel( m_pChoiceBook
, ID_PANEL
, wxDefaultPosition
, wxDefaultSize
, wxTAB_TRAVERSAL
);
147 wxBoxSizer
* itemBoxSizer11
= new wxBoxSizer(wxVERTICAL
);
148 itemPanel10
->SetSizer(itemBoxSizer11
);
150 m_pParentTreeCtrl
= new wxTreeCtrl( itemPanel10
, ID_TREECTRL
, wxDefaultPosition
, wxSize(100, 100), wxTR_HAS_BUTTONS
|wxTR_SINGLE
);
151 itemBoxSizer11
->Add(m_pParentTreeCtrl
, 1, wxGROW
, 5);
153 m_pChoiceBook
->AddPage(itemPanel10
, _("Classes by parent"));
156 itemBoxSizer5
->Add(m_pChoiceBook
, 0, wxGROW
|wxALL
, 5);
158 m_pTextCtrl
= new wxTextCtrl( this, ID_TEXTCTRL
, _T(""), wxDefaultPosition
, wxSize(500, -1), wxTE_MULTILINE
|wxTE_READONLY
);
159 itemBoxSizer5
->Add(m_pTextCtrl
, 3, wxGROW
|wxALL
, 5);
161 wxStdDialogButtonSizer
* itemStdDialogButtonSizer17
= new wxStdDialogButtonSizer
;
163 itemBoxSizer2
->Add(itemStdDialogButtonSizer17
, 0, wxGROW
|wxALL
, 5);
164 wxButton
* itemButton18
= new wxButton( this, wxID_OK
, _("&OK"), wxDefaultPosition
, wxDefaultSize
, 0 );
165 itemStdDialogButtonSizer17
->AddButton(itemButton18
);
167 wxButton
* itemButton19
= new wxButton( this, wxID_CANCEL
, _("&Cancel"), wxDefaultPosition
, wxDefaultSize
, 0 );
168 itemStdDialogButtonSizer17
->AddButton(itemButton19
);
170 itemStdDialogButtonSizer17
->Realize();
175 int ClassListDialog::AddClassesWithParent(const wxClassInfo
*parent
, const wxTreeItemId
&id
)
177 const wxClassInfo
*ci
= wxClassInfo::GetFirst();
181 // is this class derived from the given parent?
182 if (wxString(ci
->GetBaseClassName1()) == parent
->GetClassName() ||
183 wxString(ci
->GetBaseClassName2()) == parent
->GetClassName())
185 wxTreeItemId child
= m_pParentTreeCtrl
->AppendItem(id
, ci
->GetClassName());
187 // update the name of this child with the count of the children classes
188 int ret
= AddClassesWithParent(ci
, child
);
189 m_pParentTreeCtrl
->SetItemText(child
,
190 m_pParentTreeCtrl
->GetItemText(child
) +
191 wxString::Format(wxT(" [%d]"), ret
));
198 // reorder all the children we've just added
199 m_pParentTreeCtrl
->SortChildren(id
);
204 int GetSizeOfClass(const wxString
&cn
)
206 const wxClassInfo
*ci
= wxClassInfo::FindClass(cn
);
208 return ci
->GetSize();
212 int CompareClassSizes(const wxString
&class1
, const wxString
&class2
)
214 return GetSizeOfClass(class1
) - GetSizeOfClass(class2
);
217 void ClassListDialog::InitControls()
219 // create a wxArrayString with the names of all classes:
220 const wxClassInfo
*ci
= wxClassInfo::GetFirst();
224 arr
.Add(ci
->GetClassName());
228 arr
.Sort(); // sort alphabetically
230 // now add it to the raw-mode listbox
231 for (unsigned int i
=0; i
<arr
.GetCount(); i
++)
232 if (!IsToDiscard(arr
[i
]))
233 m_pRawListBox
->Append(arr
[i
]);
234 m_nCount
= m_pRawListBox
->GetCount();
236 // sort again using size as sortkey
237 arr
.Sort((wxArrayString::CompareFunction
)CompareClassSizes
);
239 // now add it to the size-mode listbox
240 for (unsigned int i
=0; i
<arr
.GetCount(); i
++)
241 if (!IsToDiscard(arr
[i
]))
242 m_pSizeListBox
->Append(arr
[i
]);
244 // add root item to parent-mode treectrl
245 wxTreeItemId id
= m_pParentTreeCtrl
->AddRoot(_T("wxObject"));
247 // recursively add all leaves to the treectrl
248 int count
= AddClassesWithParent(CLASSINFO(wxObject
), id
);
249 m_pParentTreeCtrl
->SetItemText(id
, m_pParentTreeCtrl
->GetItemText(id
) +
250 wxString::Format(wxT(" [%d]"), count
));
252 // initially expand the root item
253 m_pParentTreeCtrl
->Expand(id
);
255 m_nTotalCount
= arr
.GetCount();
258 // don't leave blank the XTI info display
259 m_pChoiceBook
->ChangeSelection(0);
260 m_pRawListBox
->Select(0);
261 UpdateClassInfo(m_pRawListBox
->GetStringSelection());
264 bool ClassListDialog::IsToDiscard(const wxString
&classname
) const
266 wxCheckBox
*cb
= wx_static_cast(wxCheckBox
*, FindWindow(ID_SHOW_ONLY_XTI
));
267 if (!cb
|| !cb
->IsChecked())
270 // check if this class has XTI infos
271 wxClassInfo
*info
= wxClassInfo::FindClass(classname
);
274 if (info
->GetFirstProperty() != NULL
|| info
->GetFirstHandler() != NULL
)
275 return false; // has XTI info
276 return true; // no XTI info
279 void ClassListDialog::UpdateFilterText()
281 // tell the user how many registered classes are present and
282 // how many are we showing
283 m_pClassCountText
->SetLabel(
285 wxT("Showing %d classes on a total of %d registered classes in wxXTI."),
286 m_nCount
, m_nTotalCount
));
289 void ClassListDialog::UpdateClassInfo(const wxString
&itemName
)
291 wxString classname
= itemName
.BeforeFirst(_T(' '));
292 wxCheckBox
*cb
= wx_static_cast(wxCheckBox
*, FindWindow(ID_SHOW_PROPERTIES_RECURSIVELY
));
294 m_pTextCtrl
->SetValue(
295 DumpClassInfo(wxClassInfo::FindClass(classname
), cb
->IsChecked()));
299 // ----------------------------------------------------------------------------
300 // ClassListDialog - event handlers
301 // ----------------------------------------------------------------------------
303 void ClassListDialog::OnShowOnlyXTICheckbox( wxCommandEvent
& WXUNUSED(event
) )
305 m_pRawListBox
->Clear();
306 m_pParentTreeCtrl
->DeleteAllItems();
307 m_pSizeListBox
->Clear();
312 void ClassListDialog::OnShowRecursiveInfoCheckbox( wxCommandEvent
& WXUNUSED(event
) )
314 m_pRawListBox
->Clear();
315 m_pParentTreeCtrl
->DeleteAllItems();
316 m_pSizeListBox
->Clear();
321 void ClassListDialog::OnListboxSelected( wxCommandEvent
& event
)
323 UpdateClassInfo(event
.GetString());
326 void ClassListDialog::OnTreectrlSelChanged( wxTreeEvent
& event
)
328 UpdateClassInfo(m_pParentTreeCtrl
->GetItemText(event
.GetItem()));
331 void ClassListDialog::OnChoiceBookPageChange( wxChoicebookEvent
& event
)
333 switch (event
.GetSelection())
336 if (m_pRawListBox
->GetCount())
338 m_pRawListBox
->Select(0);
339 UpdateClassInfo(m_pRawListBox
->GetStringSelection());
343 if (m_pSizeListBox
->GetCount())
345 m_pSizeListBox
->Select(0);
346 UpdateClassInfo(m_pSizeListBox
->GetStringSelection());
351 wxTreeItemId root
= m_pParentTreeCtrl
->GetRootItem();
354 m_pParentTreeCtrl
->SelectItem(root
);
355 UpdateClassInfo(m_pParentTreeCtrl
->GetItemText(root
));
364 // ----------------------------------------------------------------------------
366 // ----------------------------------------------------------------------------
368 wxString
DumpStr(const wxString
&str
)
375 wxString
DumpTypeInfo(const wxTypeInfo
*ti
)
380 return DumpStr(ti
->GetTypeName());
383 wxString
DumpPropertyAccessor(const wxPropertyAccessor
*acc
, int indent
)
385 wxString ind
= _T("\n") + wxString(indent
, wxT(' '));
389 return ind
+ _T("no property accessors");
391 if (acc
->HasSetter())
392 infostr
<< ind
<< _T("setter name: ") << acc
->GetSetterName();
393 if (acc
->HasCollectionGetter())
394 infostr
<< ind
<< _T("collection getter name: ") << acc
->GetCollectionGetterName();
395 if (acc
->HasGetter())
396 infostr
<< ind
<< _T("getter name: ") << acc
->GetGetterName();
398 infostr
<< ind
<< _T("adder name: ") << acc
->GetAdderName();
403 wxString
DumpPropertyInfo(const wxPropertyInfo
*prop
, int indent
)
405 wxString ind
= _T("\n") + wxString(indent
, wxT(' '));
409 return ind
+ _T("none");
411 infostr
<< ind
<< _T("flags: ");
412 if (prop
->GetFlags() & wxPROP_DEPRECATED
)
413 infostr
<< _T("wxPROP_DEPRECATED,");
414 if (prop
->GetFlags() & wxPROP_OBJECT_GRAPH
)
415 infostr
<< _T("wxPROP_OBJECT_GRAPH,");
416 if (prop
->GetFlags() & wxPROP_ENUM_STORE_LONG
)
417 infostr
<< _T("wxPROP_ENUM_STORE_LONG,");
418 if (prop
->GetFlags() & wxPROP_DONT_STREAM
)
419 infostr
<< _T("wxPROP_DONT_STREAM,");
421 if (prop
->GetFlags() == 0)
422 infostr
<< _T("none");
424 infostr
.RemoveLast(); // remove last comma
426 infostr
<< ind
<< _T("help string: ") << DumpStr(prop
->GetHelpString());
427 infostr
<< ind
<< _T("group string: ") << DumpStr(prop
->GetGroupString());
429 infostr
<< ind
<< _T("collection element type: ") << DumpTypeInfo(prop
->GetCollectionElementTypeInfo());
430 infostr
<< ind
<< _T("type: ") << DumpTypeInfo(prop
->GetTypeInfo());
432 infostr
<< ind
<< _T("default value: ") << DumpStr(prop
->GetDefaultValue().GetAsString());
433 infostr
<< DumpPropertyAccessor(prop
->GetAccessor(), indent
+1);
438 wxString
DumpHandlerInfo(const wxHandlerInfo
*phdlr
, int indent
)
440 wxString ind
= _T("\n") + wxString(indent
, wxT(' '));
444 return ind
+ _T("none");
446 infostr
<< ind
<< _T("event class: ") <<
447 (phdlr
->GetEventClassInfo() ? phdlr
->GetEventClassInfo()->GetClassName() : wxT("none"));
452 int DumpProperties(const wxClassInfo
*info
, wxString
& infostr
, bool recursive
)
454 const wxPropertyInfo
*prop
;
456 for (prop
= info
->GetFirstProperty(), pcount
= 0;
458 prop
= prop
->GetNext(), pcount
++)
460 infostr
<< _T("\n\n [") << pcount
+1 << _T("] Property: ") << prop
->GetName();
461 infostr
<< DumpPropertyInfo(prop
, 4);
465 infostr
<< _T("\n None");
469 const wxClassInfo
**parent
= info
->GetParents();
472 for (int i
=0; parent
[i
] != NULL
; i
++)
474 int ppcount
= DumpProperties(parent
[i
], str
, recursive
);
478 infostr
<< _T("\n\n ") << parent
[i
]->GetClassName() << _T(" PARENT'S PROPERTIES:");
487 int DumpHandlers(const wxClassInfo
*info
, wxString
& infostr
, bool recursive
)
489 const wxHandlerInfo
*h
;
491 for (h
= info
->GetFirstHandler(), hcount
= 0;
493 h
= h
->GetNext(), hcount
++)
495 infostr
<< _T("\n\n [") << hcount
+1 << _T("] Handler: ") << h
->GetName();
496 infostr
<< DumpHandlerInfo(h
, 4);
500 infostr
<< _T("\n None");
504 const wxClassInfo
**parent
= info
->GetParents();
507 for (int i
=0; parent
[i
] != NULL
; i
++)
509 int hhcount
= DumpHandlers(parent
[i
], str
, recursive
);
513 infostr
<< _T("\n\n ") << parent
[i
]->GetClassName() << _T(" PARENT'S HANDLERS:");
522 wxString
DumpClassInfo(const wxClassInfo
*info
, bool recursive
)
527 return wxEmptyString
;
531 infostr
<< _T("\n BASIC RTTI INFO ABOUT ") << info
->GetClassName();
532 infostr
<< _T("\n =================================================");
533 infostr
<< _T("\n Base class #1: ") << DumpStr(info
->GetBaseClassName1());
534 infostr
<< _T("\n Base class #2: ") << DumpStr(info
->GetBaseClassName2());
535 infostr
<< _T("\n Include file: ") << DumpStr(info
->GetIncludeName());
536 infostr
<< _T("\n Size: ") << info
->GetSize();
537 infostr
<< _T("\n Dynamic: ") << (info
->IsDynamic() ? _T("true") : _T("false"));
542 infostr
<< _T("\n\n\n ADVANCED RTTI INFO ABOUT ") << info
->GetClassName();
543 infostr
<< _T("\n =================================================\n");
544 infostr
<< _T("\n PROPERTIES");
545 infostr
<< _T("\n -----------------------------------------");
546 int pcount
= DumpProperties(info
, infostr
, recursive
);
547 infostr
<< _T("\n\n HANDLERS");
548 infostr
<< _T("\n -----------------------------------------");
549 int hcount
= DumpHandlers(info
, infostr
, recursive
);
551 if (pcount
+hcount
== 0)
552 infostr
<< _T("\n\n no advanced info\n");
555 infostr
<< _T("\n\n Total count of properties: ") << pcount
;
556 infostr
<< _T("\n Total count of handlers: ") << hcount
<< _T("\n");