1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/docview.cpp 
   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     #include "wx/filename.h" 
  56 #if wxUSE_PRINTING_ARCHITECTURE 
  57   #include "wx/prntbase.h" 
  58   #include "wx/printdlg.h" 
  61 #include "wx/msgdlg.h" 
  62 #include "wx/choicdlg.h" 
  63 #include "wx/docview.h" 
  64 #include "wx/confbase.h" 
  66 #include "wx/cmdproc.h" 
  71 #if wxUSE_STD_IOSTREAM 
  72   #include "wx/ioswrap.h" 
  79   #include "wx/wfstream.h" 
  82 // ---------------------------------------------------------------------------- 
  84 // ---------------------------------------------------------------------------- 
  86 IMPLEMENT_ABSTRACT_CLASS(wxDocument
, wxEvtHandler
) 
  87 IMPLEMENT_ABSTRACT_CLASS(wxView
, wxEvtHandler
) 
  88 IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate
, wxObject
) 
  89 IMPLEMENT_DYNAMIC_CLASS(wxDocManager
, wxEvtHandler
) 
  90 IMPLEMENT_CLASS(wxDocChildFrame
, wxFrame
) 
  91 IMPLEMENT_CLASS(wxDocParentFrame
, wxFrame
) 
  93 #if wxUSE_PRINTING_ARCHITECTURE 
  94     IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout
, wxPrintout
) 
  97 IMPLEMENT_DYNAMIC_CLASS(wxFileHistory
, wxObject
) 
  99 // ---------------------------------------------------------------------------- 
 100 // function prototypes 
 101 // ---------------------------------------------------------------------------- 
 103 static inline wxString 
FindExtension(const wxChar 
*path
); 
 105 // ---------------------------------------------------------------------------- 
 107 // ---------------------------------------------------------------------------- 
 109 static const wxChar 
*s_MRUEntryFormat 
= wxT("&%d %s"); 
 111 // ============================================================================ 
 113 // ============================================================================ 
 115 // ---------------------------------------------------------------------------- 
 117 // ---------------------------------------------------------------------------- 
 119 static wxString 
FindExtension(const wxChar 
*path
) 
 122     wxSplitPath(path
, NULL
, NULL
, &ext
); 
 124     // VZ: extensions are considered not case sensitive - is this really a good 
 126     return ext
.MakeLower(); 
 129 // ---------------------------------------------------------------------------- 
 130 // Definition of wxDocument 
 131 // ---------------------------------------------------------------------------- 
 133 wxDocument::wxDocument(wxDocument 
*parent
) 
 135     m_documentModified 
= FALSE
; 
 136     m_documentParent 
= parent
; 
 137     m_documentTemplate 
= (wxDocTemplate 
*) NULL
; 
 138     m_commandProcessor 
= (wxCommandProcessor
*) NULL
; 
 142 bool wxDocument::DeleteContents() 
 147 wxDocument::~wxDocument() 
 151     if (m_commandProcessor
) 
 152         delete m_commandProcessor
; 
 154     if (GetDocumentManager()) 
 155         GetDocumentManager()->RemoveDocument(this); 
 157     // Not safe to do here, since it'll invoke virtual view functions 
 158     // expecting to see valid derived objects: and by the time we get here, 
 159     // we've called destructors higher up. 
 163 bool wxDocument::Close() 
 165     if (OnSaveModified()) 
 166         return OnCloseDocument(); 
 171 bool wxDocument::OnCloseDocument() 
 173     // Tell all views that we're about to close 
 180 // Note that this implicitly deletes the document when the last view is 
 182 bool wxDocument::DeleteAllViews() 
 184     wxDocManager
* manager 
= GetDocumentManager(); 
 186     wxNode 
*node 
= m_documentViews
.GetFirst(); 
 189         wxView 
*view 
= (wxView 
*)node
->GetData(); 
 193         wxNode 
*next 
= node
->GetNext(); 
 195         delete view
; // Deletes node implicitly 
 198     // If we haven't yet deleted the document (for example 
 199     // if there were no views) then delete it. 
 200     if (manager 
&& manager
->GetDocuments().Member(this)) 
 206 wxView 
*wxDocument::GetFirstView() const 
 208     if (m_documentViews
.GetCount() == 0) 
 209         return (wxView 
*) NULL
; 
 210     return (wxView 
*)m_documentViews
.GetFirst()->GetData(); 
 213 wxDocManager 
*wxDocument::GetDocumentManager() const 
 215     return (m_documentTemplate 
? m_documentTemplate
->GetDocumentManager() : (wxDocManager
*) NULL
); 
 218 bool wxDocument::OnNewDocument() 
 220     if (!OnSaveModified()) 
 223     if (OnCloseDocument()==FALSE
) return FALSE
; 
 226     SetDocumentSaved(FALSE
); 
 229     GetDocumentManager()->MakeDefaultName(name
); 
 231     SetFilename(name
, TRUE
); 
 236 bool wxDocument::Save() 
 238     if (!IsModified() && m_savedYet
) 
 241     if ( m_documentFile
.empty() || !m_savedYet 
) 
 244     return OnSaveDocument(m_documentFile
); 
 247 bool wxDocument::SaveAs() 
 249     wxDocTemplate 
*docTemplate 
= GetDocumentTemplate(); 
 253     wxString tmp 
= wxFileSelector(_("Save as"), 
 254             docTemplate
->GetDirectory(), 
 255             wxFileNameFromPath(GetFilename()), 
 256             docTemplate
->GetDefaultExtension(), 
 257             docTemplate
->GetFileFilter(), 
 258             wxSAVE 
| wxOVERWRITE_PROMPT
, 
 259             GetDocumentWindow()); 
 264     wxString 
fileName(tmp
); 
 265     wxString path
, name
, ext
; 
 266     wxSplitPath(fileName
, & path
, & name
, & ext
); 
 268     if (ext
.IsEmpty() || ext 
== wxT("")) 
 270         fileName 
+= wxT("."); 
 271         fileName 
+= docTemplate
->GetDefaultExtension(); 
 274     SetFilename(fileName
); 
 275     SetTitle(wxFileNameFromPath(fileName
)); 
 277     GetDocumentManager()->AddFileToHistory(fileName
); 
 279     // Notify the views that the filename has changed 
 280     wxNode 
*node 
= m_documentViews
.GetFirst(); 
 283         wxView 
*view 
= (wxView 
*)node
->GetData(); 
 284         view
->OnChangeFilename(); 
 285         node 
= node
->GetNext(); 
 288     return OnSaveDocument(m_documentFile
); 
 291 bool wxDocument::OnSaveDocument(const wxString
& file
) 
 297     if (wxTheApp
->GetAppName() != wxT("")) 
 298         msgTitle 
= wxTheApp
->GetAppName(); 
 300         msgTitle 
= wxString(_("File error")); 
 302 #if wxUSE_STD_IOSTREAM 
 303     wxSTD ofstream 
store(file
.mb_str()); 
 304     if (store
.fail() || store
.bad()) 
 306     wxFileOutputStream 
