In practice names are not often used so typically whenever you want to make a window settings persistent you also need to set its name and the it's convenient to let a single function do both tasks, so add an overload taking the name string (this is a separate function instead of optional parameter to avoid compilation errors if this is ever used with non-wxWindow-derived objects which don't have SetName() method). Also expand the documentation slightly and add @since tags. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64887 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			254 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			8.5 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);
 | |
| 
 | |
| }
 | |
| 
 | |
| // A helper function which also sets the name for the (wxWindow-derived) object
 | |
| // before registering and restoring it.
 | |
| template <typename T>
 | |
| inline bool wxPersistentRegisterAndRestore(T *obj, const wxString& name)
 | |
| {
 | |
|     obj->SetName(name);
 | |
| 
 | |
|     return wxPersistentRegisterAndRestore(obj);
 | |
| }
 | |
| 
 | |
| #endif // _WX_PERSIST_H_
 | |
| 
 |