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