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" 
  50 #if wxUSE_PRINTING_ARCHITECTURE 
  51   #include "wx/prntbase.h" 
  52   #include "wx/printdlg.h" 
  55 #include "wx/msgdlg.h" 
  56 #include "wx/choicdlg.h" 
  57 #include "wx/docview.h" 
  58 #include "wx/confbase.h" 
  63 #if wxUSE_STD_IOSTREAM 
  64   #include "wx/ioswrap.h" 
  71   #include "wx/wfstream.h" 
  74 // ---------------------------------------------------------------------------- 
  76 // ---------------------------------------------------------------------------- 
  78 #if !USE_SHARED_LIBRARY 
  79     IMPLEMENT_ABSTRACT_CLASS(wxDocument
, wxEvtHandler
) 
  80     IMPLEMENT_ABSTRACT_CLASS(wxView
, wxEvtHandler
) 
  81     IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate
, wxObject
) 
  82     IMPLEMENT_DYNAMIC_CLASS(wxDocManager
, wxEvtHandler
) 
  83     IMPLEMENT_CLASS(wxDocChildFrame
, wxFrame
) 
  84     IMPLEMENT_CLASS(wxDocParentFrame
, wxFrame
) 
  86     #if wxUSE_PRINTING_ARCHITECTURE 
  87         IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout
, wxPrintout
) 
  90     IMPLEMENT_CLASS(wxCommand
, wxObject
) 
  91     IMPLEMENT_DYNAMIC_CLASS(wxCommandProcessor
, wxObject
) 
  92     IMPLEMENT_DYNAMIC_CLASS(wxFileHistory
, wxObject
) 
  95 // ---------------------------------------------------------------------------- 
  96 // function prototypes 
  97 // ---------------------------------------------------------------------------- 
  99 static inline wxString 
FindExtension(const wxChar 
*path
); 
 101 // ============================================================================ 
 103 // ============================================================================ 
 105 // ---------------------------------------------------------------------------- 
 107 // ---------------------------------------------------------------------------- 
 109 static wxString 
FindExtension(const wxChar 
*path
) 
 112     wxSplitPath(path
, NULL
, NULL
, &ext
); 
 114     // VZ: extensions are considered not case sensitive - is this really a good 
 116     return ext
.MakeLower(); 
 119 // ---------------------------------------------------------------------------- 
 120 // Definition of wxDocument 
 121 // ---------------------------------------------------------------------------- 
 123 wxDocument::wxDocument(wxDocument 
*parent
) 
 125     m_documentModified 
= FALSE
; 
 126     m_documentParent 
= parent
; 
 127     m_documentTemplate 
= (wxDocTemplate 
*) NULL
; 
 131 bool wxDocument::DeleteContents() 
 136 wxDocument::~wxDocument() 
 140     if (m_commandProcessor
) 
 141         delete m_commandProcessor
; 
 143     GetDocumentManager()->RemoveDocument(this); 
 145     // Not safe to do here, since it'll invoke virtual view functions 
 146     // expecting to see valid derived objects: and by the time we get here, 
 147     // we've called destructors higher up. 
 151 bool wxDocument::Close() 
 153     if (OnSaveModified()) 
 154         return OnCloseDocument(); 
 159 bool wxDocument::OnCloseDocument() 
 166 // Note that this implicitly deletes the document when the last view is 
 168 bool wxDocument::DeleteAllViews() 
 170     wxNode 
*node 
= m_documentViews
.First(); 
 173         wxView 
*view 
= (wxView 
*)node
->Data(); 
 177         wxNode 
*next 
= node
->Next(); 
 179         delete view
; // Deletes node implicitly 
 185 wxView 
*wxDocument::GetFirstView() const 
 187     if (m_documentViews
.Number() == 0) 
 188         return (wxView 
*) NULL
; 
 189     return (wxView 
*)m_documentViews
.First()->Data(); 
 192 wxDocManager 
*wxDocument::GetDocumentManager() const 
 194     return m_documentTemplate
->GetDocumentManager(); 
 197 bool wxDocument::OnNewDocument() 
 199     if (!OnSaveModified()) 
 202     if (OnCloseDocument()==FALSE
) return FALSE
; 
 205     SetDocumentSaved(FALSE
); 
 208     GetDocumentManager()->MakeDefaultName(name
); 
 210     SetFilename(name
, TRUE
); 
 215 bool wxDocument::Save() 
 219     if (!IsModified()) return TRUE
; 
 220     if (m_documentFile 
== _T("") || !m_savedYet
) 
 223         ret 
= OnSaveDocument(m_documentFile
); 
 225         SetDocumentSaved(TRUE
); 
 229 bool wxDocument::SaveAs() 
 231     wxDocTemplate 
*docTemplate 
= GetDocumentTemplate(); 
 235     wxString tmp 
= wxFileSelector(_("Save as"), 
 236             docTemplate
->GetDirectory(), 
 238             docTemplate
->GetDefaultExtension(), 
 239             docTemplate
->GetFileFilter(), 
 240             wxSAVE 
| wxOVERWRITE_PROMPT
, 
 241             GetDocumentWindow()); 
 246     wxString 
fileName(tmp
); 
 247     wxString path
, name
, ext
; 
 248     wxSplitPath(fileName
, & path
, & name
, & ext
); 
 250     if (ext
.IsEmpty() || ext 
== _T("")) 
 253         fileName 
+= docTemplate
->GetDefaultExtension(); 
 256     SetFilename(fileName
); 
 257     SetTitle(wxFileNameFromPath(fileName
)); 
 259     GetDocumentManager()->AddFileToHistory(fileName
); 
 261     // Notify the views that the filename has changed 
 262     wxNode 
*node 
= m_documentViews
.First(); 
 265         wxView 
*view 
= (wxView 
*)node
->Data(); 
 266         view
->OnChangeFilename(); 
 270     return OnSaveDocument(m_documentFile
); 
 273 bool wxDocument::OnSaveDocument(const wxString
& file
) 
 279     if (wxTheApp
->GetAppName() != _T("")) 
 280         msgTitle 
= wxTheApp
->GetAppName(); 
 282         msgTitle 
= wxString(_("File error")); 
 284 #if wxUSE_STD_IOSTREAM 
 285     ofstream 
store(wxString(file
.fn_str())); 
 286     if (store
.fail() || store
.bad()) 
 288     wxFileOutputStream 
