1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     XRC resources 
   4 // Author:      Vaclav Slavik 
   7 // Copyright:   (c) 2000 Vaclav Slavik 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation "xmlres.h" 
  15 // For compilers that support precompilation, includes "wx.h". 
  16 #include "wx/wxprec.h" 
  22 #include "wx/dialog.h" 
  25 #include "wx/wfstream.h" 
  26 #include "wx/filesys.h" 
  27 #include "wx/filename.h" 
  30 #include "wx/tokenzr.h" 
  31 #include "wx/fontenum.h" 
  32 #include "wx/module.h" 
  33 #include "wx/bitmap.h" 
  35 #include "wx/fontmap.h" 
  36 #include "wx/artprov.h" 
  38 #include "wx/xml/xml.h" 
  39 #include "wx/xrc/xmlres.h" 
  41 #include "wx/arrimpl.cpp" 
  42 WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords
); 
  45 wxXmlResource 
*wxXmlResource::ms_instance 
= NULL
; 
  47 /*static*/ wxXmlResource 
*wxXmlResource::Get() 
  50         ms_instance 
= new wxXmlResource
; 
  54 /*static*/ wxXmlResource 
*wxXmlResource::Set(wxXmlResource 
*res
) 
  56     wxXmlResource 
*old 
= ms_instance
; 
  61 wxXmlResource::wxXmlResource(int flags
) 
  63     m_handlers
.DeleteContents(TRUE
); 
  68 wxXmlResource::wxXmlResource(const wxString
& filemask
, int flags
) 
  72     m_handlers
.DeleteContents(TRUE
); 
  76 wxXmlResource::~wxXmlResource() 
  82 bool wxXmlResource::Load(const wxString
& filemask
) 
  85     wxXmlResourceDataRecord 
*drec
; 
  86     bool iswild 
= wxIsWild(filemask
); 
  91 #   define wxXmlFindFirst  fsys.FindFirst(filemask, wxFILE) 
  92 #   define wxXmlFindNext   fsys.FindNext() 
  94 #   define wxXmlFindFirst  wxFindFirstFile(filemask, wxFILE) 
  95 #   define wxXmlFindNext   wxFindNextFile() 
 103         // NB: Load() accepts both filenames and URLs (should probably be 
 104         //     changed to filenames only, but embedded resources currently 
 105         //     rely on its ability to handle URLs - FIXME). This check 
 106         //     serves as a quick way to determine whether found name is 
 107         //     filename and not URL: 
 108         if (wxFileName::FileExists(fnd
)) 
 110             // Make the name absolute filename, because the app may 
 111             // change working directory later: 
 116                 fnd 
= fn
.GetFullPath(); 
 119             fnd 
= wxFileSystem::FileNameToURL(fnd
); 
 124         if (fnd
.Lower().Matches(wxT("*.zip")) || 
 125             fnd
.Lower().Matches(wxT("*.xrs"))) 
 127             wxString 
url(wxFileSystem::FileNameToURL(fnd
)); 
 128             rt 
= rt 
&& Load(url 
+ wxT("#zip:*.xrc")); 
 133             drec 
= new wxXmlResourceDataRecord
; 
 143 #   undef wxXmlFindFirst 
 144 #   undef wxXmlFindNext 
 149 IMPLEMENT_ABSTRACT_CLASS(wxXmlResourceHandler
, wxObject
) 
 151 void wxXmlResource::AddHandler(wxXmlResourceHandler 
*handler
) 
 153     m_handlers
.Append(handler
); 
 154     handler
->SetParentResource(this); 
 157 void wxXmlResource::InsertHandler(wxXmlResourceHandler 
*handler
) 
 159     m_handlers
.Insert(handler
); 
 160     handler
->SetParentResource(this); 
 165 void wxXmlResource::ClearHandlers() 
 171 wxMenu 
*wxXmlResource::LoadMenu(const wxString
& name
) 
 173     return (wxMenu
*)CreateResFromNode(FindResource(name
, wxT("wxMenu")), NULL
, NULL
); 
 178 wxMenuBar 
*wxXmlResource::LoadMenuBar(wxWindow 
*parent
, const wxString
& name
) 
 180     return (wxMenuBar
*)CreateResFromNode(FindResource(name
, wxT("wxMenuBar")), parent
, NULL
); 
 186 wxToolBar 
*wxXmlResource::LoadToolBar(wxWindow 
*parent
, const wxString
& name
) 
 188     return (wxToolBar
*)CreateResFromNode(FindResource(name
, wxT("wxToolBar")), parent
, NULL
); 
 193 wxDialog 
*wxXmlResource::LoadDialog(wxWindow 
*parent
, const wxString
& name
) 
 195     return (wxDialog
*)CreateResFromNode(FindResource(name
, wxT("wxDialog")), parent
, NULL
); 
 198 bool wxXmlResource::LoadDialog(wxDialog 
*dlg
, wxWindow 
*parent
, const wxString
& name
) 
 200     return CreateResFromNode(FindResource(name
, wxT("wxDialog")), parent
, dlg
) != NULL
; 
 205 wxPanel 
