implemented subclass factories for XRC

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17375 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2002-09-25 11:10:39 +00:00
parent 5e3012152c
commit 3ce501311b
4 changed files with 152 additions and 20 deletions

View File

@@ -37,6 +37,9 @@ class WXDLLEXPORT wxFrame;
class WXDLLEXPORT wxToolBar; class WXDLLEXPORT wxToolBar;
class WXXMLDLLEXPORT wxXmlResourceHandler; class WXXMLDLLEXPORT wxXmlResourceHandler;
class WXXMLDLLEXPORT wxXmlSubclassFactory;
class WXXMLDLLEXPORT wxXmlSubclassFactoriesList;
class wxXmlResourceModule;
// These macros indicate current version of XML resources (this information is // These macros indicate current version of XML resources (this information is
@@ -134,6 +137,11 @@ public:
// Removes all handlers // Removes all handlers
void ClearHandlers(); void ClearHandlers();
// Registers subclasses factory for use in XRC. This function is not meant
// for public use, please see the comment above wxXmlSubclassFactory
// definition.
static void AddSubclassFactory(wxXmlSubclassFactory *factory);
// Loads menu from resource. Returns NULL on failure. // Loads menu from resource. Returns NULL on failure.
wxMenu *LoadMenu(const wxString& name); wxMenu *LoadMenu(const wxString& name);
@@ -244,6 +252,9 @@ private:
#endif #endif
friend class wxXmlResourceHandler; friend class wxXmlResourceHandler;
friend class wxXmlResourceModule;
static wxXmlSubclassFactoriesList *ms_subclassFactories;
// singleton instance: // singleton instance:
static wxXmlResource *ms_instance; static wxXmlResource *ms_instance;
@@ -438,6 +449,20 @@ protected:
void wxXmlInitResourceModule(); void wxXmlInitResourceModule();
// This class is used to create instances of XRC "object" nodes with "subclass"
// property. It is _not_ supposed to be used by XRC users, you should instead
// register your subclasses via wxWindows' RTTI mechanism. This class is useful
// only for language bindings developer who need a way to implement subclassing
// in wxWindows ports that don't support wxRTTI (e.g. wxPython).
class WXXMLDLLEXPORT wxXmlSubclassFactory
{
public:
// Try to create instance of given class and return it, return NULL on failure:
virtual wxObject *Create(const wxString& className) = 0;
virtual ~wxXmlSubclassFactory() {}
};
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
Backward compatibility macros. Do *NOT* use, they may disappear in future Backward compatibility macros. Do *NOT* use, they may disappear in future
versions of the XRC library! versions of the XRC library!

View File

@@ -547,6 +547,40 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wx
} }
#include "wx/listimpl.cpp"
WX_DECLARE_LIST(wxXmlSubclassFactory, wxXmlSubclassFactoriesList);
WX_DEFINE_LIST(wxXmlSubclassFactoriesList);
wxXmlSubclassFactoriesList *wxXmlResource::ms_subclassFactories = NULL;
/*static*/ void wxXmlResource::AddSubclassFactory(wxXmlSubclassFactory *factory)
{
if (!ms_subclassFactories)
{
ms_subclassFactories = new wxXmlSubclassFactoriesList;
ms_subclassFactories->DeleteContents(TRUE);
}
ms_subclassFactories->Append(factory);
}
class wxXmlSubclassFactoryCXX : public wxXmlSubclassFactory
{
public:
~wxXmlSubclassFactoryCXX() {}
wxObject *Create(const wxString& className)
{
wxClassInfo* classInfo = wxClassInfo::FindClass(className);
if (classInfo)
return classInfo->CreateObject();
else
return NULL;
}
};
wxXmlResourceHandler::wxXmlResourceHandler() wxXmlResourceHandler::wxXmlResourceHandler()
@@ -568,18 +602,23 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent
!(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING)) !(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING))
{ {
wxString subclass = node->GetPropVal(wxT("subclass"), wxEmptyString); wxString subclass = node->GetPropVal(wxT("subclass"), wxEmptyString);
wxClassInfo* classInfo = wxClassInfo::FindClass(subclass); if (!subclass.empty())
{
if (classInfo) for (wxXmlSubclassFactoriesList::Node *i = wxXmlResource::ms_subclassFactories->GetFirst();
m_instance = classInfo->CreateObject(); i; i = i->GetNext())
{
m_instance = i->GetData()->Create(subclass);
if (m_instance)
break;
}
if (!m_instance) if (!m_instance)
{ {
wxString name = node->GetPropVal(wxT("name"), wxEmptyString);
wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"), wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"),
subclass.c_str(), node->GetPropVal(wxT("name"), wxEmptyString).c_str()); subclass.c_str(), name.c_str());
}
} }
m_instance = classInfo->CreateObject();
} }
m_node = node; m_node = node;
@@ -1167,11 +1206,13 @@ public:
wxXmlResourceModule() {} wxXmlResourceModule() {}
bool OnInit() bool OnInit()
{ {
wxXmlResource::AddSubclassFactory(new wxXmlSubclassFactoryCXX);
return TRUE; return TRUE;
} }
void OnExit() void OnExit()
{ {
delete wxXmlResource::Set(NULL); delete wxXmlResource::Set(NULL);
wxDELETE(wxXmlResource::ms_subclassFactories);
CleanXRCID_Records(); CleanXRCID_Records();
} }
}; };

