1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Document/view classes 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "docview.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  31 #if wxUSE_DOC_VIEW_ARCHITECTURE 
  34     #include "wx/string.h" 
  38     #include "wx/dialog.h" 
  41     #include "wx/filedlg.h" 
  49 #if wxUSE_PRINTING_ARCHITECTURE 
  50   #include "wx/prntbase.h" 
  51   #include "wx/printdlg.h" 
  54 #include "wx/msgdlg.h" 
  55 #include "wx/choicdlg.h" 
  56 #include "wx/docview.h" 
  57 #include "wx/confbase.h" 
  62 #if wxUSE_STD_IOSTREAM 
  63   #include "wx/ioswrap.h" 
  70   #include "wx/wfstream.h" 
  73 // ---------------------------------------------------------------------------- 
  75 // ---------------------------------------------------------------------------- 
  77 #if !USE_SHARED_LIBRARY 
  78     IMPLEMENT_ABSTRACT_CLASS(wxDocument
, wxEvtHandler
) 
  79     IMPLEMENT_ABSTRACT_CLASS(wxView
, wxEvtHandler
) 
  80     IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate
, wxObject
) 
  81     IMPLEMENT_DYNAMIC_CLASS(wxDocManager
, wxEvtHandler
) 
  82     IMPLEMENT_CLASS(wxDocChildFrame
, wxFrame
) 
  83     IMPLEMENT_CLASS(wxDocParentFrame
, wxFrame
) 
  85     #if wxUSE_PRINTING_ARCHITECTURE 
  86         IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout
, wxPrintout
) 
  89     IMPLEMENT_CLASS(wxCommand
, wxObject
) 
  90     IMPLEMENT_DYNAMIC_CLASS(wxCommandProcessor
, wxObject
) 
  91     IMPLEMENT_DYNAMIC_CLASS(wxFileHistory
, wxObject
) 
  94 // ---------------------------------------------------------------------------- 
  95 // function prototypes 
  96 // ---------------------------------------------------------------------------- 
  98 static inline wxString 
FindExtension(const wxChar 
*path
); 
 100 // ============================================================================ 
 102 // ============================================================================ 
 104 // ---------------------------------------------------------------------------- 
 106 // ---------------------------------------------------------------------------- 
 108 static wxString 
FindExtension(const wxChar 
*path
) 
 111     wxSplitPath(path
, NULL
, NULL
, &ext
); 
 113     // VZ: extensions are considered not case sensitive - is this really a good 
 115     return ext
.MakeLower(); 
 118 // ---------------------------------------------------------------------------- 
 119 // Definition of wxDocument 
 120 // ---------------------------------------------------------------------------- 
 122 wxDocument::wxDocument(wxDocument 
*parent
) 
 124     m_documentModified 
= FALSE
; 
 125     m_documentParent 
= parent
; 
 126     m_documentTemplate 
= (wxDocTemplate 
*) NULL
; 
 130 bool wxDocument::DeleteContents() 
 135 wxDocument::~wxDocument() 
 139     if (m_commandProcessor
) 
 140         delete m_commandProcessor
; 
 142     GetDocumentManager()->RemoveDocument(this); 
 144     // Not safe to do here, since it'll invoke virtual view functions 
 145     // expecting to see valid derived objects: and by the time we get here, 
 146     // we've called destructors higher up. 
 150 bool wxDocument::Close() 
 152     if (OnSaveModified()) 
 153         return OnCloseDocument(); 
 158 bool wxDocument::OnCloseDocument() 
 165 // Note that this implicitly deletes the document when the last view is 
 167 bool wxDocument::DeleteAllViews() 
 169     wxNode 
*node 
= m_documentViews
.First(); 
 172         wxView 
*view 
= (wxView 
*)node
->Data(); 
 176         wxNode 
*next 
= node
->Next(); 
 178         delete view
; // Deletes node implicitly 
 184 wxView 
*wxDocument::GetFirstView() const 
 186     if (m_documentViews
.Number() == 0) 
 187         return (wxView 
*) NULL
; 
 188     return (wxView 
*)m_documentViews
.First()->Data(); 
 191 wxDocManager 
*wxDocument::GetDocumentManager() const 
 193     return m_documentTemplate
->GetDocumentManager(); 
 196 bool wxDocument::OnNewDocument() 
 198     if (!OnSaveModified()) 
 201     if (OnCloseDocument()==FALSE
) return FALSE
; 
 204     SetDocumentSaved(FALSE
); 
 207     GetDocumentManager()->MakeDefaultName(name
); 
 209     SetFilename(name
, TRUE
); 
 214 bool wxDocument::Save() 
 218     if (!IsModified()) return TRUE
; 
 219     if (m_documentFile 
== _T("") || !m_savedYet
) 
 222         ret 
= OnSaveDocument(m_documentFile
); 
 224         SetDocumentSaved(TRUE
); 
 228 bool wxDocument::SaveAs() 
 230     wxDocTemplate 
*docTemplate 
= GetDocumentTemplate(); 
 234     wxString tmp 
= wxFileSelector(_("Save as"), 
 235             docTemplate
->GetDirectory(), 
 237             docTemplate
->GetDefaultExtension(), 
 238             docTemplate
->GetFileFilter(), 
 239             wxSAVE 
| wxOVERWRITE_PROMPT
, 
 240             GetDocumentWindow()); 
 245     wxString 
fileName(tmp
); 
 246     wxString path
, name
, ext
; 
 247     wxSplitPath(fileName
, & path
, & name
, & ext
); 
 249     if (ext
.IsEmpty() || ext 
== _T("")) 
 252         fileName 
+= docTemplate
->GetDefaultExtension(); 
 255     SetFilename(fileName
); 
 256     SetTitle(wxFileNameFromPath(fileName
)); 
 258     GetDocumentManager()->AddFileToHistory(fileName
); 
 260     // Notify the views that the filename has changed 
 261     wxNode 
*node 
= m_documentViews
.First(); 
 264         wxView 
*view 
= (wxView 
*)node
->Data(); 
 265         view
->OnChangeFilename(); 
 269     return OnSaveDocument(m_documentFile
); 
 272 bool wxDocument::OnSaveDocument(const wxString
& file
) 
 278     if (wxTheApp
->GetAppName() != _T("")) 
 279         msgTitle 
= wxTheApp
->GetAppName(); 
 281         msgTitle 
= wxString(_("File error")); 
 283 #if wxUSE_STD_IOSTREAM 
 284     ofstream 
