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