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: doc.cpp 55142 2008-08-21 08:56:50Z SC $ 8// Copyright: (c) Julian Smart 9// Licence: wxWindows license 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx/wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __BORLANDC__ 16#pragma hdrstop 17#endif 18 19#ifndef WX_PRECOMP 20#include "wx/wx.h" 21#endif 22#ifdef __WXMAC__ 23#include "wx/filename.h" 24#endif 25 26#if wxUSE_STD_IOSTREAM 27 #include "wx/ioswrap.h" 28#else 29 #include "wx/txtstrm.h" 30#endif 31 32#if !wxUSE_DOC_VIEW_ARCHITECTURE 33#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h! 34#endif 35 36#include "doc.h" 37#include "view.h" 38IMPLEMENT_DYNAMIC_CLASS(DrawingDocument, wxDocument) 39 40DrawingDocument::~DrawingDocument(void) 41{ 42 WX_CLEAR_LIST(wxList, doodleSegments); 43} 44 45#if wxUSE_STD_IOSTREAM 46wxSTD ostream& DrawingDocument::SaveObject(wxSTD ostream& stream) 47{ 48 wxDocument::SaveObject(stream); 49 50 wxInt32 n = doodleSegments.GetCount(); 51 stream << n << '\n'; 52 53 wxList::compatibility_iterator node = doodleSegments.GetFirst(); 54 while (node) 55 { 56 DoodleSegment *segment = (DoodleSegment *)node->GetData(); 57 segment->SaveObject(stream); 58 stream << '\n'; 59 60 node = node->GetNext(); 61 } 62 63 return stream; 64} 65#else 66wxOutputStream& DrawingDocument::SaveObject(wxOutputStream& stream) 67{ 68 wxDocument::SaveObject(stream); 69 70 wxTextOutputStream text_stream( stream ); 71 72 wxInt32 n = doodleSegments.GetCount(); 73 text_stream << n << '\n'; 74 75 wxList::compatibility_iterator node = doodleSegments.GetFirst(); 76 while (node) 77 { 78 DoodleSegment *segment = (DoodleSegment *)node->GetData(); 79 segment->SaveObject(stream); 80 text_stream << '\n'; 81 82 node = node->GetNext(); 83 } 84 85 return stream; 86} 87#endif 88 89#if wxUSE_STD_IOSTREAM 90wxSTD istream& DrawingDocument::LoadObject(wxSTD istream& stream) 91{ 92 wxDocument::LoadObject(stream); 93 94 wxInt32 n = 0; 95 stream >> n; 96 97 for (int i = 0; i < n; i++) 98 { 99 DoodleSegment *segment = new DoodleSegment; 100 segment->LoadObject(stream); 101 doodleSegments.Append(segment); 102 } 103 104 return stream; 105} 106#else 107wxInputStream& DrawingDocument::LoadObject(wxInputStream& stream) 108{ 109 wxDocument::LoadObject(stream); 110 111 wxTextInputStream text_stream( stream ); 112 113 wxInt32 n = 0; 114 text_stream >> n; 115 116 for (int i = 0; i < n; i++) 117 { 118 DoodleSegment *segment = new DoodleSegment; 119 segment->LoadObject(stream); 120 doodleSegments.Append(segment); 121 } 122 123 return stream; 124} 125#endif 126 127DoodleSegment::DoodleSegment(const DoodleSegment& seg):wxObject() 128{ 129 wxList::compatibility_iterator node = seg.lines.GetFirst(); 130 while (node) 131 { 132 DoodleLine *line = (DoodleLine *)node->GetData(); 133 DoodleLine *newLine = new DoodleLine; 134 newLine->x1 = line->x1; 135 newLine->y1 = line->y1; 136 newLine->x2 = line->x2; 137 newLine->y2 = line->y2; 138 139 lines.Append(newLine); 140 141 node = node->GetNext(); 142 } 143} 144 145DoodleSegment::~DoodleSegment(void) 146{ 147 WX_CLEAR_LIST(wxList, lines); 148} 149 150#if wxUSE_STD_IOSTREAM 151wxSTD ostream& DoodleSegment::SaveObject(wxSTD ostream& stream) 152{ 153 wxInt32 n = lines.GetCount(); 154 stream << n << '\n'; 155 156 wxList::compatibility_iterator node = lines.GetFirst(); 157 while (node) 158 { 159 DoodleLine *line = (DoodleLine *)node->GetData(); 160 stream << line->x1 << " " << 161 line->y1 << " " << 162 line->x2 << " " << 163 line->y2 << "\n"; 164 node = node->GetNext(); 165 } 166 167 return stream; 168} 169#else 170wxOutputStream &DoodleSegment::SaveObject(wxOutputStream& stream) 171{ 172 wxTextOutputStream text_stream( stream ); 173 174 wxInt32 n = lines.GetCount(); 175 text_stream << n << _T("\n"); 176 177 wxList::compatibility_iterator node = lines.GetFirst(); 178 while (node) 179 { 180 DoodleLine *line = (DoodleLine *)node->GetData(); 181 text_stream << line->x1 << _T(" ") << 182 line->y1 << _T(" ") << 183 line->x2 << _T(" ") << 184 line->y2 << _T("\n"); 185 node = node->GetNext(); 186 } 187 188 return stream; 189} 190#endif 191 192#if wxUSE_STD_IOSTREAM 193wxSTD istream& DoodleSegment::LoadObject(wxSTD istream& stream) 194{ 195 wxInt32 n = 0; 196 stream >> n; 197 198 for (int i = 0; i < n; i++) 199 { 200 DoodleLine *line = new DoodleLine; 201 stream >> line->x1 >> 202 line->y1 >> 203 line->x2 >> 204 line->y2; 205 lines.Append(line); 206 } 207 208 return stream; 209} 210#else 211wxInputStream &DoodleSegment::LoadObject(wxInputStream& stream) 212{ 213 wxTextInputStream text_stream( stream ); 214 215 wxInt32 n = 0; 216 text_stream >> n; 217 218 for (int i = 0; i < n; i++) 219 { 220 DoodleLine *line = new DoodleLine; 221 text_stream >> line->x1 >> 222 line->y1 >> 223 line->x2 >> 224 line->y2; 225 lines.Append(line); 226 } 227 228 return stream; 229} 230#endif 231 232void DoodleSegment::Draw(wxDC *dc) 233{ 234 wxList::compatibility_iterator node = lines.GetFirst(); 235 while (node) 236 { 237 DoodleLine *line = (DoodleLine *)node->GetData(); 238 dc->DrawLine(line->x1, line->y1, line->x2, line->y2); 239 node = node->GetNext(); 240 } 241} 242 243/* 244* Implementation of drawing command 245*/ 246 247DrawingCommand::DrawingCommand(const wxString& name, int command, DrawingDocument *ddoc, DoodleSegment *seg): 248wxCommand(true, name) 249{ 250 doc = ddoc; 251 segment = seg; 252 cmd = command; 253} 254 255DrawingCommand::~DrawingCommand(void) 256{ 257 if (segment) 258 delete segment; 259} 260 261bool DrawingCommand::Do(void) 262{ 263 switch (cmd) 264 { 265 case DOODLE_CUT: 266 { 267 // Cut the last segment 268 if (doc->GetDoodleSegments().GetCount() > 0) 269 { 270 wxList::compatibility_iterator node = doc->GetDoodleSegments().GetLast(); 271 if (segment) 272 delete segment; 273 274 segment = (DoodleSegment *)node->GetData(); 275 doc->GetDoodleSegments().Erase(node); 276 277 doc->Modify(true); 278 doc->UpdateAllViews(); 279 } 280 break; 281 } 282 case DOODLE_ADD: 283 { 284 doc->GetDoodleSegments().Append(new DoodleSegment(*segment)); 285 doc->Modify(true); 286 doc->UpdateAllViews(); 287 break; 288 } 289 } 290 return true; 291} 292 293bool DrawingCommand::Undo(void) 294{ 295 switch (cmd) 296 { 297 case DOODLE_CUT: 298 { 299 // Paste the segment 300 if (segment) 301 { 302 doc->GetDoodleSegments().Append(segment); 303 doc->Modify(true); 304 doc->UpdateAllViews(); 305 segment = (DoodleSegment *) NULL; 306 } 307 doc->Modify(true); 308 doc->UpdateAllViews(); 309 break; 310 } 311 case DOODLE_ADD: 312 { 313 // Cut the last segment 314 if (doc->GetDoodleSegments().GetCount() > 0) 315 { 316 wxList::compatibility_iterator node = doc->GetDoodleSegments().GetLast(); 317 DoodleSegment *seg = (DoodleSegment *)node->GetData(); 318 delete seg; 319 doc->GetDoodleSegments().Erase(node); 320 321 doc->Modify(true); 322 doc->UpdateAllViews(); 323 } 324 } 325 } 326 return true; 327} 328 329IMPLEMENT_DYNAMIC_CLASS(TextEditDocument, wxDocument) 330 331// Since text windows have their own method for saving to/loading from files, 332// we override DoSave/OpenDocument instead of Save/LoadObject 333bool TextEditDocument::DoSaveDocument(const wxString& filename) 334{ 335 TextEditView *view = (TextEditView *)GetFirstView(); 336 337 if (!view->textsw->SaveFile(filename)) 338 return false; 339 340 return true; 341} 342 343bool TextEditDocument::DoOpenDocument(const wxString& filename) 344{ 345 TextEditView *view = (TextEditView *)GetFirstView(); 346 if (!view->textsw->LoadFile(filename)) 347 return false; 348 349 return true; 350} 351 352bool TextEditDocument::IsModified(void) const 353{ 354 TextEditView *view = (TextEditView *)GetFirstView(); 355 if (view) 356 { 357 return (wxDocument::IsModified() || view->textsw->IsModified()); 358 } 359 else 360 return wxDocument::IsModified(); 361} 362 363void TextEditDocument::Modify(bool mod) 364{ 365 TextEditView *view = (TextEditView *)GetFirstView(); 366 367 wxDocument::Modify(mod); 368 369 if (!mod && view && view->textsw) 370 view->textsw->DiscardEdits(); 371} 372