store(file
.fn_str()); 
 285     if (store
.fail() || store
.bad()) 
 287     wxFileOutputStream 
store(file
.fn_str()); 
 288     if (store
.LastError() != 0) 
 291         (void)wxMessageBox(_("Sorry, could not open this file for saving."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 292                            GetDocumentWindow()); 
 296     if (SaveObject(store
)==FALSE
) 
 298         (void)wxMessageBox(_("Sorry, could not save this file."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 299                            GetDocumentWindow()); 
 308 bool wxDocument::OnOpenDocument(const wxString
& file
) 
 310     if (!OnSaveModified()) 
 314     if (wxTheApp
->GetAppName() != _T("")) 
 315         msgTitle 
= wxTheApp
->GetAppName(); 
 317         msgTitle 
= wxString(_("File error")); 
 319 #if wxUSE_STD_IOSTREAM 
 320     ifstream 
store(file
.fn_str()); 
 321     if (store
.fail() || store
.bad()) 
 323     wxFileInputStream 
store(file
.fn_str()); 
 324     if (store
.LastError() != 0) 
 327         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 328                            GetDocumentWindow()); 
 331     if (LoadObject(store
)==FALSE
) 
 333         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 334                            GetDocumentWindow()); 
 337     SetFilename(file
, TRUE
); 
 346 #if wxUSE_STD_IOSTREAM 
 347 istream
& wxDocument::LoadObject(istream
& stream
) 
 352 ostream
& wxDocument::SaveObject(ostream
& stream
) 
 357 bool wxDocument::LoadObject(wxInputStream
& stream
) 
 362 bool wxDocument::SaveObject(wxOutputStream
& stream
) 
 368 bool wxDocument::Revert() 
 374 // Get title, or filename if no title, else unnamed 
 375 bool wxDocument::GetPrintableName(wxString
& buf
) const 
 377     if (m_documentTitle 
!= _T("")) 
 379         buf 
= m_documentTitle
; 
 382     else if (m_documentFile 
!= _T("")) 
 384         buf 
= wxFileNameFromPath(m_documentFile
); 
 394 wxWindow 
*wxDocument::GetDocumentWindow() const 
 396     wxView 
*view 
= GetFirstView(); 
 398         return view
->GetFrame(); 
 400         return wxTheApp
->GetTopWindow(); 
 403 wxCommandProcessor 
*wxDocument::OnCreateCommandProcessor() 
 405     return new wxCommandProcessor
; 
 408 // TRUE if safe to close 
 409 bool wxDocument::OnSaveModified() 
 414         GetPrintableName(title
); 
 417         if (wxTheApp
->GetAppName() != _T("")) 
 418             msgTitle 
= wxTheApp
->GetAppName(); 
 420             msgTitle 
= wxString(_("Warning")); 
 423         prompt
.Printf(_("Do you want to save changes to document %s?"), 
 424                 (const wxChar 
*)title
); 
 425         int res 
= wxMessageBox(prompt
, msgTitle
, 
 426                 wxYES_NO
|wxCANCEL
|wxICON_QUESTION
, 
 427                 GetDocumentWindow()); 
 433         else if (res 
== wxYES
) 
 435         else if (res 
== wxCANCEL
) 
 441 bool wxDocument::Draw(wxDC
& WXUNUSED(context
)) 
 446 bool wxDocument::AddView(wxView 
*view
) 
 448     if (!m_documentViews
.Member(view
)) 
 450         m_documentViews
.Append(view
); 
 456 bool wxDocument::RemoveView(wxView 
*view
) 
 458     (void)m_documentViews
.DeleteObject(view
); 
 463 bool wxDocument::OnCreate(const wxString
& WXUNUSED(path
), long flags
) 
 465     if (GetDocumentTemplate()->CreateView(this, flags
)) 
 471 // Called after a view is added or removed. 
 472 // The default implementation deletes the document if 
 473 // there are no more views. 
 474 void wxDocument::OnChangedViewList() 
 476     if (m_documentViews
.Number() == 0) 
 478         if (OnSaveModified()) 
 485 void wxDocument::UpdateAllViews(wxView 
*sender
, wxObject 
*hint
) 
 487     wxNode 
*node 
= m_documentViews
.First(); 
 490         wxView 
*view 
= (wxView 
*)node
->Data(); 
 491         view
->OnUpdate(sender
, hint
); 
 496 void wxDocument::SetFilename(const wxString
& filename
, bool notifyViews
) 
 498     m_documentFile 
= filename
; 
 501         // Notify the views that the filename has changed 
 502         wxNode 
*node 
= m_documentViews
.First(); 
 505             wxView 
*view 
= (wxView 
*)node
->Data(); 
 506             view
->OnChangeFilename(); 
 512 // ---------------------------------------------------------------------------- 
 514 // ---------------------------------------------------------------------------- 
 519     m_viewDocument 
= (wxDocument
*) NULL
; 
 522     m_viewFrame 
= (wxFrame 
*) NULL
; 
 527     GetDocumentManager()->ActivateView(this, FALSE
, TRUE
); 
 528     m_viewDocument
->RemoveView(this); 
 531 // Extend event processing to search the document's event table 
 532 bool wxView::ProcessEvent(wxEvent
& event
) 
 534     if ( !GetDocument() || !GetDocument()->ProcessEvent(event
) ) 
 535         return wxEvtHandler::ProcessEvent(event
); 
 540 void wxView::OnActivateView(bool WXUNUSED(activate
), wxView 
*WXUNUSED(activeView
), wxView 
*WXUNUSED(deactiveView
)) 
 544 void wxView::OnPrint(wxDC 
*dc
, wxObject 
*WXUNUSED(info
)) 
 549 void wxView::OnUpdate(wxView 
*WXUNUSED(sender
), wxObject 
*WXUNUSED(hint
)) 
 553 void wxView::OnChangeFilename() 
 555     if (GetFrame() && GetDocument()) 
 558         GetDocument()->GetPrintableName(name
); 
 560         GetFrame()->SetTitle(name
); 
 564 void wxView::SetDocument(wxDocument 
*doc
) 
 566     m_viewDocument 
= doc
; 
 571 bool wxView::Close(bool deleteWindow
) 
 573     if (OnClose(deleteWindow
)) 
 579 void wxView::Activate(bool activate
) 
 581     if (GetDocumentManager()) 
 583         OnActivateView(activate
, this, GetDocumentManager()->GetCurrentView()); 
 584         GetDocumentManager()->ActivateView(this, activate
); 
 588 bool wxView::OnClose(bool WXUNUSED(deleteWindow
)) 
 590     return GetDocument() ? GetDocument()->Close() : TRUE