*wxXmlResource::LoadPanel(wxWindow 
*parent
, const wxString
& name
) 
 207     return (wxPanel
*)CreateResFromNode(FindResource(name
, wxT("wxPanel")), parent
, NULL
); 
 210 bool wxXmlResource::LoadPanel(wxPanel 
*panel
, wxWindow 
*parent
, const wxString
& name
) 
 212     return CreateResFromNode(FindResource(name
, wxT("wxPanel")), parent
, panel
) != NULL
; 
 215 wxFrame 
*wxXmlResource::LoadFrame(wxWindow
* parent
, const wxString
& name
) 
 217     return (wxFrame
*)CreateResFromNode(FindResource(name
, wxT("wxFrame")), parent
, NULL
); 
 220 bool wxXmlResource::LoadFrame(wxFrame
* frame
, wxWindow 
*parent
, const wxString
& name
) 
 222     return CreateResFromNode(FindResource(name
, wxT("wxFrame")), parent
, frame
) != NULL
; 
 225 wxBitmap 
wxXmlResource::LoadBitmap(const wxString
& name
) 
 227     wxBitmap 
*bmp 
= (wxBitmap
*)CreateResFromNode( 
 228                                FindResource(name
, wxT("wxBitmap")), NULL
, NULL
); 
 231     if (bmp
) { rt 
= *bmp
; delete bmp
; } 
 235 wxIcon 
wxXmlResource::LoadIcon(const wxString
& name
) 
 237     wxIcon 
*icon 
= (wxIcon
*)CreateResFromNode( 
 238                             FindResource(name
, wxT("wxIcon")), NULL
, NULL
); 
 241     if (icon
) { rt 
= *icon
; delete icon
; } 
 246 wxObject 
*wxXmlResource::LoadObject(wxWindow 
*parent
, const wxString
& name
, const wxString
& classname
) 
 248     return CreateResFromNode(FindResource(name
, classname
), parent
, NULL
); 
 251 bool wxXmlResource::LoadObject(wxObject 
*instance
, wxWindow 
*parent
, const wxString
& name
, const wxString
& classname
) 
 253     return CreateResFromNode(FindResource(name
, classname
), parent
, instance
) != NULL
; 
 257 bool wxXmlResource::AttachUnknownControl(const wxString
& name
, 
 258                                          wxWindow 
*control
, wxWindow 
*parent
) 
 261         parent 
= control
->GetParent(); 
 262     wxWindow 
*container 
= parent
->FindWindow(name 
+ wxT("_container")); 
 265         wxLogError(_("Cannot find container for unknown control '%s'."), name
.c_str()); 
 268     return control
->Reparent(container
); 
 272 static void ProcessPlatformProperty(wxXmlNode 
*node
) 
 277     wxXmlNode 
*c 
= node
->GetChildren(); 
 281         if (!c
->GetPropVal(wxT("platform"), &s
)) 
 285             wxStringTokenizer 
tkn(s
, wxT(" |")); 
 287             while (tkn
.HasMoreTokens()) 
 289                 s 
= tkn
.GetNextToken(); 
 291                 if (s 
== wxT("win")) isok 
= true; 
 293 #if defined(__MAC__) || defined(__APPLE__) 
 294                 if (s 
== wxT("mac")) isok 
= true; 
 295 #elif defined(__UNIX__) 
 296                 if (s 
== wxT("unix")) isok 
= true; 
 299                 if (s 
== wxT("os2")) isok 
= true; 
 309             ProcessPlatformProperty(c
); 
 314             wxXmlNode 
*c2 
= c
->GetNext(); 
 315             node
->RemoveChild(c
); 
 324 void wxXmlResource::UpdateResources() 
 327 #   if wxUSE_FILESYSTEM 
 328     wxFSFile 
*file 
= NULL
; 
 332     wxString 
encoding(wxT("UTF-8")); 
 333 #if !wxUSE_UNICODE && wxUSE_INTL 
 334     if ( (GetFlags() & wxXRC_USE_LOCALE
) == 0 ) 
 336         // In case we are not using wxLocale to translate strings, convert the 
 337         // strings GUI's charset. This must not be done when wxXRC_USE_LOCALE 
 338         // is on, because it could break wxGetTranslation lookup. 
 339         encoding 
= wxLocale::GetSystemEncodingName(); 
 343     for (size_t i 
= 0; i 
< m_data
.GetCount(); i
++) 
 345         modif 
= (m_data
[i
].Doc 
== NULL
); 
 349 #           if wxUSE_FILESYSTEM 
 350             file 
= fsys
.OpenFile(m_data
[i
].File
); 
 351             modif 
= file 
&& file
->GetModificationTime() > m_data
[i
].Time
; 
 353                 wxLogError(_("Cannot open file '%s'."), m_data
[i
].File
.c_str()); 
 356             modif 
= wxDateTime(wxFileModificationTime(m_data
[i
].File
)) > m_data
[i
].Time
; 
 362             wxInputStream 
