wxWidgets/samples/xti/classlist.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

560 lines
18 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: classlist.cpp
// Purpose: ClassListDialog implementation
// Author: Francesco Montorsi
// Modified by:
// Created: 03/06/2007 14:49:55
// Copyright: (c) 2007 Francesco Montorsi
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "classlist.h"
#if !wxUSE_EXTENDED_RTTI
#error This sample requires XTI (eXtended RTTI) enabled
#endif
// IMPLEMENT_DYNAMIC_CLASS( ClassListDialog, wxDialog ) -- see the header
BEGIN_EVENT_TABLE( ClassListDialog, wxDialog )
EVT_LISTBOX( ID_LISTBOX, ClassListDialog::OnListboxSelected )
EVT_TREE_SEL_CHANGED( ID_TREECTRL, ClassListDialog::OnTreectrlSelChanged )
EVT_CHOICEBOOK_PAGE_CHANGED( ID_LISTMODE, ClassListDialog::OnChoiceBookPageChange )
EVT_CHECKBOX( ID_SHOW_ONLY_XTI, ClassListDialog::OnShowOnlyXTICheckbox )
EVT_CHECKBOX( ID_SHOW_PROPERTIES_RECURSIVELY, ClassListDialog::OnShowRecursiveInfoCheckbox )
END_EVENT_TABLE()
// defined later
wxString DumpClassInfo(const wxClassInfo*, bool recursive);
// ----------------------------------------------------------------------------
// ClassListDialog
// ----------------------------------------------------------------------------
ClassListDialog::ClassListDialog()
{
Init();
}
ClassListDialog::ClassListDialog( wxWindow* parent, wxWindowID id,
const wxString& caption, const wxPoint& pos,
const wxSize& size, long style )
{
Init();
Create(parent, id, caption, pos, size, style);
}
bool ClassListDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption,
const wxPoint& pos, const wxSize& size, long style )
{
SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
wxDialog::Create( parent, id, caption, pos, size, style );
CreateControls();
if (GetSizer())
{
GetSizer()->SetSizeHints(this);
}
Centre();
return true;
}
ClassListDialog::~ClassListDialog()
{
}
void ClassListDialog::Init()
{
m_pClassCountText = NULL;
m_pRawListBox = NULL;
m_pParentTreeCtrl = NULL;
m_pSizeListBox = NULL;
m_pTextCtrl = NULL;
}
void ClassListDialog::CreateControls()
{
wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
this->SetSizer(itemBoxSizer2);
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 );
itemBoxSizer2->Add(itemStaticText3, 0, wxALIGN_LEFT|wxALL, 5);
// filters
wxBoxSizer* filters = new wxBoxSizer(wxHORIZONTAL);
itemBoxSizer2->Add(filters, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5);
filters->Add(new wxCheckBox(this, ID_SHOW_ONLY_XTI,
wxT("Show only classes with eXtended infos")));
filters->AddSpacer(10);
filters->Add(new wxCheckBox(this, ID_SHOW_PROPERTIES_RECURSIVELY,
wxT("Show properties of parent classes")));
// show how many have we filtered out
m_pClassCountText = new wxStaticText( this, wxID_STATIC,
wxT("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
wxDefaultPosition, wxDefaultSize, 0 );
m_pClassCountText->SetFont(wxFont(8, wxSWISS, wxNORMAL, wxBOLD, false, wxT("Tahoma")));
itemBoxSizer2->Add(m_pClassCountText, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxBOTTOM, 5);
wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
itemBoxSizer2->Add(itemBoxSizer5, 1, wxGROW, 5);
m_pChoiceBook = new wxChoicebook( this, ID_LISTMODE, wxDefaultPosition, wxDefaultSize, wxCHB_DEFAULT );
// raw-list page
wxPanel* itemPanel7 = new wxPanel( m_pChoiceBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL);
itemPanel7->SetSizer(itemBoxSizer8);
wxArrayString m_pRawListBoxStrings;
m_pRawListBox = new wxListBox( itemPanel7, ID_LISTBOX, wxDefaultPosition, wxDefaultSize, m_pRawListBoxStrings, wxLB_SINGLE );
itemBoxSizer8->Add(m_pRawListBox, 1, wxGROW, 5);
m_pChoiceBook->AddPage(itemPanel7, _("Raw list"));
// by-size page
wxPanel* itemPanel13 = new wxPanel( m_pChoiceBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
wxBoxSizer* itemBoxSizer14 = new wxBoxSizer(wxHORIZONTAL);
itemPanel13->SetSizer(itemBoxSizer14);
wxArrayString m_pSizeListBoxStrings;
m_pSizeListBox = new wxListBox( itemPanel13, ID_LISTBOX, wxDefaultPosition, wxDefaultSize, m_pSizeListBoxStrings, wxLB_SINGLE );
itemBoxSizer14->Add(m_pSizeListBox, 1, wxGROW, 5);
m_pChoiceBook->AddPage(itemPanel13, _("Classes by size"));
// tree page
wxPanel* itemPanel10 = new wxPanel( m_pChoiceBook, ID_PANEL, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxVERTICAL);
itemPanel10->SetSizer(itemBoxSizer11);
m_pParentTreeCtrl = new wxTreeCtrl( itemPanel10, ID_TREECTRL, wxDefaultPosition, wxSize(100, 100), wxTR_HAS_BUTTONS |wxTR_SINGLE );
itemBoxSizer11->Add(m_pParentTreeCtrl, 1, wxGROW, 5);
m_pChoiceBook->AddPage(itemPanel10, _("Classes by parent"));
itemBoxSizer5->Add(m_pChoiceBook, 0, wxGROW|wxALL, 5);
m_pTextCtrl = new wxTextCtrl( this, ID_TEXTCTRL, wxT(""), wxDefaultPosition, wxSize(500, -1), wxTE_MULTILINE|wxTE_READONLY );
itemBoxSizer5->Add(m_pTextCtrl, 3, wxGROW|wxALL, 5);
wxStdDialogButtonSizer* itemStdDialogButtonSizer17 = new wxStdDialogButtonSizer;
itemBoxSizer2->Add(itemStdDialogButtonSizer17, 0, wxGROW|wxALL, 5);
wxButton* itemButton18 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
itemStdDialogButtonSizer17->AddButton(itemButton18);
wxButton* itemButton19 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
itemStdDialogButtonSizer17->AddButton(itemButton19);
itemStdDialogButtonSizer17->Realize();
InitControls();
}
int ClassListDialog::AddClassesWithParent(const wxClassInfo *parent, const wxTreeItemId &id)
{
const wxClassInfo *ci = wxClassInfo::GetFirst();
int count = 0;
while (ci)
{
// is this class derived from the given parent?
if (wxString(ci->GetBaseClassName1()) == parent->GetClassName() ||
wxString(ci->GetBaseClassName2()) == parent->GetClassName())
{
wxTreeItemId child = m_pParentTreeCtrl->AppendItem(id, ci->GetClassName());
// update the name of this child with the count of the children classes
int ret = AddClassesWithParent(ci, child);
m_pParentTreeCtrl->SetItemText(child,
m_pParentTreeCtrl->GetItemText(child) +
wxString::Format(wxT(" [%d]"), ret));
count += ret+1;
}
ci = ci->GetNext();
}
// reorder all the children we've just added
m_pParentTreeCtrl->SortChildren(id);
return count;
}
int GetSizeOfClass(const wxString &cn)
{
const wxClassInfo *ci = wxClassInfo::FindClass(cn);
if (ci)
return ci->GetSize();
return 0;
}
int CompareClassSizes(const wxString &class1, const wxString &class2)
{
return GetSizeOfClass(class1) - GetSizeOfClass(class2);
}
void ClassListDialog::InitControls()
{
// create a wxArrayString with the names of all classes:
const wxClassInfo *ci = wxClassInfo::GetFirst();
wxArrayString arr;
while (ci)
{
arr.Add(ci->GetClassName());
ci = ci->GetNext();
}
arr.Sort(); // sort alphabetically
// now add it to the raw-mode listbox
for (unsigned int i=0; i<arr.GetCount(); i++)
if (!IsToDiscard(arr[i]))
m_pRawListBox->Append(arr[i]);
m_nCount = m_pRawListBox->GetCount();
// sort again using size as sortkey
arr.Sort((wxArrayString::CompareFunction)CompareClassSizes);
// now add it to the size-mode listbox
for (unsigned int i=0; i<arr.GetCount(); i++)
if (!IsToDiscard(arr[i]))
m_pSizeListBox->Append(arr[i]);
// add root item to parent-mode treectrl
wxTreeItemId id = m_pParentTreeCtrl->AddRoot(wxT("wxObject"));
// recursively add all leaves to the treectrl
int count = AddClassesWithParent(CLASSINFO(wxObject), id);
m_pParentTreeCtrl->SetItemText(id, m_pParentTreeCtrl->GetItemText(id) +
wxString::Format(wxT(" [%d]"), count));
// initially expand the root item
m_pParentTreeCtrl->Expand(id);
m_nTotalCount = arr.GetCount();
UpdateFilterText();
// don't leave blank the XTI info display
m_pChoiceBook->ChangeSelection(0);
m_pRawListBox->Select(0);
UpdateClassInfo(m_pRawListBox->GetStringSelection());
}
bool ClassListDialog::IsToDiscard(const wxString &classname) const
{
wxCheckBox *cb = wx_static_cast(wxCheckBox*, FindWindow(ID_SHOW_ONLY_XTI));
if (!cb || !cb->IsChecked())
return false;
// check if this class has XTI infos
wxClassInfo *info = wxClassInfo::FindClass(classname);
if (!info)
return false;
if (info->GetFirstProperty() != NULL || info->GetFirstHandler() != NULL)
return false; // has XTI info
return true; // no XTI info
}
void ClassListDialog::UpdateFilterText()
{
// tell the user how many registered classes are present and
// how many are we showing
m_pClassCountText->SetLabel(
wxString::Format(
wxT("Showing %d classes on a total of %d registered classes in wxXTI."),
m_nCount, m_nTotalCount));
}
void ClassListDialog::UpdateClassInfo(const wxString &itemName)
{
wxString classname = itemName.BeforeFirst(wxT(' '));
wxCheckBox *cb = wx_static_cast(wxCheckBox*, FindWindow(ID_SHOW_PROPERTIES_RECURSIVELY));
m_pTextCtrl->SetValue(
DumpClassInfo(wxClassInfo::FindClass(classname), cb->IsChecked()));
}
// ----------------------------------------------------------------------------
// ClassListDialog - event handlers
// ----------------------------------------------------------------------------
void ClassListDialog::OnShowOnlyXTICheckbox( wxCommandEvent& WXUNUSED(event) )
{
m_pRawListBox->Clear();
m_pParentTreeCtrl->DeleteAllItems();
m_pSizeListBox->Clear();
InitControls();
}
void ClassListDialog::OnShowRecursiveInfoCheckbox( wxCommandEvent& WXUNUSED(event) )
{
m_pRawListBox->Clear();
m_pParentTreeCtrl->DeleteAllItems();
m_pSizeListBox->Clear();
InitControls();
}
void ClassListDialog::OnListboxSelected( wxCommandEvent& event )
{
UpdateClassInfo(event.GetString());
}
void ClassListDialog::OnTreectrlSelChanged( wxTreeEvent& event )
{
UpdateClassInfo(m_pParentTreeCtrl->GetItemText(event.GetItem()));
}
void ClassListDialog::OnChoiceBookPageChange( wxChoicebookEvent& event )
{
switch (event.GetSelection())
{
case 0:
if (m_pRawListBox->GetCount())
{
m_pRawListBox->Select(0);
UpdateClassInfo(m_pRawListBox->GetStringSelection());
}
break;
case 1:
if (m_pSizeListBox->GetCount())
{
m_pSizeListBox->Select(0);
UpdateClassInfo(m_pSizeListBox->GetStringSelection());
}
break;
case 2:
{
wxTreeItemId root = m_pParentTreeCtrl->GetRootItem();
if (root.IsOk())
{
m_pParentTreeCtrl->SelectItem(root);
UpdateClassInfo(m_pParentTreeCtrl->GetItemText(root));
}
}
break;
}
}
// ----------------------------------------------------------------------------
// dump functions
// ----------------------------------------------------------------------------
wxString DumpStr(const wxString &str)
{
if (str.empty())
return wxT("none");
return str;
}
wxString DumpTypeInfo(const wxTypeInfo *ti)
{
if (!ti)
return wxT("none");
return DumpStr(ti->GetTypeName());
}
wxString DumpPropertyAccessor(const wxPropertyAccessor *acc, int indent)
{
wxString ind = wxT("\n") + wxString(indent, wxT(' '));
wxString infostr;
if (!acc)
return ind + wxT("no property accessors");
if (acc->HasSetter())
infostr << ind << wxT("setter name: ") << acc->GetSetterName();
if (acc->HasCollectionGetter())
infostr << ind << wxT("collection getter name: ") << acc->GetCollectionGetterName();
if (acc->HasGetter())
infostr << ind << wxT("getter name: ") << acc->GetGetterName();
if (acc->HasAdder())
infostr << ind << wxT("adder name: ") << acc->GetAdderName();
return infostr;
}
wxString DumpPropertyInfo(const wxPropertyInfo *prop, int indent)
{
wxString ind = wxT("\n") + wxString(indent, wxT(' '));
wxString infostr;
if (!prop)
return ind + wxT("none");
infostr << ind << wxT("flags: ");
if (prop->GetFlags() & wxPROP_DEPRECATED)
infostr << wxT("wxPROP_DEPRECATED,");
if (prop->GetFlags() & wxPROP_OBJECT_GRAPH)
infostr << wxT("wxPROP_OBJECT_GRAPH,");
if (prop->GetFlags() & wxPROP_ENUM_STORE_LONG)
infostr << wxT("wxPROP_ENUM_STORE_LONG,");
if (prop->GetFlags() & wxPROP_DONT_STREAM)
infostr << wxT("wxPROP_DONT_STREAM,");
if (prop->GetFlags() == 0)
infostr << wxT("none");
else
infostr.RemoveLast(); // remove last comma
infostr << ind << wxT("help string: ") << DumpStr(prop->GetHelpString());
infostr << ind << wxT("group string: ") << DumpStr(prop->GetGroupString());
infostr << ind << wxT("collection element type: ") << DumpTypeInfo(prop->GetCollectionElementTypeInfo());
infostr << ind << wxT("type: ") << DumpTypeInfo(prop->GetTypeInfo());
infostr << ind << wxT("default value: ") << DumpStr(wxAnyGetAsString(prop->GetDefaultValue()));
infostr << DumpPropertyAccessor(prop->GetAccessor(), indent+1);
return infostr;
}
wxString DumpHandlerInfo(const wxHandlerInfo *phdlr, int indent)
{
wxString ind = wxT("\n") + wxString(indent, wxT(' '));
wxString infostr;
if (!phdlr)
return ind + wxT("none");
infostr << ind << wxT("event class: ") <<
(phdlr->GetEventClassInfo() ? phdlr->GetEventClassInfo()->GetClassName() : wxT("none"));
return infostr;
}
int DumpProperties(const wxClassInfo *info, wxString& infostr, bool recursive)
{
const wxPropertyInfo *prop;
int pcount;
for (prop = info->GetFirstProperty(), pcount = 0;
prop;
prop = prop->GetNext(), pcount++)
{
infostr << wxT("\n\n [") << pcount+1 << wxT("] Property: ") << prop->GetName();
infostr << DumpPropertyInfo(prop, 4);
}
if (pcount == 0)
infostr << wxT("\n None");
if (recursive)
{
const wxClassInfo **parent = info->GetParents();
wxString str;
for (int i=0; parent[i] != NULL; i++)
{
int ppcount = DumpProperties(parent[i], str, recursive);
if (ppcount)
{
pcount += ppcount;
infostr << wxT("\n\n ") << parent[i]->GetClassName() << wxT(" PARENT'S PROPERTIES:");
infostr << str;
}
}
}
return pcount;
}
int DumpHandlers(const wxClassInfo *info, wxString& infostr, bool recursive)
{
const wxHandlerInfo *h;
int hcount;
for (h = info->GetFirstHandler(), hcount = 0;
h;
h = h->GetNext(), hcount++)
{
infostr << wxT("\n\n [") << hcount+1 << wxT("] Handler: ") << h->GetName();
infostr << DumpHandlerInfo(h, 4);
}
if (hcount == 0)
infostr << wxT("\n None");
if (recursive)
{
const wxClassInfo **parent = info->GetParents();
wxString str;
for (int i=0; parent[i] != NULL; i++)
{
int hhcount = DumpHandlers(parent[i], str, recursive);
if (hhcount)
{
hcount += hhcount;
infostr << wxT("\n\n ") << parent[i]->GetClassName() << wxT(" PARENT'S HANDLERS:");
infostr << str;
}
}
}
return hcount;
}
wxString DumpClassInfo(const wxClassInfo *info, bool recursive)
{
wxString infostr;
if (!info)
return wxEmptyString;
// basic stuff:
infostr << wxT("\n BASIC RTTI INFO ABOUT ") << info->GetClassName();
infostr << wxT("\n =================================================");
infostr << wxT("\n Base class #1: ") << DumpStr(info->GetBaseClassName1());
infostr << wxT("\n Base class #2: ") << DumpStr(info->GetBaseClassName2());
infostr << wxT("\n Include file: ") << DumpStr(info->GetIncludeName());
infostr << wxT("\n Size: ") << info->GetSize();
infostr << wxT("\n Dynamic: ") << (info->IsDynamic() ? wxT("true") : wxT("false"));
// advanced stuff:
infostr << wxT("\n\n\n ADVANCED RTTI INFO ABOUT ") << info->GetClassName();
infostr << wxT("\n =================================================\n");
infostr << wxT("\n PROPERTIES");
infostr << wxT("\n -----------------------------------------");
int pcount = DumpProperties(info, infostr, recursive);
infostr << wxT("\n\n HANDLERS");
infostr << wxT("\n -----------------------------------------");
int hcount = DumpHandlers(info, infostr, recursive);
if (pcount+hcount == 0)
infostr << wxT("\n\n no advanced info\n");
else
{
infostr << wxT("\n\n Total count of properties: ") << pcount;
infostr << wxT("\n Total count of handlers: ") << hcount << wxT("\n");
}
return infostr;
}