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" 
  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" 
  60 #include "wx/cmdproc.h" 
  65 #if wxUSE_STD_IOSTREAM 
  66   #include "wx/ioswrap.h" 
  73   #include "wx/wfstream.h" 
  76 // ---------------------------------------------------------------------------- 
  78 // ---------------------------------------------------------------------------- 
  80 IMPLEMENT_ABSTRACT_CLASS(wxDocument
, wxEvtHandler
) 
  81 IMPLEMENT_ABSTRACT_CLASS(wxView
, wxEvtHandler
) 
  82 IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate
, wxObject
) 
  83 IMPLEMENT_DYNAMIC_CLASS(wxDocManager
, wxEvtHandler
) 
  84 IMPLEMENT_CLASS(wxDocChildFrame
, wxFrame
) 
  85 IMPLEMENT_CLASS(wxDocParentFrame
, wxFrame
) 
  87 #if wxUSE_PRINTING_ARCHITECTURE 
  88     IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout
, wxPrintout
) 
  91 IMPLEMENT_DYNAMIC_CLASS(wxFileHistory
, wxObject
) 
  93 // ---------------------------------------------------------------------------- 
  94 // function prototypes 
  95 // ---------------------------------------------------------------------------- 
  97 static inline wxString 
FindExtension(const wxChar 
*path
); 
  99 // ---------------------------------------------------------------------------- 
 101 // ---------------------------------------------------------------------------- 
 103 static const wxChar 
*s_MRUEntryFormat 
= wxT("&%d %s"); 
 105 // ============================================================================ 
 107 // ============================================================================ 
 109 // ---------------------------------------------------------------------------- 
 111 // ---------------------------------------------------------------------------- 
 113 static wxString 
FindExtension(const wxChar 
*path
) 
 116     wxSplitPath(path
, NULL
, NULL
, &ext
); 
 118     // VZ: extensions are considered not case sensitive - is this really a good 
 120     return ext
.MakeLower(); 
 123 // ---------------------------------------------------------------------------- 
 124 // Definition of wxDocument 
 125 // ---------------------------------------------------------------------------- 
 127 wxDocument::wxDocument(wxDocument 
*parent
) 
 129     m_documentModified 
= FALSE
; 
 130     m_documentParent 
= parent
; 
 131     m_documentTemplate 
= (wxDocTemplate 
*) NULL
; 
 132     m_commandProcessor 
= (wxCommandProcessor
*) NULL
; 
 136 bool wxDocument::DeleteContents() 
 141 wxDocument::~wxDocument() 
 145     if (m_commandProcessor
) 
 146         delete m_commandProcessor
; 
 148     if (GetDocumentManager()) 
 149         GetDocumentManager()->RemoveDocument(this); 
 151     // Not safe to do here, since it'll invoke virtual view functions 
 152     // expecting to see valid derived objects: and by the time we get here, 
 153     // we've called destructors higher up. 
 157 bool wxDocument::Close() 
 159     if (OnSaveModified()) 
 160         return OnCloseDocument(); 
 165 bool wxDocument::OnCloseDocument() 
 172 // Note that this implicitly deletes the document when the last view is 
 174 bool wxDocument::DeleteAllViews() 
 176     wxDocManager
* manager 
= GetDocumentManager(); 
 178     wxNode 
*node 
= m_documentViews
.First(); 
 181         wxView 
*view 
= (wxView 
*)node
->Data(); 
 185         wxNode 
*next 
= node
->Next(); 
 187         delete view
; // Deletes node implicitly 
 190     // If we haven't yet deleted the document (for example 
 191     // if there were no views) then delete it. 
 192     if (manager 
&& manager
->GetDocuments().Member(this)) 
 198 wxView 
*wxDocument::GetFirstView() const 
 200     if (m_documentViews
.Number() == 0) 
 201         return (wxView 
*) NULL
; 
 202     return (wxView 
*)m_documentViews
.First()->Data(); 
 205 wxDocManager 
*wxDocument::GetDocumentManager() const 
 207     return (m_documentTemplate 
? m_documentTemplate
->GetDocumentManager() : (wxDocManager
*) NULL
); 
 210 bool wxDocument::OnNewDocument() 
 212     if (!OnSaveModified()) 
 215     if (OnCloseDocument()==FALSE
) return FALSE
; 
 218     SetDocumentSaved(FALSE
); 
 221     GetDocumentManager()->MakeDefaultName(name
); 
 223     SetFilename(name
, TRUE
); 
 228 bool wxDocument::Save() 
 230     if (!IsModified() && m_savedYet
) 
 233     if ( m_documentFile
.empty() || !m_savedYet 
) 
 236     return OnSaveDocument(m_documentFile
); 
 239 bool wxDocument::SaveAs() 
 241     wxDocTemplate 
*docTemplate 
= GetDocumentTemplate(); 
 245     wxString tmp 
= wxFileSelector(_("Save as"), 
 246             docTemplate
->GetDirectory(), 
 247             wxFileNameFromPath(GetFilename()), 
 248             docTemplate
->GetDefaultExtension(), 
 249             docTemplate
->GetFileFilter(), 
 250             wxSAVE 
| wxOVERWRITE_PROMPT
, 
 251             GetDocumentWindow()); 
 256     wxString 
fileName(tmp
); 
 257     wxString path
, name
, ext
; 
 258     wxSplitPath(fileName
, & path
, & name
, & ext
); 
 260     if (ext
.IsEmpty() || ext 
== wxT("")) 
 263         fileName 
+= docTemplate
->GetDefaultExtension(); 
 266     SetFilename(fileName
); 
 267     SetTitle(wxFileNameFromPath(fileName
)); 
 269     GetDocumentManager()->AddFileToHistory(fileName
); 
 271     // Notify the views that the filename has changed 
 272     wxNode 
*node 
= m_documentViews
.First(); 
 275         wxView 
*view 
= (wxView 
*)node
->Data(); 
 276         view
->OnChangeFilename(); 
 280     return OnSaveDocument(m_documentFile
); 
 283 bool wxDocument::OnSaveDocument(const wxString
& file
) 
 289     if (wxTheApp
->GetAppName() != wxT("")) 
 290         msgTitle 
= wxTheApp
->GetAppName(); 
 292         msgTitle 
= wxString(_("File error")); 
 294 #if wxUSE_STD_IOSTREAM 
 295     wxSTD ofstream 
store(wxString(file
.fn_str()).mb_str()); 
 296     if (store
.fail() || store
.bad()) 
 298     wxFileOutputStream 