*stream 
= NULL
; 
 364 #           if wxUSE_FILESYSTEM 
 365             file 
= fsys
.OpenFile(m_data
[i
].File
); 
 367                                 stream 
= file
->GetStream(); 
 369             stream 
= new wxFileInputStream(m_data
[i
].File
); 
 374                 delete m_data
[i
].Doc
; 
 375                 m_data
[i
].Doc 
= new wxXmlDocument
; 
 377             if (!stream 
|| !m_data
[i
].Doc
->Load(*stream
, encoding
)) 
 379                 wxLogError(_("Cannot load resources from file '%s'."), 
 380                            m_data
[i
].File
.c_str()); 
 381                 wxDELETE(m_data
[i
].Doc
); 
 383             else if (m_data
[i
].Doc
->GetRoot()->GetName() != wxT("resource")) 
 385                 wxLogError(_("Invalid XRC resource '%s': doesn't have root node 'resource'."), m_data
[i
].File
.c_str()); 
 386                 wxDELETE(m_data
[i
].Doc
); 
 392                 wxString verstr 
= m_data
[i
].Doc
->GetRoot()->GetPropVal( 
 393                                       wxT("version"), wxT("0.0.0.0")); 
 394                 if (wxSscanf(verstr
.c_str(), wxT("%i.%i.%i.%i"), 
 395                     &v1
, &v2
, &v3
, &v4
) == 4) 
 396                     version 
= v1
*256*256*256+v2
*256*256+v3
*256+v4
; 
 401                 if (m_version 
!= version
) 
 402                     wxLogError(_("Resource files must have same version number!")); 
 404                 ProcessPlatformProperty(m_data
[i
].Doc
->GetRoot()); 
 405                                 m_data
[i
].Time 
= file
->GetModificationTime(); 
 408 #           if wxUSE_FILESYSTEM 
 418 wxXmlNode 
*wxXmlResource::DoFindResource(wxXmlNode 
*parent
, 
 419                                          const wxString
& name
, 
 420                                          const wxString
& classname
, 
 426     // first search for match at the top-level nodes (as this is 
 427     // where the resource is most commonly looked for): 
 428     for (node 
= parent
->GetChildren(); node
; node 
= node
->GetNext()) 
 430         if ( node
->GetType() == wxXML_ELEMENT_NODE 
&& 
 431                  (node
->GetName() == wxT("object") || 
 432                   node
->GetName() == wxT("object_ref")) && 
 433              node
->GetPropVal(wxT("name"), &dummy
) && dummy 
== name 
) 
 435             wxString 
cls(node
->GetPropVal(wxT("class"), wxEmptyString
)); 
 436             if (!classname 
|| cls 
== classname
) 
 438             // object_ref may not have 'class' property: 
 439             if (cls
.empty() && node
->GetName() == wxT("object_ref")) 
 441                 wxString refName 
= node
->GetPropVal(wxT("ref"), wxEmptyString
); 
 444                 wxXmlNode
* refNode 
= FindResource(refName
, wxEmptyString
, TRUE
); 
 446                     refNode
->GetPropVal(wxT("class"), wxEmptyString
) == classname
) 
 455         for (node 
= parent
->GetChildren(); node
; node 
= node
->GetNext()) 
 457             if ( node
->GetType() == wxXML_ELEMENT_NODE 
&& 
 458                  (node
->GetName() == wxT("object") || 
 459                   node
->GetName() == wxT("object_ref")) ) 
 461                 wxXmlNode
* found 
= DoFindResource(node
, name
, classname
, TRUE
); 
 470 wxXmlNode 
