]> git.saurik.com Git - wxWidgets.git/blob - include/wx/persist.h
Dramatically optimise inserting many items in wxGenericListCtrl.
[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 // 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