; 
 593 #if wxUSE_PRINTING_ARCHITECTURE 
 594 wxPrintout 
*wxView::OnCreatePrintout() 
 596     return new wxDocPrintout(this); 
 598 #endif // wxUSE_PRINTING_ARCHITECTURE 
 600 // ---------------------------------------------------------------------------- 
 602 // ---------------------------------------------------------------------------- 
 604 wxDocTemplate::wxDocTemplate(wxDocManager 
*manager
, 
 605                              const wxString
& descr
, 
 606                              const wxString
& filter
, 
 609                              const wxString
& docTypeName
, 
 610                              const wxString
& viewTypeName
, 
 611                              wxClassInfo 
*docClassInfo
, 
 612                              wxClassInfo 
*viewClassInfo
, 
 615     m_documentManager 
= manager
; 
 616     m_description 
= descr
; 
 619     m_fileFilter 
= filter
; 
 621     m_docTypeName 
= docTypeName
; 
 622     m_viewTypeName 
= viewTypeName
; 
 623     m_documentManager
->AssociateTemplate(this); 
 625     m_docClassInfo 
= docClassInfo
; 
 626     m_viewClassInfo 
= viewClassInfo
; 
 629 wxDocTemplate::~wxDocTemplate() 
 631     m_documentManager
->DisassociateTemplate(this); 
 634 // Tries to dynamically construct an object of the right class. 
 635 wxDocument 
*wxDocTemplate::CreateDocument(const wxString
& path
, long flags
) 
 638         return (wxDocument 
*) NULL
; 
 639     wxDocument 
*doc 
= (wxDocument 
*)m_docClassInfo
->CreateObject(); 
 640     doc
->SetFilename(path
); 
 641     doc
->SetDocumentTemplate(this); 
 642     GetDocumentManager()->AddDocument(doc
); 
 643     doc
->SetCommandProcessor(doc
->OnCreateCommandProcessor()); 
 645     if (doc
->OnCreate(path
, flags
)) 
 650         return (wxDocument 
*) NULL
; 
 654 wxView 
*wxDocTemplate::CreateView(wxDocument 
*doc
, long flags
) 
 656     if (!m_viewClassInfo
) 
 657         return (wxView 
*) NULL
; 
 658     wxView 
*view 
= (wxView 
*)m_viewClassInfo
->CreateObject(); 
 659     view
->SetDocument(doc
); 
 660     if (view
->OnCreate(doc
, flags
)) 
 667         return (wxView 
*) NULL
; 
 671 // The default (very primitive) format detection: check is the extension is 
 672 // that of the template 
 673 bool wxDocTemplate::FileMatchesTemplate(const wxString
& path
) 
 675     return GetDefaultExtension().IsSameAs(FindExtension(path
)); 
 678 // ---------------------------------------------------------------------------- 
 680 // ---------------------------------------------------------------------------- 
 682 BEGIN_EVENT_TABLE(wxDocManager
, wxEvtHandler
) 
 683     EVT_MENU(wxID_OPEN
, wxDocManager::OnFileOpen
) 
 684     EVT_MENU(wxID_CLOSE
, wxDocManager::OnFileClose
) 
 685     EVT_MENU(wxID_REVERT
, wxDocManager::OnFileRevert
) 
 686     EVT_MENU(wxID_NEW
, wxDocManager::OnFileNew
) 
 687     EVT_MENU(wxID_SAVE
, wxDocManager::OnFileSave
) 
 688     EVT_MENU(wxID_SAVEAS
, wxDocManager::OnFileSaveAs
) 
 689     EVT_MENU(wxID_UNDO
, wxDocManager::OnUndo
) 
 690     EVT_MENU(wxID_REDO
, wxDocManager::OnRedo
) 
 691 #if wxUSE_PRINTING_ARCHITECTURE 
 692     EVT_MENU(wxID_PRINT
, wxDocManager::OnPrint
) 
 693     EVT_MENU(wxID_PRINT_SETUP
, wxDocManager::OnPrintSetup
) 
 694     EVT_MENU(wxID_PREVIEW
, wxDocManager::OnPreview
) 
 698 wxDocManager::wxDocManager(long flags
, bool initialize
) 
 700     m_defaultDocumentNameCounter 
= 1; 
 702     m_currentView 
= (wxView 
*) NULL
; 
 703     m_maxDocsOpen 
= 10000; 
 704     m_fileHistory 
= (wxFileHistory 
*) NULL
; 
 709 wxDocManager::~wxDocManager() 
 713         delete m_fileHistory
; 
 716 bool wxDocManager::Clear(bool force
) 
 718     wxNode 
*node 
= m_docs
.First(); 
 721         wxDocument 
*doc 
= (wxDocument 
*)node
->Data(); 
 722         wxNode 
*next 
= node
->Next(); 
 724         if (!doc
->Close() && !force
) 
 727         // Implicitly deletes the document when the last 
 728         // view is removed (deleted) 
 729         doc
->DeleteAllViews(); 
 731         // Check document is deleted 
 732         if (m_docs
.Member(doc
)) 
 735         // This assumes that documents are not connected in 
 736         // any way, i.e. deleting one document does NOT 
 740     node 
= m_templates
.First(); 
 743         wxDocTemplate 
*templ 
= (wxDocTemplate
*) node
->Data(); 
 744         wxNode
* next 
= node
->Next(); 
 751 bool wxDocManager::Initialize() 
 753     m_fileHistory 
= OnCreateFileHistory(); 
 757 wxFileHistory 
*wxDocManager::OnCreateFileHistory() 
 759     return new wxFileHistory
; 
 762 void wxDocManager::OnFileClose(wxCommandEvent
& WXUNUSED(event
)) 
 764     wxDocument 
*doc 
= GetCurrentDocument(); 
 769         doc
->DeleteAllViews(); 
 770         if (m_docs
.Member(doc
)) 
 775 void wxDocManager::OnFileNew(wxCommandEvent
& WXUNUSED(event
)) 
 777     CreateDocument(wxString(""), wxDOC_NEW
); 
 780 void wxDocManager::OnFileOpen(wxCommandEvent
& WXUNUSED(event
)) 
 782     CreateDocument(wxString(""), 0); 
 785 void wxDocManager::OnFileRevert(wxCommandEvent
& WXUNUSED(event
)) 
 787     wxDocument 
*doc 
= GetCurrentDocument(); 
 793 void wxDocManager::OnFileSave(wxCommandEvent
& WXUNUSED(event
)) 
 795     wxDocument 
*doc 
= GetCurrentDocument(); 
 801 void wxDocManager::OnFileSaveAs(wxCommandEvent
& WXUNUSED(event
)) 
 803     wxDocument 
*doc 
= GetCurrentDocument(); 
 809 void wxDocManager::OnPrint(wxCommandEvent
& WXUNUSED(event
)) 
 811 #if wxUSE_PRINTING_ARCHITECTURE 
 812     wxView 
*view 
= GetCurrentView(); 
 816     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 820         printer
.Print(view
->GetFrame(), printout
, TRUE
); 
 824 #endif // wxUSE_PRINTING_ARCHITECTURE 
 827 void wxDocManager::OnPrintSetup(wxCommandEvent
& WXUNUSED(event
)) 
 829 #if wxUSE_PRINTING_ARCHITECTURE 
 830     wxWindow 
*parentWin 
= wxTheApp
->GetTopWindow(); 
 831     wxView 
*view 
= GetCurrentView(); 
 833         parentWin 
= view
->GetFrame(); 
 835     wxPrintDialogData data
; 
 837     wxPrintDialog 
printerDialog(parentWin
, & data
); 
 838     printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
); 
 839     printerDialog