*wxXmlResource::FindResource(const wxString
& name
, 
 471                                        const wxString
& classname
, 
 474     UpdateResources(); //ensure everything is up-to-date 
 477     for (size_t f 
= 0; f 
< m_data
.GetCount(); f
++) 
 479         if ( m_data
[f
].Doc 
== NULL 
|| m_data
[f
].Doc
->GetRoot() == NULL 
) 
 482         wxXmlNode
* found 
= DoFindResource(m_data
[f
].Doc
->GetRoot(), 
 483                                           name
, classname
, recursive
); 
 487             m_curFileSystem
.ChangePathTo(m_data
[f
].File
); 
 493     wxLogError(_("XRC resource '%s' (class '%s') not found!"), 
 494                name
.c_str(), classname
.c_str()); 
 498 static void MergeNodes(wxXmlNode
& dest
, wxXmlNode
& with
) 
 501     for (wxXmlProperty 
*prop 
= with
.GetProperties(); prop
; prop 
= prop
->GetNext()) 
 503         wxXmlProperty 
*dprop
; 
 504         for (dprop 
= dest
.GetProperties(); dprop
; dprop 
= dprop
->GetNext()) 
 507             if ( dprop
->GetName() == prop
->GetName() ) 
 509                 dprop
->SetValue(prop
->GetValue()); 
 515             dest
.AddProperty(prop
->GetName(), prop
->GetValue()); 
 518     // Merge child nodes: 
 519     for (wxXmlNode
* node 
= with
.GetChildren(); node
; node 
= node
->GetNext()) 
 521         wxString name 
= node
->GetPropVal(wxT("name"), wxEmptyString
); 
 524         for (dnode 
= dest
.GetChildren(); dnode
; dnode 
= dnode
->GetNext() ) 
 526             if ( dnode
->GetName() == node
->GetName() && 
 527                  dnode
->GetPropVal(wxT("name"), wxEmptyString
) == name 
&& 
 528                  dnode
->GetType() == node
->GetType() ) 
 530                 MergeNodes(*dnode
, *node
); 
 536             dest
.AddChild(new wxXmlNode(*node
)); 
 539     if ( dest
.GetType() == wxXML_TEXT_NODE 
&& with
.GetContent().Length() ) 
 540          dest
.SetContent(with
.GetContent()); 
 543 wxObject 
*wxXmlResource::CreateResFromNode(wxXmlNode 
*node
, wxObject 
*parent
, 
 545                                            wxXmlResourceHandler 
*handlerToUse
) 
 547     if (node 
== NULL
) return NULL
; 
 549     // handling of referenced resource 
 550     if ( node
->GetName() == wxT("object_ref") ) 
 552         wxString refName 
= node
->GetPropVal(wxT("ref"), wxEmptyString
); 
 553         wxXmlNode
* refNode 
= FindResource(refName
, wxEmptyString
, TRUE
); 
 557             wxLogError(_("Referenced object node with ref=\"%s\" not found!"), 
 562         wxXmlNode 
copy(*refNode
); 
 563         MergeNodes(copy
, *node
); 
 565         return CreateResFromNode(©
, parent
, instance
); 
 568     wxXmlResourceHandler 
*handler
; 
 572         if (handlerToUse
->CanHandle(node
)) 
 574             return handlerToUse
->CreateResource(node
, parent
, instance
); 
 577     else if (node
->GetName() == wxT("object")) 
 579         wxNode 
*ND 
= m_handlers
.GetFirst(); 
 582             handler 
= (wxXmlResourceHandler
*)ND
->GetData(); 
 583             if (handler
->CanHandle(node
)) 
 585                 return handler
->CreateResource(node
, parent
, instance
); 
 591     wxLogError(_("No handler found for XML node '%s', class '%s'!"), 
 592                node
->GetName().c_str(), 
 593                node
->GetPropVal(wxT("class"), wxEmptyString
).c_str()); 
 598 #include "wx/listimpl.cpp" 
 599 WX_DECLARE_LIST(wxXmlSubclassFactory
, wxXmlSubclassFactoriesList
); 
 600 WX_DEFINE_LIST(wxXmlSubclassFactoriesList
); 
 602 wxXmlSubclassFactoriesList 
*wxXmlResource::ms_subclassFactories 
= NULL
; 
 604 /*static*/ void wxXmlResource::AddSubclassFactory(wxXmlSubclassFactory 
*factory
) 
 606     if (!ms_subclassFactories
) 
 608         ms_subclassFactories 
= new wxXmlSubclassFactoriesList
; 
 609         ms_subclassFactories
->DeleteContents(TRUE
); 
 611     ms_subclassFactories
->Append(factory
); 
 614 class wxXmlSubclassFactoryCXX 
: public wxXmlSubclassFactory
 
 617     ~wxXmlSubclassFactoryCXX() {} 
 619     wxObject 
*Create(const wxString
& className
) 
 621         wxClassInfo
* classInfo 
= wxClassInfo::FindClass(className
); 
 624             return classInfo
->CreateObject(); 
 634 wxXmlResourceHandler::wxXmlResourceHandler() 
 635         : m_node(NULL
), m_parent(NULL
), m_instance(NULL
), 
 636           m_parentAsWindow(NULL
), m_instanceAsWindow(NULL
) 
 641 wxObject 
*wxXmlResourceHandler::CreateResource(wxXmlNode 
*node
, wxObject 
*parent
, wxObject 
*instance
) 
 643     wxXmlNode 
*myNode 
= m_node
; 
 644     wxString myClass 
= m_class
; 
 645     wxObject 
*myParent 
= m_parent
, *myInstance 
= m_instance
; 
 646     wxWindow 
*myParentAW 
= m_parentAsWindow
, *myInstanceAW 
= m_instanceAsWindow
; 
 648     m_instance 
= instance
; 
 649     if (!m_instance 
&& node
->HasProp(wxT("subclass")) && 
 650         !(m_resource
->GetFlags() & wxXRC_NO_SUBCLASSING
)) 
 652         wxString subclass 
= node
->GetPropVal(wxT("subclass"), wxEmptyString
); 
 653         if (!subclass
.empty()) 
 655             for (wxXmlSubclassFactoriesList::Node 
*i 
= wxXmlResource::ms_subclassFactories
->GetFirst(); 
 658                 m_instance 
= i
->GetData()->Create(subclass
); 
 665                 wxString name 
= node
->GetPropVal(wxT("name"), wxEmptyString
); 
 666                 wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"), 
 667                            subclass
.c_str(), name
.c_str()); 
 673     m_class 
= node
->GetPropVal(wxT("class"), wxEmptyString
); 
 675     m_parentAsWindow 
= wxDynamicCast(m_parent
, wxWindow
); 
 676     m_instanceAsWindow 
= wxDynamicCast(m_instance
, wxWindow
); 
 678     wxObject 
*returned 
= DoCreateResource(); 
 682     m_parent 
= myParent
; m_parentAsWindow 
= myParentAW
; 
 683     m_instance 
= myInstance
; m_instanceAsWindow 
= myInstanceAW
; 
 689 void wxXmlResourceHandler::AddStyle(const wxString
& name
, int value
) 
 691     m_styleNames
.Add(name
); 
 692     m_styleValues
.Add(value
); 
 697 void wxXmlResourceHandler::AddWindowStyles() 
 699     XRC_ADD_STYLE(wxSIMPLE_BORDER
); 
 700     XRC_ADD_STYLE(wxSUNKEN_BORDER
); 
 701     XRC_ADD_STYLE(wxDOUBLE_BORDER
); 
 702     XRC_ADD_STYLE(wxRAISED_BORDER
); 
 703     XRC_ADD_STYLE(wxSTATIC_BORDER
); 
 704     XRC_ADD_STYLE(wxNO_BORDER
); 
 705     XRC_ADD_STYLE(wxTRANSPARENT_WINDOW
); 
 706     XRC_ADD_STYLE(wxWANTS_CHARS
); 
 707     XRC_ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE
); 
 712 bool wxXmlResourceHandler::HasParam(const wxString
& param
) 
 714     return (GetParamNode(param
) != NULL
); 
 718 int wxXmlResourceHandler::GetStyle(const wxString
& param
, int defaults
) 
 720     wxString s 
= GetParamValue(param
); 
 722     if (!s
) return defaults
; 
 724     wxStringTokenizer 
tkn(s
, wxT("| \t\n"), wxTOKEN_STRTOK
); 
 728     while (tkn
.HasMoreTokens()) 
 730         fl 
= tkn
.GetNextToken(); 
 731         index 
= m_styleNames
.Index(fl
); 
 732         if (index 
!= wxNOT_FOUND
) 
 733             style 
|= m_styleValues
[index
]; 
 735             wxLogError(_("Unknown style flag ") + fl
); 
 742 wxString 
wxXmlResourceHandler::GetText(const wxString
& param
, bool translate
) 
 744     wxString 
str1(GetParamValue(param
)); 
 749     // VS: First version of XRC resources used $ instead of & (which is 
 750     //     illegal in XML), but later I realized that '_' fits this purpose 
 751     //     much better (because &File means "File with F underlined"). 
 752     if (m_resource
->CompareVersion(2,3,0,1) < 0) 
 757     for (dt 
= str1
.c_str(); *dt
; dt
++) 
 759         // Remap amp_char to &, map double amp_char to amp_char (for things 
 760         // like "&File..." -- this is illegal in XML, so we use "_File..."): 
 763             if ( *(++dt
) == amp_char 
) 
 766                 str2 
<< wxT('&') << *dt
; 
 768         // Remap \n to CR, \r to LF, \t to TAB: 
 769         else if (*dt 
== wxT('\\')) 
 772                 case wxT('n') : str2 
<< wxT('\n'); break; 
 773                 case wxT('t') : str2 
<< wxT('\t'); break; 
 774                 case wxT('r') : str2 
<< wxT('\r'); break; 
 775                 default       : str2 
<< wxT('\\') << *dt
; break; 
 780     if (translate 
&& m_resource
->GetFlags() & wxXRC_USE_LOCALE
) 
 781         return wxGetTranslation(str2
); 
 789 long wxXmlResourceHandler::GetLong(const wxString
& param
, long defaultv
) 
 792     wxString str1 
= GetParamValue(param
); 
 794     if (!str1
.ToLong(&value
)) 
 802 int wxXmlResourceHandler::GetID() 
 804     return wxXmlResource::GetXRCID(GetName()); 
 809 wxString 
wxXmlResourceHandler::GetName() 
 811     return m_node
->GetPropVal(wxT("name"), wxT("-1")); 
 816 bool wxXmlResourceHandler::GetBool(const wxString
& param
, bool defaultv
) 
 818     wxString v 
= GetParamValue(param
); 
 820     if (!v
) return defaultv
; 
 821     else return (v 
== wxT("1")); 
 826 wxColour 
wxXmlResourceHandler::GetColour(const wxString
& param
) 
 828     wxString v 
= GetParamValue(param
); 
 829     unsigned long tmp 
= 0; 
 831     if (v
.Length() != 7 || v
[0u] != wxT('#') || 
 832         wxSscanf(v
.c_str(), wxT("#%lX"), &tmp
) != 1) 
 834         wxLogError(_("XRC resource: Incorrect colour specification '%s' for property '%s'."), 
 835                    v
.c_str(), param
.c_str()); 
 839     return wxColour((unsigned char) ((tmp 
& 0xFF0000) >> 16) , 
 840                     (unsigned char) ((tmp 
& 0x00FF00) >> 8), 
 841                     (unsigned char) ((tmp 
& 0x0000FF))); 
 846 wxBitmap 
wxXmlResourceHandler::GetBitmap(const wxString
& param
, 
 847                                          const wxArtClient
& defaultArtClient
, 
 850     /* If the bitmap is specified as stock item, query wxArtProvider for it: */ 
 851     wxXmlNode 
*bmpNode 
= GetParamNode(param
); 
 854         wxString sid 
= bmpNode
->GetPropVal(wxT("stock_id"), wxEmptyString
); 
 857             wxString scl 
= bmpNode
->GetPropVal(wxT("stock_client"), defaultArtClient
); 
 859                 wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(sid
), 
 860                                          wxART_MAKE_CLIENT_ID_FROM_STR(scl
), 
 867     /* ...or load the bitmap from file: */ 
 868     wxString name 
= GetParamValue(param
); 
 869     if (name
.IsEmpty()) return wxNullBitmap
; 
 871     wxFSFile 
*fsfile 
= GetCurFileSystem().OpenFile(name
); 
 874         wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), 
 878     wxImage 
img(*(fsfile
->GetStream())); 
 881     wxImage 
img(GetParamValue(wxT("bitmap"))); 
 886         wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), param
