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