]>
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 | |
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 | // accessor to the unique persistence manager object | |
48 | static wxPersistenceManager& Get(); | |
49 | ||
50 | ||
51 | // globally disable restoring or saving the persistent properties (both are | |
52 | // enabled by default) | |
53 | void DisableSaving() { m_doSave = false; } | |
54 | void DisableRestoring() { m_doRestore = false; } | |
55 | ||
56 | ||
57 | // register an object with the manager: when using the first overload, | |
58 | // wxCreatePersistentObject() must be specialized for this object class; | |
59 | // with the second one the persistent adapter is created by the caller | |
60 | // | |
61 | // the object shouldn't be already registered with us | |
62 | template <class T> | |
63 | wxPersistentObject *Register(T *obj) | |
64 | { | |
65 | return Register(obj, wxCreatePersistentObject(obj)); | |
66 | } | |
67 | ||
68 | wxPersistentObject *Register(void *obj, wxPersistentObject *po); | |
69 | ||
70 | // check if the object is registered and return the associated | |
71 | // wxPersistentObject if it is or NULL otherwise | |
72 | wxPersistentObject *Find(void *obj) const; | |
73 | ||
74 | // unregister the object, this is called by wxPersistentObject itself so | |
75 | // there is usually no need to do it explicitly | |
76 | // | |
77 | // deletes the associated wxPersistentObject | |
78 | void Unregister(void *obj); | |
79 | ||
80 | ||
81 | // save/restore the state of an object | |
82 | // | |
83 | // these methods do nothing if DisableSaving/Restoring() was called | |
84 | // | |
85 | // Restore() returns true if the object state was really restored | |
86 | void Save(void *obj); | |
87 | bool Restore(void *obj); | |
88 | ||
89 | // combines both Save() and Unregister() calls | |
90 | void SaveAndUnregister(void *obj) | |
91 | { | |
92 | Save(obj); | |
93 | Unregister(obj); | |
94 | } | |
95 | ||
96 | // combines both Register() and Restore() calls | |
97 | template <class T> | |
98 | bool RegisterAndRestore(T *obj) | |
99 | { | |
100 | return Register(obj) && Restore(obj); | |
101 | } | |
102 | ||
103 | bool RegisterAndRestore(void *obj, wxPersistentObject *po) | |
104 | { | |
105 | return Register(obj, po) && Restore(obj); | |
106 | } | |
107 | ||
108 | ||
109 | // methods used by the persistent objects to save and restore the data | |
110 | // | |
111 | // currently these methods simply use wxConfig::Get() but they may be | |
112 | // overridden in the derived class (once we allow creating custom | |
113 | // persistent managers) | |
114 | #define wxPERSIST_DECLARE_SAVE_RESTORE_FOR(Type) \ | |
115 | virtual bool SaveValue(const wxPersistentObject& who, \ | |
116 | const wxString& name, \ | |
117 | Type value); \ | |
118 | \ | |
119 | virtual bool \ | |
120 | RestoreValue(const wxPersistentObject& who, \ | |
121 | const wxString& name, \ | |
122 | Type *value) | |
123 | ||
124 | wxPERSIST_DECLARE_SAVE_RESTORE_FOR(bool); | |
125 | wxPERSIST_DECLARE_SAVE_RESTORE_FOR(int); | |
126 | wxPERSIST_DECLARE_SAVE_RESTORE_FOR(long); | |
127 | wxPERSIST_DECLARE_SAVE_RESTORE_FOR(wxString); | |
128 | ||
129 | #undef wxPERSIST_DECLARE_SAVE_RESTORE_FOR | |
130 | ||
131 | private: | |
132 | // ctor is private, use Get() | |
133 | wxPersistenceManager() | |
134 | { | |
135 | m_doSave = | |
136 | m_doRestore = true; | |
137 | } | |
138 | ||
139 | // helpers of Save/Restore() | |
140 | // | |
141 | // TODO: make this customizable by allowing | |
142 | // (a) specifying custom wxConfig object to use | |
143 | // (b) allowing to use something else entirely | |
144 | wxConfigBase *GetConfig() const { return wxConfigBase::Get(); } | |
145 | wxString GetKey(const wxPersistentObject& who, const wxString& name) const; | |
146 | ||
147 | ||
148 | // map with the registered objects as keys and associated | |
149 | // wxPersistentObjects as values | |
150 | wxPersistentObjectsMap m_persistentObjects; | |
151 | ||
152 | // true if we should restore/save the settings (it doesn't make much sense | |
153 | // to use this class when both of them are false but setting one of them to | |
154 | // false may make sense in some situations) | |
155 | bool m_doSave, | |
156 | m_doRestore; | |
157 | ||
d77df9f7 | 158 | DECLARE_NO_COPY_CLASS(wxPersistenceManager) |
1f0539a4 VZ |
159 | }; |
160 | ||
161 | // ---------------------------------------------------------------------------- | |
162 | // wxPersistentObject: ABC for anything persistent | |
163 | // ---------------------------------------------------------------------------- | |
164 | ||
165 | class wxPersistentObject | |
166 | { | |
167 | public: | |
168 | // ctor associates us with the object whose options we save/restore | |
169 | wxPersistentObject(void *obj) : m_obj(obj) { } | |
170 | ||
171 | // trivial but virtual dtor | |
172 | virtual ~wxPersistentObject() { } | |
173 | ||
174 | ||
175 | // methods used by wxPersistenceManager | |
176 | // ------------------------------------ | |
177 | ||
178 | // save/restore the corresponding objects settings | |
179 | // | |
180 | // these methods shouldn't be used directly as they don't respect the | |
181 | // global wxPersistenceManager::DisableSaving/Restoring() settings, use | |
182 | // wxPersistenceManager methods with the same name instead | |
183 | virtual void Save() const = 0; | |
184 | virtual bool Restore() = 0; | |
185 | ||
186 | ||
187 | // get the kind of the objects we correspond to, e.g. "Frame" | |
188 | virtual wxString GetKind() const = 0; | |
189 | ||
190 | // get the name of the object we correspond to, e.g. "Main" | |
191 | virtual wxString GetName() const = 0; | |
192 | ||
193 | ||
194 | // return the associated object | |
195 | void *GetObject() const { return m_obj; } | |
196 | ||
197 | protected: | |
198 | // wrappers for wxPersistenceManager methods which don't require passing | |
199 | // "this" as the first parameter all the time | |
200 | template <typename T> | |
201 | bool SaveValue(const wxString& name, T value) const | |
202 | { | |
203 | return wxPersistenceManager::Get().SaveValue(*this, name, value); | |
204 | } | |
205 | ||
206 | template <typename T> | |
207 | bool RestoreValue(const wxString& name, T *value) | |
208 | { | |
209 | return wxPersistenceManager::Get().RestoreValue(*this, name, value); | |
210 | } | |
211 | ||
212 | private: | |
213 | void * const m_obj; | |
214 | ||
215 | DECLARE_NO_COPY_CLASS(wxPersistentObject) | |
216 | }; | |
217 | ||
77cc73a7 VZ |
218 | // FIXME-VC6: VC6 has troubles with template methods of DLL-exported classes, |
219 | // apparently it believes they should be defined in the DLL (which | |
220 | // is, of course, impossible as the DLL doesn't know for which types | |
221 | // will they be instantiated) instead of compiling them when | |
222 | // building the main application itself. Because of this problem | |
223 | // (which only arises in debug build!) we can't use the usual | |
224 | // RegisterAndRestore(obj) with it and need to explicitly create the | |
225 | // persistence adapter. To hide this ugliness we define a global | |
226 | // function which does it for us. | |
227 | template <typename T> | |
228 | inline bool wxPersistentRegisterAndRestore(T *obj) | |
229 | { | |
230 | wxPersistentObject * const pers = wxCreatePersistentObject(obj); | |
231 | ||
232 | return wxPersistenceManager::Get().RegisterAndRestore(obj, pers); | |
233 | ||
234 | } | |
235 | ||
1f0539a4 VZ |
236 | #endif // _WX_PERSIST_H_ |
237 |