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