store(wxString(file
.fn_str())); 
 299     if (store
.LastError() != wxSTREAM_NOERROR
) 
 302         (void)wxMessageBox(_("Sorry, could not open this file for saving."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 303                            GetDocumentWindow()); 
 307     if (!SaveObject(store
)) 
 309         (void)wxMessageBox(_("Sorry, could not save this file."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
 310                            GetDocumentWindow()); 
 316     SetDocumentSaved(TRUE
); 
 320 bool wxDocument::OnOpenDocument(const wxString
& file
) 
 322     if (!OnSaveModified()) 
 326     if (wxTheApp
->GetAppName() != wxT("")) 
 327         msgTitle 
= wxTheApp
->GetAppName(); 
 329         msgTitle 
= wxString(_("File error")); 
 331 #if wxUSE_STD_IOSTREAM 
 332     wxSTD ifstream 
store(wxString(file
.fn_str()).mb_str()); 
 333     if (store
.fail() || store
.bad()) 
 335     wxFileInputStream 
store(wxString(file
.fn_str())); 
 336     if (store
.LastError() != wxSTREAM_NOERROR
) 
 339         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 340                            GetDocumentWindow()); 
 343 #if wxUSE_STD_IOSTREAM 
 345     if ( !store 
&& !store
.eof() ) 
 347     int res 
= LoadObject(store
).LastError(); 
 348     if ((res 
!= wxSTREAM_NOERROR
) && 
 349         (res 
!= wxSTREAM_EOF
)) 
 352         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK
|wxICON_EXCLAMATION
, 
 353                            GetDocumentWindow()); 
 356     SetFilename(file
, TRUE
); 
 365 #if wxUSE_STD_IOSTREAM 
 366 wxSTD istream
& wxDocument::LoadObject(wxSTD istream
& stream
) 
 368 wxInputStream
& wxDocument::LoadObject(wxInputStream
& stream
) 
 374 #if wxUSE_STD_IOSTREAM 
 375 wxSTD ostream
& wxDocument::SaveObject(wxSTD ostream
& stream
) 
 377 wxOutputStream
& wxDocument::SaveObject(wxOutputStream
& stream
) 
 383 bool wxDocument::Revert() 
 389 // Get title, or filename if no title, else unnamed 
 390 bool wxDocument::GetPrintableName(wxString
& buf
) const 
 392     if (m_documentTitle 
!= wxT("")) 
 394         buf 
= m_documentTitle
; 
 397     else if (m_documentFile 
!= wxT("")) 
 399         buf 
= wxFileNameFromPath(m_documentFile
); 
 409 wxWindow 
*wxDocument::GetDocumentWindow() const 
 411     wxView 
*view 
= GetFirstView(); 
 413         return view
->GetFrame(); 
 415         return wxTheApp
->GetTopWindow(); 
 418 wxCommandProcessor 
*wxDocument::OnCreateCommandProcessor() 
 420     return new wxCommandProcessor
; 
 423 // TRUE if safe to close 
 424 bool wxDocument::OnSaveModified() 
 429         GetPrintableName(title
); 
 432         if (wxTheApp
->GetAppName() != wxT("")) 
 433             msgTitle 
= wxTheApp
->GetAppName(); 
 435             msgTitle 
= wxString(_("Warning")); 
 438         prompt
.Printf(_("Do you want to save changes to document %s?"), 
 439                 (const wxChar 
*)title
); 
 440         int res 
= wxMessageBox(prompt
, msgTitle
, 
 441                 wxYES_NO
|wxCANCEL
|wxICON_QUESTION
, 
 442                 GetDocumentWindow()); 
 448         else if (res 
== wxYES
) 
 450         else if (res 
== wxCANCEL
) 
 456 bool wxDocument::Draw(wxDC
& WXUNUSED(context
)) 
 461 bool wxDocument::AddView(wxView 
*view
) 
 463     if (!m_documentViews
.Member(view
)) 
 465         m_documentViews
.Append(view
); 
 471 bool wxDocument::RemoveView(wxView 
*view
) 
 473     (void)m_documentViews
.DeleteObject(view
); 
 478 bool wxDocument::OnCreate(const wxString
& WXUNUSED(path
), long flags
) 
 480     if (GetDocumentTemplate()->CreateView(this, flags
)) 
 486 // Called after a view is added or removed. 
 487 // The default implementation deletes the document if 
 488 // there are no more views. 
 489 void wxDocument::OnChangedViewList() 
 491     if (m_documentViews
.Number() == 0) 
 493         if (OnSaveModified()) 
 500 void wxDocument::UpdateAllViews(wxView 
*sender
, wxObject 
*hint
) 
 502     wxNode 
*node 
= m_documentViews
.First(); 
 505         wxView 
*view 
= (wxView 
*)node
->Data(); 
 506         view
->OnUpdate(sender
, hint
); 
 511 void wxDocument::SetFilename(const wxString
& filename
, bool notifyViews
) 
 513     m_documentFile 
= filename
; 
 516         // Notify the views that the filename has changed 
 517         wxNode 
*node 
= m_documentViews
.First(); 
 520             wxView 
*view 
= (wxView 
*)node
->Data(); 
 521             view
->OnChangeFilename(); 
 527 // ---------------------------------------------------------------------------- 
 529 // ---------------------------------------------------------------------------- 
 534     m_viewDocument 
= (wxDocument
*) NULL
; 
 536     m_viewTypeName 
= wxT(""); 
 537     m_viewFrame 
= (wxFrame 
*) NULL
; 
 542 //    GetDocumentManager()->ActivateView(this, FALSE, TRUE); 
 543     m_viewDocument
->RemoveView(this); 
 546 // Extend event processing to search the document's event table 
 547 bool wxView::ProcessEvent(wxEvent
& event
) 
 549     if ( !GetDocument() || !GetDocument()->ProcessEvent(event
) ) 
 550         return wxEvtHandler::ProcessEvent(event
); 
 555 void wxView::OnActivateView(bool WXUNUSED(activate
), wxView 
*WXUNUSED(activeView
), wxView 
*WXUNUSED(deactiveView
)) 
 559 void wxView::OnPrint(wxDC 
*dc
, wxObject 
*WXUNUSED(info
)) 
 564 void wxView::OnUpdate(wxView 
*WXUNUSED(sender
), wxObject 
*WXUNUSED(hint
)) 
 568 void wxView::OnChangeFilename() 
 570     if (GetFrame() && GetDocument()) 
 574         GetDocument()->GetPrintableName(title
); 
 576         GetFrame()->SetTitle(title
); 
 580 void wxView::SetDocument(wxDocument 
*doc
) 
 582     m_viewDocument 
= doc
; 
 587 bool wxView::Close(bool deleteWindow
) 
 589     if (OnClose(deleteWindow
)) 
 595 void wxView::Activate(bool activate
) 
 597     if (GetDocumentManager()) 
 599         OnActivateView(activate
, this, GetDocumentManager()->GetCurrentView()); 
 600         GetDocumentManager()->ActivateView(this, activate
); 
 604 bool wxView::OnClose(bool WXUNUSED(deleteWindow
)) 
 606     return GetDocument() ? GetDocument()->Close() : TRUE
; 
 609 #if wxUSE_PRINTING_ARCHITECTURE 
 610 wxPrintout 