store(wxString(file
.fn_str())); 
 289     if (store
.LastError() != 0) 
 292         (void)wxMessageBox(_("Sorry, could not open this file for saving."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 293                            GetDocumentWindow()); 
 297     if (!SaveObject(store
)) 
 299         (void)wxMessageBox(_("Sorry, could not save this file."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 300                            GetDocumentWindow()); 
 309 bool wxDocument::OnOpenDocument(const wxString
& file
) 
 311     if (!OnSaveModified()) 
 315     if (wxTheApp
->GetAppName() != _T("")) 
 316         msgTitle 
= wxTheApp
->GetAppName(); 
 318         msgTitle 
= wxString(_("File error")); 
 320 #if wxUSE_STD_IOSTREAM 
 321     ifstream 
store(wxString(file
.fn_str())); 
 322     if (store
.fail() || store
.bad()) 
 324     wxFileInputStream 
store(wxString(file
.fn_str())); 
 325     if (store
.LastError() != 0) 
 328         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 329                            GetDocumentWindow()); 
 332     if (!LoadObject(store
)) 
 334         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 335                            GetDocumentWindow()); 
 338     SetFilename(file
, TRUE
); 
 347 #if wxUSE_STD_IOSTREAM 
 348 istream
& wxDocument::LoadObject(istream
& stream
) 
 350 wxInputStream
& wxDocument::LoadObject(wxInputStream
& stream
) 
 356 #if wxUSE_STD_IOSTREAM 
 357 ostream
& wxDocument::SaveObject(ostream
& stream
) 
 359 wxOutputStream
& wxDocument::SaveObject(wxOutputStream
& stream
) 
 365 bool wxDocument::Revert() 
 371 // Get title, or filename if no title, else unnamed 
 372 bool wxDocument::GetPrintableName(wxString
& buf
) const 
 374     if (m_documentTitle 
!= _T("")) 
 376         buf 
= m_documentTitle
; 
 379     else if (m_documentFile 
!= _T("")) 
 381         buf 
= wxFileNameFromPath(m_documentFile
); 
 391 wxWindow 
*wxDocument::GetDocumentWindow() const 
 393     wxView 
*view 
= GetFirstView(); 
 395         return view
->GetFrame(); 
 397         return wxTheApp
->GetTopWindow(); 
 400 wxCommandProcessor 
*wxDocument::OnCreateCommandProcessor() 
 402     return new wxCommandProcessor
; 
 405 // TRUE if safe to close 
 406 bool wxDocument::OnSaveModified() 
 411         GetPrintableName(title
); 
 414         if (wxTheApp
->GetAppName() != _T("")) 
 415             msgTitle 
= wxTheApp
->GetAppName(); 
 417             msgTitle 
= wxString(_("Warning")); 
 420         prompt
.Printf(_("Do you want to save changes to document %s?"), 
 421                 (const wxChar 
*)title
); 
 422         int res 
= wxMessageBox(prompt
, msgTitle
, 
 423                 wxYES_NO
|wxCANCEL
|wxICON_QUESTION
, 
 424                 GetDocumentWindow()); 
 430         else if (res 
== wxYES
) 
 432         else if (res 
== wxCANCEL
) 
 438 bool wxDocument::Draw(wxDC
& WXUNUSED(context
)) 
 443 bool wxDocument::AddView(wxView 
*view
) 
 445     if (!m_documentViews
.Member(view
)) 
 447         m_documentViews
.Append(view
); 
 453 bool wxDocument::RemoveView(wxView 
*view
) 
 455     (void)m_documentViews
.DeleteObject(view
); 
 460 bool wxDocument::OnCreate(const wxString
& WXUNUSED(path
), long flags
) 
 462     if (GetDocumentTemplate()->CreateView(this, flags
)) 
 468 // Called after a view is added or removed. 
 469 // The default implementation deletes the document if 
 470 // there are no more views. 
 471 void wxDocument::OnChangedViewList() 
 473     if (m_documentViews
.Number() == 0) 
 475         if (OnSaveModified()) 
 482 void wxDocument::UpdateAllViews(wxView 
*sender
, wxObject 
*hint
) 
 484     wxNode 
*node 
= m_documentViews
.First(); 
 487         wxView 
*view 
= (wxView 
*)node
->Data(); 
 488         view
->OnUpdate(sender
, hint
); 
 493 void wxDocument::SetFilename(const wxString
& filename
, bool notifyViews
) 
 495     m_documentFile 
= filename
; 
 498         // Notify the views that the filename has changed 
 499         wxNode 
*node 
= m_documentViews
.First(); 
 502             wxView 
*view 
= (wxView 
*)node
->Data(); 
 503             view
->OnChangeFilename(); 
 509 // ---------------------------------------------------------------------------- 
 511 // ---------------------------------------------------------------------------- 
 516     m_viewDocument 
= (wxDocument
*) NULL
; 
 519     m_viewFrame 
= (wxFrame 
*) NULL
; 
 524     GetDocumentManager()->ActivateView(this, FALSE
, TRUE
); 
 525     m_viewDocument
->RemoveView(this); 
 528 // Extend event processing to search the document's event table 
 529 bool wxView::ProcessEvent(wxEvent
& event
) 
 531     if ( !GetDocument() || !GetDocument()->ProcessEvent(event
) ) 
 532         return wxEvtHandler::ProcessEvent(event
); 
 537 void wxView::OnActivateView(bool WXUNUSED(activate
), wxView 
*WXUNUSED(activeView
), wxView 
*WXUNUSED(deactiveView
)) 
 541 void wxView::OnPrint(wxDC 
*dc
, wxObject 
*WXUNUSED(info
)) 
 546 void wxView::OnUpdate(wxView 
*WXUNUSED(sender
), wxObject 
*WXUNUSED(hint
)) 
 550 void wxView::OnChangeFilename() 
 552     if (GetFrame() && GetDocument()) 
 555         GetDocument()->GetPrintableName(name
); 
 557         GetFrame()->SetTitle(name
); 
 561 void wxView::SetDocument(wxDocument 
*doc
) 
 563     m_viewDocument 
= doc
; 
 568 bool wxView::Close(bool deleteWindow
) 
 570     if (OnClose(deleteWindow
)) 
 576 void wxView::Activate(bool activate
) 
 578     if (GetDocumentManager()) 
 580         OnActivateView(activate
, this, GetDocumentManager()->GetCurrentView()); 
 581         GetDocumentManager()->ActivateView(this, activate
); 
 585 bool wxView::OnClose(bool WXUNUSED(deleteWindow
)) 
 587     return GetDocument() ? GetDocument()->Close() : TRUE
