OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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.