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