; 
 590 #if wxUSE_PRINTING_ARCHITECTURE 
 591 wxPrintout 
*wxView::OnCreatePrintout() 
 593     return new wxDocPrintout(this); 
 595 #endif // wxUSE_PRINTING_ARCHITECTURE 
 597 // ---------------------------------------------------------------------------- 
 599 // ---------------------------------------------------------------------------- 
 601 wxDocTemplate::wxDocTemplate(wxDocManager 
*manager
, 
 602                              const wxString
& descr
, 
 603                              const wxString
& filter
, 
 606                              const wxString
& docTypeName
, 
 607                              const wxString
& viewTypeName
, 
 608                              wxClassInfo 
*docClassInfo
, 
 609                              wxClassInfo 
*viewClassInfo
, 
 612     m_documentManager 
= manager
; 
 613     m_description 
= descr
; 
 616     m_fileFilter 
= filter
; 
 618     m_docTypeName 
= docTypeName
; 
 619     m_viewTypeName 
= viewTypeName
; 
 620     m_documentManager
->AssociateTemplate(this); 
 622     m_docClassInfo 
= docClassInfo
; 
 623     m_viewClassInfo 
= viewClassInfo
; 
 626 wxDocTemplate::~wxDocTemplate() 
 628     m_documentManager
->DisassociateTemplate(this); 
 631 // Tries to dynamically construct an object of the right class. 
 632 wxDocument 
*wxDocTemplate::CreateDocument(const wxString
& path
, long flags
) 
 635         return (wxDocument 
*) NULL
; 
 636     wxDocument 
*doc 
= (wxDocument 
*)m_docClassInfo
->CreateObject(); 
 637     doc
->SetFilename(path
); 
 638     doc
->SetDocumentTemplate(this); 
 639     GetDocumentManager()->AddDocument(doc
); 
 640     doc
->SetCommandProcessor(doc
->OnCreateCommandProcessor()); 
 642     if (doc
->OnCreate(path
, flags
)) 
 647         return (wxDocument 
*) NULL
; 
 651 wxView 
*wxDocTemplate::CreateView(wxDocument 
*doc
, long flags
) 
 653     if (!m_viewClassInfo
) 
 654         return (wxView 
*) NULL
; 
 655     wxView 
*view 
= (wxView 
*)m_viewClassInfo
->CreateObject(); 
 656     view
->SetDocument(doc
); 
 657     if (view
->OnCreate(doc
, flags
)) 
 664         return (wxView 
*) NULL
; 
 668 // The default (very primitive) format detection: check is the extension is 
 669 // that of the template 
 670 bool wxDocTemplate::FileMatchesTemplate(const wxString
& path
) 
 672     return GetDefaultExtension().IsSameAs(FindExtension(path
)); 
 675 // ---------------------------------------------------------------------------- 
 677 // ---------------------------------------------------------------------------- 
 679 BEGIN_EVENT_TABLE(wxDocManager
, wxEvtHandler
) 
 680     EVT_MENU(wxID_OPEN
, wxDocManager::OnFileOpen
) 
 681     EVT_MENU(wxID_CLOSE
, wxDocManager::OnFileClose
) 
 682     EVT_MENU(wxID_REVERT
, wxDocManager::OnFileRevert
) 
 683     EVT_MENU(wxID_NEW
, wxDocManager::OnFileNew
) 
 684     EVT_MENU(wxID_SAVE
, wxDocManager::OnFileSave
) 
 685     EVT_MENU(wxID_SAVEAS
, wxDocManager::OnFileSaveAs
) 
 686     EVT_MENU(wxID_UNDO
, wxDocManager::OnUndo
) 
 687     EVT_MENU(wxID_REDO
, wxDocManager::OnRedo
) 
 688 #if wxUSE_PRINTING_ARCHITECTURE 
 689     EVT_MENU(wxID_PRINT
, wxDocManager::OnPrint
) 
 690     EVT_MENU(wxID_PRINT_SETUP
, wxDocManager::OnPrintSetup
) 
 691     EVT_MENU(wxID_PREVIEW
, wxDocManager::OnPreview
) 
 695 wxDocManager::wxDocManager(long flags
, bool initialize
) 
 697     m_defaultDocumentNameCounter 
= 1; 
 699     m_currentView 
= (wxView 
*) NULL
; 
 700     m_maxDocsOpen 
= 10000; 
 701     m_fileHistory 
= (wxFileHistory 
*) NULL
; 
 706 wxDocManager::~wxDocManager() 
 710         delete m_fileHistory
; 
 713 bool wxDocManager::Clear(bool force
) 
 715     wxNode 
*node 
= m_docs
.First(); 
 718         wxDocument 
*doc 
= (wxDocument 
*)node
->Data(); 
 719         wxNode 
*next 
= node
->Next(); 
 721         if (!doc
->Close() && !force
) 
 724         // Implicitly deletes the document when the last 
 725         // view is removed (deleted) 
 726         doc
->DeleteAllViews(); 
 728         // Check document is deleted 
 729         if (m_docs
.Member(doc
)) 
 732         // This assumes that documents are not connected in 
 733         // any way, i.e. deleting one document does NOT 
 737     node 
= m_templates
.First(); 
 740         wxDocTemplate 
*templ 
= (wxDocTemplate
*) node
->Data(); 
 741         wxNode
* next 
= node
->Next(); 
 748 bool wxDocManager::Initialize() 
 750     m_fileHistory 
= OnCreateFileHistory(); 
 754 wxFileHistory 
*wxDocManager::OnCreateFileHistory() 
 756     return new wxFileHistory
; 
 759 void wxDocManager::OnFileClose(wxCommandEvent
& WXUNUSED(event
)) 
 761     wxDocument 
*doc 
= GetCurrentDocument(); 
 766         doc
->DeleteAllViews(); 
 767         if (m_docs
.Member(doc
)) 
 772 void wxDocManager::OnFileNew(wxCommandEvent
& WXUNUSED(event
)) 
 774     CreateDocument(wxString(""), wxDOC_NEW
); 
 777 void wxDocManager::OnFileOpen(wxCommandEvent
& WXUNUSED(event
)) 
 779     CreateDocument(wxString(""), 0); 
 782 void wxDocManager::OnFileRevert(wxCommandEvent
& WXUNUSED(event
)) 
 784     wxDocument 
*doc 
= GetCurrentDocument(); 
 790 void wxDocManager::OnFileSave(wxCommandEvent
& WXUNUSED(event
)) 
 792     wxDocument 
*doc 
= GetCurrentDocument(); 
 798 void wxDocManager::OnFileSaveAs(wxCommandEvent
& WXUNUSED(event
)) 
 800     wxDocument 
*doc 
= GetCurrentDocument(); 
 806 void wxDocManager::OnPrint(wxCommandEvent
& WXUNUSED(event
)) 
 808 #if wxUSE_PRINTING_ARCHITECTURE 
 809     wxView 
*view 
= GetCurrentView(); 
 813     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 817         printer
.Print(view
->GetFrame(), printout
, TRUE
); 
 821 #endif // wxUSE_PRINTING_ARCHITECTURE 
 824 void wxDocManager::OnPrintSetup(wxCommandEvent
& WXUNUSED(event
)) 
 826 #if wxUSE_PRINTING_ARCHITECTURE 
 827     wxWindow 
*parentWin 
= wxTheApp
->GetTopWindow(); 
 828     wxView 
*view 
= GetCurrentView(); 
 830         parentWin 
= view
->GetFrame(); 
 832     wxPrintDialogData data
; 
 834     wxPrintDialog 
printerDialog(parentWin
, &data
); 
 835     printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
); 
 836     printerDialog