.ShowModal(); 
 840 #endif // wxUSE_PRINTING_ARCHITECTURE 
 843 void wxDocManager::OnPreview(wxCommandEvent
& WXUNUSED(event
)) 
 845 #if wxUSE_PRINTING_ARCHITECTURE 
 846     wxView 
*view 
= GetCurrentView(); 
 850     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 853         // Pass two printout objects: for preview, and possible printing. 
 854         wxPrintPreviewBase 
*preview 
= (wxPrintPreviewBase 
*) NULL
; 
 855         preview 
= new wxPrintPreview(printout
, view
->OnCreatePrintout()); 
 857         wxPreviewFrame 
*frame 
= new wxPreviewFrame(preview
, (wxFrame 
*)wxTheApp
->GetTopWindow(), _("Print Preview"), 
 858                 wxPoint(100, 100), wxSize(600, 650)); 
 859         frame
->Centre(wxBOTH
); 
 863 #endif // wxUSE_PRINTING_ARCHITECTURE 
 866 void wxDocManager::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 868     wxDocument 
*doc 
= GetCurrentDocument(); 
 871     if (doc
->GetCommandProcessor()) 
 872         doc
->GetCommandProcessor()->Undo(); 
 875 void wxDocManager::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 877     wxDocument 
*doc 
= GetCurrentDocument(); 
 880     if (doc
->GetCommandProcessor()) 
 881         doc
->GetCommandProcessor()->Redo(); 
 884 wxView 
*wxDocManager::GetCurrentView() const 
 887         return m_currentView
; 
 888     if (m_docs
.Number() == 1) 
 890         wxDocument
* doc 
= (wxDocument
*) m_docs
.First()->Data(); 
 891         return doc
->GetFirstView(); 
 893     return (wxView 
*) NULL
; 
 896 // Extend event processing to search the view's event table 
 897 bool wxDocManager::ProcessEvent(wxEvent
& event
) 
 899     wxView
* view 
= GetCurrentView(); 
 902         if (view
->ProcessEvent(event
)) 
 905     return wxEvtHandler::ProcessEvent(event
); 
 908 wxDocument 
*wxDocManager::CreateDocument(const wxString
& path
, long flags
) 
 910     wxDocTemplate 
**templates 
= new wxDocTemplate 
*[m_templates
.Number()]; 
 913     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
 915         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Nth(i
)->Data()); 
 916         if (temp
->IsVisible()) 
 925         return (wxDocument 
*) NULL
; 
 928     // If we've reached the max number of docs, close the 
 930     if (GetDocuments().Number() >= m_maxDocsOpen
) 
 932         wxDocument 
*doc 
= (wxDocument 
*)GetDocuments().First()->Data(); 
 935             // Implicitly deletes the document when 
 936             // the last view is deleted 
 937             doc
->DeleteAllViews(); 
 939             // Check we're really deleted 
 940             if (m_docs
.Member(doc
)) 
 944             return (wxDocument 
*) NULL
; 
 947     // New document: user chooses a template, unless there's only one. 
 948     if (flags 
& wxDOC_NEW
) 
 952             wxDocTemplate 
*temp 
= templates
[0]; 
 954             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
 957                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
 958                 newDoc
->SetDocumentTemplate(temp
); 
 959                 newDoc
->OnNewDocument(); 
 964         wxDocTemplate 
*temp 
= SelectDocumentType(templates
, n
); 
 968             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
 971                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
 972                 newDoc
->SetDocumentTemplate(temp
); 
 973                 newDoc
->OnNewDocument(); 
 978             return (wxDocument 
*) NULL
; 
 982     wxDocTemplate 
*temp 
= (wxDocTemplate 
*) NULL
; 
 984     wxString 
path2(_T("")); 
 988     if (flags 
& wxDOC_SILENT
) 
 989         temp 
= FindTemplateForPath(path2
); 
 991         temp 
= SelectDocumentPath(templates
, n
, path2
, flags
); 
 997         wxDocument 
