]> git.saurik.com Git - wxWidgets.git/blob - src/common/objstrm.cpp
Added in-place editiging in wxListCtrl
[wxWidgets.git] / src / common / objstrm.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: objstrm.cpp
3 // Purpose: wxObjectStream classes
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 16/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11 #ifdef __GNUG__
12 #pragma implementation "objstrm.h"
13 #endif
14
15 #include "wx/object.h"
16 #include "wx/objstrm.h"
17 #include "wx/datstrm.h"
18
19 #define WXOBJ_BEGIN "OBEGIN"
20 #define WXOBJ_BEG_LEN 6
21
22 #define TAG_EMPTY_OBJECT "NULL"
23
24 // ----------------------------------------------------------------------------
25 // wxObjectOutputStream
26 // ----------------------------------------------------------------------------
27
28 wxObjectOutputStream::wxObjectOutputStream(wxOutputStream& s)
29 : wxFilterOutputStream(s)
30 {
31 m_saving = FALSE;
32 }
33
34 wxString wxObjectOutputStream::GetObjectName(wxObject *obj)
35 {
36 wxString name;
37
38 name.Printf("%x", (unsigned long)obj);
39 return name;
40 }
41
42 void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo& info)
43 {
44 wxDataOutputStream data_s(*this);
45
46 Write(WXOBJ_BEGIN, WXOBJ_BEG_LEN);
47
48 if (info.object) {
49 data_s.WriteString(info.object->GetClassInfo()->GetClassName());
50 } else {
51 data_s.WriteString(TAG_EMPTY_OBJECT);
52 }
53
54 data_s.WriteString(GetObjectName(info.object));
55
56 // I assume an object will not have millions of children
57 data_s.Write8(info.children.Number());
58 }
59
60 void wxObjectOutputStream::AddChild(wxObject *obj)
61 {
62 wxObjectStreamInfo *info;
63
64 if (!FirstStage())
65 return;
66
67 info = new wxObjectStreamInfo;
68 info->n_children = 0;
69 info->object = obj;
70 info->parent = m_current_info; // Not useful here.
71 m_current_info->n_children++;
72 m_current_info->children.Append(info);
73 }
74
75 void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo *info)
76 {
77 wxNode *node;
78
79 m_current_info = info;
80 // First stage: get children of obj
81 if (info->object)
82 info->object->StoreObject(*this);
83
84 // Prepare and write the sub-entry about the child obj.
85 WriteObjectDef(*info);
86
87 node = info->children.First();
88
89 while (node) {
90 ProcessObjectDef((wxObjectStreamInfo *)node->Data());
91 node = node->Next();
92 }
93 }
94
95 void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo *info)
96 {
97 wxNode *node = info->children.First();
98
99 m_current_info = info;
100
101 if (info->object)
102 info->object->StoreObject(*this);
103
104 while (node) {
105 ProcessObjectData((wxObjectStreamInfo *)node->Data());
106 node = node->Next();
107 }
108 }
109
110 bool wxObjectOutputStream::SaveObject(wxObject& obj)
111 {
112 wxObjectStreamInfo info;
113
114 if (m_saving)
115 return FALSE;
116
117 m_saving = TRUE;
118
119 // First stage
120 m_stage = 0;
121 info.object = &obj;
122 info.n_children = 0;
123 ProcessObjectDef(&info);
124
125 m_stage = 1;
126 ProcessObjectData(&info);
127
128 info.children.Clear();
129
130 m_saving = FALSE;
131
132 return TRUE;
133 }
134
135 // ----------------------------------------------------------------------------
136 // wxObjectInputStream
137 // ----------------------------------------------------------------------------
138
139 wxObjectInputStream::wxObjectInputStream(wxInputStream& s)
140 : wxFilterInputStream(s)
141 {
142 }
143
144 wxObject *wxObjectInputStream::SolveName(const wxString& name) const
145 {
146 wxNode *node = m_solver.First();
147 wxObjectStreamInfo *info;
148
149 while (node) {
150 info = (wxObjectStreamInfo *)node->Data();
151 if (info->object_name == name)
152 return info->object;
153
154 node = node->Next();
155 }
156 return NULL;
157 }
158
159 wxObject *wxObjectInputStream::GetParent() const
160 {
161 if (!m_current_info->parent)
162 return NULL;
163
164 return m_current_info->parent->object;
165 }
166
167 wxObject *wxObjectInputStream::GetChild(int no) const
168 {
169 wxNode *node = m_current_info->children.Nth(m_current_info->children_removed+no);
170 wxObjectStreamInfo *info;
171
172 if (!node)
173 return NULL;
174
175 info = (wxObjectStreamInfo *)node->Data();
176
177 return info->object;
178 }
179
180 void wxObjectInputStream::RemoveChildren(int nb)
181 {
182 m_current_info->children_removed += nb;
183 }
184
185 bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo *info)
186 {
187 wxDataInputStream data_s(*this);
188 char sig[WXOBJ_BEG_LEN+1];
189 wxString class_name;
190
191 Read(sig, WXOBJ_BEG_LEN);
192 sig[WXOBJ_BEG_LEN] = 0;
193 if (wxString(sig) != WXOBJ_BEGIN)
194 return FALSE;
195
196 class_name = data_s.ReadString();
197 printf("class_name = %s\n", WXSTRINGCAST class_name);
198 if (class_name == TAG_EMPTY_OBJECT)
199 info->object = NULL;
200 else
201 info->object = wxCreateDynamicObject( WXSTRINGCAST class_name);
202 info->object_name = data_s.ReadString();
203 printf("object_name = %s\n", WXSTRINGCAST info->object_name);
204 info->n_children = data_s.Read8();
205 info->children_removed = 0;
206 printf("n_children = %d\n", info->n_children);
207
208 return TRUE;
209 }
210
211 wxObjectStreamInfo *wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo *parent)
212 {
213 wxObjectStreamInfo *info, *c_info;
214 int c;
215
216 info = new wxObjectStreamInfo;
217 info->parent = parent;
218 info->children.DeleteContents(TRUE);
219
220 m_solver.Append(info);
221
222 if (!ReadObjectDef(info))
223 return NULL;
224
225 for (c=0;c<info->n_children;c++) {
226 c_info = ProcessObjectDef(info);
227 if (!c_info)
228 return NULL;
229 info->children.Append(c_info);
230 }
231
232 return info;
233 }
234
235 void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo *info)
236 {
237 wxNode *node = info->children.First();
238 wxObjectStreamInfo *c_info;
239
240 m_current_info = info;
241
242 if (info->object)
243 info->object->LoadObject(*this);
244 while (node) {
245 ProcessObjectData((wxObjectStreamInfo *)node->Data());
246 node = node->Next();
247 }
248 }
249
250 wxObject *wxObjectInputStream::LoadObject()
251 {
252 wxObjectStreamInfo *info;
253 wxObject *object;
254
255 info = ProcessObjectDef(NULL);
256 if (!info)
257 return NULL;
258 ProcessObjectData(info);
259
260 object = info->object;
261
262 delete info; // It's magic ! The whole tree is destroyed.
263
264 return object;
265 }