Index: census_document.cpp
===================================================================
RCS file: /sources/lmi/lmi/census_document.cpp,v
retrieving revision 1.19
diff -U 3 -r1.19 census_document.cpp
--- census_document.cpp	27 Dec 2008 02:56:37 -0000	1.19
+++ census_document.cpp	15 Mar 2009 15:52:09 -0000
@@ -39,13 +39,50 @@
 
 IMPLEMENT_DYNAMIC_CLASS(CensusDocument, wxDocument)
 
-CensusDocument::CensusDocument()
-    :wxDocument()
+CensusDocument::CensusDocument(wxDocument* parent)
+    :wxDocument(parent)
 {
+#if 0 // An lmi CensusDocument never actually has a parent.
+    if(m_documentParent)
+        m_documentParent->m_documentChildren->Insert(this);
+#endif // 0
 }
 
 CensusDocument::~CensusDocument()
 {
+#if 0
+// DEFECT: Enabling this block causes crashes.
+// Could it be that OnCloseDocument() already did some of this work?
+    m_documentChildren.DeleteContents(true);
+    m_documentChildren.Clear();
+#endif // 0
+
+#if 0 // An lmi CensusDocument never actually has a parent.
+    if(m_documentParent) {
+        m_documentParent->m_documentChildren.DeleteObject(this);
+        }
+#endif // 0
+}
+
+bool CensusDocument::OnCloseDocument()
+{
+warning() << "CensusDocument::OnCloseDocument()" << LMI_FLUSH;
+    const wxList::iterator end = m_documentChildren.end();
+    for ( wxList::iterator i = m_documentChildren.begin(); i != end; ++i )
+    {
+        wxDocument *doc = (wxDocument *)*i;
+warning() << "Handling child " << doc << LMI_FLUSH;
+        if ( !doc->DeleteAllViews() )
+            return false;
+        // Isn't this done implicitly by DeleteAllViews()?
+#if 0
+        if ( !doc->Close() )
+            return false;
+#endif // 0
+    }
+
+warning() << "CensusDocument::OnCloseDocument() returning normally." << LMI_FLUSH;
+    return wxDocument::OnCloseDocument();
 }
 
 wxListView& CensusDocument::PredominantViewWindow() const
Index: census_document.hpp
===================================================================
RCS file: /sources/lmi/lmi/census_document.hpp,v
retrieving revision 1.14
diff -U 3 -r1.14 census_document.hpp
--- census_document.hpp	27 Dec 2008 02:56:37 -0000	1.14
+++ census_document.hpp	15 Mar 2009 15:52:09 -0000
@@ -33,6 +33,8 @@
 
 #include <wx/docview.h>
 
+#include <cstddef> // NULL
+
 class WXDLLIMPEXP_FWD_CORE wxListView;
 
 class CensusDocument
@@ -42,13 +44,27 @@
     friend class CensusView;
 
   public:
-    CensusDocument();
+    CensusDocument(wxDocument* parent = NULL);
     virtual ~CensusDocument();
 
+#if 0 // Not actually needed by lmi: a CensusDocument never needs a parent.
+    wxDocument* GetParent() const {
+        return m_documentParent;
+        }
+#endif // 0
+
+    // Kludge: make these public, only so that other
+    // wxDocument-derived classes can use them.
+    using wxDocument::m_documentParent;
+    // Private member to add to class wxDocument
+    wxList m_documentChildren;
+    // Isn't that a template? e.g., wxList<wxDocument> m_documentChildren;
+
   private:
     wxListView& PredominantViewWindow() const;
 
     // wxDocument overrides.
+    virtual bool OnCloseDocument();
     virtual bool OnCreate(wxString const& filename, long int flags);
     virtual bool OnNewDocument();
     virtual bool DoOpenDocument(wxString const& filename);
Index: census_view.cpp
===================================================================
RCS file: /sources/lmi/lmi/census_view.cpp,v
retrieving revision 1.87
diff -U 3 -r1.87 census_view.cpp
--- census_view.cpp	27 Dec 2008 02:56:38 -0000	1.87
+++ census_view.cpp	15 Mar 2009 15:52:09 -0000
@@ -867,6 +867,7 @@
     IllustrationView& illview = MakeNewIllustrationDocAndView
         (document().GetDocumentManager()
         ,serial_file_path(base_filename(), name, index, "ill").string().c_str()
+        ,&document()
         );
     illview.Run(&cell_parms()[index]);
 }
@@ -888,6 +889,7 @@
         IllustrationView& illview = MakeNewIllustrationDocAndView
             (document().GetDocumentManager()
             ,serial_file_path(base_filename(), name, -1, "ill").string().c_str()
+            ,&document()
             );
 
         // This is necessary for the view to be able to print.
