]> git.saurik.com Git - wxWidgets.git/blob - include/wx/persist.h
Applied #15226 with modifications: wxRichTextCtrl: Implement setting properties with...
[wxWidgets.git] / include / wx / persist.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/persist.h
3 // Purpose: common classes for persistence support
4 // Author: Vadim Zeitlin
5 // Created: 2009-01-18
6 // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #ifndef _WX_PERSIST_H_
11 #define _WX_PERSIST_H_
12
13 #include "wx/string.h"
14 #include "wx/hashmap.h"
15 #include "wx/confbase.h"
16
17 class wxPersistentObject;
18
19 WX_DECLARE_VOIDPTR_HASH_MAP(wxPersistentObject *, wxPersistentObjectsMap);
20
21 // ----------------------------------------------------------------------------
22 // global functions
23 // ----------------------------------------------------------------------------
24
25 /*
26 We do _not_ declare this function as doing this would force us to specialize
27 it for the user classes deriving from the standard persistent classes.
28 However we do define overloads of wxCreatePersistentObject() for all the wx
29 classes which means that template wxPersistentObject::Restore() picks up the
30 right overload to use provided that the header defining the correct overload
31 is included before calling it. And a compilation error happens if this is
32 not done.
33
34 template <class T>
35 wxPersistentObject *wxCreatePersistentObject(T *obj);
36
37 */
38
39 // ----------------------------------------------------------------------------
40 // wxPersistenceManager: global aspects of persistent windows
41 // ----------------------------------------------------------------------------
42
43 class WXDLLIMPEXP_CORE wxPersistenceManager
44 {
45 public:
46 // Call this method to specify a non-default persistence manager to use.
47 // This function should usually be called very early to affect creation of
48 // all persistent controls and the object passed to it must have a lifetime
49 // long enough to be still alive when the persistent controls are destroyed
50 // and need it to save their state so typically this would be a global or a
51 // wxApp member.
52 static void Set(wxPersistenceManager& manager);
53
54 // accessor to the unique persistence manager object
55 static wxPersistenceManager& Get();
56
57 // trivial but virtual dtor
58 //
59 // FIXME-VC6: this only needs to be public because of VC6 bug
60 virtual ~wxPersistenceManager();
61
62
63 // globally disable restoring or saving the persistent properties (both are
64 // enabled by default)
65 void DisableSaving() { m_doSave = false; }
66 void DisableRestoring() { m_doRestore = false; }
67
68
69 // register an object with the manager: when using the first overload,
70 // wxCreatePersistentObject() must be specialized for this object class;
71 // with the second one the persistent adapter is created by the caller
72 //
73 // the object shouldn't be already registered with us
74 template <class T>
75 wxPersistentObject *Register(T *obj)
76 {
77 return Register(obj, wxCreatePersistentObject(obj));
78 }
79
80 wxPersistentObject *Register(void *obj, wxPersistentObject *po);
81
82 // check if the object is registered and return the associated
83 // wxPersistentObject if it is or NULL otherwise
84 wxPersistentObject *Find(void *obj) const;
85
86 // unregister the object, this is called by wxPersistentObject itself so
87 // there is usually no need to do it explicitly
88 //
89 // deletes the associated wxPersistentObject
90 void Unregister(void *obj);
91
92
93 // save/restore the state of an object
94 //
95 // these methods do nothing if DisableSaving/Restoring() was called
96 //
97 // Restore() returns true if the object state was really restored
98 void Save(void *obj);
99 bool Restore(void *obj);
100
101 // combines both Save() and Unregister() calls
102 void SaveAndUnregister(void *obj)
103 {
104 Save(obj);
105 Unregister(obj);
106 }
107
108 // combines both Register() and Restore() calls
109 template <class T>
110 bool RegisterAndRestore(T *obj)
111 {
112 return Register(obj) && Restore(obj);
113 }
114
115 bool RegisterAndRestore(void *obj, wxPersistentObject *po)
116 {
117 return Register(obj, po) && Restore(obj);
118 }
119
120
121 // methods used by the persistent objects to save and restore the data
122 //
123 // currently these methods simply use wxConfig::Get() but they may be
124 // overridden in the derived class (once we allow creating custom
125 // persistent managers)
126 #define wxPERSIST_DECLARE_SAVE_RESTORE_FOR(Type) \
127 virtual bool SaveValue(const wxPersistentObject& who, \
128 const wxString& name, \
129 Type value); \
130 \
131 virtual bool \
132 RestoreValue(const wxPersistentObject& who, \
133 const wxString& name, \
134 Type *value)
135
136 wxPERSIST_DECLARE_SAVE_RESTORE_FOR(bool);
137 wxPERSIST_DECLARE_SAVE_RESTORE_FOR(int);
138 wxPERSIST_DECLARE_SAVE_RESTORE_FOR(long);
139 wxPERSIST_DECLARE_SAVE_RESTORE_FOR(wxString);
140
141 #undef wxPERSIST_DECLARE_SAVE_RESTORE_FOR
142
143 protected:
144 // ctor is private, use Get()
145 wxPersistenceManager()
146 {
147 m_doSave =
148 m_doRestore = true;
149 }
150
151
152 // Return the config object to use, by default just the global one but a
153 // different one could be used by the derived class if needed.
154 virtual wxConfigBase *GetConfig() const { return wxConfigBase::Get(); }
155
156 // Return the path to use for saving the setting with the given name for
157 // the specified object (notice that the name is the name of the setting,
158 // not the name of the object itself which can be retrieved with GetName()).
159 virtual wxString GetKey(const wxPersistentObject& who,
160 const wxString& name) const;
161
162
163 private:
164 // map with the registered objects as keys and associated
165 // wxPersistentObjects as values
166 wxPersistentObjectsMap m_persistentObjects;
167
168 // true if we should restore/save the settings (it doesn't make much sense
169 // to use this class when both of them are false but setting one of them to
170 // false may make sense in some situations)
171 bool m_doSave,
172 m_doRestore;
173
174 wxDECLARE_NO_COPY_CLASS(wxPersistenceManager);
175 };
176
177 // ----------------------------------------------------------------------------
178 // wxPersistentObject: ABC for anything persistent
179 // ----------------------------------------------------------------------------
180
181 class wxPersistentObject
182 {
183 public:
184 // ctor associates us with the object whose options we save/restore
185 wxPersistentObject(void *obj) : m_obj(obj) { }
186
187 // trivial but virtual dtor
188 virtual ~wxPersistentObject() { }
189
190
191 // methods used by wxPersistenceManager
192 // ------------------------------------
193
194 // save/restore the corresponding objects settings
195 //
196 // these methods shouldn't be used directly as they don't respect the
197 // global wxPersistenceManager::DisableSaving/Restoring() settings, use
198 // wxPersistenceManager methods with the same name instead
199 virtual void Save() const = 0;
200 virtual bool Restore() = 0;
201
202
203 // get the kind of the objects we correspond to, e.g. "Frame"
204 virtual wxString GetKind() const = 0;
205
206 // get the name of the object we correspond to, e.g. "Main"
207 virtual wxString GetName() const = 0;
208
209
210 // return the associated object
211 void *GetObject() const { return m_obj; }
212
213 protected:
214 // wrappers for wxPersistenceManager methods which don't require passing
215 // "this" as the first parameter all the time
216 template <typename T>
217 bool SaveValue(const wxString& name, T value) const
218 {
219 return wxPersistenceManager::Get().SaveValue(*this, name, value);
220 }
221
222 template <typename T>
223 bool RestoreValue(const wxString& name, T *value)
224 {
225 return wxPersistenceManager::Get().RestoreValue(*this, name, value);
226 }
227
228 private:
229 void * const m_obj;
230
231 wxDECLARE_NO_COPY_CLASS(wxPersistentObject);
232 };
233
234 // FIXME-VC6: VC6 has troubles with template methods of DLL-exported classes,
235 // apparently it believes they should be defined in the DLL (which
236 // is, of course, impossible as the DLL doesn't know for which types
237 // will they be instantiated) instead of compiling them when
238 // building the main application itself. Because of this problem
239 // (which only arises in debug build!) we can't use the usual
240 // RegisterAndRestore(obj) with it and need to explicitly create the
241 // persistence adapter. To hide this ugliness we define a global
242 // function which does it for us.
243 template <typename T>
244 inline bool wxPersistentRegisterAndRestore(T *obj)
245 {
246 wxPersistentObject * const pers = wxCreatePersistentObject(obj);
247
248 return wxPersistenceManager::Get().RegisterAndRestore(obj, pers);
249
250 }
251
252 // A helper function which also sets the name for the (wxWindow-derived) object
253 // before registering and restoring it.
254 template <typename T>
255 inline bool wxPersistentRegisterAndRestore(T *obj, const wxString& name)
256 {
257 obj->SetName(name);
258
259 return wxPersistentRegisterAndRestore(obj);
260 }
261
262 #endif // _WX_PERSIST_H_
263