Applied #10811: Image in docview sample
[wxWidgets.git] / samples / docview / doc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/docview/doc.cpp
3 // Purpose: Implements document functionality
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin: merge with the MDI version and general cleanup
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Julian Smart
9 // (c) 2008 Vadim Zeitlin
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13 // ----------------------------------------------------------------------------
14 // headers
15 // ----------------------------------------------------------------------------
16
17 // For compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #if !wxUSE_DOC_VIEW_ARCHITECTURE
25 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
26 #endif
27
28 #ifndef WX_PRECOMP
29 #include "wx/wx.h"
30 #endif
31
32 #if wxUSE_STD_IOSTREAM
33 #include "wx/ioswrap.h"
34 #else
35 #include "wx/txtstrm.h"
36 #endif
37 #include "wx/wfstream.h"
38
39 #include "doc.h"
40 #include "view.h"
41
42 // ----------------------------------------------------------------------------
43 // DrawingDocument implementation
44 // ----------------------------------------------------------------------------
45
46 IMPLEMENT_DYNAMIC_CLASS(DrawingDocument, wxDocument)
47
48 DocumentOstream& DrawingDocument::SaveObject(DocumentOstream& ostream)
49 {
50 #if wxUSE_STD_IOSTREAM
51 DocumentOstream& stream = ostream;
52 #else
53 wxTextOutputStream stream(ostream);
54 #endif
55
56 wxDocument::SaveObject(ostream);
57
58 const wxInt32 count = m_doodleSegments.size();
59 stream << count << '\n';
60
61 for ( int n = 0; n < count; n++ )
62 {
63 m_doodleSegments[n].SaveObject(ostream);
64 stream << '\n';
65 }
66
67 return ostream;
68 }
69
70 DocumentIstream& DrawingDocument::LoadObject(DocumentIstream& istream)
71 {
72 #if wxUSE_STD_IOSTREAM
73 DocumentIstream& stream = istream;
74 #else
75 wxTextInputStream stream(istream);
76 #endif
77
78 wxDocument::LoadObject(istream);
79
80 wxInt32 count = 0;
81 stream >> count;
82
83 for ( int n = 0; n < count; n++ )
84 {
85 DoodleSegment segment;
86 segment.LoadObject(istream);
87 m_doodleSegments.push_back(segment);
88 }
89
90 return istream;
91 }
92
93 void DrawingDocument::DoUpdate()
94 {
95 Modify(true);
96 UpdateAllViews();
97 }
98
99 void DrawingDocument::AddDoodleSegment(const DoodleSegment& segment)
100 {
101 m_doodleSegments.push_back(segment);
102
103 DoUpdate();
104 }
105
106 bool DrawingDocument::PopLastSegment(DoodleSegment *segment)
107 {
108 if ( m_doodleSegments.empty() )
109 return false;
110
111 if ( segment )
112 *segment = m_doodleSegments.back();
113
114 m_doodleSegments.pop_back();
115
116 DoUpdate();
117
118 return true;
119 }
120
121 // ----------------------------------------------------------------------------
122 // DoodleSegment implementation
123 // ----------------------------------------------------------------------------
124
125 DocumentOstream& DoodleSegment::SaveObject(DocumentOstream& ostream)
126 {
127 #if wxUSE_STD_IOSTREAM
128 DocumentOstream& stream = ostream;
129 #else
130 wxTextOutputStream stream(ostream);
131 #endif
132
133 const wxInt32 count = m_lines.size();
134 stream << count << '\n';
135
136 for ( int n = 0; n < count; n++ )
137 {
138 const DoodleLine& line = m_lines[n];
139 stream
140 << line.x1 << ' '
141 << line.y1 << ' '
142 << line.x2 << ' '
143 << line.y2 << '\n';
144 }
145
146 return ostream;
147 }
148
149 DocumentIstream& DoodleSegment::LoadObject(DocumentIstream& istream)
150 {
151 #if wxUSE_STD_IOSTREAM
152 DocumentIstream& stream = istream;
153 #else
154 wxTextInputStream stream(istream);
155 #endif
156
157 wxInt32 count = 0;
158 stream >> count;
159
160 for ( int n = 0; n < count; n++ )
161 {
162 DoodleLine line;
163 stream
164 >> line.x1
165 >> line.y1
166 >> line.x2
167 >> line.y2;
168 m_lines.push_back(line);
169 }
170
171 return istream;
172 }
173
174 // ----------------------------------------------------------------------------
175 // wxTextDocument: wxDocument and wxTextCtrl married
176 // ----------------------------------------------------------------------------
177
178 IMPLEMENT_CLASS(wxTextDocument, wxDocument)
179
180 bool wxTextDocument::OnCreate(const wxString& path, long flags)
181 {
182 if ( !wxDocument::OnCreate(path, flags) )
183 return false;
184
185 // subscribe to changes in the text control to update the document state
186 // when it's modified
187 GetTextCtrl()->Connect
188 (
189 wxEVT_COMMAND_TEXT_UPDATED,
190 wxCommandEventHandler(wxTextDocument::OnTextChange),
191 NULL,
192 this
193 );
194
195 return true;
196 }
197
198 // Since text windows have their own method for saving to/loading from files,
199 // we override DoSave/OpenDocument instead of Save/LoadObject
200 bool wxTextDocument::DoSaveDocument(const wxString& filename)
201 {
202 return GetTextCtrl()->SaveFile(filename);
203 }
204
205 bool wxTextDocument::DoOpenDocument(const wxString& filename)
206 {
207 if ( !GetTextCtrl()->LoadFile(filename) )
208 return false;
209
210 // we're not modified by the user yet
211 Modify(false);
212
213 return true;
214 }
215
216 bool wxTextDocument::IsModified() const
217 {
218 wxTextCtrl* wnd = GetTextCtrl();
219 return wxDocument::IsModified() || (wnd && wnd->IsModified());
220 }
221
222 void wxTextDocument::Modify(bool modified)
223 {
224 wxDocument::Modify(modified);
225
226 wxTextCtrl* wnd = GetTextCtrl();
227 if (wnd && !modified)
228 {
229 wnd->DiscardEdits();
230 }
231 }
232
233 void wxTextDocument::OnTextChange(wxCommandEvent& event)
234 {
235 Modify(true);
236
237 event.Skip();
238 }
239
240 // ----------------------------------------------------------------------------
241 // TextEditDocument implementation
242 // ----------------------------------------------------------------------------
243
244 IMPLEMENT_DYNAMIC_CLASS(TextEditDocument, wxDocument)
245
246 wxTextCtrl* TextEditDocument::GetTextCtrl() const
247 {
248 wxView* view = GetFirstView();
249 return view ? wxStaticCast(view, TextEditView)->GetText() : NULL;
250 }
251
252 // ----------------------------------------------------------------------------
253 // wxImageDocument implementation
254 // ----------------------------------------------------------------------------
255
256 /////////////////////////////////////////////////////////////////////////////
257 // wxImageDocument
258
259 IMPLEMENT_DYNAMIC_CLASS(wxImageDocument, wxDocument)
260
261 wxImageDocument::wxImageDocument() : wxDocument()
262 {
263 }
264
265 wxImageDocument::~wxImageDocument()
266 {
267 }
268
269 bool wxImageDocument::DeleteContents()
270 {
271 bool ok = wxDocument::DeleteContents();
272 if (ok && m_image.IsOk())
273 {
274 m_image.Destroy();
275 }
276 return ok;
277 }
278
279 bool wxImageDocument::SaveFile(wxOutputStream* stream, wxBitmapType type) const
280 {
281 return m_image.IsOk() && m_image.SaveFile(*stream, type);
282 }
283
284 bool wxImageDocument::DoOpenDocument(const wxString& file)
285 {
286 wxFileInputStream stream(file);
287 return stream.IsOk() && DoOpenDocument(&stream);
288 }
289
290 bool wxImageDocument::DoSaveDocument(const wxString& file)
291 {
292 wxFileOutputStream stream(file);
293 return stream.IsOk() && DoSaveDocument(&stream);
294 }
295
296 bool wxImageDocument::DoOpenDocument(wxInputStream* stream)
297 {
298 return m_image.LoadFile(*stream);
299 }
300
301 bool wxImageDocument::DoSaveDocument(wxOutputStream* stream) const
302 {
303 return m_image.IsOk() && SaveFile(stream, m_image.GetType());
304 }
305