Index: illustration_document.cpp
===================================================================
RCS file: /sources/lmi/lmi/illustration_document.cpp,v
retrieving revision 1.24
diff -U 3 -r1.24 illustration_document.cpp
--- illustration_document.cpp	13 Mar 2009 16:21:30 -0000	1.24
+++ illustration_document.cpp	15 Mar 2009 15:52:10 -0000
@@ -38,13 +38,48 @@
 
 IMPLEMENT_DYNAMIC_CLASS(IllustrationDocument, wxDocument)
 
-IllustrationDocument::IllustrationDocument()
-    :is_phony_(false)
-{
+// Include only for proposed new wxDocument members. If they were in
+// the wx class already, then this wouldn't be needed.
+#include "census_document.hpp"
+
+IllustrationDocument::IllustrationDocument(wxDocument* parent)
+    :wxDocument(parent)
+    ,is_phony_ (false)
+{
+    if(m_documentParent)
+        // Cast only because wxDocument lacks m_documentChildren.
+        ((CensusDocument*)m_documentParent)->m_documentChildren.Insert(this);
 }
 
 IllustrationDocument::~IllustrationDocument()
 {
+    m_documentChildren.DeleteContents(true);
+    m_documentChildren.Clear();
+
+#if 0
+// DEFECT: Enabling this block causes crashes.
+// Probably I have misunderstood DeleteObject().
+    if(m_documentParent) {
+        // Cast only because wxDocument lacks m_documentChildren.
+warning() << "~IllustrationDocument(): parent had " << ((CensusDocument*)m_documentParent)->m_documentChildren.GetCount() << " children." << LMI_FLUSH;
+        ((CensusDocument*)m_documentParent)->m_documentChildren.DeleteObject(this);
+warning() << "~IllustrationDocument(): parent now has " << ((CensusDocument*)m_documentParent)->m_documentChildren.GetCount() << " children." << LMI_FLUSH;
+        }
+#endif // 0
+}
+
+// Not actually needed for lmi: an IllustrationDocument never has any children.
+bool IllustrationDocument::OnCloseDocument()
+{
+    const wxList::iterator end = m_documentChildren.end();
+    for ( wxList::iterator i = m_documentChildren.begin(); i != end; ++i )
+    {
+        wxDocument *doc = (wxDocument *)*i;
+        if ( !doc->Close() )
+            return false;
+    }
+
+    return wxDocument::OnCloseDocument();
 }
 
 IllustrationView& IllustrationDocument::PredominantView() const
Index: illustration_document.hpp
===================================================================
RCS file: /sources/lmi/lmi/illustration_document.hpp,v
retrieving revision 1.16
diff -U 3 -r1.16 illustration_document.hpp
--- illustration_document.hpp	13 Mar 2009 16:21:36 -0000	1.16
+++ illustration_document.hpp	15 Mar 2009 15:52:10 -0000
@@ -33,6 +33,8 @@
 
 #include <wx/docview.h>
 
+#include <cstddef> // NULL
+
 /// WX !! The wx document-view implementation has no notion of 'child'
 /// documents, but sometimes lmi creates a document that logically is
 /// a 'child' of a parent CensusDocument: it corresponds to no actual,
@@ -56,15 +58,27 @@
     friend class IllustrationView;
 
   public:
-    IllustrationDocument();
+    IllustrationDocument(wxDocument* parent = NULL);
     virtual ~IllustrationDocument();
 
+    wxDocument* GetParent() const {
+        return m_documentParent;
+        }
+
     IllustrationView& PredominantView() const;
 
+    // Kludge: make these public, only so that other
+    // wxDocument-derived classes can use them.
+    using wxDocument::m_documentParent;
+    // Private member to add to class wxDocument
+    wxList m_documentChildren;
+    // Isn't that a template? e.g., wxList<wxDocument> m_documentChildren;
+
   private:
     wxHtmlWindow& PredominantViewWindow() const;
 
     // wxDocument overrides.
+    virtual bool OnCloseDocument();
     virtual bool OnCreate(wxString const& filename, long int flags);
 #if !wxCHECK_VERSION(2,9,0)
     virtual bool OnNewDocument();
Index: illustration_view.cpp
===================================================================
RCS file: /sources/lmi/lmi/illustration_view.cpp,v
retrieving revision 1.105
diff -U 3 -r1.105 illustration_view.cpp
--- illustration_view.cpp	14 Mar 2009 13:41:37 -0000	1.105
+++ illustration_view.cpp	15 Mar 2009 15:52:10 -0000
@@ -125,6 +125,7 @@
 
 int IllustrationView::EditProperties()
 {
+HOPEFULLY(is_phony_ == (NULL != document().GetParent()));
     if(is_phony_)
         {
 warning() << "That command should have been disabled." << LMI_FLUSH;
@@ -245,6 +246,7 @@
 void IllustrationView::UponProperties(wxCommandEvent&)
 {
 // may have to check is_phony_ here--but that's bogus
+HOPEFULLY(is_phony_ == (NULL != document().GetParent()));
     if(is_phony_)
         {
 //        return;
@@ -261,6 +263,7 @@
 
 void IllustrationView::UponUpdateFileSave(wxUpdateUIEvent& e)
 {
+HOPEFULLY(is_phony_ == (NULL != document().GetParent()));
     e.Enable(!is_phony_ && document().IsModified());
 }
 
@@ -269,6 +272,7 @@
 
 void IllustrationView::UponUpdateFileSaveAs(wxUpdateUIEvent& e)
 {
+HOPEFULLY(is_phony_ == (NULL != document().GetParent()));
     e.Enable(!is_phony_);
 }
 
@@ -279,6 +283,7 @@
 
 void IllustrationView::UponUpdateProperties(wxUpdateUIEvent& e)
 {
+HOPEFULLY(is_phony_ == (NULL != document().GetParent()));
     e.Enable(!is_phony_);
 }
 
@@ -323,9 +328,13 @@
 /// This could be generalized as a function template if that ever
 /// becomes useful.
 
+// Include only because wxDocument lacks m_documentChildren.
+#include "census_document.hpp"
+
 IllustrationView& MakeNewIllustrationDocAndView
     (wxDocManager* dm
     ,char const*   filename
+    ,wxDocument*   parent
     )
 {
     LMI_ASSERT(0 != dm);
@@ -342,6 +351,26 @@
     IllustrationDocument& illdoc =
         safely_dereference_as<IllustrationDocument>(new_document)
         ;
+
+    // Really want wx doc-view to handle this, passing parent to
+    // wxDocument ctor. That would remove the need for the
+    // LMI_WX_CHILD_DOCUMENT kludge.
+    //   true  == LMI_WX_CHILD_DOCUMENT --> NULL != parent_document
+    //   false == LMI_WX_CHILD_DOCUMENT --> NULL == parent_document
+    // i.e.,
+    //   you're     a child if you       have a parent
+    //   you're not a child if you don't have a parent
+    // The is_phony_ kludge could also be removed.
+    //   true  == is_phony_ --> this view has no savable IllustrationDocument
+    //   false == is_phony_ --> this view has a  savable IllustrationDocument
+    // Creating a document with LMI_WX_CHILD_DOCUMENT style causes it
+    // to have the is_phony_ nature:
+    //    LMI_WX_CHILD_DOCUMENT -->  is_phony_
+    //   !LMI_WX_CHILD_DOCUMENT --> !is_phony_
+    //
+    illdoc.m_documentParent = parent;
+    ((CensusDocument*)illdoc.m_documentParent)->m_documentChildren.Insert(new_document);
+
     illdoc.SetFilename(filename, true);
     illdoc.Modify(false);
     illdoc.SetDocumentSaved(true);
@@ -378,9 +407,16 @@
             else
                 {
                 LMI_ASSERT(0 != dm);
+                // Use 0 as document parent for now. The legacy application
+                // created a dummy document and used that as the parent.
+                // Reason: this view doesn't have a real IllustrationDocument
+                // that could possibly be saved; and the legacy code used
+                // (NULL != parent) as its criterion for disabling the save
+                // command.
                 IllustrationView& illview = MakeNewIllustrationDocAndView
                     (dm
                     ,(c.custom_output_filename() + ".ill").c_str()
+                    ,0
                     );
                 illview.SetLedger(z.principal_ledger());
                 illview.DisplaySelectedValuesAsHtml();
Index: illustration_view.hpp
===================================================================
RCS file: /sources/lmi/lmi/illustration_view.hpp,v
retrieving revision 1.38
diff -U 3 -r1.38 illustration_view.hpp
--- illustration_view.hpp	27 Dec 2008 02:56:45 -0000	1.38
+++ illustration_view.hpp	15 Mar 2009 15:52:10 -0000
@@ -106,6 +106,7 @@
 IllustrationView& MakeNewIllustrationDocAndView
     (wxDocManager* dm
     ,char const*   filename
+    ,wxDocument*   parent
     );
 
 bool custom_io_0_run_if_file_exists(wxDocManager*);
