+void wxIdRangeManager::AddRange(const wxXmlNode* node)
+{
+ wxString name = node->GetAttribute("name");
+ wxString start = node->GetAttribute("start", "0");
+ wxString size = node->GetAttribute("size", "0");
+ if (name.empty())
+ {
+ wxXmlResource::Get()->ReportError
+ (
+ node,
+ "xrc file contains an id-range without a name"
+ );
+ return;
+ }
+
+ int index = Find(name);
+ if (index == wxNOT_FOUND)
+ {
+ wxLogTrace("xrcrange",
+ "Adding ID range, name=%s start=%s size=%s",
+ name, start, size);
+
+ m_IdRanges.push_back(new wxIdRange(node, name, start, size));
+ }
+ else
+ {
+ // There was already a range with this name. Let's hope this is
+ // from an Unload()/(re)Load(), not an unintentional duplication
+ wxLogTrace("xrcrange",
+ "Replacing ID range, name=%s start=%s size=%s",
+ name, start, size);
+
+ wxIdRange* oldrange = m_IdRanges.at(index);
+ m_IdRanges.at(index) = new wxIdRange(node, name, start, size);
+ delete oldrange;
+ }
+}
+
+wxIdRange *
+wxIdRangeManager::FindRangeForItem(const wxXmlNode* node,
+ const wxString& item,
+ wxString& value) const
+{
+ wxString basename = item.BeforeFirst('[');
+ wxCHECK_MSG( !basename.empty(), NULL,
+ "an id-range item without a range name" );
+
+ int index = Find(basename);
+ if (index == wxNOT_FOUND)
+ {
+ // Don't assert just because we've found an unexpected foo[123]
+ // Someone might just want such a name, nothing to do with ranges
+ return NULL;
+ }
+
+ value = item.Mid(basename.Len());
+ if (value.at(value.length()-1)==']')
+ {
+ return m_IdRanges.at(index);
+ }
+ wxXmlResource::Get()->ReportError(node, "a malformed id-range item");
+ return NULL;
+}
+
+void
+wxIdRangeManager::NotifyRangeOfItem(const wxXmlNode* node,
+ const wxString& item) const
+{
+ wxString value;
+ wxIdRange* range = FindRangeForItem(node, item, value);
+ if (range)
+ range->NoteItem(node, value);
+}
+
+int wxIdRangeManager::Find(const wxString& rangename) const
+{
+ for ( int i=0; i < (int)m_IdRanges.size(); ++i )
+ {
+ if (m_IdRanges.at(i)->GetName() == rangename)
+ return i;
+ }
+
+ return wxNOT_FOUND;
+}
+
+void wxIdRangeManager::FinaliseRanges(const wxXmlNode* node) const
+{
+ for ( wxVector<wxIdRange*>::const_iterator i = m_IdRanges.begin();
+ i != m_IdRanges.end(); ++i )
+ {
+ // Check if this range has already been finalised. Quite possible,
+ // as FinaliseRanges() gets called for each .xrc file loaded
+ if (!(*i)->IsFinalised())
+ {
+ wxLogTrace("xrcrange", "Finalising ID range %s", (*i)->GetName());
+ (*i)->Finalise(node);
+ }
+ }
+}
+
+
+class wxXmlSubclassFactories : public wxVector<wxXmlSubclassFactory*>
+{
+ // this is a class so that it can be forward-declared
+};
+
+wxXmlSubclassFactories *wxXmlResource::ms_subclassFactories = NULL;
+
+/*static*/ void wxXmlResource::AddSubclassFactory(wxXmlSubclassFactory *factory)
+{
+ if (!ms_subclassFactories)
+ {
+ ms_subclassFactories = new wxXmlSubclassFactories;
+ }
+ ms_subclassFactories->push_back(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;
+ }
+};
+
+
+
+
+wxXmlResourceHandlerImpl::wxXmlResourceHandlerImpl(wxXmlResourceHandler *handler)
+ :wxXmlResourceHandlerImplBase(handler)
+{
+}
+
+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())
+ {
+ for (wxXmlSubclassFactories::iterator i = wxXmlResource::ms_subclassFactories->begin();
+ i != wxXmlResource::ms_subclassFactories->end(); ++i)
+ {
+ m_handler->m_instance = (*i)->Create(subclass);
+ if (m_handler->m_instance)
+ break;
+ }
+
+ if (!m_handler->m_instance)
+ {
+ wxString name = node->GetAttribute(wxT("name"), wxEmptyString);
+ ReportError
+ (
+ node,
+ wxString::Format
+ (
+ "subclass \"%s\" not found for resource \"%s\", not subclassing",
+ subclass, name
+ )
+ );
+ }
+ }
+ }
+
+ 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 = GetHandler()->DoCreateResource();
+
+ 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;
+}
+
+bool wxXmlResourceHandlerImpl::HasParam(const wxString& param)
+{
+ return (GetParamNode(param) != NULL);
+}
+
+
+int wxXmlResourceHandlerImpl::GetStyle(const wxString& param, int defaults)
+{
+ wxString s = GetParamValue(param);
+
+ if (!s) return defaults;
+
+ wxStringTokenizer tkn(s, wxT("| \t\n"), wxTOKEN_STRTOK);