xmlres.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,711 行 · 第 1/4 页
CPP
1,711 行
/////////////////////////////////////////////////////////////////////////////
// Name: xmlres.cpp
// Purpose: XRC resources
// Author: Vaclav Slavik
// Created: 2000/03/05
// RCS-ID: $Id: xmlres.cpp,v 1.72.2.4 2006/03/04 18:55:38 VZ Exp $
// Copyright: (c) 2000 Vaclav Slavik
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "xmlres.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_XRC
#ifndef __WXWINCE__
#include <locale.h>
#endif
#include "wx/dialog.h"
#include "wx/panel.h"
#include "wx/frame.h"
#include "wx/wfstream.h"
#include "wx/filesys.h"
#include "wx/filename.h"
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/tokenzr.h"
#include "wx/fontenum.h"
#include "wx/module.h"
#include "wx/bitmap.h"
#include "wx/image.h"
#include "wx/fontmap.h"
#include "wx/artprov.h"
#include "wx/settings.h"
#include "wx/xml/xml.h"
#include "wx/xrc/xmlres.h"
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
wxXmlResource *wxXmlResource::ms_instance = NULL;
/*static*/ wxXmlResource *wxXmlResource::Get()
{
if ( !ms_instance )
ms_instance = new wxXmlResource;
return ms_instance;
}
/*static*/ wxXmlResource *wxXmlResource::Set(wxXmlResource *res)
{
wxXmlResource *old = ms_instance;
ms_instance = res;
return old;
}
wxXmlResource::wxXmlResource(int flags)
{
m_flags = flags;
m_version = -1;
}
wxXmlResource::wxXmlResource(const wxString& filemask, int flags)
{
m_flags = flags;
m_version = -1;
Load(filemask);
}
wxXmlResource::~wxXmlResource()
{
ClearHandlers();
}
/* static */
wxString wxXmlResource::ConvertFileNameToURL(const wxString& filename)
{
wxString fnd(filename);
// NB: as Load() and Unload() accept both filenames and URLs (should
// probably be changed to filenames only, but embedded resources
// currently rely on its ability to handle URLs - FIXME) we need to
// determine whether found name is filename and not URL and this is the
// fastest/simplest way to do it
if (wxFileName::FileExists(fnd))
{
// Make the name absolute filename, because the app may
// change working directory later:
wxFileName fn(fnd);
if (fn.IsRelative())
{
fn.MakeAbsolute();
fnd = fn.GetFullPath();
}
#if wxUSE_FILESYSTEM
fnd = wxFileSystem::FileNameToURL(fnd);
#endif
}
return fnd;
}
#if wxUSE_FILESYSTEM
/* static */
bool wxXmlResource::IsArchive(const wxString& filename)
{
const wxString fnd = filename.Lower();
return fnd.Matches(wxT("*.zip")) || fnd.Matches(wxT("*.xrs"));
}
#endif // wxUSE_FILESYSTEM
bool wxXmlResource::Load(const wxString& filemask)
{
wxString fnd;
wxXmlResourceDataRecord *drec;
bool iswild = wxIsWild(filemask);
bool rt = true;
#if wxUSE_FILESYSTEM
wxFileSystem fsys;
# define wxXmlFindFirst fsys.FindFirst(filemask, wxFILE)
# define wxXmlFindNext fsys.FindNext()
#else
# define wxXmlFindFirst wxFindFirstFile(filemask, wxFILE)
# define wxXmlFindNext wxFindNextFile()
#endif
if (iswild)
fnd = wxXmlFindFirst;
else
fnd = filemask;
while (!fnd.empty())
{
fnd = ConvertFileNameToURL(fnd);
#if wxUSE_FILESYSTEM
if ( IsArchive(fnd) )
{
rt = rt && Load(fnd + wxT("#zip:*.xrc"));
}
else // a single resource URL
#endif // wxUSE_FILESYSTEM
{
drec = new wxXmlResourceDataRecord;
drec->File = fnd;
m_data.Add(drec);
}
if (iswild)
fnd = wxXmlFindNext;
else
fnd = wxEmptyString;
}
# undef wxXmlFindFirst
# undef wxXmlFindNext
return rt && UpdateResources();
}
bool wxXmlResource::Unload(const wxString& filename)
{
wxASSERT_MSG( !wxIsWild(filename),
_T("wildcards not supported by wxXmlResource::Unload()") );
wxString fnd = ConvertFileNameToURL(filename);
#if wxUSE_FILESYSTEM
const bool isArchive = IsArchive(fnd);
if ( isArchive )
fnd += _T("#zip:");
#endif // wxUSE_FILESYSTEM
bool unloaded = false;
const size_t count = m_data.GetCount();
for ( size_t i = 0; i < count; i++ )
{
#if wxUSE_FILESYSTEM
if ( isArchive )
{
if ( m_data[i].File.StartsWith(fnd) )
unloaded = true;
// don't break from the loop, we can have other matching files
}
else // a single resource URL
#endif // wxUSE_FILESYSTEM
{
if ( m_data[i].File == fnd )
{
m_data.RemoveAt(i);
unloaded = true;
// no sense in continuing, there is only one file with this URL
break;
}
}
}
return unloaded;
}
IMPLEMENT_ABSTRACT_CLASS(wxXmlResourceHandler, wxObject)
void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
{
m_handlers.Append(handler);
handler->SetParentResource(this);
}
void wxXmlResource::InsertHandler(wxXmlResourceHandler *handler)
{
m_handlers.Insert(handler);
handler->SetParentResource(this);
}
void wxXmlResource::ClearHandlers()
{
WX_CLEAR_LIST(wxList, m_handlers);
}
wxMenu *wxXmlResource::LoadMenu(const wxString& name)
{
return (wxMenu*)CreateResFromNode(FindResource(name, wxT("wxMenu")), NULL, NULL);
}
wxMenuBar *wxXmlResource::LoadMenuBar(wxWindow *parent, const wxString& name)
{
return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), parent, NULL);
}
#if wxUSE_TOOLBAR
wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
{
return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("wxToolBar")), parent, NULL);
}
#endif
wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name)
{
return (wxDialog*)CreateResFromNode(FindResource(name, wxT("wxDialog")), parent, NULL);
}
bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
{
return CreateResFromNode(FindResource(name, wxT("wxDialog")), parent, dlg) != NULL;
}
wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
{
return (wxPanel*)CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, NULL);
}
bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
{
return CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, panel) != NULL;
}
wxFrame *wxXmlResource::LoadFrame(wxWindow* parent, const wxString& name)
{
return (wxFrame*)CreateResFromNode(FindResource(name, wxT("wxFrame")), parent, NULL);
}
bool wxXmlResource::LoadFrame(wxFrame* frame, wxWindow *parent, const wxString& name)
{
return CreateResFromNode(FindResource(name, wxT("wxFrame")), parent, frame) != NULL;
}
wxBitmap wxXmlResource::LoadBitmap(const wxString& name)
{
wxBitmap *bmp = (wxBitmap*)CreateResFromNode(
FindResource(name, wxT("wxBitmap")), NULL, NULL);
wxBitmap rt;
if (bmp) { rt = *bmp; delete bmp; }
return rt;
}
wxIcon wxXmlResource::LoadIcon(const wxString& name)
{
wxIcon *icon = (wxIcon*)CreateResFromNode(
FindResource(name, wxT("wxIcon")), NULL, NULL);
wxIcon rt;
if (icon) { rt = *icon; delete icon; }
return rt;
}
wxObject *wxXmlResource::LoadObject(wxWindow *parent, const wxString& name, const wxString& classname)
{
return CreateResFromNode(FindResource(name, classname), parent, NULL);
}
bool wxXmlResource::LoadObject(wxObject *instance, wxWindow *parent, const wxString& name, const wxString& classname)
{
return CreateResFromNode(FindResource(name, classname), parent, instance) != NULL;
}
bool wxXmlResource::AttachUnknownControl(const wxString& name,
wxWindow *control, wxWindow *parent)
{
if (parent == NULL)
parent = control->GetParent();
wxWindow *container = parent->FindWindow(name + wxT("_container"));
if (!container)
{
wxLogError(_("Cannot find container for unknown control '%s'."), name.c_str());
return false;
}
return control->Reparent(container);
}
static void ProcessPlatformProperty(wxXmlNode *node)
{
wxString s;
bool isok;
wxXmlNode *c = node->GetChildren();
while (c)
{
isok = false;
if (!c->GetPropVal(wxT("platform"), &s))
isok = true;
else
{
wxStringTokenizer tkn(s, wxT(" |"));
while (tkn.HasMoreTokens())
{
s = tkn.GetNextToken();
#ifdef __WINDOWS__
if (s == wxT("win")) isok = true;
#endif
#if defined(__MAC__) || defined(__APPLE__)
if (s == wxT("mac")) isok = true;
#elif defined(__UNIX__)
if (s == wxT("unix")) isok = true;
#endif
#ifdef __OS2__
if (s == wxT("os2")) isok = true;
#endif
if (isok)
break;
}
}
if (isok)
{
ProcessPlatformProperty(c);
c = c->GetNext();
}
else
{
wxXmlNode *c2 = c->GetNext();
node->RemoveChild(c);
delete c;
c = c2;
}
}
}
bool wxXmlResource::UpdateResources()
{
bool rt = true;
bool modif;
# if wxUSE_FILESYSTEM
wxFSFile *file = NULL;
wxUnusedVar(file);
wxFileSystem fsys;
# endif
wxString encoding(wxT("UTF-8"));
#if !wxUSE_UNICODE && wxUSE_INTL
if ( (GetFlags() & wxXRC_USE_LOCALE) == 0 )
{
// In case we are not using wxLocale to translate strings, convert the
// strings GUI's charset. This must not be done when wxXRC_USE_LOCALE
// is on, because it could break wxGetTranslation lookup.
encoding = wxLocale::GetSystemEncodingName();
}
#endif
for (size_t i = 0; i < m_data.GetCount(); i++)
{
modif = (m_data[i].Doc == NULL);
if (!modif && !(m_flags & wxXRC_NO_RELOADING))
{
# if wxUSE_FILESYSTEM
file = fsys.OpenFile(m_data[i].File);
modif = file && file->GetModificationTime() > m_data[i].Time;
if (!file)
{
wxLogError(_("Cannot open file '%s'."), m_data[i].File.c_str());
rt = false;
}
wxDELETE(file);
wxUnusedVar(file);
# else
modif = wxDateTime(wxFileModificationTime(m_data[i].File)) > m_data[i].Time;
# endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?