]> git.saurik.com Git - wxWidgets.git/blob - samples/docvwmdi/doc.cpp
Elliptic arc fix for getting bounds
[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
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 WX_CLEAR_LIST(wxList, doodleSegments);
40 }
41
42 #if wxUSE_STD_IOSTREAM
43 wxSTD ostream& DrawingDocument::SaveObject(wxSTD ostream& stream)
44 {
45 wxDocument::SaveObject(stream);
46
47 wxInt32 n = doodleSegments.GetCount();
48 stream << n << _T('\n');
49
50 wxList::compatibility_iterator node = doodleSegments.GetFirst();
51 while (node)
52 {
53 DoodleSegment *segment = (DoodleSegment *)node->GetData();
54 segment->SaveObject(stream);
55 stream << _T('\n');
56
57 node = node->GetNext();
58 }
59
60 return stream;
61 }
62 #else
63 wxOutputStream& DrawingDocument::SaveObject(wxOutputStream& stream)
64 {
65 wxDocument::SaveObject(stream);
66
67 wxTextOutputStream text_stream( stream );
68
69 wxInt32 n = doodleSegments.GetCount();
70 text_stream << n << _T('\n');
71
72 wxList::compatibility_iterator node = doodleSegments.GetFirst();
73 while (node)
74 {
75 DoodleSegment *segment = (DoodleSegment *)node->GetData();
76 segment->SaveObject(stream);
77 text_stream << _T('\n');
78
79 node = node->GetNext();
80 }
81
82 return stream;
83 }
84 #endif
85
86 #if wxUSE_STD_IOSTREAM
87 wxSTD istream& DrawingDocument::LoadObject(wxSTD istream& stream)
88 {
89 wxDocument::LoadObject(stream);
90
91 wxInt32 n = 0;
92 stream >> n;
93
94 for (int i = 0; i < n; i++)
95 {
96 DoodleSegment *segment = new DoodleSegment;
97 segment->LoadObject(stream);
98 doodleSegments.Append(segment);
99 }
100
101 return stream;
102 }
103 #else
104 wxInputStream& DrawingDocument::LoadObject(wxInputStream& stream)
105 {
106 wxDocument::LoadObject(stream);
107
108 wxTextInputStream text_stream( stream );
109
110 wxInt32 n = 0;
111 text_stream >> n;
112
113 for (int i = 0; i < n; i++)
114 {
115 DoodleSegment *segment = new DoodleSegment;
116 segment->LoadObject(stream);
117 doodleSegments.Append(segment);
118 }
119
120 return stream;
121 }
122 #endif
123
124 DoodleSegment::DoodleSegment(DoodleSegment& seg)
125 :wxObject()
126 {
127 wxList::compatibility_iterator node = seg.lines.GetFirst();
128 while (node)
129 {
130 DoodleLine *line = (DoodleLine *)node->GetData();
131 DoodleLine *newLine = new DoodleLine;
132 newLine->x1 = line->x1;
133 newLine->y1 = line->y1;
134 newLine->x2 = line->x2;
135 newLine->y2 = line->y2;
136
137 lines.Append(newLine);
138
139 node = node->GetNext();
140 }
141 }
142
143 DoodleSegment::~DoodleSegment(void)
144 {
145 WX_CLEAR_LIST(wxList, lines);
146 }
147
148 #if wxUSE_STD_IOSTREAM
149 wxSTD ostream& DoodleSegment::SaveObject(wxSTD ostream& stream)
150 {
151 wxInt32 n = lines.GetCount();
152 stream << n << _T('\n');
153
154 wxList::compatibility_iterator node = lines.GetFirst();
155 while (node)
156 {
157 DoodleLine *line = (DoodleLine *)node->GetData();
158 stream << line->x1 << _T(" ") <<
159 line->y1 << _T(" ") <<
160 line->x2 << _T(" ") <<
161 line->y2 << _T("\n");
162 node = node->GetNext();
163 }
164
165 return stream;
166 }
167 #else
168 wxOutputStream &DoodleSegment::SaveObject(wxOutputStream& stream)
169 {
170 wxTextOutputStream text_stream( stream );
171
172 wxInt32 n = lines.GetCount();
173 text_stream << n << _T('\n');
174
175 wxList::compatibility_iterator node = lines.GetFirst();
176 while (node)
177 {
178 DoodleLine *line = (DoodleLine *)node->GetData();
179 text_stream << line->x1 << _T(" ") <<
180 line->y1 << _T(" ") <<
181 line->x2 << _T(" ") <<
182 line->y2 << _T("\n");
183 node = node->GetNext();
184 }
185
186 return stream;
187 }
188 #endif
189
190 #if wxUSE_STD_IOSTREAM
191 wxSTD istream& DoodleSegment::LoadObject(wxSTD istream& stream)
192 {
193 wxInt32 n = 0;
194 stream >> n;
195
196 for (int i = 0; i < n; i++)
197 {
198 DoodleLine *line = new DoodleLine;
199 stream >> line->x1 >>
200 line->y1 >>
201 line->x2 >>
202 line->y2;
203 lines.Append(line);
204 }
205
206 return stream;
207 }
208 #else
209 wxInputStream &DoodleSegment::LoadObject(wxInputStream& stream)
210 {
211 wxTextInputStream text_stream( stream );
212
213 wxInt32 n = 0;
214 text_stream >> n;
215
216 for (int i = 0; i < n; i++)
217 {
218 DoodleLine *line = new DoodleLine;
219 text_stream >> line->x1 >>
220 line->y1 >>
221 line->x2 >>
222 line->y2;
223 lines.Append(line);
224 }
225
226 return stream;
227 }
228 #endif
229 void DoodleSegment::Draw(wxDC *dc)
230 {
231 wxList::compatibility_iterator node = lines.GetFirst();
232 while (node)
233 {
234 DoodleLine *line = (DoodleLine *)node->GetData();
235 dc->DrawLine(line->x1, line->y1, line->x2, line->y2);
236 node = node->GetNext();
237 }
238 }
239
240 /*
241 * Implementation of drawing command
242 */
243
244 DrawingCommand::DrawingCommand(const wxString& name, int command, DrawingDocument *ddoc, DoodleSegment *seg):
245 wxCommand(true, name)
246 {
247 doc = ddoc;
248 segment = seg;
249 cmd = command;
250 }
251
252 DrawingCommand::~DrawingCommand(void)
253 {
254 if (segment)
255 delete segment;
256 }
257
258 bool DrawingCommand::Do(void)
259 {
260 switch (cmd)
261 {
262 case DOODLE_CUT:
263 {
264 // Cut the last segment
265 if (doc->GetDoodleSegments().GetCount() > 0)
266 {
267 wxList::compatibility_iterator node = doc->GetDoodleSegments().GetLast();
268 if (segment)
269 delete segment;
270
271 segment = (DoodleSegment *)node->GetData();
272 doc->GetDoodleSegments().Erase(node);
273
274 doc->Modify(true);
275 doc->UpdateAllViews();
276 }
277 break;
278 }
279 case DOODLE_ADD:
280 {
281 doc->GetDoodleSegments().Append(new DoodleSegment(*segment));
282 doc->Modify(true);
283 doc->UpdateAllViews();
284 break;
285 }
286 }
287 return true;
288 }
289
290 bool DrawingCommand::Undo(void)
291 {
292 switch (cmd)
293 {
294 case DOODLE_CUT:
295 {
296 // Paste the segment
297 if (segment)
298 {
299 doc->GetDoodleSegments().Append(segment);
300 doc->Modify(true);
301 doc->UpdateAllViews();
302 segment = (DoodleSegment *) NULL;
303 }
304 doc->Modify(true);
305 doc->UpdateAllViews();
306 break;
307 }
308 case DOODLE_ADD:
309 {
310 // Cut the last segment
311 if (doc->GetDoodleSegments().GetCount() > 0)
312 {
313 wxList::compatibility_iterator node = doc->GetDoodleSegments().GetLast();
314 DoodleSegment *seg = (DoodleSegment *)node->GetData();
315 delete seg;
316 doc->GetDoodleSegments().Erase(node);
317
318 doc->Modify(true);
319 doc->UpdateAllViews();
320 }
321 }
322 }
323 return true;
324 }
325
326 IMPLEMENT_DYNAMIC_CLASS(TextEditDocument, wxDocument)
327
328 // Since text windows have their own method for saving to/loading from files,
329 // we override OnSave/OpenDocument instead of Save/LoadObject
330 bool TextEditDocument::OnSaveDocument(const wxString& filename)
331 {
332 TextEditView *view = (TextEditView *)GetFirstView();
333
334 if (!view->textsw->SaveFile(filename))
335 return false;
336 Modify(false);
337 return true;
338 }
339
340 bool TextEditDocument::OnOpenDocument(const wxString& filename)
341 {
342 TextEditView *view = (TextEditView *)GetFirstView();
343 if (!view->textsw->LoadFile(filename))
344 return false;
345
346 SetFilename(filename, true);
347 Modify(false);
348 UpdateAllViews();
349 return true;
350 }
351
352 bool TextEditDocument::IsModified(void) const
353 {
354 TextEditView *view = (TextEditView *)GetFirstView();
355 if (view)
356 {
357 return (wxDocument::IsModified() || view->textsw->IsModified());
358 }
359 else
360 return wxDocument::IsModified();
361 }
362
363 void TextEditDocument::Modify(bool mod)
364 {
365 TextEditView *view = (TextEditView *)GetFirstView();
366
367 wxDocument::Modify(mod);
368
369 if (!mod && view && view->textsw)
370 view->textsw->DiscardEdits();
371 }