Refactor wxXRC to allow defining handlers outside of xrc library.

Split wxXmlResourceHandler into an ABC and the real implementation to allow
referencing the ABC in the core library itself but without pulling in all of
the XRC into it. This also allows defining XRC handlers, which only depend on
this ABC and not the xrc library, in other libraries, such as richtext, as
demonstrated by the now enabled wxRichTextXMLHandler.

Closes #10996.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72727 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2012-10-23 13:51:32 +00:00
parent 4dca3e02a6
commit a3b9c43bbc
23 changed files with 1169 additions and 469 deletions

View File

@@ -431,16 +431,18 @@ bool wxXmlResource::Unload(const wxString& filename)
}
IMPLEMENT_ABSTRACT_CLASS(wxXmlResourceHandler, wxObject)
void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
{
wxXmlResourceHandlerImpl *impl = new wxXmlResourceHandlerImpl(handler);
handler->SetImpl(impl);
m_handlers.push_back(handler);
handler->SetParentResource(this);
}
void wxXmlResource::InsertHandler(wxXmlResourceHandler *handler)
{
wxXmlResourceHandlerImpl *impl = new wxXmlResourceHandlerImpl(handler);
handler->SetImpl(impl);
m_handlers.insert(m_handlers.begin(), handler);
handler->SetParentResource(this);
}
@@ -1401,23 +1403,35 @@ public:
wxXmlResourceHandler::wxXmlResourceHandler()
: m_node(NULL), m_parent(NULL), m_instance(NULL),
m_parentAsWindow(NULL)
{}
wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
wxXmlResourceHandlerImpl::wxXmlResourceHandlerImpl(wxXmlResourceHandler *handler)
:wxXmlResourceHandlerImplBase(handler)
{
wxXmlNode *myNode = m_node;
wxString myClass = m_class;
wxObject *myParent = m_parent, *myInstance = m_instance;
wxWindow *myParentAW = m_parentAsWindow;
}
m_instance = instance;
if (!m_instance && node->HasAttribute(wxT("subclass")) &&
!(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING))
wxObject *wxXmlResourceHandlerImpl::CreateResFromNode(wxXmlNode *node,
wxObject *parent, wxObject *instance)
{
return m_handler->m_resource->CreateResFromNode(node, parent, instance);
}
#if wxUSE_FILESYSTEM
wxFileSystem& wxXmlResourceHandlerImpl::GetCurFileSystem()
{
return m_handler->m_resource->GetCurFileSystem();
}
#endif
wxObject *wxXmlResourceHandlerImpl::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
{
wxXmlNode *myNode = m_handler->m_node;
wxString myClass = m_handler->m_class;
wxObject *myParent = m_handler->m_parent, *myInstance = m_handler->m_instance;
wxWindow *myParentAW = m_handler->m_parentAsWindow;
m_handler->m_instance = instance;
if (!m_handler->m_instance && node->HasAttribute(wxT("subclass")) &&
!(m_handler->m_resource->GetFlags() & wxXRC_NO_SUBCLASSING))
{
wxString subclass = node->GetAttribute(wxT("subclass"), wxEmptyString);
if (!subclass.empty())
@@ -1425,12 +1439,12 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent
for (wxXmlSubclassFactories::iterator i = wxXmlResource::ms_subclassFactories->begin();
i != wxXmlResource::ms_subclassFactories->end(); ++i)
{
m_instance = (*i)->Create(subclass);
if (m_instance)
m_handler->m_instance = (*i)->Create(subclass);
if (m_handler->m_instance)
break;
}
if (!m_instance)
if (!m_handler->m_instance)
{
wxString name = node->GetAttribute(wxT("name"), wxEmptyString);
ReportError
@@ -1446,70 +1460,28 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent
}
}
m_node = node;
m_class = node->GetAttribute(wxT("class"), wxEmptyString);
m_parent = parent;
m_parentAsWindow = wxDynamicCast(m_parent, wxWindow);
m_handler->m_node = node;
m_handler->m_class = node->GetAttribute(wxT("class"), wxEmptyString);
m_handler->m_parent = parent;
m_handler->m_parentAsWindow = wxDynamicCast(m_handler->m_parent, wxWindow);
wxObject *returned = DoCreateResource();
wxObject *returned = GetHandler()->DoCreateResource();
m_node = myNode;
m_class = myClass;
m_parent = myParent; m_parentAsWindow = myParentAW;
m_instance = myInstance;
m_handler->m_node = myNode;
m_handler->m_class = myClass;
m_handler->m_parent = myParent; m_handler->m_parentAsWindow = myParentAW;
m_handler->m_instance = myInstance;
return returned;
}
void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
{
m_styleNames.Add(name);
m_styleValues.Add(value);
}
void wxXmlResourceHandler::AddWindowStyles()
{
XRC_ADD_STYLE(wxCLIP_CHILDREN);
// the border styles all have the old and new names, recognize both for now
XRC_ADD_STYLE(wxSIMPLE_BORDER); XRC_ADD_STYLE(wxBORDER_SIMPLE);
XRC_ADD_STYLE(wxSUNKEN_BORDER); XRC_ADD_STYLE(wxBORDER_SUNKEN);
XRC_ADD_STYLE(wxDOUBLE_BORDER); XRC_ADD_STYLE(wxBORDER_DOUBLE); // deprecated
XRC_ADD_STYLE(wxBORDER_THEME);
XRC_ADD_STYLE(wxRAISED_BORDER); XRC_ADD_STYLE(wxBORDER_RAISED);
XRC_ADD_STYLE(wxSTATIC_BORDER); XRC_ADD_STYLE(wxBORDER_STATIC);
XRC_ADD_STYLE(wxNO_BORDER); XRC_ADD_STYLE(wxBORDER_NONE);
XRC_ADD_STYLE(wxBORDER_DEFAULT);
XRC_ADD_STYLE(wxTRANSPARENT_WINDOW);
XRC_ADD_STYLE(wxWANTS_CHARS);
XRC_ADD_STYLE(wxTAB_TRAVERSAL);
XRC_ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE);
XRC_ADD_STYLE(wxFULL_REPAINT_ON_RESIZE);
XRC_ADD_STYLE(wxVSCROLL);
XRC_ADD_STYLE(wxHSCROLL);
XRC_ADD_STYLE(wxALWAYS_SHOW_SB);
XRC_ADD_STYLE(wxWS_EX_BLOCK_EVENTS);
XRC_ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
XRC_ADD_STYLE(wxWS_EX_TRANSIENT);
XRC_ADD_STYLE(wxWS_EX_CONTEXTHELP);
XRC_ADD_STYLE(wxWS_EX_PROCESS_IDLE);
XRC_ADD_STYLE(wxWS_EX_PROCESS_UI_UPDATES);
}
bool wxXmlResourceHandler::HasParam(const wxString& param)
bool wxXmlResourceHandlerImpl::HasParam(const wxString& param)
{
return (GetParamNode(param) != NULL);
}
int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
int wxXmlResourceHandlerImpl::GetStyle(const wxString& param, int defaults)
{
wxString s = GetParamValue(param);
@@ -1522,10 +1494,10 @@ int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
while (tkn.HasMoreTokens())
{
fl = tkn.GetNextToken();
index = m_styleNames.Index(fl);
index = m_handler->m_styleNames.Index(fl);
if (index != wxNOT_FOUND)
{
style |= m_styleValues[index];
style |= m_handler->m_styleValues[index];
}
else
{
@@ -1541,19 +1513,19 @@ int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate)
wxString wxXmlResourceHandlerImpl::GetText(const wxString& param, bool translate)
{
wxXmlNode *parNode = GetParamNode(param);
wxString str1(GetNodeContent(parNode));
wxString str2;
// "\\" wasn't translated to "\" prior to 2.5.3.0:
const bool escapeBackslash = (m_resource->CompareVersion(2,5,3,0) >= 0);
const bool escapeBackslash = (m_handler->m_resource->CompareVersion(2,5,3,0) >= 0);
// VS: First version of XRC resources used $ instead of & (which is
// illegal in XML), but later I realized that '_' fits this purpose
// much better (because &File means "File with F underlined").
const wxChar amp_char = (m_resource->CompareVersion(2,3,0,1) < 0)
const wxChar amp_char = (m_handler->m_resource->CompareVersion(2,3,0,1) < 0)
? '$' : '_';
for ( wxString::const_iterator dt = str1.begin(); dt != str1.end(); ++dt )
@@ -1604,12 +1576,12 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate)
}
}
if (m_resource->GetFlags() & wxXRC_USE_LOCALE)
if (m_handler->m_resource->GetFlags() & wxXRC_USE_LOCALE)
{
if (translate && parNode &&
parNode->GetAttribute(wxT("translate"), wxEmptyString) != wxT("0"))
{
return wxGetTranslation(str2, m_resource->GetDomain());
return wxGetTranslation(str2, m_handler->m_resource->GetDomain());
}
else
{
@@ -1631,7 +1603,7 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate)
long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
long wxXmlResourceHandlerImpl::GetLong(const wxString& param, long defaultv)
{
long value = defaultv;
wxString str1 = GetParamValue(param);
@@ -1651,7 +1623,7 @@ long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
return value;
}
float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv)
float wxXmlResourceHandlerImpl::GetFloat(const wxString& param, float defaultv)
{
wxString str = GetParamValue(param);
@@ -1675,27 +1647,27 @@ float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv)
}
int wxXmlResourceHandler::GetID()
int wxXmlResourceHandlerImpl::GetID()
{
return wxXmlResource::GetXRCID(GetName());
}
wxString wxXmlResourceHandler::GetName()
wxString wxXmlResourceHandlerImpl::GetName()
{
return m_node->GetAttribute(wxT("name"), wxT("-1"));
return m_handler->m_node->GetAttribute(wxT("name"), wxT("-1"));
}
bool wxXmlResourceHandler::GetBoolAttr(const wxString& attr, bool defaultv)
bool wxXmlResourceHandlerImpl::GetBoolAttr(const wxString& attr, bool defaultv)
{
wxString v;
return m_node->GetAttribute(attr, &v) ? v == '1' : defaultv;
return m_handler->m_node->GetAttribute(attr, &v) ? v == '1' : defaultv;
}
bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
bool wxXmlResourceHandlerImpl::GetBool(const wxString& param, bool defaultv)
{
const wxString v = GetParamValue(param);
@@ -1752,7 +1724,7 @@ static wxColour GetSystemColour(const wxString& name)
return wxNullColour;
}
wxColour wxXmlResourceHandler::GetColour(const wxString& param, const wxColour& defaultv)
wxColour wxXmlResourceHandlerImpl::GetColour(const wxString& param, const wxColour& defaultv)
{
wxString v = GetParamValue(param);
@@ -1812,7 +1784,7 @@ bool GetStockArtAttrs(const wxXmlNode *paramNode,
} // anonymous namespace
wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param,
wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxString& param,
const wxArtClient& defaultArtClient,
wxSize size)
{
@@ -1833,7 +1805,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param,
return GetBitmap(node, defaultArtClient, size);
}
wxBitmap wxXmlResourceHandler::GetBitmap(const wxXmlNode* node,
wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxXmlNode* node,
const wxArtClient& defaultArtClient,
wxSize size)
{
@@ -1883,7 +1855,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxXmlNode* node,
}
wxIcon wxXmlResourceHandler::GetIcon(const wxString& param,
wxIcon wxXmlResourceHandlerImpl::GetIcon(const wxString& param,
const wxArtClient& defaultArtClient,
wxSize size)
{
@@ -1901,7 +1873,7 @@ wxIcon wxXmlResourceHandler::GetIcon(const wxString& param,
return GetIcon(node, defaultArtClient, size);
}
wxIcon wxXmlResourceHandler::GetIcon(const wxXmlNode* node,
wxIcon wxXmlResourceHandlerImpl::GetIcon(const wxXmlNode* node,
const wxArtClient& defaultArtClient,
wxSize size)
{
@@ -1911,7 +1883,7 @@ wxIcon wxXmlResourceHandler::GetIcon(const wxXmlNode* node,
}
wxIconBundle wxXmlResourceHandler::GetIconBundle(const wxString& param,
wxIconBundle wxXmlResourceHandlerImpl::GetIconBundle(const wxString& param,
const wxArtClient& defaultArtClient)
{
wxString art_id, art_client;
@@ -1959,14 +1931,14 @@ wxIconBundle wxXmlResourceHandler::GetIconBundle(const wxString& param,
}
wxImageList *wxXmlResourceHandler::GetImageList(const wxString& param)
wxImageList *wxXmlResourceHandlerImpl::GetImageList(const wxString& param)
{
wxXmlNode * const imagelist_node = GetParamNode(param);
if ( !imagelist_node )
return NULL;
wxXmlNode * const oldnode = m_node;
m_node = imagelist_node;
wxXmlNode * const oldnode = m_handler->m_node;
m_handler->m_node = imagelist_node;
// Get the size if we have it, otherwise we will use the size of the first
// list element.
@@ -1978,7 +1950,7 @@ wxImageList *wxXmlResourceHandler::GetImageList(const wxString& param)
wxString parambitmap = wxT("bitmap");
if ( HasParam(parambitmap) )
{
wxXmlNode *n = m_node->GetChildren();
wxXmlNode *n = m_handler->m_node->GetChildren();
while (n)
{
if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == parambitmap)
@@ -2003,15 +1975,15 @@ wxImageList *wxXmlResourceHandler::GetImageList(const wxString& param)
}
}
m_node = oldnode;
m_handler->m_node = oldnode;
return imagelist;
}
wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
wxXmlNode *wxXmlResourceHandlerImpl::GetParamNode(const wxString& param)
{
wxCHECK_MSG(m_node, NULL, wxT("You can't access handler data before it was initialized!"));
wxCHECK_MSG(m_handler->m_node, NULL, wxT("You can't access handler data before it was initialized!"));
wxXmlNode *n = m_node->GetChildren();
wxXmlNode *n = m_handler->m_node->GetChildren();
while (n)
{
@@ -2030,15 +2002,14 @@ wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
return NULL;
}
/* static */
bool wxXmlResourceHandler::IsOfClass(wxXmlNode *node, const wxString& classname)
bool wxXmlResourceHandlerImpl::IsOfClass(wxXmlNode *node, const wxString& classname) const
{
return node->GetAttribute(wxT("class")) == classname;
}
wxString wxXmlResourceHandler::GetNodeContent(const wxXmlNode *node)
wxString wxXmlResourceHandlerImpl::GetNodeContent(const wxXmlNode *node)
{
const wxXmlNode *n = node;
if (n == NULL) return wxEmptyString;
@@ -2056,21 +2027,21 @@ wxString wxXmlResourceHandler::GetNodeContent(const wxXmlNode *node)
wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
wxString wxXmlResourceHandlerImpl::GetParamValue(const wxString& param)
{
if (param.empty())
return GetNodeContent(m_node);
return GetNodeContent(m_handler->m_node);
else
return GetNodeContent(GetParamNode(param));
}
wxString wxXmlResourceHandler::GetParamValue(const wxXmlNode* node)
wxString wxXmlResourceHandlerImpl::GetParamValue(const wxXmlNode* node)
{
return GetNodeContent(node);
}
wxSize wxXmlResourceHandler::GetSize(const wxString& param,
wxSize wxXmlResourceHandlerImpl::GetSize(const wxString& param,
wxWindow *windowToUse)
{
wxString s = GetParamValue(param);
@@ -2098,9 +2069,9 @@ wxSize wxXmlResourceHandler::GetSize(const wxString& param,
{
return wxDLG_UNIT(windowToUse, wxSize(sx, sy));
}
else if (m_parentAsWindow)
else if (m_handler->m_parentAsWindow)
{
return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, sy));
return wxDLG_UNIT(m_handler->m_parentAsWindow, wxSize(sx, sy));
}
else
{
@@ -2118,7 +2089,7 @@ wxSize wxXmlResourceHandler::GetSize(const wxString& param,
wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
wxPoint wxXmlResourceHandlerImpl::GetPosition(const wxString& param)
{
wxSize sz = GetSize(param);
return wxPoint(sz.x, sz.y);
@@ -2126,7 +2097,7 @@ wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
wxCoord wxXmlResourceHandler::GetDimension(const wxString& param,
wxCoord wxXmlResourceHandlerImpl::GetDimension(const wxString& param,
wxCoord defaultv,
wxWindow *windowToUse)
{
@@ -2154,9 +2125,9 @@ wxCoord wxXmlResourceHandler::GetDimension(const wxString& param,
{
return wxDLG_UNIT(windowToUse, wxSize(sx, 0)).x;
}
else if (m_parentAsWindow)
else if (m_handler->m_parentAsWindow)
{
return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, 0)).x;
return wxDLG_UNIT(m_handler->m_parentAsWindow, wxSize(sx, 0)).x;
}
else
{
@@ -2173,7 +2144,7 @@ wxCoord wxXmlResourceHandler::GetDimension(const wxString& param,
}
wxDirection
wxXmlResourceHandler::GetDirection(const wxString& param, wxDirection dirDefault)
wxXmlResourceHandlerImpl::GetDirection(const wxString& param, wxDirection dirDefault)
{
wxDirection dir;
@@ -2227,7 +2198,7 @@ static wxFont GetSystemFont(const wxString& name)
return wxNullFont;
}
wxFont wxXmlResourceHandler::GetFont(const wxString& param, wxWindow* parent)
wxFont wxXmlResourceHandlerImpl::GetFont(const wxString& param, wxWindow* parent)
{
wxXmlNode *font_node = GetParamNode(param);
if (font_node == NULL)
@@ -2237,8 +2208,8 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param, wxWindow* parent)
return wxNullFont;
}
wxXmlNode *oldnode = m_node;
m_node = font_node;
wxXmlNode *oldnode = m_handler->m_node;
m_handler->m_node = font_node;
// font attributes:
@@ -2422,12 +2393,12 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param, wxWindow* parent)
underlined, facename, enc);
}
m_node = oldnode;
m_handler->m_node = oldnode;
return font;
}
void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
void wxXmlResourceHandlerImpl::SetupWindow(wxWindow *wnd)
{
//FIXME : add cursor
@@ -2463,28 +2434,28 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
}
void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
void wxXmlResourceHandlerImpl::CreateChildren(wxObject *parent, bool this_hnd_only)
{
for ( wxXmlNode *n = m_node->GetChildren(); n; n = n->GetNext() )
for ( wxXmlNode *n = m_handler->m_node->GetChildren(); n; n = n->GetNext() )
{
if ( IsObjectNode(n) )
{
m_resource->DoCreateResFromNode(*n, parent, NULL,
this_hnd_only ? this : NULL);
}
m_handler->m_resource->DoCreateResFromNode(*n, parent, NULL,
this_hnd_only ? this->GetHandler() : NULL);
}
}
}
void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode)
void wxXmlResourceHandlerImpl::CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode)
{
wxXmlNode *root;
if (rootnode == NULL) root = m_node; else root = rootnode;
if (rootnode == NULL) root = m_handler->m_node; else root = rootnode;
wxXmlNode *n = root->GetChildren();
while (n)
{
if (n->GetType() == wxXML_ELEMENT_NODE && CanHandle(n))
if (n->GetType() == wxXML_ELEMENT_NODE && GetHandler()->CanHandle(n))
{
CreateResource(n, parent, NULL);
}
@@ -2497,21 +2468,21 @@ void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode *
// errors reporting
//-----------------------------------------------------------------------------
void wxXmlResourceHandler::ReportError(const wxString& message)
void wxXmlResourceHandlerImpl::ReportError(const wxString& message)
{
m_resource->ReportError(m_node, message);
m_handler->m_resource->ReportError(m_handler->m_node, message);
}
void wxXmlResourceHandler::ReportError(wxXmlNode *context,
void wxXmlResourceHandlerImpl::ReportError(wxXmlNode *context,
const wxString& message)
{
m_resource->ReportError(context ? context : m_node, message);
m_handler->m_resource->ReportError(context ? context : m_handler->m_node, message);
}
void wxXmlResourceHandler::ReportParamError(const wxString& param,
void wxXmlResourceHandlerImpl::ReportParamError(const wxString& param,
const wxString& message)
{
m_resource->ReportError(GetParamNode(param), message);
m_handler->m_resource->ReportError(GetParamNode(param), message);
}
void wxXmlResource::ReportError(const wxXmlNode *context, const wxString& message)