*newDoc 
= temp
->CreateDocument(path2
, flags
); 
1000             newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1001             newDoc
->SetDocumentTemplate(temp
); 
1002             if (!newDoc
->OnOpenDocument(path2
)) 
1005                 return (wxDocument 
*) NULL
; 
1007             AddFileToHistory(path2
); 
1012         return (wxDocument 
*) NULL
; 
1015 wxView 
*wxDocManager::CreateView(wxDocument 
*doc
, long flags
) 
1017     wxDocTemplate 
**templates 
= new wxDocTemplate 
*[m_templates
.Number()]; 
1020     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1022         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Nth(i
)->Data()); 
1023         if (temp
->IsVisible()) 
1025             if (temp
->GetDocumentName() == doc
->GetDocumentName()) 
1027                 templates
[n
] = temp
; 
1035         return (wxView 
*) NULL
; 
1039         wxDocTemplate 
*temp 
= templates
[0]; 
1041         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1043             view
->SetViewName(temp
->GetViewName()); 
1047     wxDocTemplate 
*temp 
= SelectViewType(templates
, n
); 
1051         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1053             view
->SetViewName(temp
->GetViewName()); 
1057         return (wxView 
*) NULL
; 
1060 // Not yet implemented 
1061 void wxDocManager::DeleteTemplate(wxDocTemplate 
*WXUNUSED(temp
), long WXUNUSED(flags
)) 
1065 // Not yet implemented 
1066 bool wxDocManager::FlushDoc(wxDocument 
*WXUNUSED(doc
)) 
1071 wxDocument 
*wxDocManager::GetCurrentDocument() const 
1074         return m_currentView
->GetDocument(); 
1076         return (wxDocument 
*) NULL
; 
1079 // Make a default document name 
1080 bool wxDocManager::MakeDefaultName(wxString
& name
) 
1082     name
.Printf(_("unnamed%d"), m_defaultDocumentNameCounter
); 
1083     m_defaultDocumentNameCounter
++; 
1088 // Not yet implemented 
1089 wxDocTemplate 
*wxDocManager::MatchTemplate(const wxString
& WXUNUSED(path
)) 
1091     return (wxDocTemplate 
*) NULL
; 
1094 // File history management 
1095 void wxDocManager::AddFileToHistory(const wxString
& file
) 
1098         m_fileHistory
->AddFileToHistory(file
); 
1101 wxString 
wxDocManager::GetHistoryFile(int i
) const 
1106         histFile 
= m_fileHistory
->GetHistoryFile(i
); 
1111 void wxDocManager::FileHistoryUseMenu(wxMenu 
*menu
) 
1114         m_fileHistory
->UseMenu(menu
); 
1117 void wxDocManager::FileHistoryRemoveMenu(wxMenu 
*menu
) 
1120         m_fileHistory
->RemoveMenu(menu
); 
1124 void wxDocManager::FileHistoryLoad(wxConfigBase
& config
) 
1127         m_fileHistory
->Load(config
); 
1130 void wxDocManager::FileHistorySave(wxConfigBase
& config
) 
1133         m_fileHistory
->Save(config
); 
1137 void wxDocManager::FileHistoryAddFilesToMenu(wxMenu
* menu
) 
1140         m_fileHistory
->AddFilesToMenu(menu
); 
1143 void wxDocManager::FileHistoryAddFilesToMenu() 
1146         m_fileHistory
->AddFilesToMenu(); 
1149 int wxDocManager::GetNoHistoryFiles() const 
1152         return m_fileHistory
->GetNoHistoryFiles(); 
1158 // Find out the document template via matching in the document file format 
1159 // against that of the template 
1160 wxDocTemplate 
*wxDocManager::FindTemplateForPath(const wxString
& path
) 
1162     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*) NULL
; 
1164     // Find the template which this extension corresponds to 
1166     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1168         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)m_templates
.Nth(i
)->Data(); 
1169         if ( temp
->FileMatchesTemplate(path
) ) 
1178 // Prompts user to open a file, using file specs in templates. 
1179 // How to implement in wxWindows? Must extend the file selector 
1180 // dialog or implement own; OR match the extension to the 
1181 // template extension. 
1183 wxDocTemplate 
*wxDocManager::SelectDocumentPath(wxDocTemplate 
**templates
, 
1187                                                 int WXUNUSED(noTemplates
), 
1190                                                 long WXUNUSED(flags
), 
1191                                                 bool WXUNUSED(save
)) 
1193     // We can only have multiple filters in Windows 
1198     for (i 
= 0; i 
< noTemplates
; i
++) 
1200         if (templates
[i
]->IsVisible()) 
1202             // add a '|' to separate this filter from the previous one 
1203             if ( !descrBuf
.IsEmpty() ) 
1204                 descrBuf 
<< _T('|'); 
1206             descrBuf 
<< templates
[i
]->GetDescription() 
1207                 << _T(" (") << templates
[i
]->GetFileFilter() << _T(") |") 
1208                 << templates
[i
]->GetFileFilter(); 
1212     wxString descrBuf 
= _T("*.*"); 
1215     int FilterIndex 
= 0; 
1216     wxString pathTmp 
= wxFileSelectorEx(_("Select a file"), 
1222                                         wxTheApp
->GetTopWindow()); 
1224     if (!pathTmp
.IsEmpty()) 
1227         wxString theExt 
= FindExtension(path
); 
1229             return (wxDocTemplate 
*) NULL
; 
1231         // This is dodgy in that we're selecting the template on the 
1232         // basis of the file extension, which may not be a standard 
1233         // one. We really want to know exactly which template was 
1234         // chosen by using a more advanced file selector. 
1235         wxDocTemplate 
*theTemplate 
= FindTemplateForPath(path
); 
1237             theTemplate 
= templates
[FilterIndex
]; 
1244         return (wxDocTemplate 
*) NULL
; 
1247     // In all other windowing systems, until we have more advanced 
1248     // file selectors, we must select the document type (template) first, and 
1249     // _then_ pop up the file selector. 
1250     wxDocTemplate 
*temp 
= SelectDocumentType(templates
, noTemplates
); 
1252         return (wxDocTemplate 
*) NULL
; 
1254     wxChar 
*pathTmp 
= wxFileSelector(_("Select a file"), _T(""), _T(""), 
1255             temp
->GetDefaultExtension(), 
1256             temp
->GetFileFilter(), 
1257             0, wxTheApp
->GetTopWindow()); 
1265         return (wxDocTemplate 
*) NULL
; 
1269 wxDocTemplate 
*wxDocManager::SelectDocumentType(wxDocTemplate 
**templates
, 
1272     wxChar 
**strings 
= new wxChar 
*[noTemplates
]; 
1273     wxChar 
**data 
= new wxChar 
*[noTemplates
]; 
1276     for (i 
= 0; i 
< noTemplates
; i
++) 
1278         if (templates
[i
]->IsVisible()) 
1280             strings
[n
] = WXSTRINGCAST templates
[i
]->m_description
; 
1281             data
[n
] = (wxChar 
*)templates
[i
]; 
1289         return (wxDocTemplate 
*) NULL
; 
1293         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)data
[0]; 
1299     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData(_("Select a document template"), _("Templates"), n
, 
1306 wxDocTemplate 
*wxDocManager::SelectViewType(wxDocTemplate 
**templates
, 
1309     wxChar 
**strings 
= new wxChar 
*[noTemplates
]; 
1310     wxChar 
**data 
= new wxChar 
*[noTemplates
]; 
1313     for (i 
= 0; i 
< noTemplates
; i
++) 
1315         if (templates
[i
]->IsVisible() && (templates
[i
]->GetViewName() != _T(""))) 
1317             strings
[n
] = WXSTRINGCAST templates
[i
]->m_viewTypeName
; 
1318             data
[n
] = (wxChar 
*)templates
[i
]; 
1322     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData(_("Select a document view"), _("Views"), n
, 
1329 void wxDocManager::AssociateTemplate(wxDocTemplate 
*temp
) 
1331     if (!m_templates
.Member(temp
)) 
1332         m_templates
.Append(temp
); 
1335 void wxDocManager::DisassociateTemplate(wxDocTemplate 
*temp
) 
1337     m_templates
.DeleteObject(temp
); 
1340 // Add and remove a document from the manager's list 
1341 void wxDocManager::AddDocument(wxDocument 
*doc
) 
1343     if (!m_docs
.Member(doc
)) 
1347 void wxDocManager::RemoveDocument(wxDocument 
*doc
) 
1349     m_docs
.DeleteObject(doc
); 
1352 // Views or windows should inform the document manager 
1353 // when a view is going in or out of focus 
1354 void wxDocManager::ActivateView(wxView 
*view
, bool activate
, bool WXUNUSED(deleting
)) 
1356     // If we're deactiving, and if we're not actually deleting the view, then 
1357     // don't reset the current view because we may be going to 
1358     // a window without a view. 
1359     // WHAT DID I MEAN BY THAT EXACTLY? 
1363        if (m_currentView == view) 
1364        m_currentView = NULL; 
1370             m_currentView 
= view
; 
1372             m_currentView 
= (wxView 
*) NULL
; 
1376 // ---------------------------------------------------------------------------- 
1377 // Default document child frame 
1378 // ---------------------------------------------------------------------------- 
1380 BEGIN_EVENT_TABLE(wxDocChildFrame
, wxFrame
) 
1381     EVT_ACTIVATE(wxDocChildFrame::OnActivate
) 
1382     EVT_CLOSE(wxDocChildFrame::OnCloseWindow
) 
1385 wxDocChildFrame::wxDocChildFrame(wxDocument 
*doc
, 
1389                                  const wxString
& title
, 
1393                                  const wxString
& name
) 
1394                : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1396     m_childDocument 
= doc
; 
1399         view
->SetFrame(this); 
1402 wxDocChildFrame::~wxDocChildFrame() 
1406 // Extend event processing to search the view's event table 
1407 bool wxDocChildFrame::ProcessEvent(wxEvent
& event
) 
1410         m_childView
->Activate(TRUE
); 
1412     if ( !m_childView 
|| ! m_childView
->ProcessEvent(event
) ) 
1414         // Only hand up to the parent if it's a menu command 
1415         if (!event
.IsKindOf(CLASSINFO(wxCommandEvent
)) || !GetParent() || !GetParent()->ProcessEvent(event
)) 
1416             return wxEvtHandler::ProcessEvent(event
); 
1424 void wxDocChildFrame::OnActivate(wxActivateEvent
& event
) 
1426     wxFrame::OnActivate(event
); 
1429         m_childView
->Activate(event
.GetActive()); 
1432 void wxDocChildFrame::OnCloseWindow(wxCloseEvent
& event
) 
1437         if (!event
.CanVeto()) 
1438             ans 
= TRUE
; // Must delete. 
1440             ans 
= m_childView
->Close(FALSE
); // FALSE means don't delete associated window 
1444             m_childView
->Activate(FALSE
); 
1446             m_childView 
= (wxView 
*) NULL
; 
1447             m_childDocument 
= (wxDocument 
*) NULL
; 
1458 // ---------------------------------------------------------------------------- 
1459 // Default parent frame 
1460 // ---------------------------------------------------------------------------- 
1462 BEGIN_EVENT_TABLE(wxDocParentFrame
, wxFrame
) 
1463     EVT_MENU(wxID_EXIT
, wxDocParentFrame::OnExit
) 
1464     EVT_MENU_RANGE(wxID_FILE1
, wxID_FILE9
, wxDocParentFrame::OnMRUFile
) 
1465     EVT_CLOSE(wxDocParentFrame::OnCloseWindow
) 
1468 wxDocParentFrame::wxDocParentFrame(wxDocManager 
*manager
, 
1471                                    const wxString
& title
, 
1475                                    const wxString
& name
) 
1476                 : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1478     m_docManager 
= manager
; 
1481 void wxDocParentFrame::OnExit(wxCommandEvent
& WXUNUSED(event
)) 
1486 void wxDocParentFrame::OnMRUFile(wxCommandEvent
& event
) 
1488     wxString 
f(m_docManager
->GetHistoryFile(event
.GetSelection() - wxID_FILE1
)); 
1490         (void)m_docManager
->CreateDocument(f
, wxDOC_SILENT
); 
1493 // Extend event processing to search the view's event table 
1494 bool wxDocParentFrame::ProcessEvent(wxEvent
& event
) 
1496     // Try the document manager, then do default processing 
1497     if (!m_docManager 
|| !m_docManager
->ProcessEvent(event
)) 
1498         return wxEvtHandler::ProcessEvent(event
); 
1503 // Define the behaviour for the frame closing 
1504 // - must delete all frames except for the main one. 
1505 void wxDocParentFrame::OnCloseWindow(wxCloseEvent
& event
) 
1507     if (m_docManager
->Clear(!event
.CanVeto())) 
1515 #if wxUSE_PRINTING_ARCHITECTURE 
1517 wxDocPrintout::wxDocPrintout(wxView 
*view
, const wxString
& title
) 
1518              : wxPrintout(WXSTRINGCAST title
) 
1520     m_printoutView 
= view
; 
1523 bool wxDocPrintout::OnPrintPage(int WXUNUSED(page
)) 
1527     // Get the logical pixels per inch of screen and printer 
1528     int ppiScreenX
, ppiScreenY
; 
1529     GetPPIScreen(&ppiScreenX
, &ppiScreenY
); 
1530     int ppiPrinterX
, ppiPrinterY
; 
1531     GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
); 
1533     // This scales the DC so that the printout roughly represents the 
1534     // the screen scaling. The text point size _should_ be the right size 
1535     // but in fact is too small for some reason. This is a detail that will 
1536     // need to be addressed at some point but can be fudged for the 
1538     float scale 
= (float)((float)ppiPrinterX
/(float)ppiScreenX
); 
1540     // Now we have to check in case our real page size is reduced 
1541     // (e.g. because we're drawing to a print preview memory DC) 
1542     int pageWidth
, pageHeight
; 
1544     dc
->GetSize(&w
, &h
); 
1545     GetPageSizePixels(&pageWidth
, &pageHeight
); 
1547     // If printer pageWidth == current DC width, then this doesn't 
1548     // change. But w might be the preview bitmap width, so scale down. 
1549     float overallScale 
= scale 
* (float)(w
/(float)pageWidth
); 
1550     dc
->SetUserScale(overallScale
, overallScale
); 
1554         m_printoutView
->OnDraw(dc
); 
1559 bool wxDocPrintout::HasPage(int pageNum
) 
1561     return (pageNum 
== 1); 
1564 bool wxDocPrintout::OnBeginDocument(int startPage
, int endPage
) 
1566     if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) 
1572 void wxDocPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
) 
1580 #endif // wxUSE_PRINTING_ARCHITECTURE 
1582 // ---------------------------------------------------------------------------- 
1583 // Command processing framework 
1584 // ---------------------------------------------------------------------------- 
1586 wxCommand::wxCommand(bool canUndoIt
, const wxString
& name
) 
1588     m_canUndo 
= canUndoIt
; 
1589     m_commandName 
= name
; 
1592 wxCommand::~wxCommand() 
1596 // Command processor 
1597 wxCommandProcessor::wxCommandProcessor(int maxCommands
) 
1599     m_maxNoCommands 
= maxCommands
; 
1600     m_currentCommand 
= (wxNode 
*) NULL
; 
1601     m_commandEditMenu 
= (wxMenu 
*) NULL
; 
1604 wxCommandProcessor::~wxCommandProcessor() 
1609 // Pass a command to the processor. The processor calls Do(); 
1610 // if successful, is appended to the command history unless 
1611 // storeIt is FALSE. 
1612 bool wxCommandProcessor::Submit(wxCommand 
*command
, bool storeIt
) 
1614     bool success 
= command
->Do(); 
1615     if (success 
&& storeIt
) 
1617         if (m_commands
.Number() == m_maxNoCommands
) 
1619             wxNode 
*firstNode 
= m_commands
.First(); 
1620             wxCommand 
*firstCommand 
= (wxCommand 
*)firstNode
->Data(); 
1621             delete firstCommand
; 
1625         // Correct a bug: we must chop off the current 'branch' 
1626         // so that we're at the end of the command list. 
1627         if (!m_currentCommand
) 
1631             wxNode 
*node 
= m_currentCommand
->Next(); 
1634                 wxNode 
*next 
= node
->Next(); 
1635                 delete (wxCommand 
*)node
->Data(); 
1641         m_commands
.Append(command
); 
1642         m_currentCommand 
= m_commands
.Last(); 
1648 bool wxCommandProcessor::Undo() 
1650     if (m_currentCommand
) 
1652         wxCommand 
*command 
= (wxCommand 
*)m_currentCommand
->Data(); 
1653         if (command
->CanUndo()) 
1655             bool success 
= command
->Undo(); 
1658                 m_currentCommand 
= m_currentCommand
->Previous(); 
1667 bool wxCommandProcessor::Redo() 
1669     wxCommand 
*redoCommand 
= (wxCommand 
*) NULL
; 
1670     wxNode 
*redoNode 
= (wxNode 
*) NULL
; 
1671     if (m_currentCommand 
&& m_currentCommand
->Next()) 
1673         redoCommand 
= (wxCommand 
*)m_currentCommand
->Next()->Data(); 
1674         redoNode 
= m_currentCommand
->Next(); 
1678         if (m_commands
.Number() > 0) 
1680             redoCommand 
= (wxCommand 
*)m_commands
.First()->Data(); 
1681             redoNode 
= m_commands
.First(); 
1687         bool success 
= redoCommand
->Do(); 
1690             m_currentCommand 
= redoNode
; 
1698 bool wxCommandProcessor::CanUndo() const 
1700     if (m_currentCommand
) 
1701         return ((wxCommand 
*)m_currentCommand
->Data())->CanUndo(); 
1705 bool wxCommandProcessor::CanRedo() const 
1707     if ((m_currentCommand 
!= (wxNode
*) NULL
) && (m_currentCommand
->Next() == (wxNode
*) NULL
)) 
1710     if ((m_currentCommand 
!= (wxNode
*) NULL
) && (m_currentCommand
->Next() != (wxNode
*) NULL
)) 
1713     if ((m_currentCommand 
== (wxNode
*) NULL
) && (m_commands
.Number() > 0)) 
1719 void wxCommandProcessor::Initialize() 
1721     m_currentCommand 
= m_commands
.Last(); 
1725 void wxCommandProcessor::SetMenuStrings() 
1727     if (m_commandEditMenu
) 
1730         if (m_currentCommand
) 
1732             wxCommand 
*command 
= (wxCommand 
*)m_currentCommand
->Data(); 
1733             wxString 
commandName(command
->GetName()); 
1734             if (commandName 
== _T("")) commandName 
= _("Unnamed command"); 
1735             bool canUndo 
= command
->CanUndo(); 
1737                 buf 
= wxString(_("&Undo ")) + commandName
; 
1739                 buf 
= wxString(_("Can't &Undo ")) + commandName
; 
1741             m_commandEditMenu
->SetLabel(wxID_UNDO
, buf
); 
1742             m_commandEditMenu
->Enable(wxID_UNDO
, canUndo
); 
1744             // We can redo, if we're not at the end of the history. 
1745             if (m_currentCommand
->Next()) 
1747                 wxCommand 
*redoCommand 
= (wxCommand 
*)m_currentCommand
->Next()->Data(); 
1748                 wxString 
redoCommandName(redoCommand
->GetName()); 
1749                 if (redoCommandName 
== _T("")) redoCommandName 
= _("Unnamed command"); 
1750                 buf 
= wxString(_("&Redo ")) + redoCommandName
; 
1751                 m_commandEditMenu
->SetLabel(wxID_REDO
, buf
); 
1752                 m_commandEditMenu
->Enable(wxID_REDO
, TRUE
); 
1756                 m_commandEditMenu
->SetLabel(wxID_REDO
, _("&Redo")); 
1757                 m_commandEditMenu
->Enable(wxID_REDO
, FALSE
); 
1762             m_commandEditMenu
->SetLabel(wxID_UNDO
, _("&Undo")); 
1763             m_commandEditMenu
->Enable(wxID_UNDO
, FALSE
); 
1765             if (m_commands
.Number() == 0) 
1767                 m_commandEditMenu
->SetLabel(wxID_REDO
, _("&Redo")); 
1768                 m_commandEditMenu
->Enable(wxID_REDO
, FALSE
); 
1772                 // currentCommand is NULL but there are commands: this means that 
1773                 // we've undone to the start of the list, but can redo the first. 
1774                 wxCommand 
*redoCommand 
= (wxCommand 
*)m_commands
.First()->Data(); 
1775                 wxString 
redoCommandName(redoCommand
->GetName()); 
1776                 if (redoCommandName 
== _T("")) redoCommandName 
= _("Unnamed command"); 
1777                 buf 
= wxString(_("&Redo ")) + redoCommandName
; 
1778                 m_commandEditMenu
->SetLabel(wxID_REDO
, buf
); 
1779                 m_commandEditMenu
->Enable(wxID_REDO
, TRUE
); 
1785 void wxCommandProcessor::ClearCommands() 
1787     wxNode 
*node 
= m_commands
.First(); 
1790         wxCommand 
*command 
= (wxCommand 
*)node
->Data(); 
1793         node 
= m_commands
.First(); 
1795     m_currentCommand 
= (wxNode 
*) NULL
; 
1798 // ---------------------------------------------------------------------------- 
1799 // File history processor 
1800 // ---------------------------------------------------------------------------- 
1802 wxFileHistory::wxFileHistory(int maxFiles
) 
1804     m_fileMaxFiles 
= maxFiles
; 
1806     m_fileHistory 
= new wxChar 
*[m_fileMaxFiles
]; 
1809 wxFileHistory::~wxFileHistory() 
1812     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1813         delete[] m_fileHistory
[i
]; 
1814     delete[] m_fileHistory
; 
1817 // File history management 
1818 void wxFileHistory::AddFileToHistory(const wxString
& file
) 
1821     // Check we don't already have this file 
1822     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1824         if (m_fileHistory
[i
] && wxString(m_fileHistory
[i
]) == file
) 
1828     // Add to the project file history: 
1829     // Move existing files (if any) down so we can insert file at beginning. 
1831     // First delete filename that has popped off the end of the array (if any) 
1832     if (m_fileHistoryN 
== m_fileMaxFiles
) 
1834         delete[] m_fileHistory
[m_fileMaxFiles
-1]; 
1835         m_fileHistory
[m_fileMaxFiles
-1] = (wxChar 
*) NULL
; 
1837     if (m_fileHistoryN 
< m_fileMaxFiles
) 
1839         wxNode
* node 
= m_fileMenus
.First(); 
1842             wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1843             if (m_fileHistoryN 
== 0) 
1844                 menu
->AppendSeparator(); 
1845             menu
->Append(wxID_FILE1
+m_fileHistoryN
, _("[EMPTY]")); 
1846             node 
= node
->Next(); 
1850     // Shuffle filenames down 
1851     for (i 
= (m_fileHistoryN
-1); i 
> 0; i
--) 
1853         m_fileHistory
[i
] = m_fileHistory
[i
-1]; 
1855     m_fileHistory
[0] = copystring(file
); 
1857     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1858         if (m_fileHistory
[i
]) 
1861             buf
.Printf(_T("&%d %s"), i
+1, m_fileHistory
[i
]); 
1862             wxNode
* node 
= m_fileMenus
.First(); 
1865                 wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1866                 menu
->SetLabel(wxID_FILE1
+i
, buf
); 
1867                 node 
= node
->Next(); 
1872 wxString 
wxFileHistory::GetHistoryFile(int i
) const 
1874     if (i 
< m_fileHistoryN
) 
1875         return wxString(m_fileHistory
[i
]); 
1877         return wxString(""); 
1880 void wxFileHistory::UseMenu(wxMenu 
*menu
) 
1882     if (!m_fileMenus
.Member(menu
)) 
1883         m_fileMenus
.Append(menu
); 
1886 void wxFileHistory::RemoveMenu(wxMenu 
*menu
) 
1888     m_fileMenus
.DeleteObject(menu
); 
1892 void wxFileHistory::Load(wxConfigBase
& config
) 
1896     buf
.Printf(_T("file%d"), m_fileHistoryN
+1); 
1897     wxString historyFile
; 
1898     while ((m_fileHistoryN 
<= m_fileMaxFiles
) && config
.Read(buf
, &historyFile
) && (historyFile 
!= _T(""))) 
1900         m_fileHistory
[m_fileHistoryN
] = copystring((const wxChar
*) historyFile
); 
1902         buf
.Printf(_T("file%d"), m_fileHistoryN
+1); 
1908 void wxFileHistory::Save(wxConfigBase
& config
) 
1911     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1914         buf
.Printf(_T("file%d"), i
+1); 
1915         config
.Write(buf
, wxString(m_fileHistory
[i
])); 
1918 #endif // wxUSE_CONFIG 
1920 void wxFileHistory::AddFilesToMenu() 
1922     if (m_fileHistoryN 
> 0) 
1924         wxNode
* node 
= m_fileMenus
.First(); 
1927             wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1928             menu
->AppendSeparator(); 
1930             for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1932                 if (m_fileHistory
[i
]) 
1935                     buf
.Printf(_T("&%d %s"), i
+1, m_fileHistory
[i
]); 
1936                     menu
->Append(wxID_FILE1
+i
, buf
); 
1939             node 
= node
->Next(); 
1944 void wxFileHistory::AddFilesToMenu(wxMenu
* menu
) 
1946     if (m_fileHistoryN 
> 0) 
1948         menu
->AppendSeparator(); 
1950         for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1952             if (m_fileHistory
[i
]) 
1955                 buf
.Printf(_T("&%d %s"), i
+1, m_fileHistory
[i
]); 
1956                 menu
->Append(wxID_FILE1
+i
, buf
); 
1962 // ---------------------------------------------------------------------------- 
1963 // Permits compatibility with existing file formats and functions that 
1964 // manipulate files directly 
1965 // ---------------------------------------------------------------------------- 
1967 #if wxUSE_STD_IOSTREAM 
1968 bool wxTransferFileToStream(const wxString
& filename
, ostream
& stream
) 
1973     if ((fd1 
= fopen (filename
.fn_str(), "rb")) == NULL
) 
1976     while ((ch 
= getc (fd1
)) != EOF
) 
1977         stream 
<< (unsigned char)ch
; 
1983 bool wxTransferStreamToFile(istream
& stream
, const wxString
& filename
) 
1988     if ((fd1 
= fopen (filename
.fn_str(), "wb")) == NULL
) 
1993     while (!stream
.eof()) 
2004 #endif // wxUSE_DOC_VIEW_ARCHITECTURE