.c_str()); 
 889     if (!(size 
== wxDefaultSize
)) img
.Rescale(size
.x
, size
.y
); 
 890     return wxBitmap(img
); 
 896 wxIcon 
wxXmlResourceHandler::GetIcon(const wxString
& param
, 
 897                                      const wxArtClient
& defaultArtClient
, 
 901     icon
.CopyFromBitmap(GetBitmap(param
, defaultArtClient
, size
)); 
 907 wxXmlNode 
*wxXmlResourceHandler::GetParamNode(const wxString
& param
) 
 909     wxCHECK_MSG(m_node
, NULL
, wxT("You can't access handler data before it was initialized!")); 
 911     wxXmlNode 
*n 
= m_node
->GetChildren(); 
 915         if (n
->GetType() == wxXML_ELEMENT_NODE 
&& n
->GetName() == param
) 
 923 wxString 
wxXmlResourceHandler::GetNodeContent(wxXmlNode 
*node
) 
 926     if (n 
== NULL
) return wxEmptyString
; 
 927     n 
= n
->GetChildren(); 
 931         if (n
->GetType() == wxXML_TEXT_NODE 
|| 
 932             n
->GetType() == wxXML_CDATA_SECTION_NODE
) 
 933             return n
->GetContent(); 
 936     return wxEmptyString
; 
 941 wxString 
wxXmlResourceHandler::GetParamValue(const wxString
& param
) 
 944         return GetNodeContent(m_node
); 
 946         return GetNodeContent(GetParamNode(param
)); 
 951 wxSize 
wxXmlResourceHandler::GetSize(const wxString
& param
) 
 953     wxString s 
= GetParamValue(param
); 
 954     if (s
.IsEmpty()) s 
= wxT("-1,-1"); 
 958     is_dlg 
= s
[s
.Length()-1] == wxT('d'); 
 959     if (is_dlg
) s
.RemoveLast(); 
 961     if (!s
.BeforeFirst(wxT(',')).ToLong(&sx
) || 
 962         !s
.AfterLast(wxT(',')).ToLong(&sy
)) 
 964         wxLogError(_("Cannot parse coordinates from '%s'."), s
.c_str()); 
 965         return wxDefaultSize
; 
 970         if (m_instanceAsWindow
) 
 971             return wxDLG_UNIT(m_instanceAsWindow
, wxSize(sx
, sy
)); 
 972         else if (m_parentAsWindow
) 
 973             return wxDLG_UNIT(m_parentAsWindow
, wxSize(sx
, sy
)); 
 976             wxLogError(_("Cannot convert dialog units: dialog unknown.")); 
 977             return wxDefaultSize
; 
 980     else return wxSize(sx
, sy
); 
 985 wxPoint 
wxXmlResourceHandler::GetPosition(const wxString
& param
) 
 987     wxSize sz 
= GetSize(param
); 
 988     return wxPoint(sz
.x
, sz
.y
); 
 993 wxCoord 
wxXmlResourceHandler::GetDimension(const wxString
& param
, wxCoord defaultv
) 
 995     wxString s 
= GetParamValue(param
); 
 996     if (s
.IsEmpty()) return defaultv
; 
1000     is_dlg 
= s
[s
.Length()-1] == wxT('d'); 
1001     if (is_dlg
) s
.RemoveLast(); 
1005         wxLogError(_("Cannot parse dimension from '%s'."), s
.c_str()); 
1011         if (m_instanceAsWindow
) 
1012             return wxDLG_UNIT(m_instanceAsWindow
, wxSize(sx
, 0)).x
; 
1013         else if (m_parentAsWindow
) 
1014             return wxDLG_UNIT(m_parentAsWindow
, wxSize(sx
, 0)).x
; 
1017             wxLogError(_("Cannot convert dialog units: dialog unknown.")); 
1026 wxFont 
wxXmlResourceHandler::GetFont(const wxString
& param
) 
1028     wxXmlNode 
*font_node 
= GetParamNode(param
); 
1029     if (font_node 
== NULL
) 
1031         wxLogError(_("Cannot find font node '%s'."), param
.c_str()); 
1035     wxXmlNode 
*oldnode 
= m_node
; 
1038     long size 
= GetLong(wxT("size"), 12); 
1040     wxString style 
= GetParamValue(wxT("style")); 
1041     wxString weight 
= GetParamValue(wxT("weight")); 
1042     int istyle 
= wxNORMAL
, iweight 
= wxNORMAL
; 
1043     if (style 
== wxT("italic")) istyle 
= wxITALIC
; 
1044     else if (style 
== wxT("slant")) istyle 
= wxSLANT
; 
1045     if (weight 
== wxT("bold")) iweight 
= wxBOLD
; 
1046     else if (weight 
== wxT("light")) iweight 
= wxLIGHT
; 
1048     wxString family 
= GetParamValue(wxT("family")); 
1049     int ifamily 
= wxDEFAULT
; 
1050          if (family 
== wxT("decorative")) ifamily 
= wxDECORATIVE
; 
1051     else if (family 
== wxT("roman")) ifamily 
= wxROMAN
; 
1052     else if (family 
== wxT("script")) ifamily 
= wxSCRIPT
; 
1053     else if (family 
== wxT("swiss")) ifamily 
= wxSWISS
; 
1054     else if (family 
== wxT("modern")) ifamily 
= wxMODERN
; 
1056     bool underlined 
= GetBool(wxT("underlined"), FALSE
); 
1058     wxString encoding 
= GetParamValue(wxT("encoding")); 
1059     wxFontMapper mapper
; 
1060     wxFontEncoding enc 
= wxFONTENCODING_DEFAULT
; 
1061     if (!encoding
.IsEmpty()) 
1062         enc 
= mapper
.CharsetToEncoding(encoding
); 
1063     if (enc 
== wxFONTENCODING_SYSTEM
) 
1064         enc 
= wxFONTENCODING_DEFAULT
; 
1066     wxString faces 
= GetParamValue(wxT("face")); 
1067     wxString facename 
= wxEmptyString
; 
1068     wxFontEnumerator enu
; 
1069     enu
.EnumerateFacenames(); 
1070     wxStringTokenizer 
tk(faces
, wxT(",")); 
1071     while (tk
.HasMoreTokens()) 
1073         int index 
= enu
.GetFacenames()->Index(tk
.GetNextToken(), FALSE
); 
1074         if (index 
!= wxNOT_FOUND
) 
1076             facename 
= (*enu
.GetFacenames())[index
]; 
1083     wxFont 
font(size
, ifamily
, istyle
, iweight
, underlined
, facename
, enc
); 
1088 void wxXmlResourceHandler::SetupWindow(wxWindow 
*wnd
) 
1090     //FIXME : add cursor 
1092     if (HasParam(wxT("exstyle"))) 
1093         wnd
->SetExtraStyle(GetStyle(wxT("exstyle"))); 
1094     if (HasParam(wxT("bg"))) 
1095         wnd
->SetBackgroundColour(GetColour(wxT("bg"))); 
1096     if (HasParam(wxT("fg"))) 
1097         wnd
->SetForegroundColour(GetColour(wxT("fg"))); 
1098     if (GetBool(wxT("enabled"), 1) == 0) 
1100     if (GetBool(wxT("focused"), 0) == 1) 
1102     if (GetBool(wxT("hidden"), 0) == 1) 
1105     if (HasParam(wxT("tooltip"))) 
1106         wnd
->SetToolTip(GetText(wxT("tooltip"))); 
1108     if (HasParam(wxT("font"))) 
1109         wnd
->SetFont(GetFont()); 
1113 void wxXmlResourceHandler::CreateChildren(wxObject 
*parent
, bool this_hnd_only
) 
1115     wxXmlNode 
*n 
= m_node
->GetChildren(); 
1119         if (n
->GetType() == wxXML_ELEMENT_NODE 
&& 
1120            (n
->GetName() == wxT("object") || n
->GetName() == wxT("object_ref"))) 
1122             m_resource
->CreateResFromNode(n
, parent
, NULL
, 
1123                                           this_hnd_only 
? this : NULL
); 
1130 void wxXmlResourceHandler::CreateChildrenPrivately(wxObject 
*parent
, wxXmlNode 
*rootnode
) 
1133     if (rootnode 
== NULL
) root 
= m_node
; else root 
= rootnode
; 
1134     wxXmlNode 
*n 
= root
->GetChildren(); 
1138         if (n
->GetType() == wxXML_ELEMENT_NODE 
&& CanHandle(n
)) 
1140             CreateResource(n
, parent
, NULL
); 
1152 // --------------- XRCID implementation ----------------------------- 
1154 #define XRCID_TABLE_SIZE     1024 
1164 static XRCID_record 
*XRCID_Records
[XRCID_TABLE_SIZE
] = {NULL
}; 
1166 static int XRCID_Lookup(const wxChar 
*str_id
, int value_if_not_found 
= -2) 
1168     static int XRCID_LastID 
= wxID_HIGHEST
; 
1172     for (const wxChar 
*c 
= str_id
; *c 
!= wxT('\0'); c
++) index 
+= (int)*c
; 
1173     index 
%= XRCID_TABLE_SIZE
; 
1175     XRCID_record 
*oldrec 
= NULL
; 
1177     for (XRCID_record 
*rec 
= XRCID_Records
[index
]; rec
; rec 
= rec
->next
) 
1179         if (wxStrcmp(rec
->key
, str_id
) == 0) 
1187     XRCID_record 
**rec_var 
= (oldrec 
== NULL
) ? 
1188                               &XRCID_Records
[index
] : &oldrec
->next
; 
1189     *rec_var 
= new XRCID_record
; 
1190     (*rec_var
)->key 
= wxStrdup(str_id
); 
1191     (*rec_var
)->next 
= NULL
; 
1194     if (value_if_not_found 
!= -2) 
1195         (*rec_var
)->id 
= value_if_not_found
; 
1198         int asint 
= wxStrtol(str_id
, &end
, 10); 
1199         if (*str_id 
&& *end 
== 0) 
1201             // if str_id was integer, keep it verbosely: 
1202             (*rec_var
)->id 
= asint
; 
1206             (*rec_var
)->id 
= ++XRCID_LastID
; 
1210     return (*rec_var
)->id
; 
1213 /*static*/ int wxXmlResource::GetXRCID(const wxChar 
*str_id
) 
1215     return XRCID_Lookup(str_id
); 
1219 static void CleanXRCID_Record(XRCID_record 
*rec
) 
1223         CleanXRCID_Record(rec
->next
); 
1229 static void CleanXRCID_Records() 
1231     for (int i 
= 0; i 
< XRCID_TABLE_SIZE
; i
++) 
1233         CleanXRCID_Record(XRCID_Records
[i
]); 
1234         XRCID_Records
[i
] = NULL
; 
1238 static void AddStdXRCID_Records() 
1240 #define stdID(id) XRCID_Lookup(wxT(#id), id) 
1242     stdID(wxID_OPEN
); stdID(wxID_CLOSE
); stdID(wxID_NEW
); 
1243     stdID(wxID_SAVE
); stdID(wxID_SAVEAS
); stdID(wxID_REVERT
); 
1244     stdID(wxID_EXIT
); stdID(wxID_UNDO
); stdID(wxID_REDO
); 
1245     stdID(wxID_HELP
); stdID(wxID_PRINT
); stdID(wxID_PRINT_SETUP
); 
1246     stdID(wxID_PREVIEW
); stdID(wxID_ABOUT
); stdID(wxID_HELP_CONTENTS
); 
1247     stdID(wxID_HELP_COMMANDS
); stdID(wxID_HELP_PROCEDURES
); 
1248     stdID(wxID_CUT
); stdID(wxID_COPY
); stdID(wxID_PASTE
); 
1249     stdID(wxID_CLEAR
); stdID(wxID_FIND
); stdID(wxID_DUPLICATE
); 
1250     stdID(wxID_SELECTALL
); stdID(wxID_OK
); stdID(wxID_CANCEL
); 
1251     stdID(wxID_APPLY
); stdID(wxID_YES
); stdID(wxID_NO
); 
1252     stdID(wxID_STATIC
); stdID(wxID_FORWARD
); stdID(wxID_BACKWARD
); 
1253     stdID(wxID_DEFAULT
); stdID(wxID_MORE
); stdID(wxID_SETUP
); 
1254     stdID(wxID_RESET
); stdID(wxID_HELP_CONTEXT
); 
1255     stdID(wxID_CLOSE_ALL
); 
1263 // --------------- module and globals ----------------------------- 
1265 class wxXmlResourceModule
: public wxModule
 
1267 DECLARE_DYNAMIC_CLASS(wxXmlResourceModule
) 
1269     wxXmlResourceModule() {} 
1272         AddStdXRCID_Records(); 
1273         wxXmlResource::AddSubclassFactory(new wxXmlSubclassFactoryCXX
); 
1278         delete wxXmlResource::Set(NULL
); 
1279         wxDELETE(wxXmlResource::ms_subclassFactories
); 
1280         CleanXRCID_Records(); 
1284 IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule
, wxModule
) 
1287 // When wxXml is loaded dynamically after the application is already running 
1288 // then the built-in module system won't pick this one up.  Add it manually. 
1289 void wxXmlInitResourceModule() 
1291     wxModule
* module = new wxXmlResourceModule
; 
1293     wxModule::RegisterModule(module);