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