git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58757 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			244 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/persist.h
 | 
						|
// Purpose:     common classes for persistence support
 | 
						|
// Author:      Vadim Zeitlin
 | 
						|
// Created:     2009-01-18
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_PERSIST_H_
 | 
						|
#define _WX_PERSIST_H_
 | 
						|
 | 
						|
#include "wx/string.h"
 | 
						|
#include "wx/hashmap.h"
 | 
						|
#include "wx/confbase.h"
 | 
						|
 | 
						|
class wxPersistentObject;
 | 
						|
 | 
						|
WX_DECLARE_VOIDPTR_HASH_MAP(wxPersistentObject *, wxPersistentObjectsMap);
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// global functions
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
/*
 | 
						|
   We do _not_ declare this function as doing this would force us to specialize
 | 
						|
   it for the user classes deriving from the standard persistent classes.
 | 
						|
   However we do define overloads of wxCreatePersistentObject() for all the wx
 | 
						|
   classes which means that template wxPersistentObject::Restore() picks up the
 | 
						|
   right overload to use provided that the header defining the correct overload
 | 
						|
   is included before calling it. And a compilation error happens if this is
 | 
						|
   not done.
 | 
						|
 | 
						|
template <class T>
 | 
						|
wxPersistentObject *wxCreatePersistentObject(T *obj);
 | 
						|
 | 
						|
 */
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// wxPersistenceManager: global aspects of persistent windows
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
class WXDLLIMPEXP_CORE wxPersistenceManager
 | 
						|
{
 | 
						|
public:
 | 
						|
    // accessor to the unique persistence manager object
 | 
						|
    static wxPersistenceManager& Get();
 | 
						|
 | 
						|
    // trivial but virtual dtor
 | 
						|
    //
 | 
						|
    // FIXME-VC6: this only needs to be public because of VC6 bug
 | 
						|
    virtual ~wxPersistenceManager();
 | 
						|
 | 
						|
 | 
						|
    // globally disable restoring or saving the persistent properties (both are
 | 
						|
    // enabled by default)
 | 
						|
    void DisableSaving() { m_doSave = false; }
 | 
						|
    void DisableRestoring() { m_doRestore = false; }
 | 
						|
 | 
						|
 | 
						|
    // register an object with the manager: when using the first overload,
 | 
						|
    // wxCreatePersistentObject() must be specialized for this object class;
 | 
						|
    // with the second one the persistent adapter is created by the caller
 | 
						|
    //
 | 
						|
    // the object shouldn't be already registered with us
 | 
						|
    template <class T>
 | 
						|
    wxPersistentObject *Register(T *obj)
 | 
						|
    {
 | 
						|
        return Register(obj, wxCreatePersistentObject(obj));
 | 
						|
    }
 | 
						|
 | 
						|
    wxPersistentObject *Register(void *obj, wxPersistentObject *po);
 | 
						|
 | 
						|
    // check if the object is registered and return the associated
 | 
						|
    // wxPersistentObject if it is or NULL otherwise
 | 
						|
    wxPersistentObject *Find(void *obj) const;
 | 
						|
 | 
						|
    // unregister the object, this is called by wxPersistentObject itself so
 | 
						|
    // there is usually no need to do it explicitly
 | 
						|
    //
 | 
						|
    // deletes the associated wxPersistentObject
 | 
						|
    void Unregister(void *obj);
 | 
						|
 | 
						|
 | 
						|
    // save/restore the state of an object
 | 
						|
    //
 | 
						|
    // these methods do nothing if DisableSaving/Restoring() was called
 | 
						|
    //
 | 
						|
    // Restore() returns true if the object state was really restored
 | 
						|
    void Save(void *obj);
 | 
						|
    bool Restore(void *obj);
 | 
						|
 | 
						|
    // combines both Save() and Unregister() calls
 | 
						|
    void SaveAndUnregister(void *obj)
 | 
						|
    {
 | 
						|
        Save(obj);
 | 
						|
        Unregister(obj);
 | 
						|
    }
 | 
						|
 | 
						|
    // combines both Register() and Restore() calls
 | 
						|
    template <class T>
 | 
						|
    bool RegisterAndRestore(T *obj)
 | 
						|
    {
 | 
						|
        return Register(obj) && Restore(obj);
 | 
						|
    }
 | 
						|
 | 
						|
    bool RegisterAndRestore(void *obj, wxPersistentObject *po)
 | 
						|
    {
 | 
						|
        return Register(obj, po) && Restore(obj);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    // methods used by the persistent objects to save and restore the data
 | 
						|
    //
 | 
						|
    // currently these methods simply use wxConfig::Get() but they may be
 | 
						|
    // overridden in the derived class (once we allow creating custom
 | 
						|
    // persistent managers)
 | 
						|
#define wxPERSIST_DECLARE_SAVE_RESTORE_FOR(Type)                              \
 | 
						|
    virtual bool SaveValue(const wxPersistentObject& who,                     \
 | 
						|
                           const wxString& name,                              \
 | 
						|
                           Type value);                                       \
 | 
						|
                                                                              \
 | 
						|
    virtual bool                                                              \
 | 
						|
    RestoreValue(const wxPersistentObject& who,                               \
 | 
						|
                 const wxString& name,                                        \
 | 
						|
                 Type *value)
 | 
						|
 | 
						|
    wxPERSIST_DECLARE_SAVE_RESTORE_FOR(bool);
 | 
						|
    wxPERSIST_DECLARE_SAVE_RESTORE_FOR(int);
 | 
						|
    wxPERSIST_DECLARE_SAVE_RESTORE_FOR(long);
 | 
						|
    wxPERSIST_DECLARE_SAVE_RESTORE_FOR(wxString);
 | 
						|
 | 
						|
#undef wxPERSIST_DECLARE_SAVE_RESTORE_FOR
 | 
						|
 | 
						|
private:
 | 
						|
    // ctor is private, use Get()
 | 
						|
    wxPersistenceManager()
 | 
						|
    {
 | 
						|
        m_doSave =
 | 
						|
        m_doRestore = true;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    // helpers of Save/Restore()
 | 
						|
    //
 | 
						|
    // TODO: make this customizable by allowing
 | 
						|
    //          (a) specifying custom wxConfig object to use
 | 
						|
    //          (b) allowing to use something else entirely
 | 
						|
    wxConfigBase *GetConfig() const { return wxConfigBase::Get(); }
 | 
						|
    wxString GetKey(const wxPersistentObject& who, const wxString& name) const;
 | 
						|
 | 
						|
 | 
						|
    // map with the registered objects as keys and associated
 | 
						|
    // wxPersistentObjects as values
 | 
						|
    wxPersistentObjectsMap m_persistentObjects;
 | 
						|
 | 
						|
    // true if we should restore/save the settings (it doesn't make much sense
 | 
						|
    // to use this class when both of them are false but setting one of them to
 | 
						|
    // false may make sense in some situations)
 | 
						|
    bool m_doSave,
 | 
						|
         m_doRestore;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(wxPersistenceManager);
 | 
						|
};
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// wxPersistentObject: ABC for anything persistent
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
class wxPersistentObject
 | 
						|
{
 | 
						|
public:
 | 
						|
    // ctor associates us with the object whose options we save/restore
 | 
						|
    wxPersistentObject(void *obj) : m_obj(obj) { }
 | 
						|
 | 
						|
    // trivial but virtual dtor
 | 
						|
    virtual ~wxPersistentObject() { }
 | 
						|
 | 
						|
 | 
						|
    // methods used by wxPersistenceManager
 | 
						|
    // ------------------------------------
 | 
						|
 | 
						|
    // save/restore the corresponding objects settings
 | 
						|
    //
 | 
						|
    // these methods shouldn't be used directly as they don't respect the
 | 
						|
    // global wxPersistenceManager::DisableSaving/Restoring() settings, use
 | 
						|
    // wxPersistenceManager methods with the same name instead
 | 
						|
    virtual void Save() const = 0;
 | 
						|
    virtual bool Restore() = 0;
 | 
						|
 | 
						|
 | 
						|
    // get the kind of the objects we correspond to, e.g. "Frame"
 | 
						|
    virtual wxString GetKind() const = 0;
 | 
						|
 | 
						|
    // get the name of the object we correspond to, e.g. "Main"
 | 
						|
    virtual wxString GetName() const = 0;
 | 
						|
 | 
						|
 | 
						|
    // return the associated object
 | 
						|
    void *GetObject() const { return m_obj; }
 | 
						|
 | 
						|
protected:
 | 
						|
    // wrappers for wxPersistenceManager methods which don't require passing
 | 
						|
    // "this" as the first parameter all the time
 | 
						|
    template <typename T>
 | 
						|
    bool SaveValue(const wxString& name, T value) const
 | 
						|
    {
 | 
						|
        return wxPersistenceManager::Get().SaveValue(*this, name, value);
 | 
						|
    }
 | 
						|
 | 
						|
    template <typename T>
 | 
						|
    bool RestoreValue(const wxString& name, T *value)
 | 
						|
    {
 | 
						|
        return wxPersistenceManager::Get().RestoreValue(*this, name, value);
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    void * const m_obj;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(wxPersistentObject);
 | 
						|
};
 | 
						|
 | 
						|
// FIXME-VC6: VC6 has troubles with template methods of DLL-exported classes,
 | 
						|
//            apparently it believes they should be defined in the DLL (which
 | 
						|
//            is, of course, impossible as the DLL doesn't know for which types
 | 
						|
//            will they be instantiated) instead of compiling them when
 | 
						|
//            building the main application itself. Because of this problem
 | 
						|
//            (which only arises in debug build!) we can't use the usual
 | 
						|
//            RegisterAndRestore(obj) with it and need to explicitly create the
 | 
						|
//            persistence adapter. To hide this ugliness we define a global
 | 
						|
//            function which does it for us.
 | 
						|
template <typename T>
 | 
						|
inline bool wxPersistentRegisterAndRestore(T *obj)
 | 
						|
{
 | 
						|
    wxPersistentObject * const pers = wxCreatePersistentObject(obj);
 | 
						|
 | 
						|
    return wxPersistenceManager::Get().RegisterAndRestore(obj, pers);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif // _WX_PERSIST_H_
 | 
						|
 |