*wxView::OnCreatePrintout() 
 612     return new wxDocPrintout(this); 
 614 #endif // wxUSE_PRINTING_ARCHITECTURE 
 616 // ---------------------------------------------------------------------------- 
 618 // ---------------------------------------------------------------------------- 
 620 wxDocTemplate::wxDocTemplate(wxDocManager 
*manager
, 
 621                              const wxString
& descr
, 
 622                              const wxString
& filter
, 
 625                              const wxString
& docTypeName
, 
 626                              const wxString
& viewTypeName
, 
 627                              wxClassInfo 
*docClassInfo
, 
 628                              wxClassInfo 
*viewClassInfo
, 
 631     m_documentManager 
= manager
; 
 632     m_description 
= descr
; 
 635     m_fileFilter 
= filter
; 
 637     m_docTypeName 
= docTypeName
; 
 638     m_viewTypeName 
= viewTypeName
; 
 639     m_documentManager
->AssociateTemplate(this); 
 641     m_docClassInfo 
= docClassInfo
; 
 642     m_viewClassInfo 
= viewClassInfo
; 
 645 wxDocTemplate::~wxDocTemplate() 
 647     m_documentManager
->DisassociateTemplate(this); 
 650 // Tries to dynamically construct an object of the right class. 
 651 wxDocument 
*wxDocTemplate::CreateDocument(const wxString
& path
, long flags
) 
 654         return (wxDocument 
*) NULL
; 
 655     wxDocument 
*doc 
= (wxDocument 
*)m_docClassInfo
->CreateObject(); 
 656     doc
->SetFilename(path
); 
 657     doc
->SetDocumentTemplate(this); 
 658     GetDocumentManager()->AddDocument(doc
); 
 659     doc
->SetCommandProcessor(doc
->OnCreateCommandProcessor()); 
 661     if (doc
->OnCreate(path
, flags
)) 
 665         if (GetDocumentManager()->GetDocuments().Member(doc
)) 
 666             doc
->DeleteAllViews(); 
 667         return (wxDocument 
*) NULL
; 
 671 wxView 
*wxDocTemplate::CreateView(wxDocument 
*doc
, long flags
) 
 673     if (!m_viewClassInfo
) 
 674         return (wxView 
*) NULL
; 
 675     wxView 
*view 
= (wxView 
*)m_viewClassInfo
->CreateObject(); 
 676     view
->SetDocument(doc
); 
 677     if (view
->OnCreate(doc
, flags
)) 
 684         return (wxView 
*) NULL
; 
 688 // The default (very primitive) format detection: check is the extension is 
 689 // that of the template 
 690 bool wxDocTemplate::FileMatchesTemplate(const wxString
& path
) 
 692     return GetDefaultExtension().IsSameAs(FindExtension(path
)); 
 695 // ---------------------------------------------------------------------------- 
 697 // ---------------------------------------------------------------------------- 
 699 BEGIN_EVENT_TABLE(wxDocManager
, wxEvtHandler
) 
 700     EVT_MENU(wxID_OPEN
, wxDocManager::OnFileOpen
) 
 701     EVT_MENU(wxID_CLOSE
, wxDocManager::OnFileClose
) 
 702     EVT_MENU(wxID_CLOSE_ALL
, wxDocManager::OnFileCloseAll
) 
 703     EVT_MENU(wxID_REVERT
, wxDocManager::OnFileRevert
) 
 704     EVT_MENU(wxID_NEW
, wxDocManager::OnFileNew
) 
 705     EVT_MENU(wxID_SAVE
, wxDocManager::OnFileSave
) 
 706     EVT_MENU(wxID_SAVEAS
, wxDocManager::OnFileSaveAs
) 
 707     EVT_MENU(wxID_UNDO
, wxDocManager::OnUndo
) 
 708     EVT_MENU(wxID_REDO
, wxDocManager::OnRedo
) 
 710     EVT_UPDATE_UI(wxID_OPEN
, wxDocManager::OnUpdateFileOpen
) 
 711     EVT_UPDATE_UI(wxID_CLOSE
, wxDocManager::OnUpdateFileClose
) 
 712     EVT_UPDATE_UI(wxID_CLOSE_ALL
, wxDocManager::OnUpdateFileClose
) 
 713     EVT_UPDATE_UI(wxID_REVERT
, wxDocManager::OnUpdateFileRevert
) 
 714     EVT_UPDATE_UI(wxID_NEW
, wxDocManager::OnUpdateFileNew
) 
 715     EVT_UPDATE_UI(wxID_SAVE
, wxDocManager::OnUpdateFileSave
) 
 716     EVT_UPDATE_UI(wxID_SAVEAS
, wxDocManager::OnUpdateFileSaveAs
) 
 717     EVT_UPDATE_UI(wxID_UNDO
, wxDocManager::OnUpdateUndo
) 
 718     EVT_UPDATE_UI(wxID_REDO
, wxDocManager::OnUpdateRedo
) 
 720 #if wxUSE_PRINTING_ARCHITECTURE 
 721     EVT_MENU(wxID_PRINT
, wxDocManager::OnPrint
) 
 722     EVT_MENU(wxID_PRINT_SETUP
, wxDocManager::OnPrintSetup
) 
 723     EVT_MENU(wxID_PREVIEW
, wxDocManager::OnPreview
) 
 725     EVT_UPDATE_UI(wxID_PRINT
, wxDocManager::OnUpdatePrint
) 
 726     EVT_UPDATE_UI(wxID_PRINT_SETUP
, wxDocManager::OnUpdatePrintSetup
) 
 727     EVT_UPDATE_UI(wxID_PREVIEW
, wxDocManager::OnUpdatePreview
) 
 731 wxDocManager
* wxDocManager::sm_docManager 
= (wxDocManager
*) NULL
; 
 733 wxDocManager::wxDocManager(long flags
, bool initialize
) 
 735     m_defaultDocumentNameCounter 
= 1; 
 737     m_currentView 
= (wxView 
*) NULL
; 
 738     m_maxDocsOpen 
= 10000; 
 739     m_fileHistory 
= (wxFileHistory 
*) NULL
; 
 742     sm_docManager 
= this; 
 745 wxDocManager::~wxDocManager() 
 749         delete m_fileHistory
; 
 750     sm_docManager 
= (wxDocManager
*) NULL
; 
 753 bool wxDocManager::CloseDocuments(bool force
) 
 755     wxNode 
*node 
= m_docs
.First(); 
 758         wxDocument 
*doc 
= (wxDocument 
*)node
->Data(); 
 759         wxNode 
*next 
= node
->Next(); 
 761         if (!doc
->Close() && !force
) 
 764         // Implicitly deletes the document when the last 
 765         // view is removed (deleted) 
 766         doc
->DeleteAllViews(); 
 768         // Check document is deleted 
 769         if (m_docs
.Member(doc
)) 
 772         // This assumes that documents are not connected in 
 773         // any way, i.e. deleting one document does NOT 
 780 bool wxDocManager::Clear(bool force
) 
 782     if (!CloseDocuments(force
)) 
 785     wxNode 
*node 
= m_templates
.First(); 
 788         wxDocTemplate 
*templ 
= (wxDocTemplate
*) node
->Data(); 
 789         wxNode
* next 
= node
->Next(); 
 796 bool wxDocManager::Initialize() 
 798     m_fileHistory 
= OnCreateFileHistory(); 
 802 wxFileHistory 
*wxDocManager::OnCreateFileHistory() 
 804     return new wxFileHistory
; 
 807 void wxDocManager::OnFileClose(wxCommandEvent
& WXUNUSED(event
)) 
 809     wxDocument 
*doc 
= GetCurrentDocument(); 
 814         doc
->DeleteAllViews(); 
 815         if (m_docs
.Member(doc
)) 
 820 void wxDocManager::OnFileCloseAll(wxCommandEvent
& WXUNUSED(event
)) 
 822     CloseDocuments(FALSE
); 
 825 void wxDocManager::OnFileNew(wxCommandEvent
& WXUNUSED(event
)) 
 827     CreateDocument(wxString(""), wxDOC_NEW
); 
 830 void wxDocManager::OnFileOpen(wxCommandEvent
& WXUNUSED(event
)) 
 832     if ( !CreateDocument(wxString(""), 0) ) 
 838 void wxDocManager::OnFileRevert(wxCommandEvent
& WXUNUSED(event
)) 
 840     wxDocument 
*doc 
= GetCurrentDocument(); 
 846 void wxDocManager::OnFileSave(wxCommandEvent
& WXUNUSED(event
)) 
 848     wxDocument 
*doc 
= GetCurrentDocument(); 
 854 void wxDocManager::OnFileSaveAs(wxCommandEvent
& WXUNUSED(event
)) 
 856     wxDocument 
*doc 
= GetCurrentDocument(); 
 862 void wxDocManager::OnPrint(wxCommandEvent
& WXUNUSED(event
)) 
 864 #if wxUSE_PRINTING_ARCHITECTURE 
 865     wxView 
*view 
= GetCurrentView(); 
 869     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 873         printer
.Print(view
->GetFrame(), printout
, TRUE
); 
 877 #endif // wxUSE_PRINTING_ARCHITECTURE 
 880 void wxDocManager::OnPrintSetup(wxCommandEvent
& WXUNUSED(event
)) 
 882 #if wxUSE_PRINTING_ARCHITECTURE 
 883     wxWindow 
*parentWin 
= wxTheApp
->GetTopWindow(); 
 884     wxView 
*view 
= GetCurrentView(); 
 886         parentWin 
= view
->GetFrame(); 
 888     wxPrintDialogData data
; 
 890     wxPrintDialog 
printerDialog(parentWin
, &data
); 
 891     printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
); 
 892     printerDialog
