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