OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
document.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1993, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of class TDocument
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9#include <owl/docmanag.h>
10#include <owl/appdict.h>
11#include <owl/docview.rh>
12#include <string.h>
13#include <stdio.h>
14
15#if defined(__BORLANDC__)
16# pragma option -w-ccc // Disable "Condition is always true/false"
17#endif
18
19namespace owl {
20
22DIAG_DECLARE_GROUP(OwlDocView); // General Doc/View diagnostic group
23
24// !BB Is provided by DocManager to avoid sharing
25// of index between multiple applications.
26// int TDocument::UntitledIndex = 0;
27
28
29//
30/// Although you do not create a TDocument object directly, you must call the
31/// constructor when you create a derived class. parent points to the parent of the
32/// new document. If no parent exists, parent is 0.
33//
35:
36 Tag(nullptr),
37 DirtyFlag(false),
38 Embedded(false),
39 ParentDoc(parent),
40 NextDoc(nullptr),
41 OpenMode(0),
42 Title(nullptr),
43 Template(nullptr),
44 ViewList(nullptr),
45 StreamList(nullptr),
46 DocPath(nullptr)
47{
48 if (parent) {
49 DocManager = parent->DocManager;
50
51 // Handle case of 'dummy' parent [parent parented to itself] which was
52 // created by the docmanager simply to pass itself to us
53 //
54 if (parent->ParentDoc == parent) {
55 ParentDoc = nullptr;
56 CHECK(DocManager);
57 DocManager->DocList.Insert(this);
58 }
59 else
60 parent->ChildDoc.Insert(this);
61 }
62 else {
64 CHECK(app);
65 DocManager = app->GetDocManager();
66 if (!DocManager)
67 TXOwl::Raise(IDS_NODOCMANAGER); // No doc manager to catch this one
68 DocManager->DocList.Insert(this);
69 }
70}
71
72//
73/// Deletes a TDocument object. Normally, Close is called first. TDocument's
74/// destructor destroys all children and closes all open streams. If this is the
75/// last document that used the template, it closes the object's template and any
76/// associated views, deletes the object's stream, and removes itself from the
77/// parent's list of children if a parent exists. If there is no parent, it removes
78/// itself from the document manager's document list.
79//
81{
82 // Is this a dummy document?
83 //
84 if (ParentDoc == this)
85 return;
86
87 // Unref template - prevents self autodelete when deleting views, including
88 // views in child documents
89 //
90 SetTemplate(nullptr);
91
93
95
96 // Delete all streams, should only be present if abort or coding error
97 //
98 while (StreamList) {
99 TRACEX(OwlDocView, 0, _T("~TDocument(): StreamList not 0!"));
100 delete StreamList;
101 }
102
103 // Detach from parent and doc manager
104 //
105 if (ParentDoc) {
106 ParentDoc->ChildDoc.Remove(this);
107 }
108 else {
109 const auto ok = DocManager != nullptr;
110 WARN(!ok, _T("TDocument::~TDocument: Terminating due to failed precondition."));
111 if (!ok) std::terminate();
112
113 DocManager->PostEvent(dnClose, *this); // WM_OWLDOCUMENT
114 DocManager->DocList.Remove(this);
115 }
116
117 delete[] Title;
118 delete[] DocPath;
119}
120
121//
122//
123//
124static const LPCTSTR PropNames[] = {
125 _T("Document Class"), // DocumentClass
126 _T("Template Name"), // TemplateName
127 _T("View Count"), // ViewCount
128 _T("Storage Path"), // StoragePath
129 _T("Document Title"), // DocTitle
130};
131
132//
133//
134//
135static int PropFlags[] = {
136 pfGetText|pfConstant, // DocumentClass
137 pfGetText, // TemplateName
138 pfGetBinary|pfGetText, // ViewCount
139 pfGetText|pfSettable, // StoragePath
140 pfGetText|pfSettable, // DocTitle
141};
142
143//
144/// Returns the name of the property given the index value (index).
145//
148{
149 if (index <= PrevProperty) {
150 TRACEX(OwlDocView, 0, _T("PropertyName(): index <= PrevProperty!"));
151 return nullptr;
152 }
153 else if (index < NextProperty)
154 return PropNames[index-PrevProperty-1];
155 else {
156 TRACEX(OwlDocView, 0, _T("PropertyName(): index >= PrevProperty!"));
157 return nullptr;
158 }
159}
160
161//
162/// Returns the attributes of a specified property given the index (index) of the
163/// property whose attributes you want to retrieve.
164//
165int
167{
168 if (index <= PrevProperty) {
169 TRACEX(OwlDocView, 0, _T("PropertyFlags(): index <= PrevProperty!"));
170 return 0;
171 }
172 else if (index < NextProperty)
173 return PropFlags[index-PrevProperty-1];
174 else {
175 TRACEX(OwlDocView, 0, _T("PropertyFlags(): index >= PrevProperty!"));
176 return 0;
177 }
178}
179
180//
181/// Gets the property index, given the property name (name). Returns either the
182/// integer index number that corresponds to the name or 0 if the name isn't found
183/// in the list of properties.
184//
185int
187{
188 PRECONDITION(name != nullptr);
189 int i;
190 for (i=0; i < NextProperty-PrevProperty-1; i++)
191 if (_tcscmp(PropNames[i], name) == 0)
192 return i+PrevProperty+1;
193
194 TRACEX(OwlDocView, 0, _T("FindProperty: Index of [") << name << _T("] not found") );
195 return 0;
196}
197
198//
199/// Retrieves the property identified by the given index.
200/// If the requested property is text, then `dest` should point to a text buffer, and `textlen`
201/// should specify the maximum number of characters the buffer can hold, excluding the terminating
202/// null-character, i.e. the buffer must have room for (`textlen` + 1) characters.
203///
204/// If the requested property is numerical, then it may be requested either as text or in its
205/// binary form. To request the property as text, pass a text buffer as described above. To request
206/// the property in binary form, `dest` should point to storage of sufficent size, and `textlen`
207/// should be zero.
208///
209/// Non-text properties without textual representation, e.g. file handles, may only be requested
210/// in binary form, i.e. `dest` must point to sufficient storage, and `textlen` must be zero.
211///
212/// \return If the parameter `textlen` is non-zero, which means that the property is requested in
213/// string form, the function returns the length of the string, i.e. the character count excluding
214/// the terminating null-character. If the parameter `textlen` is zero, which means that property
215/// is requested in binary form, the return value is the size of the data in bytes.
216///
217/// If the property is text, and `textlen` is zero, the function fails and returns 0. The function
218/// also fails and returns 0 if `textlen` is non-zero and the property requested can not be
219/// expressed as text. It also returns 0 if the property is not defined.
220///
221/// \sa TDocument::TDocProp
222//
223int
224TDocument::GetProperty(int index, void * dest, int textlen)
225{
226 LPCTSTR src;
227 tchar numBuf[15];
228 switch (index) {
229 case DocumentClass: {
231 src = _A2W(_OBJ_FULLTYPENAME(this));
232 }
233 break;
234
235 case TemplateName:
236 src = Template ? Template->GetDescription() : nullptr;
237 break;
238
239 case ViewCount: {
240 int cnt;
241 TView* view;
242 for (view=ViewList, cnt=0; view != nullptr; view=view->NextView, cnt++)
243 ; // Do nothing
244 if (!textlen) {
245 *(int *)dest = cnt;
246 return sizeof(int);
247 }
248 wsprintf(numBuf, _T("%d"), cnt);
249 src = numBuf;
250 break;
251 }
252
253 case StoragePath:
254 src = DocPath;
255 break;
256
257 case DocTitle:
258 src = Title;
259 break;
260
261 default:
262 TRACEX(OwlDocView, 0, _T("GetProperty(): invalid property [")
263 << index << _T("] specified!") );
264 return 0;
265 }
266
267 if (!textlen) {
268 TRACEX(OwlDocView, 0, _T("GetProperty(): 0-Length buffer specified!"));
269 return 0;
270 }
271 int srclen = src ? static_cast<int>(::_tcslen(src)) : 0;
272 if (textlen > srclen)
273 textlen = srclen;
274 if (textlen)
275 memcpy(dest, src, textlen*sizeof(tchar));
276 *(reinterpret_cast<LPTSTR>(dest) + textlen) = 0;
277 return srclen;
278}
279
280//
281/// Sets the value of the property, given index, the index value of the property,
282/// and src, the data type (either binary or text) to which the property must be
283/// set.
284//
285bool
287{
288 switch (prop) {
289 case DocTitle:
290 SetTitle(reinterpret_cast<LPCTSTR>(src));
291 break;
292
293 case StoragePath:
294 return SetDocPath(reinterpret_cast<LPCTSTR>(src));
295
296 default:
297 TRACEX(OwlDocView, 0, _T("SetProperty(): invalid prop [") << prop <<\
298 _T("] specified!"));
299 return false;
300 }
301 return true;
302}
303
304//
305/// Destroy children first if we have any. Then force close here as a last
306/// resort if derived classes have not done so. Since we have destructed down
307/// to a TDocument by now, derived closes will not be called.
308//
310{
311 ChildDoc.Destroy();
312 Close();
313}
314
315//
316/// Destroys the views attached to this document.
317//
319{
320 // NOTE: View's destructor invokes 'DetachView' which removes it from
321 // the list
322 //
323 while (ViewList)
324 delete ViewList;
325}
326
327//
328/// Returns the this pointer as the root document.
329//
332{
333 TDocument* pdoc = this;
334 while (pdoc->ParentDoc)
335 pdoc = pdoc->ParentDoc;
336 return *pdoc;
337}
338
339//
340/// Sets the current document manager to the argument dm.
341//
342void
344{
345 if (!ParentDoc) {
346 if (DocManager) // test needed for TDocManager::Streamer::Read()
347 DocManager->DocList.Remove(this);
348 dm.DocList.Insert(this);
349 }
350 DocManager = &dm;
351}
352
353//
354/// Sets the document path for Open and Save operations.
355//
356bool
358{
359 delete[] DocPath;
360 DocPath = (path && *path) ? strnewdup(path) : nullptr;
361
362 tchar title[_MAX_PATH] = _T("Unknown"); // Never used - but just in case!
363 if (!DocPath || GetFileTitle(DocPath, title, COUNTOF(title)) != 0) {
364 CHECK(DocManager);
365 CHECK(DocManager->GetApplication());
366
367 int len = DocManager->GetApplication()->LoadString(IDS_UNTITLED,
369 if (DocManager->IsFlagSet(dmMDI))
370 wsprintf(title+len, _T("%d"), ++(DocManager->GetUntitledIndex()));
371 }
373 return true; // derived classes may validate path
374}
375
376//
377/// Sets the title of the document.
378//
379void
381{
382 if (!Title || title!=Title)
383 { //This check allows calls like SetTitle(GetTitle()) (which is indirect way of calling ReindexFrames)
384 delete[] Title;
385 Title = title ? strnewdup(title) : nullptr;
386 }
387 ReindexFrames();
388}
389
390//
391/// Sets the document template. However, if the template type is incompatible with
392/// the file, the document manager will refuse to save the file as this template
393/// type.
394//
395bool
397{
398 if (Template) {
399 CHECK(DocManager);
400 DocManager->UnRefTemplate(*Template);
401 }
402 if (tpl) {
403 CHECK(DocManager);
404 DocManager->RefTemplate(*tpl);
405 }
406 Template = tpl;
407 return true;
408}
409
410//
411/// Force view title and index update.
412//
413void
414TDocument::ReindexFrames()
415{
416 TView* view;
417 int seq;
418
419 for (seq = -1, view = ViewList; view != nullptr; view = view->NextView) {
420 seq -= view->SetDocTitle(Title, seq); // decrement if title displayed
421 if (seq == -3) // need only check if more than one title displayed
422 break;
423 }
424 if (seq == -1)
425 return;
426 seq = (seq == -2 ? 0 : 1);
427 for (view = ViewList; view != nullptr; view = view->NextView)
428 {
429 //DLN: added this if condition to avoid PRECONDITIONs in debug build
430 // which occur if program closed by closing main window
431 if ( view->GetWindow() && view->GetWindow()->GetHandle() )
432 seq += view->SetDocTitle(Title, seq); // increment if title displayed
433 }
434}
435
436//
437/// Called from TStream's constructor, AttachStream attaches a stream to the current
438/// document.
439//
440void
442{
443 strm.NextStream = StreamList;
444 StreamList = &strm;
445}
446
447//
448/// Called from TStream's destructor, DetachStream detaches the stream from the
449/// current document.
450//
451void
453{
454 TStream** plist = &StreamList;
455 for ( ; *plist; plist = &(*plist)->NextStream) {
456 if (*plist == &strm) {
457 *plist = strm.NextStream;
458 return;
459 }
460 }
461}
462
463//
464/// Gets the next entry in the stream. Holds 0 if none exists.
465//
466TStream*
468{
469 return strm ? strm->NextStream : StreamList;
470}
471
472//
473/// Gets the next view in the list of views. Holds 0 if none exists.
474//
475TView*
477{
478 return view ? view->NextView : ViewList;
479}
480
481//
482/// Called from TView constructor.
483//
484void
485TDocument::AttachView(TView& view)
486{
487 TView** ppview;
488
489 for (ppview = &ViewList; *ppview; ppview = &(*ppview)->NextView)
490 ;
491 *ppview = &view; // insert at end of list
492 view.NextView = nullptr;
493 view.Doc = this;
494 NotifyViews(vnViewOpened, reinterpret_cast<TParam2>(&view), &view);
495}
496
497//
498/// Initializes the view. Notifies others a view is created by posting the dnCreate
499/// event.
500//
501TView*
503{
504 if (!view) {
505 TRACEX(OwlDocView, 0, _T("InitView(): 0 view specified!"));
506 return nullptr;
507 }
508 if (!view->IsOK()) {
509 TRACEX(OwlDocView, 0, _T("InitView(): Invalid view object specified!"));
510 delete view;
511 return nullptr;
512 }
513
514 CHECK(DocManager);
515 DocManager->PostEvent(dnCreate, *view); // WM_OWLVIEW
516
517 if (!view->IsOK()) {
518 TRACEX(OwlDocView, 0, _T("InitView(): Invalid view object post dnCreate!"));
519 delete view;
520 return nullptr;
521 }
522
523 ReindexFrames();
525
526 return view;
527}
528
529//
530/// DetachView is invoked from TView's destructor so that the view can detach
531/// itself from this document. True is returned if the detachment is successful
532/// indicating that this document should be deleted.
533//
534bool
535TDocument::DetachView(TView& view)
536{
537 TView** plist = &ViewList;
538 for (; *plist; plist = &(*plist)->NextView) {
539 if (*plist == &view) {
540
541 // Found the view, now detach it and notify app and other views
542 //
543 DocManager->PostEvent(dnClose, view); // WM_OWLVIEW
544 *plist = view.NextView;
545 NotifyViews(vnViewClosed, reinterpret_cast<TParam2>(&view), &view);
546
547 // Cleanup doc if last view was just closed and dtAutoDelete
548 // or dtAutoOpen is set. dtAutoOpen will cause an autoclose, while
549 // dtAutoDelete will delete this doc also.
550 //
551 if (!ViewList) {
552 if (Template && ((Template->Flags & dtAutoDelete) ||
553 (Template->Flags & dtAutoOpen))) {
554 // Close document streams
555 //
556 if (IsOpen())
557 Close();
558
559 // Returning true will cause ~TView to delete document. Using
560 // 'view.IsOK()' caters for cases where TView's construction failed.
561 //
562 return (Template->Flags & dtAutoDelete) && view.IsOK();
563 }
564 }
565 else {
566 ReindexFrames();
567 }
568 break;
569 }
570 }
571 return false;
572}
573
574//
575/// Saves the current data to storage. When a file is closed, the document manager
576/// calls either Commit or Revert. If force is true, all data is written to storage.
577/// Commit checks any child documents and commits their changes to storage also.
578/// Before the current data is saved, all child documents must return true. If all
579/// child documents return true, Commit flushes the views for operations that
580/// occurred since the last time the view was checked. After all data for the
581/// document is updated and saved, Commit returns true.
582//
583bool
585{
586 TDocument* pdoc = 0;
587 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr) {
588 if (!pdoc->Commit(force))
589 return false;
590 }
591
592 WARNX(OwlDocView, !DocPath, 0, _T("Commit(): 0 DocPath!"));
593 return NotifyViews(vnCommit, force);
594}
595
596//
597/// Performs the reverse of Commit() and cancels any changes made to the document
598/// since the last commit. If clear is true, data is not reloaded for views. Revert
599/// also checks all child documents and cancels any changes if all children return
600/// true. When a file is closed, the document manager calls either Commit() or Revert.
601/// Returns true if the operation is successful.
602//
603bool
605{
606 TDocument* pdoc = 0;
607 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr) {
608 if (!pdoc->Revert(clear))
609 return false;
610 }
611 return NotifyViews(vnRevert, clear);
612}
613
614//
615/// Notifies the views of this document, and the views of any child documents, of a change.
616///
617/// The notification message, WM_OWLNOTIFY, is sent with the given eventId, which is
618/// private to the particular document class, and a single generic argument, which will be
619/// cast to the actual type of the parameter of the response function. If the optional
620/// parameter `exclude` is set, the appointed view will not be notified.
621///
622/// In contrast to QueryViews, NotifyViews sends the notification message to all views,
623/// regardless of the return values. NotifyViews returns `true`, if and only if all views
624/// return `true`. If a view does not handle the notification, then a `true` return value is
625/// assumed. In other words, NotifyViews will return `false` only if a view handles the
626/// notification and explicitly returns `false`. In any case, all views are notified.
627//
628bool
630{
631 bool answer = true;
632
633 for (auto d = ChildDoc.Next(nullptr); d; d = ChildDoc.Next(d))
634 {
635 bool r = d->NotifyViews(eventId, param, exclude);
636 answer = answer && r;
637 }
638
640 for (TView* view = ViewList; view != nullptr; view = view->NextView)
641 {
642 if (view == exclude) continue;
643
644 if (view->Find(eventInfo))
645 {
646 bool r = view->Dispatch(eventInfo, 0, param) != 0;
647 answer = answer && r;
648 }
649 }
650 return answer;
651}
652
653//
654/// Notifies the views of this document of a change. Does not notify views of child documents.
655///
656/// The notification message, WM_OWLNOTIFY, is sent with the given eventId, which is
657/// private to the particular document class, and a single generic argument, which will be
658/// cast to the actual type of the parameter of the response function. If the optional
659/// parameter `exclude` is set, the appointed view will not be notified.
660///
661/// In contrast to QueryViews, NotifyOwnViews sends the notification message to all views,
662/// regardless of the return values. NotifyOwnViews returns `true`, if and only if all views
663/// return `true`. If a view does not handle the notification, then a `true` return value is
664/// assumed. In other words, NotifyOwnViews will return `false` only if a view handles the
665/// notification and explicitly returns `false`. In any case, all views are notified.
666//
667bool
669{
670 bool answer = true;
671
673 for (TView* view = ViewList; view != nullptr; view = view->NextView)
674 {
675 if (view == exclude) continue;
676
677 if (view->Find(eventInfo))
678 {
679 bool r = view->Dispatch(eventInfo, 0, param) != 0;
680 answer = answer && r;
681 }
682 }
683 return answer;
684}
685
686//
687/// Queries the views of the current document, and the views of any child documents,
688/// about a specified event.
689///
690/// The notification message, WM_OWLNOTIFY, is sent with the given eventId, which is
691/// private to the particular document class, and a single generic argument, which will be
692/// cast to the actual type of the parameter of the response function. If the optional
693/// parameter `exclude` is set, the appointed view will not be queried.
694///
695/// In contrast to NotifyViews, the query stops at the first view that returns `true`, and
696/// the pointer to the view is returned. If no view returns `true`, `nullptr` is returned.
697//
698TView*
700{
701 TView* view;
702 TDocument* pdoc = 0;
703 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr)
704 if ((view = pdoc->QueryViews(eventId, param, exclude)) != nullptr)
705 return view;
706
708 for (view = ViewList; view != nullptr; view = view->NextView)
709 {
710 if (view == exclude) continue;
711
712 if (view->Find(eventInfo))
713 if (view->Dispatch(eventInfo, 0, param))
714 return view; // Return first acknowledger
715 }
716 return nullptr;
717}
718
719//
720/// Returns true if the document or one of its views has changed but has not been
721/// saved.
722//
723bool
725{
726 if (DirtyFlag)
727 return true;
728
729 TDocument* pdoc = 0;
730 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr)
731 if (pdoc->IsDirty())
732 return true;
733
734 return QueryViews(vnIsDirty) != nullptr;
735}
736
737//
738/// Used by the document manager, HasFocus returns true if this document's view has
739/// focus. hwnd is a handle to the document. to determine if the document contains a
740/// view with a focus.
741//
742bool
744{
745 return DocWithFocus(hWnd) != nullptr;
746}
747
748//
749/// Return pointer to this document or one of its child documents if the spcecified
750/// window parameter is a view associated with the document.
751/// \note Unlike 'HasFocus', this method allows you to distinguish whether the
752/// document with focus is a child document.
753//
756{
757 TDocument* pdoc = 0;
758 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr)
759 if (pdoc->DocWithFocus(hWnd))
760 return pdoc;
761
762 return QueryViews(vnIsWindow, reinterpret_cast<TParam2>(hWnd)) ? this : nullptr;
763}
764
765//
766/// Checks to see if all child documents can be closed before closing the current
767/// document. If any child returns false, CanClose returns false and aborts the
768/// process. If all children return true, calls TDocManager::FlushDoc. If FlushDoc
769/// finds that the document has been changed but not saved, it displays a message
770/// asking the user to either save the document, discard any changes, or cancel the
771/// operation. If the document has not been changed and all children's CanClose
772/// functions return true, this CanClose function returns true.
773//
774bool
776{
777 TDocument* pdoc = 0;
778 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr)
779 if (!pdoc->CanClose())
780 return false;
781
782 return DocManager->FlushDoc(*this); // do the UI in the doc manager
783}
784
785//
786/// Closes the document but does not delete or detach the document. Before closing
787/// the document, Close checks any child documents and tries to close them before
788/// closing the parent document. Even if you write your own Close function, call
789/// TDocument's version to ensure that all child documents are checked before the
790/// parent document is closed.
791//
792bool
794{
795 TDocument* pdoc = 0;
796 while ((pdoc = ChildDoc.Next(pdoc)) != nullptr)
797 if (!pdoc->Close())
798 return false;
799
800 return true;
801}
802
803//
804/// Posts the error message passed as a string resource ID in sid. choice is one or
805/// more of the MB_Xxxx style constants.
806//
807uint
809{
810 return DocManager->PostDocError(*this, sid, choice);
811}
812
813//----------------------------------------------------------------------------
814
815//
816//
817//
820{
821 return doc ? doc->NextDoc : DocList;
822}
823
824//
825//
826//
827bool
829{
831 for (pdoc = DocList; pdoc; pdoc = pdoc->NextDoc)
832 if (pdoc == doc)
833 return false;
834 doc->NextDoc = DocList;
835 DocList = doc;
836 return true;
837}
838
839//
840//
841//
842bool
844{
846 for (ppdoc = &DocList; *ppdoc; ppdoc = &(*ppdoc)->NextDoc) {
847 if (*ppdoc == doc) {
848 *ppdoc = doc->NextDoc;
849 return true;
850 }
851 }
852 return false;
853}
854
855//
856//
857//
859{
860 for (TDocument* pDoc = DocList; pDoc; pDoc = pDoc->NextDoc)
861 if (pDoc == doc)
862 return true;
863 return false;
864}
865
866//
867//
868//
869void
871{
872 while (DocList)
873 delete DocList; // removes it entry from destructor
874}
875
876
878
879#if OWL_PERSISTENT_STREAMS
880
881//
882//
883//
884void*
885TDocument::Streamer::Read(ipstream& is, uint32 /*version*/) const
886{
887 TDocument* o = GetObject();
888
889 o->NextDoc = 0;
890 o->StreamList = 0;
891 o->DocManager = 0;
892 o->DirtyFlag = false;
893
894 is >> o->OpenMode;
895#if defined(UNICODE)
897 char * docPath = is.freadString();
898 char * title = is.freadString();
899
900 o->DocPath = _A2W(docPath);
901 o->Title = _A2W(title);
902
903 delete[] docPath;
904 delete[] title;
905#else
906 o->DocPath = is.freadString();
907 o->Title = is.freadString();
908#endif
909 is >> o->Template; // static templates must have been already streamed
910 is >> o->ParentDoc;
911 o->ViewList = 0; // must init, does not get set until after view streamed
912 is >> o->ViewList;
913
914 is >> TView::NextViewId; // static, but must get set by at least 1 document
915
916 return o;
917}
918
919//
920//
921//
922void
923TDocument::Streamer::Write(opstream& os) const
924{
925 TDocument* o = GetObject();
926
927 while (!o->CanClose()) // can't permit cancel here
928 ;
929 os << o->OpenMode;
931 os.fwriteString(_W2A(o->DocPath));
932 os.fwriteString(_W2A(o->Title));
933 os << o->Template; // templates already streamed, must be so if static
934 os << o->ParentDoc;
935 os << o->ViewList; // each view streams out the next
936 os << TView::NextViewId; // insure that this static var gets set on reload
937}
938
939#endif
940
941} // OWL namespace
942
Definition of class TAppDictionary.
#define CHECK(condition)
Definition checks.h:239
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define WARN(condition, message)
Definition checks.h:273
#define PRECONDITION(condition)
Definition checks.h:227
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
TApplication * GetApplication(uint pid=0)
Looks up and returns the application associated with a given process ID.
Definition appdict.cpp:192
Derived from TModule and TMsgThread and virtually derived from TEventHandler, TApplication acts as an...
Definition applicat.h:141
TDocManager creates a document manager object that manages the list of current documents and register...
Definition docmanag.h:100
virtual void PostEvent(int id, TDocument &doc)
changed doc status
virtual uint PostDocError(TDocument &doc, uint sid, uint choice=MB_OK)
Displays a message box with the error message passed as a string resource ID in sid.
virtual bool FlushDoc(TDocument &doc)
Method invoked when specified document is about to be closed.
Definition docmanag.cpp:914
bool IsFlagSet(int flag) const
Returns true if the specified flag is currently enabled by the DocManager or false otherwise.
Definition docmanag.h:399
TApplication * GetApplication() const
Returns the TApplication* object associated with this DocManager.
Definition docmanag.h:390
void UnRefTemplate(TDocTemplate &)
drop template ref
Definition docmanag.h:381
int & GetUntitledIndex()
Returns the index to be used by an untitled document.
Definition docmanag.h:427
void RefTemplate(TDocTemplate &)
add template ref
Definition docmanag.h:372
TDocTemplate is an abstract base class that contains document template functionality.
Definition doctpl.h:54
LPCTSTR GetDescription() const
Gets the template description to put in the file-selection list box or the File|New menu-selection li...
Definition doctpl.cpp:126
bool Contains(TDocument *doc)
Checks if doc is contained in the list.
Definition document.cpp:858
bool Remove(TDocument *doc)
Removes a document from the document list, fails if not there.
Definition document.cpp:843
void Destroy()
Deletes all documents.
Definition document.cpp:870
TDocument * Next(const TDocument *doc)
If the doc parameter is 0, Next returns the first document in the list of documents.
Definition document.cpp:819
bool Insert(TDocument *doc)
Inserts a new document into the document list. Fails if the document already exists.
Definition document.cpp:828
An abstract base class, TDocument is the base class for all document objects and serves as an interfa...
Definition docview.h:187
TDocument(TDocument *parent=nullptr)
Although you do not create a TDocument object directly, you must call the constructor when you create...
Definition document.cpp:34
TStream * NextStream(const TStream *strm)
Gets the next entry in the stream. Holds 0 if none exists.
Definition document.cpp:467
void DestroyViews()
Destroys the views attached to this document.
Definition document.cpp:318
virtual int GetProperty(int index, void *dest, int textlen=0)
Retrieves the property identified by the given index.
Definition document.cpp:224
virtual int FindProperty(LPCTSTR name)
return property index
Definition document.cpp:186
TView * NextView(const TView *view)
Gets the next view in the list of views. Holds 0 if none exists.
Definition document.cpp:476
void SetDocManager(TDocManager &dm)
Sets the current document manager to the argument dm.
Definition document.cpp:343
virtual void DetachStream(TStream &strm)
called from TStream destructor
Definition document.cpp:452
bool NotifyOwnViews(int eventId, TParam2=0, TView *exclude=nullptr)
Notifies the views of this document of a change.
Definition document.cpp:668
virtual TDocument & RootDocument()
Returns the this pointer as the root document.
Definition document.cpp:331
bool NotifyViews(int eventId, TParam2=0, TView *exclude=nullptr)
Notifies the views of this document, and the views of any child documents, of a change.
Definition document.cpp:629
virtual bool SetProperty(int index, const void *src)
native type
Definition document.cpp:286
virtual bool HasFocus(HWND hwnd)
Document (or child doc) has Focus.
Definition document.cpp:743
virtual bool CanClose()
Returns false if unable to close.
Definition document.cpp:775
bool SetTemplate(TDocTemplate *tpl)
Sets the document template.
Definition document.cpp:396
virtual LPCTSTR PropertyName(int index)
locale invariant name
Definition document.cpp:147
virtual bool Close()
close document, does not delete or detach
Definition document.cpp:793
virtual int PropertyFlags(int index)
pfXxxxx bit array
Definition document.cpp:166
void DestroyChildren()
Destroy children first if we have any.
Definition document.cpp:309
TView * InitView(TView *view)
called from template InitView
Definition document.cpp:502
virtual ~TDocument()
Deletes a TDocument object.
Definition document.cpp:80
virtual void AttachStream(TStream &strm)
called from TStream constructor
Definition document.cpp:441
TView * QueryViews(int eventId, TParam2=0, TView *exclude=nullptr)
Queries the views of the current document, and the views of any child documents, about a specified ev...
Definition document.cpp:699
virtual void SetTitle(LPCTSTR title)
Sets the title of the document.
Definition document.cpp:380
virtual TDocument * DocWithFocus(HWND hwnd)
Return pointer to this document or one of its child documents if the spcecified window parameter is a...
Definition document.cpp:755
virtual bool SetDocPath(LPCTSTR path)
Sets the document path for Open and Save operations.
Definition document.cpp:357
virtual bool IsDirty()
Also queries doc and view hierarchy.
Definition document.cpp:724
@ TemplateName
text property: Name of template attached to document
Definition docview.h:199
@ PrevProperty
Index of last property in base class (none in this case)
Definition docview.h:197
@ StoragePath
text property: Identifies object holding data of this document
Definition docview.h:201
@ NextProperty
Next index to be used by derived class.
Definition docview.h:203
@ ViewCount
int property: Number of views displaying this document
Definition docview.h:200
@ DocumentClass
text Property: Name of C++ class encapsulating document
Definition docview.h:198
@ DocTitle
text property: Caption of this document
Definition docview.h:202
virtual bool IsOpen()
Checks to see if the document has any streams in its stream list.
Definition docview.h:896
virtual bool Commit(bool force=false)
save current data, force write
Definition document.cpp:584
virtual uint PostError(uint sid, uint choice=MB_OK)
Posts the error message passed as a string resource ID in sid.
Definition document.cpp:808
virtual bool Revert(bool clear=false)
abort changes, no reload if true
Definition document.cpp:604
A nested class, TEventInfo provides specific information about the type of message sent,...
Definition eventhan.h:170
An abstract base class, TStream provides links between streams and documents, views,...
Definition docview.h:568
TStream * NextStream
Points to the next stream in the list of active streams.
Definition docview.h:577
Abstract base class for view access from document.
Definition docview.h:397
static void BumpNextViewId()
Increments an internal count used by the Doc/View subsystem to identify each view.
Definition view.cpp:247
ipstream, a specialized input stream derivative of pstream, is the base class for reading (extracting...
Definition objstrm.h:391
#define _tcscmp
Definition cygwin.h:75
#define _MAX_PATH
Definition cygwin.h:97
#define _tcslen
Definition cygwin.h:74
#define _T(x)
Definition cygwin.h:51
#define WM_OWLNOTIFY
Definition dispatch.h:4107
Definition of class TDocManager.
#define IMPLEMENT_ABSTRACT_STREAMABLE(cls)
Definition objstrm.h:1718
#define _OBJ_FULLTYPENAME(obj)
Definition objstrm.h:78
const uint dtAutoDelete
delete doc when last view is deleted
Definition doctpl.h:219
const uint pfGetText
property accessible as text format
Definition docview.h:122
const uint vnViewOpened
a new view has just been constructed
Definition docview.h:105
const uint vnViewClosed
another view is about to be destructed
Definition docview.h:106
const uint pfConstant
property is invariant for object instance
Definition docview.h:124
const uint vnCommit
document is committing, flush cached changes
Definition docview.h:109
const uint dtAutoOpen
open document upon creation
Definition doctpl.h:222
const uint pfSettable
property settable as native format
Definition docview.h:125
const uint vnRevert
document has reverted, reload data from doc
Definition docview.h:110
const uint vnIsWindow
respond true if passed HWND is that of view
Definition docview.h:112
const uint vnIsDirty
respond true if uncommitted changes present
Definition docview.h:111
const uint pfGetBinary
property accessible as native non-text format
Definition docview.h:123
const uint dmMDI
Supports multiple open documents.
Definition docmanag.h:33
@ dnCreate
New document or view has been created.
Definition docmanag.h:52
@ dnClose
Document or view has been closed.
Definition docmanag.h:53
static void Raise(const tstring &msg, uint resId=0)
Definition except.cpp:186
int LoadString(uint id, TCHAR *buf, int maxChars) const
Loads a string resource identified by id into the buffer pointed to by buff.
Definition module.cpp:586
#define _W2A(lpw)
Definition memory.h:219
char * strnewdup(const char *s, size_t minAllocSize=0)
Definition memory.cpp:25
#define _A2W(lpw)
Definition memory.h:220
#define _USES_CONVERSION
Definition memory.h:217
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
unsigned long uint32
Definition number.h:34
char tchar
Definition defs.h:77
LPARAM TParam2
Second parameter type.
Definition dispatch.h:55
TAppDictionary & OWLGetAppDictionary()
Global exported TAppDictionary in Owl.
Definition appdict.cpp:35
OWL_DIAGINFO
Definition animctrl.cpp:14
unsigned int uint
Definition number.h:25
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition defs.h:376
Definition of class TString, a flexible universal string envelope class.