store(file
); 
 307     if (store
.GetLastError() != wxSTREAM_NO_ERROR
) 
 310         (void)wxMessageBox(_("Sorry, could not open this file for saving."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 311                            GetDocumentWindow()); 
 315     if (!SaveObject(store
)) 
 317         (void)wxMessageBox(_("Sorry, could not save this file."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 318                            GetDocumentWindow()); 
 324     SetDocumentSaved(TRUE
); 
 326     wxFileName 
fn(file
) ; 
 327     fn
.MacSetDefaultTypeAndCreator() ; 
 332 bool wxDocument::OnOpenDocument(const wxString
& file
) 
 334     if (!OnSaveModified()) 
 338     if (wxTheApp
->GetAppName() != wxT("")) 
 339         msgTitle 
= wxTheApp
->GetAppName(); 
 341         msgTitle 
= wxString(_("File error")); 
 343 #if wxUSE_STD_IOSTREAM 
 344     wxSTD ifstream 
store(file
.mb_str()); 
 345     if (store
.fail() || store
.bad()) 
 347     wxFileInputStream 
store(file
); 
 348     if (store
.GetLastError() != wxSTREAM_NO_ERROR
) 
 351         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 352                            GetDocumentWindow()); 
 355 #if wxUSE_STD_IOSTREAM 
 357     if ( !store 
&& !store
.eof() ) 
 359     int res 
= LoadObject(store
).GetLastError(); 
 360     if ((res 
!= wxSTREAM_NO_ERROR
) && 
 361         (res 
!= wxSTREAM_EOF
)) 
 364         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 365                            GetDocumentWindow()); 
 368     SetFilename(file
, TRUE
); 
 377 #if wxUSE_STD_IOSTREAM 
 378 wxSTD istream
& wxDocument::LoadObject(wxSTD istream
& stream
) 
 380 wxInputStream
& wxDocument::LoadObject(wxInputStream
& stream
) 
 386 #if wxUSE_STD_IOSTREAM 
 387 wxSTD ostream
& wxDocument::SaveObject(wxSTD ostream
& stream
) 
 389 wxOutputStream
& wxDocument::SaveObject(wxOutputStream
& stream
) 
 395 bool wxDocument::Revert() 
 401 // Get title, or filename if no title, else unnamed 
 402 bool wxDocument::GetPrintableName(wxString
& buf
) const 
 404     if (m_documentTitle 
!= wxT("")) 
 406         buf 
= m_documentTitle
; 
 409     else if (m_documentFile 
!= wxT("")) 
 411         buf 
= wxFileNameFromPath(m_documentFile
); 
 421 wxWindow 
*wxDocument::GetDocumentWindow() const 
 423     wxView 
*view 
= GetFirstView(); 
 425         return view
->GetFrame(); 
 427         return wxTheApp
->GetTopWindow(); 
 430 wxCommandProcessor 
*wxDocument::OnCreateCommandProcessor() 
 432     return new wxCommandProcessor
; 
 435 // TRUE if safe to close 
 436 bool wxDocument::OnSaveModified() 
 441         GetPrintableName(title
); 
 444         if (wxTheApp
->GetAppName() != wxT("")) 
 445             msgTitle 
= wxTheApp
->GetAppName(); 
 447             msgTitle 
= wxString(_("Warning")); 
 450         prompt
.Printf(_("Do you want to save changes to document %s?"), 
 451                 (const wxChar 
*)title
); 
 452         int res 
= wxMessageBox(prompt
, msgTitle
, 
 453                 wxYES_NO
|wxCANCEL
|wxICON_QUESTION
, 
 454                 GetDocumentWindow()); 
 460         else if (res 
== wxYES
) 
 462         else if (res 
== wxCANCEL
) 
 468 bool wxDocument::Draw(wxDC
& WXUNUSED(context
)) 
 473 bool wxDocument::AddView(wxView 
*view
) 
 475     if (!m_documentViews
.Member(view
)) 
 477         m_documentViews
.Append(view
); 
 483 bool wxDocument::RemoveView(wxView 
*view
) 
 485     (void)m_documentViews
.DeleteObject(view
); 
 490 bool wxDocument::OnCreate(const wxString
& WXUNUSED(path
), long flags
) 
 492     if (GetDocumentTemplate()->CreateView(this, flags
)) 
 498 // Called after a view is added or removed. 
 499 // The default implementation deletes the document if 
 500 // there are no more views. 
 501 void wxDocument::OnChangedViewList() 
 503     if (m_documentViews
.GetCount() == 0) 
 505         if (OnSaveModified()) 
 512 void wxDocument::UpdateAllViews(wxView 
*sender
, wxObject 
*hint
) 
 514     wxNode 
*node 
= m_documentViews
.GetFirst(); 
 517         wxView 
*view 
= (wxView 
*)node
->GetData(); 
 519             view
->OnUpdate(sender
, hint
); 
 520         node 
= node
->GetNext(); 
 524 void wxDocument::NotifyClosing() 
 526     wxNode 
*node 
= m_documentViews
.GetFirst(); 
 529         wxView 
*view 
= (wxView 
*)node
->GetData(); 
 530         view
->OnClosingDocument(); 
 531         node 
= node
->GetNext(); 
 535 void wxDocument::SetFilename(const wxString
& filename
, bool notifyViews
) 
 537     m_documentFile 
= filename
; 
 540         // Notify the views that the filename has changed 
 541         wxNode 
*node 
= m_documentViews
.GetFirst(); 
 544             wxView 
*view 
= (wxView 
*)node
->GetData(); 
 545             view
->OnChangeFilename(); 
 546             node 
= node
->GetNext(); 
 551 // ---------------------------------------------------------------------------- 
 553 // ---------------------------------------------------------------------------- 
 558     m_viewDocument 
= (wxDocument
*) NULL
; 
 560     m_viewTypeName 
= wxT(""); 
 561     m_viewFrame 
= (wxFrame 
*) NULL
; 
 566 //    GetDocumentManager()->ActivateView(this, FALSE, TRUE); 
 567     m_viewDocument
->RemoveView(this); 
 570 // Extend event processing to search the document's event table 
 571 bool wxView::ProcessEvent(wxEvent
& event
) 
 573     if ( !GetDocument() || !GetDocument()->ProcessEvent(event
) ) 
 574         return wxEvtHandler::ProcessEvent(event
); 
 579 void wxView::OnActivateView(bool WXUNUSED(activate
), wxView 
*WXUNUSED(activeView
), wxView 
*WXUNUSED(deactiveView
)) 
 583 void wxView::OnPrint(wxDC 
*dc
, wxObject 
*WXUNUSED(info
)) 
 588 void wxView::OnUpdate(wxView 
*WXUNUSED(sender
), wxObject 
*WXUNUSED(hint
)) 
 592 void wxView::OnChangeFilename() 
 594     if (GetFrame() && GetDocument()) 
 598         GetDocument()->GetPrintableName(title
); 
 600         GetFrame()->SetTitle(title
); 
 604 void wxView::SetDocument(wxDocument 
*doc
) 
 606     m_viewDocument 
= doc
; 
 611 bool wxView::Close(bool deleteWindow
) 
 613     if (OnClose(deleteWindow
)) 
 619 void wxView::Activate(bool activate
) 
 621     if (GetDocument() && GetDocumentManager()) 
 623         OnActivateView(activate
, this, GetDocumentManager()->GetCurrentView()); 
 624         GetDocumentManager()->ActivateView(this, activate
); 
 628 bool wxView::OnClose(bool WXUNUSED(deleteWindow
)) 
 630     return GetDocument() ? GetDocument()->Close() : TRUE
; 
 633 #if wxUSE_PRINTING_ARCHITECTURE 
 634 wxPrintout 
