classlist.cpp 18 KB

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