.ShowModal(); 
 893 #endif // wxUSE_PRINTING_ARCHITECTURE 
 896 void wxDocManager::OnPreview(wxCommandEvent
& WXUNUSED(event
)) 
 898 #if wxUSE_PRINTING_ARCHITECTURE 
 899     wxView 
*view 
= GetCurrentView(); 
 903     wxPrintout 
*printout 
= view
->OnCreatePrintout(); 
 906         // Pass two printout objects: for preview, and possible printing. 
 907         wxPrintPreviewBase 
*preview 
= (wxPrintPreviewBase 
*) NULL
; 
 908         preview 
= new wxPrintPreview(printout
, view
->OnCreatePrintout()); 
 910         wxPreviewFrame 
*frame 
= new wxPreviewFrame(preview
, (wxFrame 
*)wxTheApp
->GetTopWindow(), _("Print Preview"), 
 911                 wxPoint(100, 100), wxSize(600, 650)); 
 912         frame
->Centre(wxBOTH
); 
 916 #endif // wxUSE_PRINTING_ARCHITECTURE 
 919 void wxDocManager::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 921     wxDocument 
*doc 
= GetCurrentDocument(); 
 924     if (doc
->GetCommandProcessor()) 
 925         doc
->GetCommandProcessor()->Undo(); 
 928 void wxDocManager::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 930     wxDocument 
*doc 
= GetCurrentDocument(); 
 933     if (doc
->GetCommandProcessor()) 
 934         doc
->GetCommandProcessor()->Redo(); 
 937 // Handlers for UI update commands 
 939 void wxDocManager::OnUpdateFileOpen(wxUpdateUIEvent
& event
) 
 941     event
.Enable( TRUE 
); 
 944 void wxDocManager::OnUpdateFileClose(wxUpdateUIEvent
& event
) 
 946     wxDocument 
*doc 
= GetCurrentDocument(); 
 947     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 950 void wxDocManager::OnUpdateFileRevert(wxUpdateUIEvent
& event
) 
 952     wxDocument 
*doc 
= GetCurrentDocument(); 
 953     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 956 void wxDocManager::OnUpdateFileNew(wxUpdateUIEvent
& event
) 
 958     event
.Enable( TRUE 
); 
 961 void wxDocManager::OnUpdateFileSave(wxUpdateUIEvent
& event
) 
 963     wxDocument 
*doc 
= GetCurrentDocument(); 
 964     event
.Enable( doc 
&& doc
->IsModified() ); 
 967 void wxDocManager::OnUpdateFileSaveAs(wxUpdateUIEvent
& event
) 
 969     wxDocument 
*doc 
= GetCurrentDocument(); 
 970     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 973 void wxDocManager::OnUpdateUndo(wxUpdateUIEvent
& event
) 
 975     wxDocument 
*doc 
= GetCurrentDocument(); 
 976     event
.Enable( (doc 
&& doc
->GetCommandProcessor() && doc
->GetCommandProcessor()->CanUndo()) ); 
 977     if (doc 
&& doc
->GetCommandProcessor()) 
 978         doc
->GetCommandProcessor()->SetMenuStrings(); 
 981 void wxDocManager::OnUpdateRedo(wxUpdateUIEvent
& event
) 
 983     wxDocument 
*doc 
= GetCurrentDocument(); 
 984     event
.Enable( (doc 
&& doc
->GetCommandProcessor() && doc
->GetCommandProcessor()->CanRedo()) ); 
 985     if (doc 
&& doc
->GetCommandProcessor()) 
 986         doc
->GetCommandProcessor()->SetMenuStrings(); 
 989 void wxDocManager::OnUpdatePrint(wxUpdateUIEvent
& event
) 
 991     wxDocument 
*doc 
= GetCurrentDocument(); 
 992     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
 995 void wxDocManager::OnUpdatePrintSetup(wxUpdateUIEvent
& event
) 
 997     event