*wxView::OnCreatePrintout() 
 636     return new wxDocPrintout(this); 
 638 #endif // wxUSE_PRINTING_ARCHITECTURE 
 640 // ---------------------------------------------------------------------------- 
 642 // ---------------------------------------------------------------------------- 
 644 wxDocTemplate::wxDocTemplate(wxDocManager 
*manager
, 
 645                              const wxString
& descr
, 
 646                              const wxString
& filter
, 
 649                              const wxString
& docTypeName
, 
 650                              const wxString
& viewTypeName
, 
 651                              wxClassInfo 
*docClassInfo
, 
 652                              wxClassInfo 
*viewClassInfo
, 
 655     m_documentManager 
= manager
; 
 656     m_description 
= descr
; 
 659     m_fileFilter 
= filter
; 
 661     m_docTypeName 
= docTypeName
; 
 662     m_viewTypeName 
= viewTypeName
; 
 663     m_documentManager
->AssociateTemplate(this); 
 665     m_docClassInfo 
= docClassInfo
; 
 666     m_viewClassInfo 
= viewClassInfo
; 
 669 wxDocTemplate::~wxDocTemplate() 
 671     m_documentManager
->DisassociateTemplate(this); 
 674 // Tries to dynamically construct an object of the right class. 
 675 wxDocument 
*wxDocTemplate::CreateDocument(const wxString
& path
, long flags
) 
 678         return (wxDocument 
*) NULL
; 
 679     wxDocument 
*doc 
= (wxDocument 
*)m_docClassInfo
->CreateObject(); 
 680     doc
->SetFilename(path
); 
 681     doc
->SetDocumentTemplate(this); 
 682     GetDocumentManager()->AddDocument(doc
); 
 683     doc
->SetCommandProcessor(doc
->OnCreateCommandProcessor()); 
 685     if (doc
->OnCreate(path
, flags
)) 
 689         if (GetDocumentManager()->GetDocuments().Member(doc
)) 
 690             doc
->DeleteAllViews(); 
 691         return (wxDocument 
*) NULL
; 
 695 wxView 
*wxDocTemplate::CreateView(wxDocument 
*doc
, long flags
) 
 697     if (!m_viewClassInfo
) 
 698         return (wxView 
*) NULL
; 
 699     wxView 
*view 
= (wxView 
*)m_viewClassInfo
->CreateObject(); 
 700     view
->SetDocument(doc
); 
 701     if (view
->OnCreate(doc
, flags
)) 
 708         return (wxView 
*) NULL
; 
 712 // The default (very primitive) format detection: check is the extension is 
 713 // that of the template 
 714 bool wxDocTemplate::FileMatchesTemplate(const wxString
& path
) 
 716     return GetDefaultExtension().IsSameAs(FindExtension(path
)); 
 719 // ---------------------------------------------------------------------------- 
 721 // ---------------------------------------------------------------------------- 
 723 BEGIN_EVENT_TABLE(wxDocManager
, wxEvtHandler
) 
 724     EVT_MENU(wxID_OPEN
, wxDocManager::OnFileOpen
) 
 725     EVT_MENU(wxID_CLOSE
, wxDocManager::OnFileClose
) 
 726     EVT_MENU(wxID_CLOSE_ALL
, wxDocManager::OnFileCloseAll
) 
 727     EVT_MENU(wxID_REVERT
, wxDocManager::OnFileRevert
) 
 728     EVT_MENU(wxID_NEW
, wxDocManager::OnFileNew
) 
 729     EVT_MENU(wxID_SAVE
, wxDocManager::OnFileSave
) 
 730     EVT_MENU(wxID_SAVEAS
, wxDocManager::OnFileSaveAs
) 
 731     EVT_MENU(wxID_UNDO
, wxDocManager::OnUndo
) 
 732     EVT_MENU(wxID_REDO
, wxDocManager::OnRedo
) 
 734     EVT_UPDATE_UI(wxID_OPEN
, wxDocManager::OnUpdateFileOpen
) 
 735     EVT_UPDATE_UI(wxID_CLOSE
, wxDocManager::OnUpdateFileClose
) 
 736     EVT_UPDATE_UI(wxID_CLOSE_ALL
, wxDocManager::OnUpdateFileClose
) 
 737     EVT_UPDATE_UI(wxID_REVERT
, wxDocManager::OnUpdateFileRevert
) 
 738     EVT_UPDATE_UI(wxID_NEW
, wxDocManager::OnUpdateFileNew
) 
 739     EVT_UPDATE_UI(wxID_SAVE
, wxDocManager::OnUpdateFileSave
) 
 740     EVT_UPDATE_UI(wxID_SAVEAS
, wxDocManager::OnUpdateFileSaveAs
) 
 741     EVT_UPDATE_UI(wxID_UNDO
, wxDocManager::OnUpdateUndo
) 
 742     EVT_UPDATE_UI(wxID_REDO
, wxDocManager::OnUpdateRedo
) 
 744 #if wxUSE_PRINTING_ARCHITECTURE 
 745     EVT_MENU(wxID_PRINT
, wxDocManager::OnPrint
) 
 746     EVT_MENU(wxID_PRINT_SETUP
, wxDocManager::OnPrintSetup
) 
 747     EVT_MENU(wxID_PREVIEW
, wxDocManager::OnPreview
) 
 749     EVT_UPDATE_UI(wxID_PRINT
, wxDocManager::OnUpdatePrint
) 
 750     EVT_UPDATE_UI(wxID_PRINT_SETUP
, wxDocManager::OnUpdatePrintSetup
) 
 751     EVT_UPDATE_UI(wxID_PREVIEW
, wxDocManager::OnUpdatePreview
) 
 755 wxDocManager
* wxDocManager::sm_docManager 
= (wxDocManager
*) NULL
; 
 757 wxDocManager::wxDocManager(long flags
, bool initialize
) 
 759     m_defaultDocumentNameCounter 
= 1; 
 761     m_currentView 
= (wxView 
*) NULL
; 
 762     m_maxDocsOpen 
= 10000; 
 763     m_fileHistory 
= (wxFileHistory 
*) NULL
; 
 766     sm_docManager 
= this; 
 769 wxDocManager::~wxDocManager() 
 773         delete m_fileHistory
; 
 774     sm_docManager 
= (wxDocManager
*) NULL
; 
 777 bool wxDocManager::CloseDocuments(bool force
) 
 779     wxNode 
*node 
= m_docs
.GetFirst(); 
 782         wxDocument 
*doc 
= (wxDocument 
*)node
->GetData(); 
 783         wxNode 
*next 
= node
->GetNext(); 
 785         if (!doc
->Close() && !force
) 
 788         // Implicitly deletes the document when the last 
 789         // view is removed (deleted) 
 790         doc
->DeleteAllViews(); 
 792         // Check document is deleted 
 793         if (m_docs
.Member(doc
)) 
 796         // This assumes that documents are not connected in 
 797         // any way, i.e. deleting one document does NOT 
 804 bool wxDocManager::Clear(bool force
) 
 806     if (!CloseDocuments(force
)) 
 809     wxNode 
*node 
= m_templates
.GetFirst(); 
 812         wxDocTemplate 
*templ 
= (wxDocTemplate
*) node
->GetData(); 
 813         wxNode
* next 
= node
->GetNext(); 
 820 bool wxDocManager::Initialize() 
 822     m_fileHistory 
= OnCreateFileHistory(); 
 826 wxFileHistory 
*wxDocManager::OnCreateFileHistory() 
 828     return new wxFileHistory
; 
 831 void wxDocManager::OnFileClose(wxCommandEvent
& WXUNUSED(event
)) 
 833     wxDocument 
*doc 
= GetCurrentDocument(); 
 838         doc
->DeleteAllViews(); 
 839         if (m_docs
.Member(doc
)) 
 844 void wxDocManager::OnFileCloseAll(wxCommandEvent
& WXUNUSED(event
)) 
 846     CloseDocuments(FALSE
); 
 849 void wxDocManager::OnFileNew(wxCommandEvent
& WXUNUSED(event
)) 
 851     CreateDocument( wxT(""), wxDOC_NEW 
); 
 854 void wxDocManager::OnFileOpen(wxCommandEvent
& WXUNUSED(event
)) 
 856     if ( !CreateDocument( wxT(""), 0) ) 
 862 void wxDocManager::OnFileRevert(wxCommandEvent
& WXUNUSED(event
)) 
 864     wxDocument 
*doc 
= GetCurrentDocument(); 
 870 void wxDocManager::OnFileSave(wxCommandEvent
& WXUNUSED(event
)) 
 872     wxDocument 
*doc 
= GetCurrentDocument(); 
 878 void wxDocManager::OnFileSaveAs(wxCommandEvent
& WXUNUSED(event
)) 
 880     wxDocument 
*doc 
= GetCurrentDocument(); 
 886 void wxDocManager::OnPrint(wxCommandEvent
& WXUNUSED(event
)) 
 888 #if wxUSE_PRINTING_ARCHITECTURE 
 889     wxView 
*view 
= GetCurrentView(); 
 893     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 897         printer
.Print(view
->GetFrame(), printout
, TRUE
); 
 901 #endif // wxUSE_PRINTING_ARCHITECTURE 
 904 void wxDocManager::OnPrintSetup(wxCommandEvent
& WXUNUSED(event
)) 
 906 #if wxUSE_PRINTING_ARCHITECTURE 
 907     wxWindow 
*parentWin 
= wxTheApp
->GetTopWindow(); 
 908     wxView 
*view 
= GetCurrentView(); 
 910         parentWin 
= view
->GetFrame(); 
 912     wxPrintDialogData data
; 
 914     wxPrintDialog 
printerDialog(parentWin
, &data
); 
 915     printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
); 
 916     printerDialog
