don't leave the document in modified state after loading it (closes #10081)
[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
38 #include "doc.h"
39 #include "view.h"
40
41 // ----------------------------------------------------------------------------
42 // DrawingDocument implementation
43 // ----------------------------------------------------------------------------
44
45 IMPLEMENT_DYNAMIC_CLASS(DrawingDocument, wxDocument)
46
47 DocumentOstream& DrawingDocument::SaveObject(DocumentOstream& ostream)
48 {
49 #if wxUSE_STD_IOSTREAM
50 DocumentOstream& stream = ostream;
51 #else
52 wxTextOutputStream stream(ostream);
53 #endif
54
55 wxDocument::SaveObject(ostream);
56
57 const wxInt32 count = m_doodleSegments.size();
58 stream << count << '\n';
59
60 for ( int n = 0; n < count; n++ )
61 {
62 m_doodleSegments[n].SaveObject(ostream);
63 stream << '\n';
64 }
65
66 return ostream;
67 }
68
69 DocumentIstream& DrawingDocument::LoadObject(DocumentIstream& istream)
70 {
71 #if wxUSE_STD_IOSTREAM
72 DocumentIstream& stream = istream;
73 #else
74 wxTextInputStream stream(istream);
75 #endif
76
77 wxDocument::LoadObject(istream);
78
79 wxInt32 count = 0;
80 stream >> count;
81
82 for ( int n = 0; n < count; n++ )
83 {
84 DoodleSegment segment;
85 segment.LoadObject(istream);
86 m_doodleSegments.push_back(segment);
87 }
88
89 return istream;
90 }
91
92 void DrawingDocument::DoUpdate()
93 {
94 Modify(true);
95 UpdateAllViews();
96 }
97
98 void DrawingDocument::AddDoodleSegment(const DoodleSegment& segment)
99 {
100 m_doodleSegments.push_back(segment);
101
102 DoUpdate();
103 }
104
105 bool DrawingDocument::PopLastSegment(DoodleSegment *segment)
106 {
107 if ( m_doodleSegments.empty() )
108 return false;
109
110 if ( segment )
111 *segment = m_doodleSegments.back();
112
113 m_doodleSegments.pop_back();
114
115 DoUpdate();
116
117 return true;
118 }
119
120 // ----------------------------------------------------------------------------
121 // DoodleSegment implementation
122 // ----------------------------------------------------------------------------
123
124 DocumentOstream& DoodleSegment::SaveObject(DocumentOstream& ostream)
125 {
126 #if wxUSE_STD_IOSTREAM
127 DocumentOstream& stream = ostream;
128 #else
129 wxTextOutputStream stream(ostream);
130 #endif
131
132 const wxInt32 count = m_lines.size();
133 stream << count << '\n';
134
135 for ( int n = 0; n < count; n++ )
136 {
137 const DoodleLine& line = m_lines[n];
138 stream
139 << line.x1 << ' '
140 << line.y1 << ' '
141 << line.x2 << ' '
142 << line.y2 << '\n';
143 }
144
145 return ostream;
146 }
147
148 DocumentIstream& DoodleSegment::LoadObject(DocumentIstream& istream)
149 {
150 #if wxUSE_STD_IOSTREAM
151 DocumentIstream& stream = istream;
152 #else
153 wxTextInputStream stream(istream);
154 #endif
155
156 wxInt32 count = 0;
157 stream >> count;
158
159 for ( int n = 0; n < count; n++ )
160 {
161 DoodleLine line;
162 stream
163 >> line.x1
164 >> line.y1
165 >> line.x2
166 >> line.y2;
167 m_lines.push_back(line);
168 }
169
170 return istream;
171 }
172
173 // ----------------------------------------------------------------------------
174 // wxTextDocument: wxDocument and wxTextCtrl married
175 // ----------------------------------------------------------------------------
176
177 IMPLEMENT_CLASS(wxTextDocument, wxDocument)
178
179 bool wxTextDocument::OnCreate(const wxString& path, long flags)
180 {
181 if ( !wxDocument::OnCreate(path, flags) )
182 return false;
183
184 // subscribe to changes in the text control to update the document state
185 // when it's modified
186 GetTextCtrl()->Connect
187 (
188 wxEVT_COMMAND_TEXT_UPDATED,
189 wxCommandEventHandler(wxTextDocument::OnTextChange),
190 NULL,
191 this
192 );
193
194 return true;
195 }
196
197 // Since text windows have their own method for saving to/loading from files,
198 // we override DoSave/OpenDocument instead of Save/LoadObject
199 bool wxTextDocument::DoSaveDocument(const wxString& filename)
200 {
201 return GetTextCtrl()->SaveFile(filename);
202 }
203
204 bool wxTextDocument::DoOpenDocument(const wxString& filename)
205 {
206 if ( !GetTextCtrl()->LoadFile(filename) )
207 return false;
208
209 // we're not modified by the user yet
210 Modify(false);
211
212 return true;
213 }
214
215 bool wxTextDocument::IsModified() const
216 {
217 wxTextCtrl* wnd = GetTextCtrl();
218 return wxDocument::IsModified() || (wnd && wnd->IsModified());
219 }
220
221 void wxTextDocument::Modify(bool modified)
222 {
223 wxDocument::Modify(modified);
224
225 wxTextCtrl* wnd = GetTextCtrl();
226 if (wnd && !modified)
227 {
228 wnd->DiscardEdits();
229 }
230 }
231
232 void wxTextDocument::OnTextChange(wxCommandEvent& event)
233 {
234 Modify(true);
235
236 event.Skip();
237 }
238
239 // ----------------------------------------------------------------------------
240 // TextEditDocument implementation
241 // ----------------------------------------------------------------------------
242
243 IMPLEMENT_DYNAMIC_CLASS(TextEditDocument, wxDocument)
244
245 wxTextCtrl* TextEditDocument::GetTextCtrl() const
246 {
247 wxView* view = GetFirstView();
248 return view ? wxStaticCast(view, TextEditView)->GetText() : NULL;
249 }