.Enable( TRUE 
); 
1000 void wxDocManager::OnUpdatePreview(wxUpdateUIEvent
& event
) 
1002     wxDocument 
*doc 
= GetCurrentDocument(); 
1003     event
.Enable( (doc 
!= (wxDocument
*) NULL
) ); 
1006 wxView 
*wxDocManager::GetCurrentView() const 
1009         return m_currentView
; 
1010     if (m_docs
.Number() == 1) 
1012         wxDocument
* doc 
= (wxDocument
*) m_docs
.First()->Data(); 
1013         return doc
->GetFirstView(); 
1015     return (wxView 
*) NULL
; 
1018 // Extend event processing to search the view's event table 
1019 bool wxDocManager::ProcessEvent(wxEvent
& event
) 
1021     wxView
* view 
= GetCurrentView(); 
1024         if (view
->ProcessEvent(event
)) 
1027     return wxEvtHandler::ProcessEvent(event
); 
1030 wxDocument 
*wxDocManager::CreateDocument(const wxString
& path
, long flags
) 
1032     wxDocTemplate 
**templates 
= new wxDocTemplate 
*[m_templates
.Number()]; 
1035     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1037         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Nth(i
)->Data()); 
1038         if (temp
->IsVisible()) 
1040             templates
[n
] = temp
; 
1047         return (wxDocument 
*) NULL
; 
1050     // If we've reached the max number of docs, close the 
1052     if (GetDocuments().Number() >= m_maxDocsOpen
) 
1054         wxDocument 
*doc 
= (wxDocument 
*)GetDocuments().First()->Data(); 
1057             // Implicitly deletes the document when 
1058             // the last view is deleted 
1059             doc
->DeleteAllViews(); 
1061             // Check we're really deleted 
1062             if (m_docs
.Member(doc
)) 
1068             return (wxDocument 
*) NULL
; 
1072     // New document: user chooses a template, unless there's only one. 
1073     if (flags 
& wxDOC_NEW
) 
1077             wxDocTemplate 
*temp 
= templates
[0]; 
1079             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
1082                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1083                 newDoc
->SetDocumentTemplate(temp
); 
1084                 newDoc
->OnNewDocument(); 
1089         wxDocTemplate 
*temp 
= SelectDocumentType(templates
, n
); 
1093             wxDocument 
*newDoc 
= temp
->CreateDocument(path
, flags
); 
1096                 newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1097                 newDoc
->SetDocumentTemplate(temp
); 
1098                 newDoc
->OnNewDocument(); 
1103             return (wxDocument 
*) NULL
; 
1106     // Existing document 
1107     wxDocTemplate 
*temp 
= (wxDocTemplate 
*) NULL
; 
1109     wxString 
path2(wxT("")); 
1110     if (path 
!= wxT("")) 
1113     if (flags 
& wxDOC_SILENT
) 
1114         temp 
= FindTemplateForPath(path2
); 
1116         temp 
= SelectDocumentPath(templates
, n
, path2
, flags
); 
1122         wxDocument 
*newDoc 
= temp
->CreateDocument(path2
, flags
); 
1125             newDoc
->SetDocumentName(temp
->GetDocumentName()); 
1126             newDoc
->SetDocumentTemplate(temp
); 
1127             if (!newDoc
->OnOpenDocument(path2
)) 
1129                 newDoc
->DeleteAllViews(); 
1130                 // delete newDoc; // Implicitly deleted by DeleteAllViews 
1131                 return (wxDocument 
*) NULL
; 
1133             AddFileToHistory(path2
); 
1138     return (wxDocument 
*) NULL
; 
1141 wxView 
*wxDocManager::CreateView(wxDocument 
*doc
, long flags
) 
1143     wxDocTemplate 
**templates 
= new wxDocTemplate 
*[m_templates
.Number()]; 
1146     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1148         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)(m_templates
.Nth(i
)->Data()); 
1149         if (temp
->IsVisible()) 
1151             if (temp
->GetDocumentName() == doc
->GetDocumentName()) 
1153                 templates
[n
] = temp
; 
1161         return (wxView 
*) NULL
; 
1165         wxDocTemplate 
*temp 
= templates
[0]; 
1167         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1169             view
->SetViewName(temp
->GetViewName()); 
1173     wxDocTemplate 
*temp 
= SelectViewType(templates
, n
); 
1177         wxView 
*view 
= temp
->CreateView(doc
, flags
); 
1179             view
->SetViewName(temp
->GetViewName()); 
1183         return (wxView 
*) NULL
; 
1186 // Not yet implemented 
1187 void wxDocManager::DeleteTemplate(wxDocTemplate 
*WXUNUSED(temp
), long WXUNUSED(flags
)) 
1191 // Not yet implemented 
1192 bool wxDocManager::FlushDoc(wxDocument 
*WXUNUSED(doc
)) 
1197 wxDocument 
*wxDocManager::GetCurrentDocument() const 
1199     wxView 
*view 
= GetCurrentView(); 
1201         return view
->GetDocument(); 
1203         return (wxDocument 
*) NULL
; 
1206 // Make a default document name 
1207 bool wxDocManager::MakeDefaultName(wxString
& name
) 
1209     name
.Printf(_("unnamed%d"), m_defaultDocumentNameCounter
); 
1210     m_defaultDocumentNameCounter
++; 
1215 // Make a frame title (override this to do something different) 
1216 // If docName is empty, a document is not currently active. 
1217 wxString 
wxDocManager::MakeFrameTitle(wxDocument
* doc
) 
1219     wxString appName 
= wxTheApp
->GetAppName(); 
1226         doc
->GetPrintableName(docName
); 
1227         title 
= docName 
+ wxString(_(" - ")) + appName
; 
1233 // Not yet implemented 
1234 wxDocTemplate 
*wxDocManager::MatchTemplate(const wxString
& WXUNUSED(path
)) 
1236     return (wxDocTemplate 
*) NULL
; 
1239 // File history management 
1240 void wxDocManager::AddFileToHistory(const wxString
& file
) 
1243         m_fileHistory
->AddFileToHistory(file
); 
1246 void wxDocManager::RemoveFileFromHistory(int i
) 
1249         m_fileHistory
->RemoveFileFromHistory(i
); 
1252 wxString 
wxDocManager::GetHistoryFile(int i
) const 
1257         histFile 
= m_fileHistory
->GetHistoryFile(i
); 
1262 void wxDocManager::FileHistoryUseMenu(wxMenu 
*menu
) 
1265         m_fileHistory
->UseMenu(menu
); 
1268 void wxDocManager::FileHistoryRemoveMenu(wxMenu 
*menu
) 
1271         m_fileHistory
->RemoveMenu(menu
); 
1275 void wxDocManager::FileHistoryLoad(wxConfigBase
& config
) 
1278         m_fileHistory
->Load(config
); 
1281 void wxDocManager::FileHistorySave(wxConfigBase
& config
) 
1284         m_fileHistory
->Save(config
); 
1288 void wxDocManager::FileHistoryAddFilesToMenu(wxMenu
* menu
) 
1291         m_fileHistory
->AddFilesToMenu(menu
); 
1294 void wxDocManager::FileHistoryAddFilesToMenu() 
1297         m_fileHistory
->AddFilesToMenu(); 
1300 int wxDocManager::GetNoHistoryFiles() const 
1303         return m_fileHistory
->GetNoHistoryFiles(); 
1309 // Find out the document template via matching in the document file format 
1310 // against that of the template 
1311 wxDocTemplate 
*wxDocManager::FindTemplateForPath(const wxString
& path
) 
1313     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*) NULL
; 
1315     // Find the template which this extension corresponds to 
1317     for (i 
= 0; i 
< m_templates
.Number(); i
++) 
1319         wxDocTemplate 
*temp 
= (wxDocTemplate 
*)m_templates
.Nth(i
)->Data(); 
1320         if ( temp
->FileMatchesTemplate(path
) ) 
1329 // Try to get a more suitable parent frame than the top window, 
1330 // for selection dialogs. Otherwise you may get an unexpected 
1331 // window being activated when a dialog is shown. 
1332 static wxWindow
* wxFindSuitableParent() 
1334     wxWindow
* parent 
= wxTheApp
->GetTopWindow(); 
1336     wxWindow
* focusWindow 
= wxWindow::FindFocus(); 
1339         while (focusWindow 
&& 
1340                 !focusWindow
->IsKindOf(CLASSINFO(wxDialog
)) && 
1341                 !focusWindow
->IsKindOf(CLASSINFO(wxFrame
))) 
1343             focusWindow 
= focusWindow
->GetParent(); 
1346             parent 
= focusWindow
; 
1351 // Prompts user to open a file, using file specs in templates. 
1352 // How to implement in wxWindows? Must extend the file selector 
1353 // dialog or implement own; OR match the extension to the 
1354 // template extension. 
1356 wxDocTemplate 
*wxDocManager::SelectDocumentPath(wxDocTemplate 
**templates
, 
1357 #if defined(__WXMSW__) || defined(__WXGTK__) 
1360                                                 int WXUNUSED(noTemplates
), 
1363                                                 long WXUNUSED(flags
), 
1364                                                 bool WXUNUSED(save
)) 
1366     // We can only have multiple filters in Windows and GTK 
1367 #if defined(__WXMSW__) || defined(__WXGTK__) 
1371     for (i 
= 0; i 
< noTemplates
; i
++) 
1373         if (templates
[i
]->IsVisible()) 
1375             // add a '|' to separate this filter from the previous one 
1376             if ( !descrBuf
.IsEmpty() ) 
1377                 descrBuf 
<< wxT('|'); 
1379             descrBuf 
<< templates
[i
]->GetDescription() 
1380                 << wxT(" (") << templates
[i
]->GetFileFilter() << wxT(") |") 
1381                 << templates
[i
]->GetFileFilter(); 
1385     wxString descrBuf 
= wxT("*.*"); 
1388     int FilterIndex 
= -1; 
1390     wxWindow
* parent 
= wxFindSuitableParent(); 
1392     wxString pathTmp 
= wxFileSelectorEx(_("Select a file"), 
1400     wxDocTemplate 
*theTemplate 
= (wxDocTemplate 
*)NULL
; 
1401     if (!pathTmp
.IsEmpty()) 
1403         if (!wxFileExists(pathTmp
)) 
1406             if (!wxTheApp
->GetAppName().IsEmpty()) 
1407                 msgTitle 
= wxTheApp
->GetAppName(); 
1409                 msgTitle 
= wxString(_("File error")); 
1411             (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle
, wxOK 
| wxICON_EXCLAMATION
, 
1415             return (wxDocTemplate 
*) NULL
; 
1417         m_lastDirectory 
= wxPathOnly(pathTmp
); 
1421         // first choose the template using the extension, if this fails (i.e. 
1422         // wxFileSelectorEx() didn't fill it), then use the path 
1423         if ( FilterIndex 
!= -1 ) 
1424             theTemplate 
= templates
[FilterIndex
]; 
1426             theTemplate 
= FindTemplateForPath(path
); 
1436     // In all other windowing systems, until we have more advanced 
1437     // file selectors, we must select the document type (template) first, and 
1438     // _then_ pop up the file selector. 
1439     wxDocTemplate 
*temp 
= SelectDocumentType(templates
, noTemplates
); 
1441         return (wxDocTemplate 
*) NULL
; 
1443     wxChar 
*pathTmp 
= wxFileSelector(_("Select a file"), wxT(""), wxT(""), 
1444             temp
->GetDefaultExtension(), 
1445             temp
->GetFileFilter(), 
1446             0, wxTheApp
->GetTopWindow()); 
1454         return (wxDocTemplate 
*) NULL
; 
1458 wxDocTemplate 
*wxDocManager::SelectDocumentType(wxDocTemplate 
**templates
, 
1459                                                 int noTemplates
, bool sort
) 
1461     wxArrayString 
strings(sort
); 
1462     wxDocTemplate 
**data 
= new wxDocTemplate 
*[noTemplates
]; 
1465         for (i 
= 0; i 
< noTemplates
; i
++) 
1467                 if (templates
[i
]->IsVisible()) 
1469                         strings
.Add(templates
[i
]->m_description
); 
1472                                 data
[n
] = templates
[i
]; 
1480                 // Yes, this will be slow, but template lists 
1481                 // are typically short. 
1483                 n 
= strings
.Count(); 
1484                 for (i 
= 0; i 
< n
; i
++) 
1486                         for (j 
= 0; j 
< noTemplates
; j
++) 
1488                                 if (strings
[i
] == templates
[j
]->m_description
) 
1489                                         data
[i
] = templates
[j
]; 
1494     wxDocTemplate 
*theTemplate
; 
1499             // no visible templates, hence nothing to choose from 
1504             // don't propose the user to choose if he heas no choice 
1505             theTemplate 
= data
[0]; 
1509             // propose the user to choose one of several 
1510             theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData
 
1512                             _("Select a document template"), 
1516                             wxFindSuitableParent() 
1525 wxDocTemplate 
*wxDocManager::SelectViewType(wxDocTemplate 
**templates
, 
1526                                             int noTemplates
, bool sort
) 
1528     wxArrayString 
strings(sort
); 
1529     wxDocTemplate 
**data 
= new wxDocTemplate 
*[noTemplates
]; 
1532     for (i 
= 0; i 
< noTemplates
; i
++) 
1534         wxDocTemplate 
*templ 
= templates
[i
]; 
1535         if ( templ
->IsVisible() && !templ
->GetViewName().empty() ) 
1537             strings
.Add(templ
->m_viewTypeName
); 
1548                 // Yes, this will be slow, but template lists 
1549                 // are typically short. 
1551                 n 
= strings
.Count(); 
1552                 for (i 
= 0; i 
< n
; i
++) 
1554                         for (j 
= 0; j 
< noTemplates
; j
++) 
1556                                 if (strings
[i
] == templates
[j
]->m_viewTypeName
) 
1557                                         data
[i
] = templates
[j
]; 
1562     wxDocTemplate 
*theTemplate
; 
1564     // the same logic as above 
1568             theTemplate 
= (wxDocTemplate 
*)NULL
; 
1572             theTemplate 
= data
[0]; 
1576             theTemplate 
= (wxDocTemplate 
*)wxGetSingleChoiceData
 
1578                             _("Select a document view"), 
1582                             wxFindSuitableParent() 
1591 void wxDocManager::AssociateTemplate(wxDocTemplate 
*temp
) 
1593     if (!m_templates
.Member(temp
)) 
1594         m_templates
.Append(temp
); 
1597 void wxDocManager::DisassociateTemplate(wxDocTemplate 
*temp
) 
1599     m_templates
.DeleteObject(temp
); 
1602 // Add and remove a document from the manager's list 
1603 void wxDocManager::AddDocument(wxDocument 
*doc
) 
1605     if (!m_docs
.Member(doc
)) 
1609 void wxDocManager::RemoveDocument(wxDocument 
*doc
) 
1611     m_docs
.DeleteObject(doc
); 
1614 // Views or windows should inform the document manager 
1615 // when a view is going in or out of focus 
1616 void wxDocManager::ActivateView(wxView 
*view
, bool activate
, bool WXUNUSED(deleting
)) 
1618     // If we're deactiving, and if we're not actually deleting the view, then 
1619     // don't reset the current view because we may be going to 
1620     // a window without a view. 
1621     // WHAT DID I MEAN BY THAT EXACTLY? 
1625        if (m_currentView == view) 
1626        m_currentView = NULL; 
1632             m_currentView 
= view
; 
1634             m_currentView 
= (wxView 
*) NULL
; 
1638 // ---------------------------------------------------------------------------- 
1639 // Default document child frame 
1640 // ---------------------------------------------------------------------------- 
1642 BEGIN_EVENT_TABLE(wxDocChildFrame
, wxFrame
) 
1643     EVT_ACTIVATE(wxDocChildFrame::OnActivate
) 
1644     EVT_CLOSE(wxDocChildFrame::OnCloseWindow
) 
1647 wxDocChildFrame::wxDocChildFrame(wxDocument 
*doc
, 
1651                                  const wxString
& title
, 
1655                                  const wxString
& name
) 
1656                : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1658     m_childDocument 
= doc
; 
1661         view
->SetFrame(this); 
1664 wxDocChildFrame::~wxDocChildFrame() 
1668 // Extend event processing to search the view's event table 
1669 bool wxDocChildFrame::ProcessEvent(wxEvent
& event
) 
1672         m_childView
->Activate(TRUE
); 
1674     if ( !m_childView 
|| ! m_childView
->ProcessEvent(event
) ) 
1676         // Only hand up to the parent if it's a menu command 
1677         if (!event
.IsKindOf(CLASSINFO(wxCommandEvent
)) || !GetParent() || !GetParent()->ProcessEvent(event
)) 
1678             return wxEvtHandler::ProcessEvent(event
); 
1686 void wxDocChildFrame::OnActivate(wxActivateEvent
& event
) 
1688     wxFrame::OnActivate(event
); 
1691         m_childView
->Activate(event
.GetActive()); 
1694 void wxDocChildFrame::OnCloseWindow(wxCloseEvent
& event
) 
1699         if (!event
.CanVeto()) 
1700             ans 
= TRUE
; // Must delete. 
1702             ans 
= m_childView
->Close(FALSE
); // FALSE means don't delete associated window 
1706             m_childView
->Activate(FALSE
); 
1708             m_childView 
= (wxView 
*) NULL
; 
1709             m_childDocument 
= (wxDocument 
*) NULL
; 
1720 // ---------------------------------------------------------------------------- 
1721 // Default parent frame 
1722 // ---------------------------------------------------------------------------- 
1724 BEGIN_EVENT_TABLE(wxDocParentFrame
, wxFrame
) 
1725     EVT_MENU(wxID_EXIT
, wxDocParentFrame::OnExit
) 
1726     EVT_MENU_RANGE(wxID_FILE1
, wxID_FILE9
, wxDocParentFrame::OnMRUFile
) 
1727     EVT_CLOSE(wxDocParentFrame::OnCloseWindow
) 
1730 wxDocParentFrame::wxDocParentFrame(wxDocManager 
*manager
, 
1733                                    const wxString
& title
, 
1737                                    const wxString
& name
) 
1738                 : wxFrame(frame
, id
, title
, pos
, size
, style
, name
) 
1740     m_docManager 
= manager
; 
1743 void wxDocParentFrame::OnExit(wxCommandEvent
& WXUNUSED(event
)) 
1748 void wxDocParentFrame::OnMRUFile(wxCommandEvent
& event
) 
1750     int n 
= event
.GetId() - wxID_FILE1
;  // the index in MRU list 
1751     wxString 
filename(m_docManager
->GetHistoryFile(n
)); 
1752     if ( !filename
.IsEmpty() ) 
1754         // verify that the file exists before doing anything else 
1755         if ( wxFile::Exists(filename
) ) 
1758             (void)m_docManager
->CreateDocument(filename
, wxDOC_SILENT
); 
1762             // remove the bogus filename from the MRU list and notify the user 
1764             m_docManager
->RemoveFileFromHistory(n
); 
1766             wxLogError(_("The file '%s' doesn't exist and couldn't be opened.\nIt has been removed from the most recently used files list."), 
1772 // Extend event processing to search the view's event table 
1773 bool wxDocParentFrame::ProcessEvent(wxEvent
& event
) 
1775     // Try the document manager, then do default processing 
1776     if (!m_docManager 
|| !m_docManager
->ProcessEvent(event
)) 
1777         return wxEvtHandler::ProcessEvent(event
); 
1782 // Define the behaviour for the frame closing 
1783 // - must delete all frames except for the main one. 
1784 void wxDocParentFrame::OnCloseWindow(wxCloseEvent
& event
) 
1786     if (m_docManager
->Clear(!event
.CanVeto())) 
1794 #if wxUSE_PRINTING_ARCHITECTURE 
1796 wxDocPrintout::wxDocPrintout(wxView 
*view
, const wxString
& title
) 
1799     m_printoutView 
= view
; 
1802 bool wxDocPrintout::OnPrintPage(int WXUNUSED(page
)) 
1806     // Get the logical pixels per inch of screen and printer 
1807     int ppiScreenX
, ppiScreenY
; 
1808     GetPPIScreen(&ppiScreenX
, &ppiScreenY
); 
1809     int ppiPrinterX
, ppiPrinterY
; 
1810     GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
); 
1812     // This scales the DC so that the printout roughly represents the 
1813     // the screen scaling. The text point size _should_ be the right size 
1814     // but in fact is too small for some reason. This is a detail that will 
1815     // need to be addressed at some point but can be fudged for the 
1817     float scale 
= (float)((float)ppiPrinterX
/(float)ppiScreenX
); 
1819     // Now we have to check in case our real page size is reduced 
1820     // (e.g. because we're drawing to a print preview memory DC) 
1821     int pageWidth
, pageHeight
; 
1823     dc
->GetSize(&w
, &h
); 
1824     GetPageSizePixels(&pageWidth
, &pageHeight
); 
1826     // If printer pageWidth == current DC width, then this doesn't 
1827     // change. But w might be the preview bitmap width, so scale down. 
1828     float overallScale 
= scale 
* (float)(w
/(float)pageWidth
); 
1829     dc
->SetUserScale(overallScale
, overallScale
); 
1833         m_printoutView
->OnDraw(dc
); 
1838 bool wxDocPrintout::HasPage(int pageNum
) 
1840     return (pageNum 
== 1); 
1843 bool wxDocPrintout::OnBeginDocument(int startPage
, int endPage
) 
1845     if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) 
1851 void wxDocPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
) 
1859 #endif // wxUSE_PRINTING_ARCHITECTURE 
1861 // ---------------------------------------------------------------------------- 
1862 // File history processor 
1863 // ---------------------------------------------------------------------------- 
1865 wxFileHistory::wxFileHistory(int maxFiles
) 
1867     m_fileMaxFiles 
= maxFiles
; 
1869     m_fileHistory 
= new wxChar 
*[m_fileMaxFiles
]; 
1872 wxFileHistory::~wxFileHistory() 
1875     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1876         delete[] m_fileHistory
[i
]; 
1877     delete[] m_fileHistory
; 
1880 // File history management 
1881 void wxFileHistory::AddFileToHistory(const wxString
& file
) 
1885     // Check we don't already have this file 
1886     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1888         if ( m_fileHistory
[i
] && (file 
== m_fileHistory
[i
]) ) 
1890             // we do have it, move it to the top of the history 
1891             RemoveFileFromHistory (i
); 
1892             AddFileToHistory (file
); 
1897     // if we already have a full history, delete the one at the end 
1898     if ( m_fileMaxFiles 
== m_fileHistoryN 
) 
1900         RemoveFileFromHistory (m_fileHistoryN 
- 1); 
1901         AddFileToHistory (file
); 
1905     // Add to the project file history: 
1906     // Move existing files (if any) down so we can insert file at beginning. 
1907     if (m_fileHistoryN 
< m_fileMaxFiles
) 
1909         wxNode
* node 
= m_fileMenus
.First(); 
1912             wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1913             if (m_fileHistoryN 
== 0) 
1914                 menu
->AppendSeparator(); 
1915             menu
->Append(wxID_FILE1
+m_fileHistoryN
, _("[EMPTY]")); 
1916             node 
= node
->Next(); 
1920     // Shuffle filenames down 
1921     for (i 
= (m_fileHistoryN
-1); i 
> 0; i
--) 
1923         m_fileHistory
[i
] = m_fileHistory
[i
-1]; 
1925     m_fileHistory
[0] = copystring(file
); 
1927     // this is the directory of the last opened file 
1928     wxString pathCurrent
; 
1929     wxSplitPath( m_fileHistory
[0], &pathCurrent
, NULL
, NULL 
); 
1930     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
1932         if ( m_fileHistory
[i
] ) 
1934             // if in same directory just show the filename; otherwise the full 
1936             wxString pathInMenu
, path
, filename
, ext
; 
1937             wxSplitPath( m_fileHistory
[i
], &path
, &filename
, &ext 
); 
1938             if ( path 
== pathCurrent 
) 
1940                 pathInMenu 
= filename
; 
1942                     pathInMenu 
= pathInMenu 
+ wxFILE_SEP_EXT 
+ ext
; 
1946                 // absolute path; could also set relative path 
1947                 pathInMenu 
= m_fileHistory
[i
]; 
1951             buf
.Printf(s_MRUEntryFormat
, i 
+ 1, pathInMenu
.c_str()); 
1952             wxNode
* node 
= m_fileMenus
.First(); 
1955                 wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1956                 menu
->SetLabel(wxID_FILE1 
+ i
, buf
); 
1957                 node 
= node
->Next(); 
1963 void wxFileHistory::RemoveFileFromHistory(int i
) 
1965     wxCHECK_RET( i 
< m_fileHistoryN
, 
1966                  wxT("invalid index in wxFileHistory::RemoveFileFromHistory") ); 
1968         // delete the element from the array (could use memmove() too...) 
1969         delete [] m_fileHistory
[i
]; 
1972         for ( j 
= i
; j 
< m_fileHistoryN 
- 1; j
++ ) 
1974             m_fileHistory
[j
] = m_fileHistory
[j 
+ 1]; 
1977     wxNode
* node 
= m_fileMenus
.First(); 
1980         wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
1983         // shuffle filenames up 
1985         for ( j 
= i
; j 
< m_fileHistoryN 
- 1; j
++ ) 
1987             buf
.Printf(s_MRUEntryFormat
, j 
+ 1, m_fileHistory
[j
]); 
1988             menu
->SetLabel(wxID_FILE1 
+ j
, buf
); 
1991         node 
= node
->Next(); 
1993         // delete the last menu item which is unused now 
1994         if (menu
->FindItem(wxID_FILE1 
+ m_fileHistoryN 
- 1)) 
1995         menu
->Delete(wxID_FILE1 
+ m_fileHistoryN 
- 1); 
1997         // delete the last separator too if no more files are left 
1998         if ( m_fileHistoryN 
== 1 ) 
2000             wxMenuItemList::Node 
*node 
= menu
->GetMenuItems().GetLast(); 
2003                 wxMenuItem 
*menuItem 
= node
->GetData(); 
2004                 if ( menuItem
->IsSeparator() ) 
2006                     menu
->Delete(menuItem
); 
2008                 //else: should we search backwards for the last separator? 
2010             //else: menu is empty somehow 
2017 wxString 
wxFileHistory::GetHistoryFile(int i
) const 
2020     if ( i 
< m_fileHistoryN 
) 
2022         s 
= m_fileHistory
[i
]; 
2026         wxFAIL_MSG( wxT("bad index in wxFileHistory::GetHistoryFile") ); 
2032 void wxFileHistory::UseMenu(wxMenu 
*menu
) 
2034     if (!m_fileMenus
.Member(menu
)) 
2035         m_fileMenus
.Append(menu
); 
2038 void wxFileHistory::RemoveMenu(wxMenu 
*menu
) 
2040     m_fileMenus
.DeleteObject(menu
); 
2044 void wxFileHistory::Load(wxConfigBase
& config
) 
2048     buf
.Printf(wxT("file%d"), m_fileHistoryN
+1); 
2049     wxString historyFile
; 
2050     while ((m_fileHistoryN 
<= m_fileMaxFiles
) && config
.Read(buf
, &historyFile
) && (historyFile 
!= wxT(""))) 
2052         m_fileHistory
[m_fileHistoryN
] = copystring((const wxChar
*) historyFile
); 
2054         buf
.Printf(wxT("file%d"), m_fileHistoryN
+1); 
2055         historyFile 
= wxT(""); 
2060 void wxFileHistory::Save(wxConfigBase
& config
) 
2063     for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
2066         buf
.Printf(wxT("file%d"), i
+1); 
2067         config
.Write(buf
, wxString(m_fileHistory
[i
])); 
2070 #endif // wxUSE_CONFIG 
2072 void wxFileHistory::AddFilesToMenu() 
2074     if (m_fileHistoryN 
> 0) 
2076         wxNode
* node 
= m_fileMenus
.First(); 
2079             wxMenu
* menu 
= (wxMenu
*) node
->Data(); 
2080             menu
->AppendSeparator(); 
2082             for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
2084                 if (m_fileHistory
[i
]) 
2087                     buf
.Printf(s_MRUEntryFormat
, i
+1, m_fileHistory
[i
]); 
2088                     menu
->Append(wxID_FILE1
+i
, buf
); 
2091             node 
= node
->Next(); 
2096 void wxFileHistory::AddFilesToMenu(wxMenu
* menu
) 
2098     if (m_fileHistoryN 
> 0) 
2100         menu
->AppendSeparator(); 
2102         for (i 
= 0; i 
< m_fileHistoryN
; i
++) 
2104             if (m_fileHistory
[i
]) 
2107                 buf
.Printf(s_MRUEntryFormat
, i
+1, m_fileHistory
[i
]); 
2108                 menu
->Append(wxID_FILE1
+i
, buf
); 
2114 // ---------------------------------------------------------------------------- 
2115 // Permits compatibility with existing file formats and functions that 
2116 // manipulate files directly 
2117 // ---------------------------------------------------------------------------- 
2119 #if wxUSE_STD_IOSTREAM 
2120 bool wxTransferFileToStream(const wxString
& filename
, wxSTD ostream
& stream
) 
2125     if ((fd1 
= wxFopen (filename
.fn_str(), _T("rb"))) == NULL
) 
2128     while ((ch 
= getc (fd1
)) != EOF
) 
2129         stream 
<< (unsigned char)ch
; 
2135 bool wxTransferStreamToFile(wxSTD istream
& stream
, const wxString
& filename
) 
2140     if ((fd1 
= wxFopen (filename
.fn_str(), _T("wb"))) == NULL
) 
2145     while (!stream
.eof()) 
2155 bool wxTransferFileToStream(const wxString
& filename
, wxOutputStream
& stream
) 
2160     if ((fd1 
= wxFopen (filename
, wxT("rb"))) == NULL
) 
2163     while ((ch 
= getc (fd1
)) != EOF
) 
2164         stream
.PutC((char) ch
); 
2170 bool wxTransferStreamToFile(wxInputStream
& stream
, const wxString
& filename
) 
2175     if ((fd1 
= wxFopen (filename
, wxT("wb"))) == NULL
) 
2180     int len 
= stream
.StreamSize(); 
2181     // TODO: is this the correct test for EOF? 
2182     while (stream
.TellI() < (len 
- 1)) 
2192 #endif // wxUSE_DOC_VIEW_ARCHITECTURE