.ShowModal(); 
 917 #endif // wxUSE_PRINTING_ARCHITECTURE 
 920 void wxDocManager::OnPreview(wxCommandEvent
& WXUNUSED(event
)) 
 922 #if wxUSE_PRINTING_ARCHITECTURE 
 923     wxView 
*view 
= GetCurrentView(); 
 927     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 930         // Pass two printout objects: for preview, and possible printing. 
 931         wxPrintPreviewBase 
*preview 
= (wxPrintPreviewBase 
*) NULL
; 
 932         preview 
= new wxPrintPreview(printout
, view
->OnCreatePrintout()); 
 934         wxPreviewFrame 
*frame 
= new wxPreviewFrame(preview
, (wxFrame 
*)wxTheApp
->GetTopWindow(), _("Print Preview"), 
 935                 wxPoint(100, 100), wxSize(600, 650)); 
 936         frame
->Centre(wxBOTH
); 
 940 #endif // wxUSE_PRINTING_ARCHITECTURE 
 943 void wxDocManager::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 945     wxDocument 
*doc 
= GetCurrentDocument(); 
 948     if (doc
->GetCommandProcessor()) 
 949         doc
->GetCommandProcessor()->Undo(); 
 952 void wxDocManager::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 954     wxDocument 
*doc 
= GetCurrentDocument(); 
 957     if (doc
->GetCommandProcessor()) 
 958         doc
->GetCommandProcessor()->Redo(); 
 961 // Handlers for UI update commands 
 963 void wxDocManager::OnUpdateFileOpen(wxUpdateUIEvent
& event
) 
 965     event
.Enable( TRUE 
); 
 968 void wxDocManager::OnUpdateFileClose(wxUpdateUIEvent
& event
) 
 970     wxDocument 
*doc 
= GetCurrentDocument(); 
 971     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 974 void wxDocManager::OnUpdateFileRevert(wxUpdateUIEvent
& event
) 
 976     wxDocument 
*doc 
= GetCurrentDocument(); 
 977     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 980 void wxDocManager::OnUpdateFileNew(wxUpdateUIEvent
& event
) 
 982     event
.Enable( TRUE 
); 
 985 void wxDocManager::OnUpdateFileSave(wxUpdateUIEvent
& event
) 
 987     wxDocument 
*doc 
= GetCurrentDocument(); 
 988     event
.Enable( doc 
&& doc
->IsModified() ); 
 991 void wxDocManager::OnUpdateFileSaveAs(wxUpdateUIEvent
& event
) 
 993     wxDocument 
*doc 
= GetCurrentDocument(); 
 994     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 997 void wxDocManager::OnUpdateUndo(wxUpdateUIEvent
& event
) 
 999     wxDocument 
