Some stubs corrections; Motif corrections incl. busy cursor fix; doc corrections
[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
27 #if !wxUSE_DOC_VIEW_ARCHITECTURE
28 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
29 #endif
30
31 #include "doc.h"
32 #include "view.h"
33
34 IMPLEMENT_DYNAMIC_CLASS(DrawingDocument, wxDocument)
35
36 DrawingDocument::DrawingDocument(void)
37 {
38 }
39
40 DrawingDocument::~DrawingDocument(void)
41 {
42 doodleSegments.DeleteContents(TRUE);
43 }
44
45 ostream& DrawingDocument::SaveObject(ostream& stream)
46 {
47 wxDocument::SaveObject(stream);
48
49 stream << doodleSegments.Number() << '\n';
50 wxNode *node = doodleSegments.First();
51 while (node)
52 {
53 DoodleSegment *segment = (DoodleSegment *)node->Data();
54 segment->SaveObject(stream);
55 stream << '\n';
56
57 node = node->Next();
58 }
59 return stream;
60 }
61
62 istream& DrawingDocument::LoadObject(istream& stream)
63 {
64 wxDocument::LoadObject(stream);
65
66 int n = 0;
67 stream >> n;
68
69 for (int i = 0; i < n; i++)
70 {
71 DoodleSegment *segment = new DoodleSegment;
72 segment->LoadObject(stream);
73 doodleSegments.Append(segment);
74 }
75
76 return stream;
77 }
78
79 DoodleSegment::DoodleSegment(void)
80 {
81 }
82
83 DoodleSegment::DoodleSegment(DoodleSegment& seg)
84 {
85 wxNode *node = seg.lines.First();
86 while (node)
87 {
88 DoodleLine *line = (DoodleLine *)node->Data();
89 DoodleLine *newLine = new DoodleLine;
90 newLine->x1 = line->x1;
91 newLine->y1 = line->y1;
92 newLine->x2 = line->x2;
93 newLine->y2 = line->y2;
94
95 lines.Append(newLine);
96
97 node = node->Next();
98 }
99 }
100
101 DoodleSegment::~DoodleSegment(void)
102 {
103 lines.DeleteContents(TRUE);
104 }
105
106 ostream& DoodleSegment::SaveObject(ostream& stream)
107 {
108 stream << lines.Number() << '\n';
109 wxNode *node = lines.First();
110 while (node)
111 {
112 DoodleLine *line = (DoodleLine *)node->Data();
113 stream << line->x1 << " " << line->y1 << " " << line->x2 << " " << line->y2 << "\n";
114 node = node->Next();
115 }
116 return stream;
117 }
118
119 istream& DoodleSegment::LoadObject(istream& stream)
120 {
121 int n = 0;
122 stream >> n;
123
124 for (int i = 0; i < n; i++)
125 {
126 DoodleLine *line = new DoodleLine;
127 stream >> line->x1 >> line->y1 >> line->x2 >> line->y2;
128 lines.Append(line);
129 }
130 return stream;
131 }
132
133 void DoodleSegment::Draw(wxDC *dc)
134 {
135 wxNode *node = lines.First();
136 while (node)
137 {
138 DoodleLine *line = (DoodleLine *)node->Data();
139 dc->DrawLine(line->x1, line->y1, line->x2, line->y2);
140 node = node->Next();
141 }
142 }
143
144 /*
145 * Implementation of drawing command
146 */
147
148 DrawingCommand::DrawingCommand(const wxString& name, int command, DrawingDocument *ddoc, DoodleSegment *seg):
149 wxCommand(TRUE, name)
150 {
151 doc = ddoc;
152 segment = seg;
153 cmd = command;
154 }
155
156 DrawingCommand::~DrawingCommand(void)
157 {
158 if (segment)
159 delete segment;
160 }
161
162 bool DrawingCommand::Do(void)
163 {
164 switch (cmd)
165 {
166 case DOODLE_CUT:
167 {
168 // Cut the last segment
169 if (doc->GetDoodleSegments().Number() > 0)
170 {
171 wxNode *node = doc->GetDoodleSegments().Last();
172 if (segment)
173 delete segment;
174
175 segment = (DoodleSegment *)node->Data();
176 delete node;
177
178 doc->Modify(TRUE);
179 doc->UpdateAllViews();
180 }
181 break;
182 }
183 case DOODLE_ADD:
184 {
185 doc->GetDoodleSegments().Append(new DoodleSegment(*segment));
186 doc->Modify(TRUE);
187 doc->UpdateAllViews();
188 break;
189 }
190 }
191 return TRUE;
192 }
193
194 bool DrawingCommand::Undo(void)
195 {
196 switch (cmd)
197 {
198 case DOODLE_CUT:
199 {
200 // Paste the segment
201 if (segment)
202 {
203 doc->GetDoodleSegments().Append(segment);
204 doc->Modify(TRUE);
205 doc->UpdateAllViews();
206 segment = (DoodleSegment *) NULL;
207 }
208 doc->Modify(TRUE);
209 doc->UpdateAllViews();
210 break;
211 }
212 case DOODLE_ADD:
213 {
214 // Cut the last segment
215 if (doc->GetDoodleSegments().Number() > 0)
216 {
217 wxNode *node = doc->GetDoodleSegments().Last();
218 DoodleSegment *seg = (DoodleSegment *)node->Data();
219 delete seg;
220 delete node;
221
222 doc->Modify(TRUE);
223 doc->UpdateAllViews();
224 }
225 }
226 }
227 return TRUE;
228 }
229
230 IMPLEMENT_DYNAMIC_CLASS(TextEditDocument, wxDocument)
231
232 // Since text windows have their own method for saving to/loading from files,
233 // we override OnSave/OpenDocument instead of Save/LoadObject
234 bool TextEditDocument::OnSaveDocument(const wxString& filename)
235 {
236 TextEditView *view = (TextEditView *)GetFirstView();
237
238 if (!view->textsw->SaveFile(filename))
239 return FALSE;
240 Modify(FALSE);
241 return TRUE;
242 }
243
244 bool TextEditDocument::OnOpenDocument(const wxString& filename)
245 {
246 TextEditView *view = (TextEditView *)GetFirstView();
247 if (!view->textsw->LoadFile(filename))
248 return FALSE;
249
250 SetFilename(filename, TRUE);
251 Modify(FALSE);
252 UpdateAllViews();
253 return TRUE;
254 }
255
256 bool TextEditDocument::IsModified(void) const
257 {
258 TextEditView *view = (TextEditView *)GetFirstView();
259 if (view)
260 {
261 return (wxDocument::IsModified() || view->textsw->IsModified());
262 }
263 else
264 return wxDocument::IsModified();
265 }
266
267 void TextEditDocument::Modify(bool mod)
268 {
269 TextEditView *view = (TextEditView *)GetFirstView();
270
271 wxDocument::Modify(mod);
272
273 if (!mod && view && view->textsw)
274 view->textsw->DiscardEdits();
275 }