1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: ClassListDialog implementation
4 // Author: Francesco Montorsi
6 // Created: 03/06/2007 14:49:55
7 // Copyright: (c) 2007 Francesco Montorsi
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
12 // ----------------------------------------------------------------------------
14 // ----------------------------------------------------------------------------
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
27 #include "classlist.h"
29 #if !wxUSE_EXTENDED_RTTI
30 #error This sample requires XTI (eXtended RTTI) enabled
33 // IMPLEMENT_DYNAMIC_CLASS( ClassListDialog, wxDialog ) -- see the header
34 BEGIN_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
)
39 EVT_CHECKBOX( ID_SHOW_ONLY_XTI
, ClassListDialog::OnShowOnlyXTICheckbox
)
40 EVT_CHECKBOX( ID_SHOW_PROPERTIES_RECURSIVELY
, ClassListDialog::OnShowRecursiveInfoCheckbox
)
44 wxString
DumpClassInfo(const wxClassInfo
*, bool recursive
);
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 ClassListDialog::ClassListDialog()
56 ClassListDialog::ClassListDialog( wxWindow
* parent
, wxWindowID id
,
57 const wxString
& caption
, const wxPoint
& pos
,
58 const wxSize
& size
, long style
)
61 Create(parent
, id
, caption
, pos
, size
, style
);
64 bool ClassListDialog::Create( wxWindow
* parent
, wxWindowID id
, const wxString
& caption
,
65 const wxPoint
& pos
, const wxSize
& size
, long style
)
67 SetExtraStyle(wxWS_EX_BLOCK_EVENTS
);
68 wxDialog::Create( parent
, id
, caption
, pos
, size
, style
);
73 GetSizer()->SetSizeHints(this);
80 ClassListDialog::~ClassListDialog()
84 void ClassListDialog::Init()
86 m_pClassCountText
= NULL
;
88 m_pParentTreeCtrl
= NULL
;
89 m_pSizeListBox
= NULL
;
93 void ClassListDialog::CreateControls()
95 wxBoxSizer
* itemBoxSizer2
= new wxBoxSizer(wxVERTICAL
);
96 this->SetSizer(itemBoxSizer2
);
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);
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")));
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);
117 wxBoxSizer
* itemBoxSizer5
= new wxBoxSizer(wxHORIZONTAL
);
118 itemBoxSizer2
->Add(itemBoxSizer5
, 1, wxGROW
, 5);
120 m_pChoiceBook
= new wxChoicebook( this, ID_LISTMODE
, wxDefaultPosition
, wxDefaultSize
, wxCHB_DEFAULT
);
123 wxPanel
* itemPanel7
= new wxPanel( m_pChoiceBook
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxTAB_TRAVERSAL
);
124 wxBoxSizer
* itemBoxSizer8
= new wxBoxSizer(wxHORIZONTAL
);
125 itemPanel7
->SetSizer(itemBoxSizer8
);
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);
131 m_pChoiceBook
->AddPage(itemPanel7
, _("Raw list"));
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
);
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);
142 m_pChoiceBook
->AddPage(itemPanel13
, _("Classes by size"));
145 wxPanel
* itemPanel10
= new wxPanel( m_pChoiceBook
, ID_PANEL
, wxDefaultPosition
, wxDefaultSize
, wxTAB_TRAVERSAL
);
146 wxBoxSizer
* itemBoxSizer11
= new wxBoxSizer(wxVERTICAL
);
147 itemPanel10
->SetSizer(itemBoxSizer11
);
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);
152 m_pChoiceBook
->AddPage(itemPanel10
, _("Classes by parent"));
155 itemBoxSizer5
->Add(m_pChoiceBook
, 0, wxGROW
|wxALL
, 5);
157 m_pTextCtrl
= new wxTextCtrl( this, ID_TEXTCTRL
, wxT(""), wxDefaultPosition
, wxSize(500, -1), wxTE_MULTILINE
|wxTE_READONLY
);
158 itemBoxSizer5
->Add(m_pTextCtrl
, 3, wxGROW
|wxALL
, 5);
160 wxStdDialogButtonSizer
* itemStdDialogButtonSizer17
= new wxStdDialogButtonSizer
;
162 itemBoxSizer2
->Add(itemStdDialogButtonSizer17
, 0, wxGROW
|wxALL
, 5);
163 wxButton
* itemButton18
= new wxButton( this, wxID_OK
, _("&OK"), wxDefaultPosition
, wxDefaultSize
, 0 );
164 itemStdDialogButtonSizer17
->AddButton(itemButton18
);
166 wxButton
* itemButton19
= new wxButton( this, wxID_CANCEL
, _("&Cancel"), wxDefaultPosition
, wxDefaultSize
, 0 );
167 itemStdDialogButtonSizer17
->AddButton(itemButton19
);
169 itemStdDialogButtonSizer17
->Realize();
174 int ClassListDialog::AddClassesWithParent(const wxClassInfo
*parent
, const wxTreeItemId
&id
)
176 const wxClassInfo
*ci
= wxClassInfo::GetFirst();
180 // is this class derived from the given parent?
181 if (wxString(ci
->GetBaseClassName1()) == parent
->GetClassName() ||
182 wxString(ci
->GetBaseClassName2()) == parent
->GetClassName())
184 wxTreeItemId child
= m_pParentTreeCtrl
->AppendItem(id
, ci
->GetClassName());
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
));
197 // reorder all the children we've just added
198 m_pParentTreeCtrl
->SortChildren(id
);
203 int GetSizeOfClass(const wxString
&cn
)
205 const wxClassInfo
*ci
= wxClassInfo::FindClass(cn
);
207 return ci
->GetSize();
211 int CompareClassSizes(const wxString
&class1
, const wxString
&class2
)
213 return GetSizeOfClass(class1
) - GetSizeOfClass(class2
);
216 void ClassListDialog::InitControls()
218 // create a wxArrayString with the names of all classes:
219 const wxClassInfo
*ci
= wxClassInfo::GetFirst();
223 arr
.Add(ci
->GetClassName());
227 arr
.Sort(); // sort alphabetically
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();
235 // sort again using size as sortkey
236 arr
.Sort((wxArrayString::CompareFunction
)CompareClassSizes
);
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
]);
243 // add root item to parent-mode treectrl
244 wxTreeItemId id
= m_pParentTreeCtrl
->AddRoot(wxT("wxObject"));
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
));
251 // initially expand the root item
252 m_pParentTreeCtrl
->Expand(id
);
254 m_nTotalCount
= arr
.GetCount();
257 // don't leave blank the XTI info display
258 m_pChoiceBook
->ChangeSelection(0);
259 m_pRawListBox
->Select(0);
260 UpdateClassInfo(m_pRawListBox
->GetStringSelection());
263 bool ClassListDialog::IsToDiscard(const wxString
&classname
) const
265 wxCheckBox
*cb
= wx_static_cast(wxCheckBox
*, FindWindow(ID_SHOW_ONLY_XTI
));
266 if (!cb
|| !cb
->IsChecked())
269 // check if this class has XTI infos
270 wxClassInfo
*info
= wxClassInfo::FindClass(classname
);
273 if (info
->GetFirstProperty() != NULL
|| info
->GetFirstHandler() != NULL
)
274 return false; // has XTI info
275 return true; // no XTI info
278 void ClassListDialog::UpdateFilterText()
280 // tell the user how many registered classes are present and
281 // how many are we showing
282 m_pClassCountText
->SetLabel(
284 wxT("Showing %d classes on a total of %d registered classes in wxXTI."),
285 m_nCount
, m_nTotalCount
));
288 void ClassListDialog::UpdateClassInfo(const wxString
&itemName
)
290 wxString classname
= itemName
.BeforeFirst(wxT(' '));
291 wxCheckBox
*cb
= wx_static_cast(wxCheckBox
*, FindWindow(ID_SHOW_PROPERTIES_RECURSIVELY
));
293 m_pTextCtrl
->SetValue(
294 DumpClassInfo(wxClassInfo::FindClass(classname
), cb
->IsChecked()));
298 // ----------------------------------------------------------------------------
299 // ClassListDialog - event handlers
300 // ----------------------------------------------------------------------------
302 void ClassListDialog::OnShowOnlyXTICheckbox( wxCommandEvent
& WXUNUSED(event
) )
304 m_pRawListBox
->Clear();
305 m_pParentTreeCtrl
->DeleteAllItems();
306 m_pSizeListBox
->Clear();
311 void ClassListDialog::OnShowRecursiveInfoCheckbox( wxCommandEvent
& WXUNUSED(event
) )
313 m_pRawListBox
->Clear();
314 m_pParentTreeCtrl
->DeleteAllItems();
315 m_pSizeListBox
->Clear();
320 void ClassListDialog::OnListboxSelected( wxCommandEvent
& event
)
322 UpdateClassInfo(event
.GetString());
325 void ClassListDialog::OnTreectrlSelChanged( wxTreeEvent
& event
)
327 UpdateClassInfo(m_pParentTreeCtrl
->GetItemText(event
.GetItem()));
330 void ClassListDialog::OnChoiceBookPageChange( wxChoicebookEvent
& event
)
332 switch (event
.GetSelection())
335 if (m_pRawListBox
->GetCount())
337 m_pRawListBox
->Select(0);
338 UpdateClassInfo(m_pRawListBox
->GetStringSelection());
342 if (m_pSizeListBox
->GetCount())
344 m_pSizeListBox
->Select(0);
345 UpdateClassInfo(m_pSizeListBox
->GetStringSelection());
350 wxTreeItemId root
= m_pParentTreeCtrl
->GetRootItem();
353 m_pParentTreeCtrl
->SelectItem(root
);
354 UpdateClassInfo(m_pParentTreeCtrl
->GetItemText(root
));
363 // ----------------------------------------------------------------------------
365 // ----------------------------------------------------------------------------
367 wxString
DumpStr(const wxString
&str
)
374 wxString
DumpTypeInfo(const wxTypeInfo
*ti
)
379 return DumpStr(ti
->GetTypeName());
382 wxString
DumpPropertyAccessor(const wxPropertyAccessor
*acc
, int indent
)
384 wxString ind
= wxT("\n") + wxString(indent
, wxT(' '));
388 return ind
+ wxT("no property accessors");
390 if (acc
->HasSetter())
391 infostr
<< ind
<< wxT("setter name: ") << acc
->GetSetterName();
392 if (acc
->HasCollectionGetter())
393 infostr
<< ind
<< wxT("collection getter name: ") << acc
->GetCollectionGetterName();
394 if (acc
->HasGetter())
395 infostr
<< ind
<< wxT("getter name: ") << acc
->GetGetterName();
397 infostr
<< ind
<< wxT("adder name: ") << acc
->GetAdderName();
402 wxString
DumpPropertyInfo(const wxPropertyInfo
*prop
, int indent
)
404 wxString ind
= wxT("\n") + wxString(indent
, wxT(' '));
408 return ind
+ wxT("none");
410 infostr
<< ind
<< wxT("flags: ");
411 if (prop
->GetFlags() & wxPROP_DEPRECATED
)
412 infostr
<< wxT("wxPROP_DEPRECATED,");
413 if (prop
->GetFlags() & wxPROP_OBJECT_GRAPH
)
414 infostr
<< wxT("wxPROP_OBJECT_GRAPH,");
415 if (prop
->GetFlags() & wxPROP_ENUM_STORE_LONG
)
416 infostr
<< wxT("wxPROP_ENUM_STORE_LONG,");
417 if (prop
->GetFlags() & wxPROP_DONT_STREAM
)
418 infostr
<< wxT("wxPROP_DONT_STREAM,");
420 if (prop
->GetFlags() == 0)
421 infostr
<< wxT("none");
423 infostr
.RemoveLast(); // remove last comma
425 infostr
<< ind
<< wxT("help string: ") << DumpStr(prop
->GetHelpString());
426 infostr
<< ind
<< wxT("group string: ") << DumpStr(prop
->GetGroupString());
428 infostr
<< ind
<< wxT("collection element type: ") << DumpTypeInfo(prop
->GetCollectionElementTypeInfo());
429 infostr
<< ind
<< wxT("type: ") << DumpTypeInfo(prop
->GetTypeInfo());
431 infostr
<< ind
<< wxT("default value: ") << DumpStr(wxAnyGetAsString(prop
->GetDefaultValue()));
432 infostr
<< DumpPropertyAccessor(prop
->GetAccessor(), indent
+1);
437 wxString
DumpHandlerInfo(const wxHandlerInfo
*phdlr
, int indent
)
439 wxString ind
= wxT("\n") + wxString(indent
, wxT(' '));
443 return ind
+ wxT("none");
445 infostr
<< ind
<< wxT("event class: ") <<
446 (phdlr
->GetEventClassInfo() ? phdlr
->GetEventClassInfo()->GetClassName() : wxT("none"));
451 int DumpProperties(const wxClassInfo
*info
, wxString
& infostr
, bool recursive
)
453 const wxPropertyInfo
*prop
;
455 for (prop
= info
->GetFirstProperty(), pcount
= 0;
457 prop
= prop
->GetNext(), pcount
++)
459 infostr
<< wxT("\n\n [") << pcount
+1 << wxT("] Property: ") << prop
->GetName();
460 infostr
<< DumpPropertyInfo(prop
, 4);
464 infostr
<< wxT("\n None");
468 const wxClassInfo
**parent
= info
->GetParents();
471 for (int i
=0; parent
[i
] != NULL
; i
++)
473 int ppcount
= DumpProperties(parent
[i
], str
, recursive
);
477 infostr
<< wxT("\n\n ") << parent
[i
]->GetClassName() << wxT(" PARENT'S PROPERTIES:");
486 int DumpHandlers(const wxClassInfo
*info
, wxString
& infostr
, bool recursive
)
488 const wxHandlerInfo
*h
;
490 for (h
= info
->GetFirstHandler(), hcount
= 0;
492 h
= h
->GetNext(), hcount
++)
494 infostr
<< wxT("\n\n [") << hcount
+1 << wxT("] Handler: ") << h
->GetName();
495 infostr
<< DumpHandlerInfo(h
, 4);
499 infostr
<< wxT("\n None");
503 const wxClassInfo
**parent
= info
->GetParents();
506 for (int i
=0; parent
[i
] != NULL
; i
++)
508 int hhcount
= DumpHandlers(parent
[i
], str
, recursive
);
512 infostr
<< wxT("\n\n ") << parent
[i
]->GetClassName() << wxT(" PARENT'S HANDLERS:");
521 wxString
DumpClassInfo(const wxClassInfo
*info
, bool recursive
)
526 return wxEmptyString
;
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"));
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 -----------------------------------------");
545 int pcount
= DumpProperties(info
, infostr
, recursive
);
546 infostr
<< wxT("\n\n HANDLERS");
547 infostr
<< wxT("\n -----------------------------------------");
548 int hcount
= DumpHandlers(info
, infostr
, recursive
);
550 if (pcount
+hcount
== 0)
551 infostr
<< wxT("\n\n no advanced info\n");
554 infostr
<< wxT("\n\n Total count of properties: ") << pcount
;
555 infostr
<< wxT("\n Total count of handlers: ") << hcount
<< wxT("\n");