.ShowModal(); 
 837 #endif // wxUSE_PRINTING_ARCHITECTURE 
 840 void wxDocManager::OnPreview(wxCommandEvent
& WXUNUSED(event
)) 
 842 #if wxUSE_PRINTING_ARCHITECTURE 
 843     wxView 
*view 
= GetCurrentView(); 
 847     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 850         // Pass two printout objects: for preview, and possible printing. 
 851         wxPrintPreviewBase 
*preview 
= (wxPrintPreviewBase 
*) NULL
; 
 852         preview 
= new wxPrintPreview(printout
, view
->OnCreatePrintout()); 
 854         wxPreviewFrame 
*frame 
= new wxPreviewFrame(preview
, (wxFrame 
*)wxTheApp
->GetTopWindow(), _("Print Preview"), 
 855                 wxPoint(100, 100), wxSize(600, 650)); 
 856         frame
->Centre(wxBOTH
); 
 860 #endif // wxUSE_PRINTING_ARCHITECTURE 
 863 void wxDocManager::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 865     wxDocument 
*doc 
= GetCurrentDocument(); 
 868     if (doc
->GetCommandProcessor()) 
 869         doc
->GetCommandProcessor()->Undo(); 
 872 void wxDocManager::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 874     wxDocument 
*doc 
= GetCurrentDocument(); 
 877     if (doc
->GetCommandProcessor()) 
 878         doc
->GetCommandProcessor()->Redo(); 
 881 wxView 
*wxDocManager::GetCurrentView() const 
 884         return m_currentView
; 
 885     if (m_docs
.Number() == 1) 
 887         wxDocument
* doc 
= (wxDocument
*) m_docs
.First()->Data(); 
 888         return doc
->GetFirstView(); 
 890     return (wxView 
*) NULL
; 
 893 // Extend event processing to search the view's event table 
 894 bool wxDocManager::ProcessEvent(wxEvent
& event
) 
 896     wxView
* view 
= GetCurrentView(); 
 899         if (view
->ProcessEvent(event
)) 
 902     return wxEvtHandler::ProcessEvent(event
); 
 905 wxDocument 
*wxDocManager::CreateDocument(const wxString
& path
, long flags
) 
 907     wxDocTemplate 
**templates 
= new wxDocTemplate 
*[m_templates
.Number()]; 
 910     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
 912         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Nth(i
)->Data()); 
 913         if (temp
->IsVisible()) 
 922         return (wxDocument 
*) NULL
; 
 925     // If we've reached the max number of docs, close the 
 927     if (GetDocuments().Number() >= m_maxDocsOpen
) 
 929         wxDocument 
*doc 
= (wxDocument 
*)GetDocuments().First()->Data(); 
 932             // Implicitly deletes the document when 
 933             // the last view is deleted 
 934             doc
->DeleteAllViews(); 
 936             // Check we're really deleted 
 937             if (m_docs
.Member(doc
)) 
 941             return (wxDocument 
*) NULL
; 
 944     // New document: user chooses a template, unless there's only one. 
 945     if (flags 
& wxDOC_NEW
) 
 949             wxDocTemplate 
*temp 
= templates
[0]; 
 951             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
 954                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
 955                 newDoc
->SetDocumentTemplate(temp
); 
 956                 newDoc
->OnNewDocument(); 
 961         wxDocTemplate 
*temp 
= SelectDocumentType(templates
, n
); 
 965             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
 968                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
 969                 newDoc
->SetDocumentTemplate(temp
); 
 970                 newDoc
->OnNewDocument(); 
 975             return (wxDocument 
*) NULL
; 
 979     wxDocTemplate 
*temp 
= (wxDocTemplate 
*) NULL
; 
 981     wxString 
path2(_T("")); 
 985     if (flags 
& wxDOC_SILENT
) 
 986         temp 
= FindTemplateForPath(path2
); 
 988         temp 
= SelectDocumentPath(templates
, n
, path2
, flags
); 
 994         wxDocument 
*newDoc 
= temp
->CreateDocument(path2
, flags
); 
 997             newDoc
->SetDocumentName(temp
->GetDocumentName()); 
 998             newDoc
