Updated testconf,
[wxWidgets.git] / samples / docvwmdi / doc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: doc.cpp
3 // Purpose: Implements document functionality
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 // #pragma implementation
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26 #include "wx/txtstrm.h"
27
28 #if !wxUSE_DOC_VIEW_ARCHITECTURE
29 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
30 #endif
31
32 #include "doc.h"
33 #include "view.h"
34
35 IMPLEMENT_DYNAMIC_CLASS(DrawingDocument, wxDocument)
36
37 DrawingDocument::DrawingDocument(void)
38 {
39 }
40
41 DrawingDocument::~DrawingDocument(void)
42 {
43 doodleSegments.DeleteContents(TRUE);
44 }
45
46 #if wxUSE_STD_IOSTREAM
47 ostream& DrawingDocument::SaveObject(ostream& stream)
48 {
49 wxDocument::SaveObject(stream);
50
51 wxInt32 n = doodleSegments.Number();
52 stream << n << '\n';
53
54 wxNode *node = doodleSegments.First();
55 while (node)
56 {
57 DoodleSegment *segment = (DoodleSegment *)node->Data();
58 segment->SaveObject(stream);
59 stream << '\n';
60
61 node = node->Next();
62 }
63
64 return stream;
65 }
66 #else
67 wxOutputStream& DrawingDocument::SaveObject(wxOutputStream& stream)
68 {
69 wxDocument::SaveObject(stream);
70
71 wxTextOutputStream text_stream( stream );
72
73 wxInt32 n = doodleSegments.Number();
74 text_stream << n << '\n';
75
76 wxNode *node = doodleSegments.First();
77 while (node)
78 {
79 DoodleSegment *segment = (DoodleSegment *)node->Data();
80 segment->SaveObject(stream);
81 text_stream << '\n';
82
83 node = node->Next();
84 }
85
86 return stream;
87 }
88 #endif
89
90 #if wxUSE_STD_IOSTREAM
91 istream& DrawingDocument::LoadObject(istream& stream)
92 {
93 wxDocument::LoadObject(stream);
94
95 wxInt32 n = 0;
96 stream >> n;
97
98 for (int i = 0; i < n; i++)
99 {
100 DoodleSegment *segment = new DoodleSegment;
101 segment->LoadObject(stream);
102 doodleSegments.Append(segment);
103 }
104
105 return stream;
106 }
107 #else
108 wxInputStream& DrawingDocument::LoadObject(wxInputStream& stream)
109 {
110 wxDocument::LoadObject(stream);
111
112 wxTextInputStream text_stream( stream );
113
114 wxInt32 n = 0;
115 text_stream >> n;
116
117 for (int i = 0; i < n; i++)
118 {
119 DoodleSegment *segment = new DoodleSegment;
120 segment->LoadObject(stream);
121 doodleSegments.Append(segment);
122 }
123
124 return stream;
125 }
126 #endif
127 DoodleSegment::DoodleSegment(void)
128 {
129 }
130
131 DoodleSegment::DoodleSegment(DoodleSegment& seg)
132 {
133 wxNode *node = seg.lines.First();
134 while (node)
135 {
136 DoodleLine *line = (DoodleLine *)node->Data();
137 DoodleLine *newLine = new DoodleLine;
138 newLine->x1 = line->x1;
139 newLine->y1 = line->y1;
140 newLine->x2 = line->x2;
141 newLine->y2 = line->y2;
142
143 lines.Append(newLine);
144
145 node = node->Next();
146 }
147 }
148
149 DoodleSegment::~DoodleSegment(void)
150 {
151 lines.DeleteContents(TRUE);
152 }
153
154 #if wxUSE_STD_IOSTREAM
155 ostream& DoodleSegment::SaveObject(ostream& stream)
156 {
157 wxInt32 n = lines.Number();
158 stream << n << '\n';
159
160 wxNode *node = lines.First();
161 while (node)
162 {
163 DoodleLine *line = (DoodleLine *)node->Data();
164 stream << line->x1 << " " <<
165 line->y1 << " " <<
166 line->x2 << " " <<
167 line->y2 << "\n";
168 node = node->Next();
169 }
170
171 return stream;
172 }
173 #else
174 wxOutputStream &DoodleSegment::SaveObject(wxOutputStream& stream)
175 {
176 wxTextOutputStream text_stream( stream );
177
178 wxInt32 n = lines.Number();
179 text_stream << n << '\n';
180
181 wxNode *node = lines.First();
182 while (node)
183 {
184 DoodleLine *line = (DoodleLine *)node->Data();
185 text_stream << line->x1 << " " <<
186 line->y1 << " " <<
187 line->x2 << " " <<
188 line->y2 << "\n";
189 node = node->Next();
190 }
191
192 return stream;
193 }
194 #endif
195
196 #if wxUSE_STD_IOSTREAM
197 istream& DoodleSegment::LoadObject(istream& stream)
198 {
199 wxInt32 n = 0;
200 stream >> n;
201
202 for (int i = 0; i < n; i++)
203 {
204 DoodleLine *line = new DoodleLine;
205 stream >> line->x1 >>
206 line->y1 >>
207 line->x2 >>
208 line->y2;
209 lines.Append(line);
210 }
211
212 return stream;
213 }
214 #else
215 wxInputStream &DoodleSegment::LoadObject(wxInputStream& stream)
216 {
217 wxTextInputStream text_stream( stream );
218
219 wxInt32 n = 0;
220 text_stream >> n;
221
222 for (int i = 0; i < n; i++)
223 {
224 DoodleLine *line = new DoodleLine;
225 text_stream >> line->x1 >>
226 line->y1 >>
227 line->x2 >>
228 line->y2;
229 lines.Append(line);
230 }
231
232 return stream;
233 }
234 #endif
235 void DoodleSegment::Draw(wxDC *dc)
236 {
237 wxNode *node = lines.First();
238 while (node)
239 {
240 DoodleLine *line = (DoodleLine *)node->Data();
241 dc->DrawLine(line->x1, line->y1, line->x2, line->y2);
242 node = node->Next();
243 }
244 }
245
246 /*
247 * Implementation of drawing command
248 */
249
250 DrawingCommand::DrawingCommand(const wxString& name, int command, DrawingDocument *ddoc, DoodleSegment *seg):
251 wxCommand(TRUE, name)
252 {
253 doc = ddoc;
254 segment = seg;
255 cmd = command;
256 }
257
258 DrawingCommand::~DrawingCommand(void)
259 {
260 if (segment)
261 delete segment;
262 }
263
264 bool DrawingCommand::Do(void)
265 {
266 switch (cmd)
267 {
268 case DOODLE_CUT:
269 {
270 // Cut the last segment
271 if (doc->GetDoodleSegments().Number() > 0)
272 {
273 wxNode *node = doc->GetDoodleSegments().Last();
274 if (segment)
275 delete segment;
276
277 segment = (DoodleSegment *)node->Data();
278 delete node;
279
280 doc->Modify(TRUE);
281 doc->UpdateAllViews();
282 }
283 break;
284 }
285 case DOODLE_ADD:
286 {
287 doc->GetDoodleSegments().Append(new DoodleSegment(*segment));
288 doc->Modify(TRUE);
289 doc->UpdateAllViews();
290 break;
291 }
292 }
293 return TRUE;
294 }
295
296 bool DrawingCommand::Undo(void)
297 {
298 switch (cmd)
299 {
300 case DOODLE_CUT:
301 {
302 // Paste the segment
303 if (segment)
304 {
305 doc->GetDoodleSegments().Append(segment);
306 doc->Modify(TRUE);
307 doc->UpdateAllViews();
308 segment = (DoodleSegment *) NULL;
309 }
310 doc->Modify(TRUE);
311 doc->UpdateAllViews();
312 break;
313 }
314 case DOODLE_ADD:
315 {
316 // Cut the last segment
317 if (doc->GetDoodleSegments().Number() > 0)
318 {
319 wxNode *node = doc->GetDoodleSegments().Last();
320 DoodleSegment *seg = (DoodleSegment *)node->Data();
321 delete seg;
322 delete node;
323
324 doc->Modify(TRUE);
325 doc->UpdateAllViews();
326 }
327 }
328 }
329 return TRUE;
330 }
331
332 IMPLEMENT_DYNAMIC_CLASS(TextEditDocument, wxDocument)
333
334 // Since text windows have their own method for saving to/loading from files,
335 // we override OnSave/OpenDocument instead of Save/LoadObject
336 bool TextEditDocument::OnSaveDocument(const wxString& filename)
337 {
338 TextEditView *view = (TextEditView *)GetFirstView();
339
340 if (!view->textsw->SaveFile(filename))
341 return FALSE;
342 Modify(FALSE);
343 return TRUE;
344 }
345
346 bool TextEditDocument::OnOpenDocument(const wxString& filename)
347 {
348 TextEditView *view = (TextEditView *)GetFirstView();
349 if (!view->textsw->LoadFile(filename))
350 return FALSE;
351
352 SetFilename(filename, TRUE);
353 Modify(FALSE);
354 UpdateAllViews();
355 return TRUE;
356 }
357
358 bool TextEditDocument::IsModified(void) const
359 {
360 TextEditView *view = (TextEditView *)GetFirstView();
361 if (view)
362 {
363 return (wxDocument::IsModified() || view->textsw->IsModified());
364 }
365 else
366 return wxDocument::IsModified();
367 }
368
369 void TextEditDocument::Modify(bool mod)
370 {
371 TextEditView *view = (TextEditView *)GetFirstView();
372
373 wxDocument::Modify(mod);
374
375 if (!mod && view && view->textsw)
376 view->textsw->DiscardEdits();
377 }