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 + -
显示快捷键?