->SetDocumentTemplate(temp
); 
 999             if (!newDoc
->OnOpenDocument(path2
)) 
1002                 return (wxDocument 
*) NULL
; 
1004             AddFileToHistory(path2
); 
1009         return (wxDocument 
*) NULL
; 
1012 wxView 
*wxDocManager::CreateView(wxDocument 
*doc
, long flags
) 
1014     wxDocTemplate 
**templates 
= new wxDocTemplate 
*[m_templates
.Number()]; 
1017     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1019         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Nth(i
)->Data()); 
1020         if (temp
->IsVisible()) 
1022             if (temp
->GetDocumentName() == doc
->GetDocumentName()) 
1024                 templates
[n
] = temp
; 
1032         return (wxView 
*) NULL
; 
1036         wxDocTemplate 
*temp 
= templates
[0]; 
1038         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1040             view
->SetViewName(temp
->GetViewName()); 
1044     wxDocTemplate 
*temp 
= SelectViewType(templates
, n
); 
1048         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1050             view
->SetViewName(temp
->GetViewName()); 
1054         return (wxView 
*) NULL
; 
1057 // Not yet implemented 
1058 void wxDocManager::DeleteTemplate(wxDocTemplate 
*WXUNUSED(temp
), long WXUNUSED(flags
)) 
1062 // Not yet implemented 
1063 bool wxDocManager::FlushDoc(wxDocument 
*WXUNUSED(doc
)) 
1068 wxDocument 
*wxDocManager::GetCurrentDocument() const 
1071         return m_currentView
->GetDocument(); 
1073         return (wxDocument 
*) NULL
; 
1076 // Make a default document name 
1077 bool wxDocManager::MakeDefaultName(wxString
& name
) 
1079     name
.Printf(_("unnamed%d"), m_defaultDocumentNameCounter
); 
1080     m_defaultDocumentNameCounter
++; 
1085 // Not yet implemented 
1086 wxDocTemplate 
*wxDocManager::MatchTemplate(const wxString
& WXUNUSED(path
)) 
1088     return (wxDocTemplate 
*) NULL
; 
1091 // File history management 
1092 void wxDocManager::AddFileToHistory(const wxString
& file
) 
1095         m_fileHistory
->AddFileToHistory(file
); 
1098 wxString 
wxDocManager::GetHistoryFile(int i
) const 
1103         histFile 
= m_fileHistory
->GetHistoryFile(i
); 
1108 void wxDocManager::FileHistoryUseMenu(wxMenu 
*menu
) 
1111         m_fileHistory
->UseMenu(menu
); 
1114 void wxDocManager::FileHistoryRemoveMenu(wxMenu 
*menu
) 
1117         m_fileHistory
->RemoveMenu(menu
); 
1121 void wxDocManager::FileHistoryLoad(wxConfigBase
& config
) 
1124         m_fileHistory
->Load(config
); 
1127 void wxDocManager::FileHistorySave(wxConfigBase
& config
) 
1130         m_fileHistory
->Save(config
); 
1134 void wxDocManager::FileHistoryAddFilesToMenu(wxMenu
* menu
) 
1137         m_fileHistory
->AddFilesToMenu(menu
); 
1140 void wxDocManager::FileHistoryAddFilesToMenu() 
1143         m_fileHistory
->AddFilesToMenu(); 
1146 int wxDocManager::GetNoHistoryFiles() const 
1149         return m_fileHistory
->GetNoHistoryFiles(); 
1155 // Find out the document template via matching in the document file format 
1156 // against that of the template 
1157 wxDocTemplate 
*wxDocManager::FindTemplateForPath(const wxString
& path
) 
1159     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*) NULL
; 
1161     // Find the template which this extension corresponds to 
1163     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1165         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)m_templates
.Nth(i
)->Data(); 
1166         if ( temp
->FileMatchesTemplate(path
) ) 
1175 // Prompts user to open a file, using file specs in templates. 
1176 // How to implement in wxWindows? Must extend the file selector 
1177 // dialog or implement own; OR match the extension to the 
1178 // template extension. 
1180 wxDocTemplate 
*wxDocManager::SelectDocumentPath(wxDocTemplate 
**templates
, 
1184                                                 int WXUNUSED(noTemplates
), 
1187                                                 long WXUNUSED(flags
), 
1188                                                 bool WXUNUSED(save
)) 
1190     // We can only have multiple filters in Windows 
1195     for (i 
= 0; i 
< noTemplates
; i
++) 
1197         if (templates
[i
]->IsVisible()) 
1199             // add a '|' to separate this filter from the previous one 
1200             if ( !descrBuf
.IsEmpty() ) 
1201                 descrBuf 
<< _T('|'); 
1203             descrBuf 
<< templates
[i
]->GetDescription() 
1204                 << _T(" (") << templates
[i
]->GetFileFilter() << _T(") |") 
1205                 << templates
[i
]->GetFileFilter(); 
1209     wxString descrBuf 
= _T("*.*"); 
1212     int FilterIndex 
= 0; 
1213     wxString pathTmp 
= wxFileSelectorEx(_("Select a file"), 
1219                                         wxTheApp
->GetTopWindow()); 
1221     if (!pathTmp
.IsEmpty()) 
1224         wxString theExt 
= FindExtension(path
); 
1226             return (wxDocTemplate 
*) NULL
; 
1228         // This is dodgy in that we're selecting the template on the 
1229         // basis of the file extension, which may not be a standard 
1230         // one. We really want to know exactly which template was 
1231         // chosen by using a more advanced file selector. 
1232         wxDocTemplate 
*theTemplate 
= FindTemplateForPath(path
); 
1234             theTemplate 
= templates
[FilterIndex
]; 
1241         return (wxDocTemplate 
*) NULL
; 
1244     // In all other windowing systems, until we have more advanced 
1245     // file selectors, we must select the document type (template) first, and 
1246     // _then_ pop up the file selector. 
1247     wxDocTemplate 
*temp 
= SelectDocumentType(templates
, noTemplates
); 
1249         return (wxDocTemplate 
*) NULL
; 
1251     wxChar 
*pathTmp 
= wxFileSelector(_("Select a file"), _T(""), _T(""), 
1252             temp
->GetDefaultExtension(), 
1253             temp
->GetFileFilter(), 
1254             0, wxTheApp
->GetTopWindow()); 
1262         return (wxDocTemplate 
*) NULL
; 
1266 wxDocTemplate 
*wxDocManager::SelectDocumentType(wxDocTemplate 
**templates
, 
1269     wxChar 
**strings 
= new wxChar 
*[noTemplates
]; 
1270     wxChar 
**data 
= new wxChar 
*[noTemplates
]; 
1273     for (i 
= 0; i 
< noTemplates
; i
++) 
1275         if (templates
[i
]->IsVisible()) 
1277             strings
[n
] = WXSTRINGCAST templates
[i
]->m_description
; 
1278             data
[n
] = (wxChar 
*)templates
[i
]; 
1286         return (wxDocTemplate 
*) NULL
; 
1290         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)data
[0]; 
1296     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData(_("Select a document template"), _("Templates"), n
, 
1297             strings
, (char **)data
); 
1303 wxDocTemplate 
*wxDocManager::SelectViewType(wxDocTemplate 
**templates
, 
1306     wxChar 
**strings 
= new wxChar 
*[noTemplates
]; 
1307     wxChar 
**data 
= new wxChar 
*[noTemplates
]; 
1310     for (i 
= 0; i 
< noTemplates
; i
++) 
1312         if (templates
[i
]->IsVisible() && (templates
[i
]->GetViewName() != _T(""))) 
1314             strings
[n
] = WXSTRINGCAST templates
[i
]->m_viewTypeName
; 
1315             data
[n
] = (wxChar 
*)templates
[i
]; 
1319     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData(_("Select a document view"), _("Views"), n
, 
1320             strings
, (char **)data
); 
1326 void wxDocManager::AssociateTemplate(wxDocTemplate 
*temp
) 
1328     if (!m_templates
.Member(temp
)) 
1329         m_templates
.Append(temp
); 
1332 void wxDocManager::DisassociateTemplate(wxDocTemplate 
*temp
) 
1334     m_templates
.DeleteObject(temp
); 
1337 // Add and remove a document from the manager's list 
1338 void wxDocManager::AddDocument(wxDocument 
*doc
) 
1340     if (!m_docs
.Member(doc
)) 
1344 void wxDocManager::RemoveDocument(wxDocument 
*doc
) 
1346     m_docs
.DeleteObject(doc
); 
1349 // Views or windows should inform the document manager 
1350 // when a view is going in or out of focus 
1351 void wxDocManager::ActivateView(wxView 
*view
, bool activate
, bool WXUNUSED(deleting
)) 
1353     // If we're deactiving, and if we're not actually deleting the view, then 
1354     // don't reset the current view because we may be going to 
1355     // a window without a view. 
1356     // WHAT DID I MEAN BY THAT EXACTLY? 
1360        if (m_currentView == view) 
1361        m_currentView = NULL; 
1367             m_currentView 
= view
; 
1369             m_currentView 
= (wxView 
*) NULL
; 
1373 // ---------------------------------------------------------------------------- 
1374 // Default document child frame 
1375 // ---------------------------------------------------------------------------- 
1377 BEGIN_EVENT_TABLE(wxDocChildFrame
, wxFrame
) 
1378     EVT_ACTIVATE(wxDocChildFrame::OnActivate
) 
1379     EVT_CLOSE(wxDocChildFrame::OnCloseWindow
) 
1382 wxDocChildFrame::wxDocChildFrame(wxDocument 
*doc
, 
1386                                  const wxString
& title
, 
1390                                  const wxString
& name
) 
1391                : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1393     m_childDocument 
= doc
; 
1396         view
->SetFrame(this); 
1399 wxDocChildFrame::~wxDocChildFrame() 
1403 // Extend event processing to search the view's event table 
1404 bool wxDocChildFrame::ProcessEvent(wxEvent
& event
) 
1407         m_childView
->Activate(TRUE
); 
1409     if ( !m_childView 
|| ! m_childView
->ProcessEvent(event
) ) 
1411         // Only hand up to the parent if it's a menu command 
1412         if (!event
.IsKindOf(CLASSINFO(wxCommandEvent
)) || !GetParent() || !GetParent()->ProcessEvent(event
)) 
1413             return wxEvtHandler::ProcessEvent(event
); 
1421 void wxDocChildFrame::OnActivate(wxActivateEvent
& event
) 
1423     wxFrame::OnActivate(event
); 
1426         m_childView
->Activate(event
.GetActive()); 
1429 void wxDocChildFrame::OnCloseWindow(wxCloseEvent
& event
) 
1434         if (!event
.CanVeto()) 
1435             ans 
= TRUE
; // Must delete. 
1437             ans 
= m_childView
->Close(FALSE
); // FALSE means don't delete associated window 
1441             m_childView
->Activate(FALSE
); 
1443             m_childView 
= (wxView 
*) NULL
; 
1444             m_childDocument 
= (wxDocument 
*) NULL
; 
1455 // ---------------------------------------------------------------------------- 
1456 // Default parent frame 
1457 // ---------------------------------------------------------------------------- 
1459 BEGIN_EVENT_TABLE(wxDocParentFrame
, wxFrame
) 
1460     EVT_MENU(wxID_EXIT
, wxDocParentFrame::OnExit
) 
1461     EVT_MENU_RANGE(wxID_FILE1
, wxID_FILE9
, wxDocParentFrame::OnMRUFile
) 
1462     EVT_CLOSE(wxDocParentFrame::OnCloseWindow
) 
1465 wxDocParentFrame::wxDocParentFrame(wxDocManager 
*manager
, 
1468                                    const wxString
& title
, 
1472                                    const wxString
& name
) 
1473                 : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1475     m_docManager 
= manager
; 
1478 void wxDocParentFrame::OnExit(wxCommandEvent
& WXUNUSED(event
)) 
1483 void wxDocParentFrame::OnMRUFile(wxCommandEvent
& event
) 
1485     wxString 
f(m_docManager
->GetHistoryFile(event
.GetSelection() - wxID_FILE1
)); 
1487         (void)m_docManager
->CreateDocument(f
, wxDOC_SILENT
); 
1490 // Extend event processing to search the view's event table 
1491 bool wxDocParentFrame::ProcessEvent(wxEvent
& event
) 
1493     // Try the document manager, then do default processing 
1494     if (!m_docManager 
|| !m_docManager
->ProcessEvent(event
)) 
1495         return wxEvtHandler::ProcessEvent(event
); 
1500 // Define the behaviour for the frame closing 
1501 // - must delete all frames except for the main one. 
1502 void wxDocParentFrame::OnCloseWindow(wxCloseEvent
& event
) 
1504     if (m_docManager
->Clear(!event
.CanVeto())) 
1512 #if wxUSE_PRINTING_ARCHITECTURE 
1514 wxDocPrintout::wxDocPrintout(wxView 
*view
, const wxString
& title
) 
1515              : wxPrintout(WXSTRINGCAST title
) 
1517     m_printoutView 
= view
; 
1520 bool wxDocPrintout::OnPrintPage(int WXUNUSED(page
)) 
1524     // Get the logical pixels per inch of screen and printer 
1525     int ppiScreenX
, ppiScreenY
; 
1526     GetPPIScreen(&ppiScreenX
, &ppiScreenY
); 
1527     int ppiPrinterX
, ppiPrinterY
; 
1528     GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
); 
1530     // This scales the DC so that the printout roughly represents the 
1531     // the screen scaling. The text point size _should_ be the right size 
1532     // but in fact is too small for some reason. This is a detail that will 
1533     // need to be addressed at some point but can be fudged for the 
1535     float scale 
= (float)((float)ppiPrinterX
/(float)ppiScreenX
); 
1537     // Now we have to check in case our real page size is reduced 
1538     // (e.g. because we're drawing to a print preview memory DC) 
1539     int pageWidth
, pageHeight
; 
1541     dc
->GetSize(&w
, &h
); 
1542     GetPageSizePixels(&pageWidth
, &pageHeight
); 
1544     // If printer pageWidth == current DC width, then this doesn't 
1545     // change. But w might be the preview bitmap width, so scale down. 
1546     float overallScale 
= scale 
* (float)(w
/(float)pageWidth
); 
1547     dc
->SetUserScale(overallScale
, overallScale
); 
1551         m_printoutView
->OnDraw(dc
); 
1556 bool wxDocPrintout::HasPage(int pageNum
) 
1558     return (pageNum 
== 1); 
1561 bool wxDocPrintout::OnBeginDocument(int startPage
, int endPage
) 
1563     if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) 
1569 void wxDocPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
) 
1577 #endif // wxUSE_PRINTING_ARCHITECTURE 
1579 // ---------------------------------------------------------------------------- 
1580 // Command processing framework 
1581 // ---------------------------------------------------------------------------- 
1583 wxCommand::wxCommand(bool canUndoIt
, const wxString
& name
) 
1585     m_canUndo 
= canUndoIt
; 
1586     m_commandName 
= name
; 
1589 wxCommand::~wxCommand() 
1593 // Command processor 
1594 wxCommandProcessor::wxCommandProcessor(int maxCommands
) 
1596     m_maxNoCommands 
= maxCommands
; 
1597     m_currentCommand 
= (wxNode 
*) NULL
; 
1598     m_commandEditMenu 
= (wxMenu 
*) NULL
; 
1601 wxCommandProcessor::~wxCommandProcessor() 
1606 // Pass a command to the processor. The processor calls Do(); 
1607 // if successful, is appended to the command history unless 
1608 // storeIt is FALSE. 
1609 bool wxCommandProcessor::Submit(wxCommand 
*command
, bool storeIt
) 
1611     bool success 
= command
->Do(); 
1612     if (success 
&& storeIt
) 
1614         if (m_commands
.Number() == m_maxNoCommands
) 
1616             wxNode 
*firstNode 
= m_commands
.First(); 
1617             wxCommand 
*firstCommand 
= (wxCommand 
*)firstNode
->Data(); 
1618             delete firstCommand
; 
1622         // Correct a bug: we must chop off the current 'branch' 
1623         // so that we're at the end of the command list. 
1624         if (!m_currentCommand
) 
1628             wxNode 
*node 
= m_currentCommand
->Next(); 
1631                 wxNode 
*next 
= node
->Next(); 
1632                 delete (wxCommand 
*)node
->Data(); 
1638         m_commands
.Append(command
); 
1639         m_currentCommand 
= m_commands
.Last(); 
1645 bool wxCommandProcessor::Undo() 
1647     if (m_currentCommand
) 
1649         wxCommand 
*command 
= (wxCommand 
*)m_currentCommand
->Data(); 
1650         if (command
->CanUndo()) 
1652             bool success 
= command
->Undo(); 
1655                 m_currentCommand 
= m_currentCommand
->Previous(); 
1664 bool wxCommandProcessor::Redo() 
1666     wxCommand 
*redoCommand 
= (wxCommand 
*) NULL
; 
1667     wxNode 
*redoNode 
= (wxNode 
*) NULL
; 
1668     if (m_currentCommand 
&& m_currentCommand
->Next()) 
1670         redoCommand 
= (wxCommand 
*)m_currentCommand
->Next()->Data(); 
1671         redoNode 
= m_currentCommand
->Next(); 
1675         if (m_commands
.Number() > 0) 
1677             redoCommand 
= (wxCommand 
*)m_commands
.First()->Data(); 
1678             redoNode 
= m_commands
.First(); 
1684         bool success 
= redoCommand
->Do(); 
1687             m_currentCommand 
= redoNode
; 
1695 bool wxCommandProcessor::CanUndo() const 
1697     if (m_currentCommand
) 
1698         return ((wxCommand 
*)m_currentCommand
->Data())->CanUndo(); 
1702 bool wxCommandProcessor::CanRedo() const 
1704     if ((m_currentCommand 
!= (wxNode
*) NULL
) && (m_currentCommand
->Next() == (wxNode
*) NULL
)) 
1707     if ((m_currentCommand 
!= (wxNode
*) NULL
) && (m_currentCommand
->Next() != (wxNode
*) NULL
)) 
1710     if ((m_currentCommand 
== (wxNode
*) NULL
) && (m_commands
.Number() > 0)) 
1716 void wxCommandProcessor::Initialize() 
1718     m_currentCommand 
= m_commands
.Last(); 
1722 void wxCommandProcessor::SetMenuStrings() 
1724     if (m_commandEditMenu
) 
1727         if (m_currentCommand
) 
1729             wxCommand 
*command 
= (wxCommand 
*)m_currentCommand
->Data(); 
1730             wxString 
commandName(command
->GetName()); 
1731             if (commandName 
== _T("")) commandName 
= _("Unnamed command"); 
1732             bool canUndo 
= command
->CanUndo(); 
1734                 buf 
= wxString(_("&Undo ")) + commandName
; 
1736                 buf 
= wxString(_("Can't &Undo ")) + commandName
; 
1738             m_commandEditMenu
->SetLabel(wxID_UNDO
, buf
); 
1739             m_commandEditMenu
->Enable(wxID_UNDO
, canUndo
); 
1741             // We can redo, if we're not at the end of the history. 
1742             if (m_currentCommand
->Next()) 
1744                 wxCommand 
*redoCommand 
= (wxCommand 
*)m_currentCommand
->Next()->Data(); 
1745                 wxString 
redoCommandName(redoCommand
->GetName()); 
1746                 if (redoCommandName 
== _T("")) redoCommandName 
= _("Unnamed command"); 
1747                 buf 
= wxString(_("&Redo ")) + redoCommandName
; 
1748                 m_commandEditMenu
->SetLabel(wxID_REDO
, buf
); 
1749                 m_commandEditMenu
->Enable(wxID_REDO
, TRUE
); 
1753                 m_commandEditMenu
->SetLabel(wxID_REDO
, _("&Redo")); 
1754                 m_commandEditMenu
->Enable(wxID_REDO
, FALSE
); 
1759             m_commandEditMenu
->SetLabel(wxID_UNDO
, _("&Undo")); 
1760             m_commandEditMenu
->Enable(wxID_UNDO
, FALSE
); 
1762             if (m_commands
.Number() == 0) 
1764                 m_commandEditMenu
->SetLabel(wxID_REDO
, _("&Redo")); 
1765                 m_commandEditMenu
->Enable(wxID_REDO
, FALSE
); 
1769                 // currentCommand is NULL but there are commands: this means that 
1770                 // we've undone to the start of the list, but can redo the first. 
1771                 wxCommand 
*redoCommand 
= (wxCommand 
*)m_commands
.First()->Data(); 
1772                 wxString 
redoCommandName(redoCommand
->GetName()); 
1773                 if (redoCommandName 
== _T("")) redoCommandName 
= _("Unnamed command"); 
1774                 buf 
= wxString(_("&Redo ")) + redoCommandName
; 
1775                 m_commandEditMenu
->SetLabel(wxID_REDO
, buf
); 
1776                 m_commandEditMenu
->Enable(wxID_REDO
, TRUE
); 
1782 void wxCommandProcessor::ClearCommands() 
1784     wxNode 
*node 
= m_commands
.First(); 
1787         wxCommand 
*command 
= (wxCommand 
*)node
->Data(); 
1790         node 
= m_commands
.First(); 
1792     m_currentCommand 
= (wxNode 
*) NULL
; 
1795 // ---------------------------------------------------------------------------- 
1796 // File history processor 
1797 // ---------------------------------------------------------------------------- 
1799 wxFileHistory::wxFileHistory(int maxFiles
) 
1801     m_fileMaxFiles 
= maxFiles
; 
1803     m_fileHistory 
= new wxChar 
*[m_fileMaxFiles
]; 
1806 wxFileHistory::~wxFileHistory() 
1809     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1810         delete[] m_fileHistory
[i
]; 
1811     delete[] m_fileHistory
; 
1814 // File history management 
1815 void wxFileHistory::AddFileToHistory(const wxString
& file
) 
1818     // Check we don't already have this file 
1819     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1821         if (m_fileHistory
[i
] && wxString(m_fileHistory
[i
]) == file
) 
1825     // Add to the project file history: 
1826     // Move existing files (if any) down so we can insert file at beginning. 
1828     // First delete filename that has popped off the end of the array (if any) 
1829     if (m_fileHistoryN 
== m_fileMaxFiles
) 
1831         delete[] m_fileHistory
[m_fileMaxFiles
-1]; 
1832         m_fileHistory
[m_fileMaxFiles
-1] = (wxChar 
*) NULL
; 
1834     if (m_fileHistoryN 
< m_fileMaxFiles
) 
1836         wxNode
* node 
= m_fileMenus
.First(); 
1839             wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1840             if (m_fileHistoryN 
== 0) 
1841                 menu
->AppendSeparator(); 
1842             menu
->Append(wxID_FILE1
+m_fileHistoryN
, _("[EMPTY]")); 
1843             node 
= node
->Next(); 
1847     // Shuffle filenames down 
1848     for (i 
= (m_fileHistoryN
-1); i 
> 0; i
--) 
1850         m_fileHistory
[i
] = m_fileHistory
[i
-1]; 
1852     m_fileHistory
[0] = copystring(file
); 
1854     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1855         if (m_fileHistory
[i
]) 
1858             buf
.Printf(_T("&%d %s"), i
+1, m_fileHistory
[i
]); 
1859             wxNode
* node 
= m_fileMenus
.First(); 
1862                 wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1863                 menu
->SetLabel(wxID_FILE1
+i
, buf
); 
1864                 node 
= node
->Next(); 
1869 wxString 
wxFileHistory::GetHistoryFile(int i
) const 
1871     if (i 
< m_fileHistoryN
) 
1872         return wxString(m_fileHistory
[i
]); 
1874         return wxString(""); 
1877 void wxFileHistory::UseMenu(wxMenu 
*menu
) 
1879     if (!m_fileMenus
.Member(menu
)) 
1880         m_fileMenus
.Append(menu
); 
1883 void wxFileHistory::RemoveMenu(wxMenu 
*menu
) 
1885     m_fileMenus
.DeleteObject(menu
); 
1889 void wxFileHistory::Load(wxConfigBase
& config
) 
1893     buf
.Printf(_T("file%d"), m_fileHistoryN
+1); 
1894     wxString historyFile
; 
1895     while ((m_fileHistoryN 
<= m_fileMaxFiles
) && config
.Read(buf
, &historyFile
) && (historyFile 
!= _T(""))) 
1897         m_fileHistory
[m_fileHistoryN
] = copystring((const wxChar
*) historyFile
); 
1899         buf
.Printf(_T("file%d"), m_fileHistoryN
+1); 
1905 void wxFileHistory::Save(wxConfigBase
& config
) 
1908     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1911         buf
.Printf(_T("file%d"), i
+1); 
1912         config
.Write(buf
, wxString(m_fileHistory
[i
])); 
1915 #endif // wxUSE_CONFIG 
1917 void wxFileHistory::AddFilesToMenu() 
1919     if (m_fileHistoryN 
> 0) 
1921         wxNode
* node 
= m_fileMenus
.First(); 
1924             wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1925             menu
->AppendSeparator(); 
1927             for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1929                 if (m_fileHistory
[i
]) 
1932                     buf
.Printf(_T("&%d %s"), i
+1, m_fileHistory
[i
]); 
1933                     menu
->Append(wxID_FILE1
+i
, buf
); 
1936             node 
= node
->Next(); 
1941 void wxFileHistory::AddFilesToMenu(wxMenu
* menu
) 
1943     if (m_fileHistoryN 
> 0) 
1945         menu
->AppendSeparator(); 
1947         for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1949             if (m_fileHistory
[i
]) 
1952                 buf
.Printf(_T("&%d %s"), i
+1, m_fileHistory
[i
]); 
1953                 menu
->Append(wxID_FILE1
+i
, buf
); 
1959 // ---------------------------------------------------------------------------- 
1960 // Permits compatibility with existing file formats and functions that 
1961 // manipulate files directly 
1962 // ---------------------------------------------------------------------------- 
1964 #if wxUSE_STD_IOSTREAM 
1965 bool wxTransferFileToStream(const wxString
& filename
, ostream
& stream
) 
1970     if ((fd1 
= fopen (filename
.fn_str(), "rb")) == NULL
) 
1973     while ((ch 
= getc (fd1
)) != EOF
) 
1974         stream 
<< (unsigned char)ch
; 
1980 bool wxTransferStreamToFile(istream
& stream
, const wxString
& filename
) 
1985     if ((fd1 
= fopen (filename
.fn_str(), "wb")) == NULL
) 
1990     while (!stream
.eof()) 
2001 #endif // wxUSE_DOC_VIEW_ARCHITECTURE