]>
Commit | Line | Data |
---|---|---|
1f0539a4 VZ |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/persist.h | |
3 | // Purpose: common classes for persistence support | |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2009-01-18 | |
1f0539a4 VZ |
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: | |
911219b2 VZ |
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 | ||
1f0539a4 VZ |
54 | // accessor to the unique persistence manager object |
55 | static wxPersistenceManager& Get(); | |
56 | ||
7d15ffcd VZ |
57 | // trivial but virtual dtor |
58 | // | |
59 | // FIXME-VC6: this only needs to be public because of VC6 bug | |
60 | virtual ~wxPersistenceManager(); | |
61 | ||
1f0539a4 VZ |
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 | ||
5bca8be2 | 92 | |
1f0539a4 VZ |
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 | ||
911219b2 | 143 | protected: |
1f0539a4 VZ |
144 | // ctor is private, use Get() |
145 | wxPersistenceManager() | |
146 | { | |
147 | m_doSave = | |
148 | m_doRestore = true; | |
149 | } | |
150 | ||
5bca8be2 | 151 | |
911219b2 VZ |
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(); } | |
1f0539a4 | 155 | |
911219b2 VZ |
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; | |
1f0539a4 | 161 | |
911219b2 VZ |
162 | |
163 | private: | |
1f0539a4 VZ |
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 | ||
c0c133e1 | 174 | wxDECLARE_NO_COPY_CLASS(wxPersistenceManager); |
1f0539a4 VZ |
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 | ||
c0c133e1 | 231 | wxDECLARE_NO_COPY_CLASS(wxPersistentObject); |
1f0539a4 VZ |
232 | }; |
233 | ||
77cc73a7 VZ |
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); | |
5bca8be2 | 249 | |
77cc73a7 VZ |
250 | } |
251 | ||
679ab0b3 VZ |
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 | ||
1f0539a4 VZ |
262 | #endif // _WX_PERSIST_H_ |
263 |