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