View File

@@ -37,6 +37,9 @@ class WXDLLEXPORT wxFrame;
class WXDLLEXPORT wxToolBar; class WXDLLEXPORT wxToolBar;
class WXXMLDLLEXPORT wxXmlResourceHandler; class WXXMLDLLEXPORT wxXmlResourceHandler;
class WXXMLDLLEXPORT wxXmlSubclassFactory;
class WXXMLDLLEXPORT wxXmlSubclassFactoriesList;
class wxXmlResourceModule;
// These macros indicate current version of XML resources (this information is // These macros indicate current version of XML resources (this information is
@@ -134,6 +137,11 @@ public:
// Removes all handlers // Removes all handlers
void ClearHandlers(); void ClearHandlers();
// Registers subclasses factory for use in XRC. This function is not meant
// for public use, please see the comment above wxXmlSubclassFactory
// definition.
static void AddSubclassFactory(wxXmlSubclassFactory *factory);
// Loads menu from resource. Returns NULL on failure. // Loads menu from resource. Returns NULL on failure.
wxMenu *LoadMenu(const wxString& name); wxMenu *LoadMenu(const wxString& name);
@@ -244,6 +252,9 @@ private:
#endif #endif
friend class wxXmlResourceHandler; friend class wxXmlResourceHandler;
friend class wxXmlResourceModule;
static wxXmlSubclassFactoriesList *ms_subclassFactories;
// singleton instance: // singleton instance:
static wxXmlResource *ms_instance; static wxXmlResource *ms_instance;
@@ -438,6 +449,20 @@ protected:
void wxXmlInitResourceModule(); void wxXmlInitResourceModule();
// This class is used to create instances of XRC "object" nodes with "subclass"
// property. It is _not_ supposed to be used by XRC users, you should instead
// register your subclasses via wxWindows' RTTI mechanism. This class is useful
// only for language bindings developer who need a way to implement subclassing
// in wxWindows ports that don't support wxRTTI (e.g. wxPython).
class WXXMLDLLEXPORT wxXmlSubclassFactory
{
public:
// Try to create instance of given class and return it, return NULL on failure:
virtual wxObject *Create(const wxString& className) = 0;
virtual ~wxXmlSubclassFactory() {}
};
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
Backward compatibility macros. Do *NOT* use, they may disappear in future Backward compatibility macros. Do *NOT* use, they may disappear in future
versions of the XRC library! versions of the XRC library!

View File

@@ -547,6 +547,40 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wx
} }
#include "wx/listimpl.cpp"
WX_DECLARE_LIST(wxXmlSubclassFactory, wxXmlSubclassFactoriesList);
WX_DEFINE_LIST(wxXmlSubclassFactoriesList);
wxXmlSubclassFactoriesList *wxXmlResource::ms_subclassFactories = NULL;
/*static*/ void wxXmlResource::AddSubclassFactory(wxXmlSubclassFactory *factory)
{
if (!ms_subclassFactories)
{
ms_subclassFactories = new wxXmlSubclassFactoriesList;
ms_subclassFactories->DeleteContents(TRUE);
}
ms_subclassFactories->Append(factory);
}
class wxXmlSubclassFactoryCXX : public wxXmlSubclassFactory
{
public:
~wxXmlSubclassFactoryCXX() {}
wxObject *Create(const wxString& className)
{
wxClassInfo* classInfo = wxClassInfo::FindClass(className);
if (classInfo)
return classInfo->CreateObject();
else
return NULL;
}
};
wxXmlResourceHandler::wxXmlResourceHandler() wxXmlResourceHandler::wxXmlResourceHandler()
@@ -568,18 +602,23 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent
!(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING)) !(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING))
{ {
wxString subclass = node->GetPropVal(wxT("subclass"), wxEmptyString); wxString subclass = node->GetPropVal(wxT("subclass"), wxEmptyString);
wxClassInfo* classInfo = wxClassInfo::FindClass(subclass); if (!subclass.empty())
{
if (classInfo) for (wxXmlSubclassFactoriesList::Node *i = wxXmlResource::ms_subclassFactories->GetFirst();
m_instance = classInfo->CreateObject(); i; i = i->GetNext())
{
m_instance = i->GetData()->Create(subclass);
if (m_instance)
break;
}
if (!m_instance) if (!m_instance)
{ {
wxString name = node->GetPropVal(wxT("name"), wxEmptyString);
wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"), wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"),
subclass.c_str(), node->GetPropVal(wxT("name"), wxEmptyString).c_str()); subclass.c_str(), name.c_str());
}
} }
m_instance = classInfo->CreateObject();
} }
m_node = node; m_node = node;
@@ -1167,11 +1206,13 @@ public:
wxXmlResourceModule() {} wxXmlResourceModule() {}
bool OnInit() bool OnInit()
{ {
wxXmlResource::AddSubclassFactory(new wxXmlSubclassFactoryCXX);
return TRUE; return TRUE;
} }
void OnExit() void OnExit()
{ {
delete wxXmlResource::Set(NULL); delete wxXmlResource::Set(NULL);
wxDELETE(wxXmlResource::ms_subclassFactories);
CleanXRCID_Records(); CleanXRCID_Records();
} }
}; };