*doc 
= GetCurrentDocument(); 
1000     event
.Enable( (doc 
&& doc
->GetCommandProcessor() && doc
->GetCommandProcessor()->CanUndo()) ); 
1001     if (doc 
&& doc
->GetCommandProcessor()) 
1002         doc
->GetCommandProcessor()->SetMenuStrings(); 
1005 void wxDocManager::OnUpdateRedo(wxUpdateUIEvent
& event
) 
1007     wxDocument 
*doc 
= GetCurrentDocument(); 
1008     event
.Enable( (doc 
&& doc
->GetCommandProcessor() && doc
->GetCommandProcessor()->CanRedo()) ); 
1009     if (doc 
&& doc
->GetCommandProcessor()) 
1010         doc
->GetCommandProcessor()->SetMenuStrings(); 
1013 void wxDocManager::OnUpdatePrint(wxUpdateUIEvent
& event
) 
1015     wxDocument 
*doc 
= GetCurrentDocument(); 
1016     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
1019 void wxDocManager::OnUpdatePrintSetup(wxUpdateUIEvent
& event
) 
1021     event
.Enable( TRUE 
); 
1024 void wxDocManager::OnUpdatePreview(wxUpdateUIEvent
& event
) 
1026     wxDocument 
*doc 
= GetCurrentDocument(); 
1027     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
1030 wxView 
*wxDocManager::GetCurrentView() const 
1033         return m_currentView
; 
1034     if (m_docs
.GetCount() == 1) 
1036         wxDocument
* doc 
= (wxDocument
*) m_docs
.GetFirst()->GetData(); 
1037         return doc
->GetFirstView(); 
1039     return (wxView 
*) NULL
; 
1042 // Extend event processing to search the view's event table 
1043 bool wxDocManager::ProcessEvent(wxEvent
& event
) 
1045     wxView
* view 
= GetCurrentView(); 
1048         if (view
->ProcessEvent(event
)) 
1051     return wxEvtHandler::ProcessEvent(event
); 
1054 wxDocument 
*wxDocManager::CreateDocument(const wxString
& path
, long flags
) 
1056     wxDocTemplate   
**templates 
= new wxDocTemplate 
*[m_templates
.GetCount()]; 
1059     for (size_t i 
= 0; i 
< m_templates
.GetCount(); i
++) 
1061         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Item(i
)->GetData()); 
1062         if (temp
->IsVisible()) 
1064             templates
[n
] = temp
; 
1071         return (wxDocument 
*) NULL
; 
1074     // If we've reached the max number of docs, close the 
1076     if ( (int)GetDocuments().GetCount() >= m_maxDocsOpen 
) 
1078         wxDocument 
*doc 
= (wxDocument 
*)GetDocuments().GetFirst()->GetData(); 
1081             // Implicitly deletes the document when 
1082             // the last view is deleted 
1083             doc
->DeleteAllViews(); 
1085             // Check we're really deleted 
1086             if (m_docs
.Member(doc
)) 
1092             return (wxDocument 
*) NULL
; 
1096     // New document: user chooses a template, unless there's only one. 
1097     if (flags 
& wxDOC_NEW
) 
1101             wxDocTemplate 
*temp 
= templates
[0]; 
1103             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
1106                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1107                 newDoc
->SetDocumentTemplate(temp
); 
1108                 newDoc
->OnNewDocument(); 
1113         wxDocTemplate 
*temp 
= SelectDocumentType(templates
, n
); 
1117             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
1120                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1121                 newDoc
->SetDocumentTemplate(temp
); 
1122                 newDoc
->OnNewDocument(); 
1127             return (wxDocument 
*) NULL
; 
1130     // Existing document 
1131     wxDocTemplate 
*temp 
= (wxDocTemplate 
*) NULL
; 
1133     wxString 
path2(wxT("")); 
1134     if (path 
!= wxT("")) 
1137     if (flags 
& wxDOC_SILENT
) 
1138         temp 
= FindTemplateForPath(path2
); 
1140         temp 
= SelectDocumentPath(templates
, n
, path2
, flags
); 
1146         wxDocument 
*newDoc 
= temp
->CreateDocument(path2
, flags
); 
1149             newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1150             newDoc
->SetDocumentTemplate(temp
); 
1151             if (!newDoc
->OnOpenDocument(path2
)) 
1153                 newDoc
->DeleteAllViews(); 
1154                 // delete newDoc; // Implicitly deleted by DeleteAllViews 
1155                 return (wxDocument 
*) NULL
; 
1157             AddFileToHistory(path2
); 
1162     return (wxDocument 
*) NULL
; 
1165 wxView 
*wxDocManager::CreateView(wxDocument 
*doc
, long flags
) 
1167     wxDocTemplate   
**templates 
= new wxDocTemplate 
*[m_templates
.GetCount()]; 
1170     for (size_t i 
= 0; i 
< m_templates
.GetCount(); i
++) 
1172         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Item(i
)->GetData()); 
1173         if (temp
->IsVisible()) 
1175             if (temp
->GetDocumentName() == doc
->GetDocumentName()) 
1177                 templates
[n
] = temp
; 
1185         return (wxView 
*) NULL
; 
1189         wxDocTemplate 
*temp 
= templates
[0]; 
1191         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1193             view
->SetViewName(temp
->GetViewName()); 
1197     wxDocTemplate 
*temp 
= SelectViewType(templates
, n
); 
1201         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1203             view
->SetViewName(temp
->GetViewName()); 
1207         return (wxView 
*) NULL
; 
1210 // Not yet implemented 
1211 void wxDocManager::DeleteTemplate(wxDocTemplate 
*WXUNUSED(temp
), long WXUNUSED(flags
)) 
1215 // Not yet implemented 
1216 bool wxDocManager::FlushDoc(wxDocument 
*WXUNUSED(doc
)) 
1221 wxDocument 
*wxDocManager::GetCurrentDocument() const 
1223     wxView 
*view 
= GetCurrentView(); 
1225         return view
->GetDocument(); 
1227         return (wxDocument 
*) NULL
; 
1230 // Make a default document name 
1231 bool wxDocManager::MakeDefaultName(wxString
& name
) 
1233     name
.Printf(_("unnamed%d"), m_defaultDocumentNameCounter
); 
1234     m_defaultDocumentNameCounter
++; 
1239 // Make a frame title (override this to do something different) 
1240 // If docName is empty, a document is not currently active. 
1241 wxString 
wxDocManager::MakeFrameTitle(wxDocument
* doc
) 
1243     wxString appName 
= wxTheApp
->GetAppName(); 
1250         doc
->GetPrintableName(docName
); 
1251         title 
= docName 
+ wxString(_(" - ")) + appName
; 
1257 // Not yet implemented 
1258 wxDocTemplate 
*wxDocManager::MatchTemplate(const wxString
& WXUNUSED(path
)) 
1260     return (wxDocTemplate 
*) NULL
; 
1263 // File history management 
1264 void wxDocManager::AddFileToHistory(const wxString
& file
) 
1267         m_fileHistory
->AddFileToHistory(file
); 
1270 void wxDocManager::RemoveFileFromHistory(int i
) 
1273         m_fileHistory
->RemoveFileFromHistory(i
); 
1276 wxString 
wxDocManager::GetHistoryFile(int i
) const 
1281         histFile 
= m_fileHistory
->GetHistoryFile(i
); 
1286 void wxDocManager::FileHistoryUseMenu(wxMenu 
*menu
) 
1289         m_fileHistory
->UseMenu(menu
); 
1292 void wxDocManager::FileHistoryRemoveMenu(wxMenu 
*menu
) 
1295         m_fileHistory
->RemoveMenu(menu
); 
1299 void wxDocManager::FileHistoryLoad(wxConfigBase
& config
) 
1302         m_fileHistory
->Load(config
); 
1305 void wxDocManager::FileHistorySave(wxConfigBase
& config
) 
1308         m_fileHistory
->Save(config
); 
1312 void wxDocManager::FileHistoryAddFilesToMenu(wxMenu
* menu
) 
1315         m_fileHistory
->AddFilesToMenu(menu
); 
1318 void wxDocManager::FileHistoryAddFilesToMenu() 
1321         m_fileHistory
->AddFilesToMenu(); 
1324 int wxDocManager::GetNoHistoryFiles() const 
1327         return m_fileHistory
->GetNoHistoryFiles(); 
1333 // Find out the document template via matching in the document file format 
1334 // against that of the template 
1335 wxDocTemplate 
*wxDocManager::FindTemplateForPath(const wxString
& path
) 
1337     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*) NULL
; 
1339     // Find the template which this extension corresponds to 
1340     for (size_t i 
= 0; i 
< m_templates
.GetCount(); i
++) 
1342         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)m_templates
.Item(i
)->GetData(); 
1343         if ( temp
->FileMatchesTemplate(path
) ) 
1352 // Try to get a more suitable parent frame than the top window, 
1353 // for selection dialogs. Otherwise you may get an unexpected 
1354 // window being activated when a dialog is shown. 
1355 static wxWindow
* wxFindSuitableParent() 
1357     wxWindow
* parent 
= wxTheApp
->GetTopWindow(); 
1359     wxWindow
* focusWindow 
= wxWindow::FindFocus(); 
1362         while (focusWindow 
&& 
1363                 !focusWindow
->IsKindOf(CLASSINFO(wxDialog
)) && 
1364                 !focusWindow
->IsKindOf(CLASSINFO(wxFrame
))) 
1366             focusWindow 
= focusWindow
->GetParent(); 
1369             parent 
= focusWindow
; 
1374 // Prompts user to open a file, using file specs in templates. 
1375 // How to implement in wxWindows? Must extend the file selector 
1376 // dialog or implement own; OR match the extension to the 
1377 // template extension. 
1379 wxDocTemplate 
*wxDocManager::SelectDocumentPath(wxDocTemplate 
**templates
, 
1380 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXMAC__) 
1383                                                 int WXUNUSED(noTemplates
), 
1386                                                 long WXUNUSED(flags
), 
1387                                                 bool WXUNUSED(save
)) 
1389     // We can only have multiple filters in Windows and GTK 
1390 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXMAC__) 
1394     for (i 
= 0; i 
< noTemplates
; i
++) 
1396         if (templates
[i
]->IsVisible()) 
1398             // add a '|' to separate this filter from the previous one 
1399             if ( !descrBuf
.IsEmpty() ) 
1400                 descrBuf 
<< wxT('|'); 
1402             descrBuf 
<< templates
[i
]->GetDescription() 
1403                 << wxT(" (") << templates
[i
]->GetFileFilter() << wxT(") |") 
1404                 << templates
[i
]->GetFileFilter(); 
1408     wxString descrBuf 
= wxT("*.*"); 
1411     int FilterIndex 
= -1; 
1413     wxWindow
* parent 
= wxFindSuitableParent(); 
1415     wxString pathTmp 
= wxFileSelectorEx(_("Select a file"), 
1423     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*)NULL
; 
1424     if (!pathTmp
.IsEmpty()) 
1426         if (!wxFileExists(pathTmp
)) 
1429             if (!wxTheApp
->GetAppName().IsEmpty()) 
1430                 msgTitle 
= wxTheApp
->GetAppName(); 
1432                 msgTitle 
= wxString(_("File error")); 
1434             (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
1438             return (wxDocTemplate 
*) NULL
; 
1440         m_lastDirectory 
= wxPathOnly(pathTmp
); 
1444         // first choose the template using the extension, if this fails (i.e. 
1445         // wxFileSelectorEx() didn't fill it), then use the path 
1446         if ( FilterIndex 
!= -1 ) 
1447             theTemplate 
= templates
[FilterIndex
]; 
1449             theTemplate 
= FindTemplateForPath(path
); 
1459     // In all other windowing systems, until we have more advanced 
1460     // file selectors, we must select the document type (template) first, and 
1461     // _then_ pop up the file selector. 
1462     wxDocTemplate 
*temp 
= SelectDocumentType(templates
, noTemplates
); 
1464         return (wxDocTemplate 
*) NULL
; 
1466     wxChar 
*pathTmp 
= wxFileSelector(_("Select a file"), wxT(""), wxT(""), 
1467             temp
->GetDefaultExtension(), 
1468             temp
->GetFileFilter(), 
1469             0, wxTheApp
->GetTopWindow()); 
1477         return (wxDocTemplate 
*) NULL
; 
1481 wxDocTemplate 
*wxDocManager::SelectDocumentType(wxDocTemplate 
**templates
, 
1482                                                 int noTemplates
, bool sort
) 
1484     wxArrayString 
strings(sort
); 
1485     wxDocTemplate 
**data 
= new wxDocTemplate 
*[noTemplates
]; 
1489         for (i 
= 0; i 
< noTemplates
; i
++) 
1491                 if (templates
[i
]->IsVisible()) 
1495                         for (j 
= 0; j 
< n
; j
++) 
1497                 //filter out NOT unique documents + view combinations 
1498                                 if ( templates
[i
]->m_docTypeName 
== data
[j
]->m_docTypeName 
&& 
1499                      templates
[i
]->m_viewTypeName 
== data
[j
]->m_viewTypeName
 
1506                         strings
.Add(templates
[i
]->m_description
); 
1508                                 data
[n
] = templates
[i
]; 
1516                 // Yes, this will be slow, but template lists 
1517                 // are typically short. 
1519                 n 
= strings
.Count(); 
1520                 for (i 
= 0; i 
< n
; i
++) 
1522                         for (j 
= 0; j 
< noTemplates
; j
++) 
1524                                 if (strings
[i
] == templates
[j
]->m_description
) 
1525                                         data
[i
] = templates
[j
]; 
1530     wxDocTemplate 
*theTemplate
; 
1535             // no visible templates, hence nothing to choose from 
1540             // don't propose the user to choose if he heas no choice 
1541             theTemplate 
= data
[0]; 
1545             // propose the user to choose one of several 
1546             theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData
 
1548                             _("Select a document template"), 
1552                             wxFindSuitableParent() 
1561 wxDocTemplate 
*wxDocManager::SelectViewType(wxDocTemplate 
**templates
, 
1562                                             int noTemplates
, bool sort
) 
1564     wxArrayString 
strings(sort
); 
1565     wxDocTemplate 
**data 
= new wxDocTemplate 
*[noTemplates
]; 
1569     for (i 
= 0; i 
< noTemplates
; i
++) 
1571         wxDocTemplate 
*templ 
= templates
[i
]; 
1572         if ( templ
->IsVisible() && !templ
->GetViewName().empty() ) 
1576                         for (j 
= 0; j 
< n
; j
++) 
1578                 //filter out NOT unique views 
1579                                 if ( templates
[i
]->m_viewTypeName 
== data
[j
]->m_viewTypeName 
) 
1585                         strings
.Add(templ
->m_viewTypeName
); 
1594                 // Yes, this will be slow, but template lists 
1595                 // are typically short. 
1597                 n 
= strings
.Count(); 
1598                 for (i 
= 0; i 
< n
; i
++) 
1600                         for (j 
= 0; j 
< noTemplates
; j
++) 
1602                                 if (strings
[i
] == templates
[j
]->m_viewTypeName
) 
1603                                         data
[i
] = templates
[j
]; 
1608     wxDocTemplate 
*theTemplate
; 
1610     // the same logic as above 
1614             theTemplate 
= (wxDocTemplate 
*)NULL
; 
1618             theTemplate 
= data
[0]; 
1622             theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData
 
1624                             _("Select a document view"), 
1628                             wxFindSuitableParent() 
1637 void wxDocManager::AssociateTemplate(wxDocTemplate 
*temp
) 
1639     if (!m_templates
.Member(temp
)) 
1640         m_templates
.Append(temp
); 
1643 void wxDocManager::DisassociateTemplate(wxDocTemplate 
*temp
) 
1645     m_templates
.DeleteObject(temp
); 
1648 // Add and remove a document from the manager's list 
1649 void wxDocManager::AddDocument(wxDocument 
*doc
) 
1651     if (!m_docs
.Member(doc
)) 
1655 void wxDocManager::RemoveDocument(wxDocument 
*doc
) 
1657     m_docs
.DeleteObject(doc
); 
1660 // Views or windows should inform the document manager 
1661 // when a view is going in or out of focus 
1662 void wxDocManager::ActivateView(wxView 
*view
, bool activate
, bool WXUNUSED(deleting
)) 
1664     // If we're deactiving, and if we're not actually deleting the view, then 
1665     // don't reset the current view because we may be going to 
1666     // a window without a view. 
1667     // WHAT DID I MEAN BY THAT EXACTLY? 
1671        if (m_currentView == view) 
1672        m_currentView = NULL; 
1678             m_currentView 
= view
; 
1680             m_currentView 
= (wxView 
*) NULL
; 
1684 // ---------------------------------------------------------------------------- 
1685 // Default document child frame 
1686 // ---------------------------------------------------------------------------- 
1688 BEGIN_EVENT_TABLE(wxDocChildFrame
, wxFrame
) 
1689     EVT_ACTIVATE(wxDocChildFrame::OnActivate
) 
1690     EVT_CLOSE(wxDocChildFrame::OnCloseWindow
) 
1693 wxDocChildFrame::wxDocChildFrame(wxDocument 
*doc
, 
1697                                  const wxString
& title
, 
1701                                  const wxString
& name
) 
1702                : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1704     m_childDocument 
= doc
; 
1707         view
->SetFrame(this); 
1710 wxDocChildFrame::~wxDocChildFrame() 
1714 // Extend event processing to search the view's event table 
1715 bool wxDocChildFrame::ProcessEvent(wxEvent
& event
) 
1718         m_childView
->Activate(TRUE
); 
1720     if ( !m_childView 
|| ! m_childView
->ProcessEvent(event
) ) 
1722         // Only hand up to the parent if it's a menu command 
1723         if (!event
.IsKindOf(CLASSINFO(wxCommandEvent
)) || !GetParent() || !GetParent()->ProcessEvent(event
)) 
1724             return wxEvtHandler::ProcessEvent(event
); 
1732 void wxDocChildFrame::OnActivate(wxActivateEvent
& event
) 
1734     wxFrame::OnActivate(event
); 
1737         m_childView
->Activate(event
.GetActive()); 
1740 void wxDocChildFrame::OnCloseWindow(wxCloseEvent
& event
) 
1745         if (!event
.CanVeto()) 
1746             ans 
= TRUE
; // Must delete. 
1748             ans 
= m_childView
->Close(FALSE
); // FALSE means don't delete associated window 
1752             m_childView
->Activate(FALSE
); 
1754             m_childView 
= (wxView 
*) NULL
; 
1755             m_childDocument 
= (wxDocument 
*) NULL
; 
1766 // ---------------------------------------------------------------------------- 
1767 // Default parent frame 
1768 // ---------------------------------------------------------------------------- 
1770 BEGIN_EVENT_TABLE(wxDocParentFrame
, wxFrame
) 
1771     EVT_MENU(wxID_EXIT
, wxDocParentFrame::OnExit
) 
1772     EVT_MENU_RANGE(wxID_FILE1
, wxID_FILE9
, wxDocParentFrame::OnMRUFile
) 
1773     EVT_CLOSE(wxDocParentFrame::OnCloseWindow
) 
1776 wxDocParentFrame::wxDocParentFrame(wxDocManager 
*manager
, 
1779                                    const wxString
& title
, 
1783                                    const wxString
& name
) 
1784                 : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1786     m_docManager 
= manager
; 
1789 void wxDocParentFrame::OnExit(wxCommandEvent
& WXUNUSED(event
)) 
1794 void wxDocParentFrame::OnMRUFile(wxCommandEvent
& event
) 
1796     int n 
= event
.GetId() - wxID_FILE1
;  // the index in MRU list 
1797     wxString 
filename(m_docManager
->GetHistoryFile(n
)); 
1798     if ( !filename
.IsEmpty() ) 
1800         // verify that the file exists before doing anything else 
1801         if ( wxFile::Exists(filename
) ) 
1804             (void)m_docManager
->CreateDocument(filename
, wxDOC_SILENT
); 
1808             // remove the bogus filename from the MRU list and notify the user 
1810             m_docManager
->RemoveFileFromHistory(n
); 
1812             wxLogError(_("The file '%s' doesn't exist and couldn't be opened.\nIt has been removed from the most recently used files list."), 
1818 // Extend event processing to search the view's event table 
1819 bool wxDocParentFrame::ProcessEvent(wxEvent
& event
) 
1821     // Try the document manager, then do default processing 
1822     if (!m_docManager 
|| !m_docManager
->ProcessEvent(event
)) 
1823         return wxEvtHandler::ProcessEvent(event
); 
1828 // Define the behaviour for the frame closing 
1829 // - must delete all frames except for the main one. 
1830 void wxDocParentFrame::OnCloseWindow(wxCloseEvent
& event
) 
1832     if (m_docManager
->Clear(!event
.CanVeto())) 
1840 #if wxUSE_PRINTING_ARCHITECTURE 
1842 wxDocPrintout::wxDocPrintout(wxView 
*view
, const wxString
& title
) 
1845     m_printoutView 
= view
; 
1848 bool wxDocPrintout::OnPrintPage(int WXUNUSED(page
)) 
1852     // Get the logical pixels per inch of screen and printer 
1853     int ppiScreenX
, ppiScreenY
; 
1854     GetPPIScreen(&ppiScreenX
, &ppiScreenY
); 
1855     int ppiPrinterX
, ppiPrinterY
; 
1856     GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
); 
1858     // This scales the DC so that the printout roughly represents the 
1859     // the screen scaling. The text point size _should_ be the right size 
1860     // but in fact is too small for some reason. This is a detail that will 
1861     // need to be addressed at some point but can be fudged for the 
1863     float scale 
= (float)((float)ppiPrinterX
/(float)ppiScreenX
); 
1865     // Now we have to check in case our real page size is reduced 
1866     // (e.g. because we're drawing to a print preview memory DC) 
1867     int pageWidth
, pageHeight
; 
1869     dc
->GetSize(&w
, &h
); 
1870     GetPageSizePixels(&pageWidth
, &pageHeight
); 
1872     // If printer pageWidth == current DC width, then this doesn't 
1873     // change. But w might be the preview bitmap width, so scale down. 
1874     float overallScale 
= scale 
* (float)(w
/(float)pageWidth
); 
1875     dc
->SetUserScale(overallScale
, overallScale
); 
1879         m_printoutView
->OnDraw(dc
); 
1884 bool wxDocPrintout::HasPage(int pageNum
) 
1886     return (pageNum 
== 1); 
1889 bool wxDocPrintout::OnBeginDocument(int startPage
, int endPage
) 
1891     if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) 
1897 void wxDocPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
) 
1905 #endif // wxUSE_PRINTING_ARCHITECTURE 
1907 // ---------------------------------------------------------------------------- 
1908 // File history processor 
1909 // ---------------------------------------------------------------------------- 
1911 wxFileHistory::wxFileHistory(int maxFiles
) 
1913     m_fileMaxFiles 
= maxFiles
; 
1915     m_fileHistory 
= new wxChar 
*[m_fileMaxFiles
]; 
1918 wxFileHistory::~wxFileHistory() 
1921     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1922         delete[] m_fileHistory
[i
]; 
1923     delete[] m_fileHistory
; 
1926 // File history management 
1927 void wxFileHistory::AddFileToHistory(const wxString
& file
) 
1931     // Check we don't already have this file 
1932     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1934         if ( m_fileHistory
[i
] && (file 
== m_fileHistory
[i
]) ) 
1936             // we do have it, move it to the top of the history 
1937             RemoveFileFromHistory (i
); 
1938             AddFileToHistory (file
); 
1943     // if we already have a full history, delete the one at the end 
1944     if ( m_fileMaxFiles 
== m_fileHistoryN 
) 
1946         RemoveFileFromHistory (m_fileHistoryN 
- 1); 
1947         AddFileToHistory (file
); 
1951     // Add to the project file history: 
1952     // Move existing files (if any) down so we can insert file at beginning. 
1953     if (m_fileHistoryN 
< m_fileMaxFiles
) 
1955         wxNode
* node 
= m_fileMenus
.GetFirst(); 
1958             wxMenu
* menu 
= (wxMenu
*) node
->GetData(); 
1959             if ( m_fileHistoryN 
== 0 && menu
->GetMenuItemCount() ) 
1961                 menu
->AppendSeparator(); 
1963             menu
->Append(wxID_FILE1
+m_fileHistoryN
, _("[EMPTY]")); 
1964             node 
= node
->GetNext(); 
1968     // Shuffle filenames down 
1969     for (i 
= (m_fileHistoryN
-1); i 
> 0; i
--) 
1971         m_fileHistory
[i
] = m_fileHistory
[i
-1]; 
1973     m_fileHistory
[0] = copystring(file
); 
1975     // this is the directory of the last opened file 
1976     wxString pathCurrent
; 
1977     wxSplitPath( m_fileHistory
[0], &pathCurrent
, NULL
, NULL 
); 
1978     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1980         if ( m_fileHistory
[i
] ) 
1982             // if in same directory just show the filename; otherwise the full 
1984             wxString pathInMenu
, path
, filename
, ext
; 
1985             wxSplitPath( m_fileHistory
[i
], &path
, &filename
, &ext 
); 
1986             if ( path 
== pathCurrent 
) 
1988                 pathInMenu 
= filename
; 
1990                     pathInMenu 
= pathInMenu 
+ wxFILE_SEP_EXT 
+ ext
; 
1994                 // absolute path; could also set relative path 
1995                 pathInMenu 
= m_fileHistory
[i
]; 
1999             buf
.Printf(s_MRUEntryFormat
, i 
+ 1, pathInMenu
.c_str()); 
2000             wxNode
* node 
= m_fileMenus
.GetFirst(); 
2003                 wxMenu
* menu 
= (wxMenu
*) node
->GetData(); 
2004                 menu
->SetLabel(wxID_FILE1 
+ i
, buf
); 
2005                 node 
= node
->GetNext(); 
2011 void wxFileHistory::RemoveFileFromHistory(int i
) 
2013     wxCHECK_RET( i 
< m_fileHistoryN
, 
2014                  wxT("invalid index in wxFileHistory::RemoveFileFromHistory") ); 
2016         // delete the element from the array (could use memmove() too...) 
2017         delete [] m_fileHistory
[i
]; 
2020         for ( j 
= i
; j 
< m_fileHistoryN 
- 1; j
++ ) 
2022             m_fileHistory
[j
] = m_fileHistory
[j 
+ 1]; 
2025     wxNode
* node 
= m_fileMenus
.GetFirst(); 
2028         wxMenu
* menu 
= (wxMenu
*) node
->GetData(); 
2031         // shuffle filenames up 
2033         for ( j 
= i
; j 
< m_fileHistoryN 
- 1; j
++ ) 
2035             buf
.Printf(s_MRUEntryFormat
, j 
+ 1, m_fileHistory
[j
]); 
2036             menu
->SetLabel(wxID_FILE1 
+ j
, buf
); 
2039         node 
= node
->GetNext(); 
2041         // delete the last menu item which is unused now 
2042         if (menu
->FindItem(wxID_FILE1 
+ m_fileHistoryN 
- 1)) 
2043         menu
->Delete(wxID_FILE1 
+ m_fileHistoryN 
- 1); 
2045         // delete the last separator too if no more files are left 
2046         if ( m_fileHistoryN 
== 1 ) 
2048             wxMenuItemList::Node 
*node 
= menu
->GetMenuItems().GetLast(); 
2051                 wxMenuItem 
*menuItem 
= node
->GetData(); 
2052                 if ( menuItem
->IsSeparator() ) 
2054                     menu
->Delete(menuItem
); 
2056                 //else: should we search backwards for the last separator? 
2058             //else: menu is empty somehow 
2065 wxString 
wxFileHistory::GetHistoryFile(int i
) const 
2068     if ( i 
< m_fileHistoryN 
) 
2070         s 
= m_fileHistory
[i
]; 
2074         wxFAIL_MSG( wxT("bad index in wxFileHistory::GetHistoryFile") ); 
2080 void wxFileHistory::UseMenu(wxMenu 
*menu
) 
2082     if (!m_fileMenus
.Member(menu
)) 
2083         m_fileMenus
.Append(menu
); 
2086 void wxFileHistory::RemoveMenu(wxMenu 
*menu
) 
2088     m_fileMenus
.DeleteObject(menu
); 
2092 void wxFileHistory::Load(wxConfigBase
& config
) 
2096     buf
.Printf(wxT("file%d"), m_fileHistoryN
+1); 
2097     wxString historyFile
; 
2098     while ((m_fileHistoryN 
< m_fileMaxFiles
) && config
.Read(buf
, &historyFile
) && (historyFile 
!= wxT(""))) 
2100         m_fileHistory
[m_fileHistoryN
] = copystring((const wxChar
*) historyFile
); 
2102         buf
.Printf(wxT("file%d"), m_fileHistoryN
+1); 
2103         historyFile 
= wxT(""); 
2108 void wxFileHistory::Save(wxConfigBase
& config
) 
2111     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
2114         buf
.Printf(wxT("file%d"), i
+1); 
2115         config
.Write(buf
, wxString(m_fileHistory
[i
])); 
2118 #endif // wxUSE_CONFIG 
2120 void wxFileHistory::AddFilesToMenu() 
2122     if (m_fileHistoryN 
> 0) 
2124         wxNode
* node 
= m_fileMenus
.GetFirst(); 
2127             wxMenu
* menu 
= (wxMenu
*) node
->GetData(); 
2128             if (menu
->GetMenuItemCount()) 
2130                 menu
->AppendSeparator(); 
2134             for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
2136                 if (m_fileHistory
[i
]) 
2139                     buf
.Printf(s_MRUEntryFormat
, i
+1, m_fileHistory
[i
]); 
2140                     menu
->Append(wxID_FILE1
+i
, buf
); 
2143             node 
= node
->GetNext(); 
2148 void wxFileHistory::AddFilesToMenu(wxMenu
* menu
) 
2150     if (m_fileHistoryN 
> 0) 
2152         if (menu
->GetMenuItemCount()) 
2154             menu
->AppendSeparator(); 
2158         for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
2160             if (m_fileHistory
[i
]) 
2163                 buf
.Printf(s_MRUEntryFormat
, i
+1, m_fileHistory
[i
]); 
2164                 menu
->Append(wxID_FILE1
+i
, buf
); 
2170 // ---------------------------------------------------------------------------- 
2171 // Permits compatibility with existing file formats and functions that 
2172 // manipulate files directly 
2173 // ---------------------------------------------------------------------------- 
2175 #if wxUSE_STD_IOSTREAM 
2177 bool wxTransferFileToStream(const wxString
& filename
, wxSTD ostream
& stream
) 
2179     wxFFile 
file(filename
, _T("rb")); 
2180     if ( !file
.IsOpened() ) 
2188         nRead 
= file
.Read(buf
, WXSIZEOF(buf
)); 
2192         stream
.write(buf
, nRead
); 
2196     while ( !file
.Eof() ); 
2201 bool wxTransferStreamToFile(wxSTD istream
& stream
, const wxString
& filename
) 
2203     wxFFile 
file(filename
, _T("wb")); 
2204     if ( !file
.IsOpened() ) 
2210         stream
.read(buf
, WXSIZEOF(buf
)); 
2211         if ( !stream
.bad() ) // fail may be set on EOF, don't use operator!() 
2213             if ( !file
.Write(buf
, stream
.gcount()) ) 
2217     while ( !stream
.eof() ); 
2222 #else // !wxUSE_STD_IOSTREAM 
2224 bool wxTransferFileToStream(const wxString
& filename
, wxOutputStream
& stream
) 
2226     wxFFile 
file(filename
, _T("rb")); 
2227     if ( !file
.IsOpened() ) 
2235         nRead 
= file
.Read(buf
, WXSIZEOF(buf
)); 
2239         stream
.Write(buf
, nRead
); 
2243     while ( !file
.Eof() ); 
2248 bool wxTransferStreamToFile(wxInputStream
& stream
, const wxString
& filename
) 
2250     wxFFile 
file(filename
, _T("wb")); 
2251     if ( !file
.IsOpened() ) 
2257         stream
.Read(buf
, WXSIZEOF(buf
)); 
2259         const size_t nRead 
= stream
.LastRead(); 
2260         if ( !nRead 
|| !file
.Write(buf
, nRead
) ) 
2263     while ( !stream
.Eof() ); 
2268 #endif // wxUSE_STD_IOSTREAM/!wxUSE_STD_IOSTREAM 
2270 #endif // wxUSE_DOC_VIEW_ARCHITECTURE