1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/docview.h
3 // Purpose:     Doc/View classes
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     01/02/97
7 // Copyright:   (c) Julian Smart
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef _WX_DOCH__
12 #define _WX_DOCH__
13 
14 #include "wx/defs.h"
15 
16 #if wxUSE_DOC_VIEW_ARCHITECTURE
17 
18 #include "wx/list.h"
19 #include "wx/dlist.h"
20 #include "wx/string.h"
21 #include "wx/frame.h"
22 #include "wx/filehistory.h"
23 #include "wx/vector.h"
24 
25 #if wxUSE_PRINTING_ARCHITECTURE
26     #include "wx/print.h"
27 #endif
28 
29 class WXDLLIMPEXP_FWD_CORE wxWindow;
30 class WXDLLIMPEXP_FWD_CORE wxDocument;
31 class WXDLLIMPEXP_FWD_CORE wxView;
32 class WXDLLIMPEXP_FWD_CORE wxDocTemplate;
33 class WXDLLIMPEXP_FWD_CORE wxDocManager;
34 class WXDLLIMPEXP_FWD_CORE wxPrintInfo;
35 class WXDLLIMPEXP_FWD_CORE wxCommandProcessor;
36 class WXDLLIMPEXP_FWD_BASE wxConfigBase;
37 
38 class wxDocChildFrameAnyBase;
39 
40 #if wxUSE_STD_IOSTREAM
41   #include "wx/iosfwrap.h"
42 #else
43   #include "wx/stream.h"
44 #endif
45 
46 // Flags for wxDocManager (can be combined).
47 enum
48 {
49     wxDOC_NEW    = 1,
50     wxDOC_SILENT = 2
51 };
52 
53 // Document template flags
54 enum
55 {
56     wxTEMPLATE_VISIBLE = 1,
57     wxTEMPLATE_INVISIBLE = 2,
58     wxDEFAULT_TEMPLATE_FLAGS = wxTEMPLATE_VISIBLE
59 };
60 
61 #define wxMAX_FILE_HISTORY 9
62 
63 typedef wxVector<wxDocument*> wxDocVector;
64 typedef wxVector<wxView*> wxViewVector;
65 typedef wxVector<wxDocTemplate*> wxDocTemplateVector;
66 
67 class WXDLLIMPEXP_CORE wxDocument : public wxEvtHandler
68 {
69 public:
70     wxDocument(wxDocument *parent = NULL);
71     virtual ~wxDocument();
72 
73     // accessors
74     void SetFilename(const wxString& filename, bool notifyViews = false);
GetFilename()75     wxString GetFilename() const { return m_documentFile; }
76 
SetTitle(const wxString & title)77     void SetTitle(const wxString& title) { m_documentTitle = title; }
GetTitle()78     wxString GetTitle() const { return m_documentTitle; }
79 
SetDocumentName(const wxString & name)80     void SetDocumentName(const wxString& name) { m_documentTypeName = name; }
GetDocumentName()81     wxString GetDocumentName() const { return m_documentTypeName; }
82 
83     // access the flag indicating whether this document had been already saved,
84     // SetDocumentSaved() is only used internally, don't call it
GetDocumentSaved()85     bool GetDocumentSaved() const { return m_savedYet; }
86     void SetDocumentSaved(bool saved = true) { m_savedYet = saved; }
87 
88     // activate the first view of the document if any
89     void Activate();
90 
91     // return true if the document hasn't been modified since the last time it
92     // was saved (implying that it returns false if it was never saved, even if
93     // the document is not modified)
AlreadySaved()94     bool AlreadySaved() const { return !IsModified() && GetDocumentSaved(); }
95 
96     virtual bool Close();
97     virtual bool Save();
98     virtual bool SaveAs();
99     virtual bool Revert();
100 
101 #if wxUSE_STD_IOSTREAM
102     virtual wxSTD ostream& SaveObject(wxSTD ostream& stream);
103     virtual wxSTD istream& LoadObject(wxSTD istream& stream);
104 #else
105     virtual wxOutputStream& SaveObject(wxOutputStream& stream);
106     virtual wxInputStream& LoadObject(wxInputStream& stream);
107 #endif
108 
109     // Called by wxWidgets
110     virtual bool OnSaveDocument(const wxString& filename);
111     virtual bool OnOpenDocument(const wxString& filename);
112     virtual bool OnNewDocument();
113     virtual bool OnCloseDocument();
114 
115     // Prompts for saving if about to close a modified document. Returns true
116     // if ok to close the document (may have saved in the meantime, or set
117     // modified to false)
118     virtual bool OnSaveModified();
119 
120     // if you override, remember to call the default
121     // implementation (wxDocument::OnChangeFilename)
122     virtual void OnChangeFilename(bool notifyViews);
123 
124     // Called by framework if created automatically by the default document
125     // manager: gives document a chance to initialise and (usually) create a
126     // view
127     virtual bool OnCreate(const wxString& path, long flags);
128 
129     // By default, creates a base wxCommandProcessor.
130     virtual wxCommandProcessor *OnCreateCommandProcessor();
GetCommandProcessor()131     virtual wxCommandProcessor *GetCommandProcessor() const
132         { return m_commandProcessor; }
SetCommandProcessor(wxCommandProcessor * proc)133     virtual void SetCommandProcessor(wxCommandProcessor *proc)
134         { m_commandProcessor = proc; }
135 
136     // Called after a view is added or removed. The default implementation
137     // deletes the document if this is there are no more views.
138     virtual void OnChangedViewList();
139 
140     // Called from OnCloseDocument(), does nothing by default but may be
141     // overridden. Return value is ignored.
142     virtual bool DeleteContents();
143 
144     virtual bool Draw(wxDC&);
IsModified()145     virtual bool IsModified() const { return m_documentModified; }
146     virtual void Modify(bool mod);
147 
148     virtual bool AddView(wxView *view);
149     virtual bool RemoveView(wxView *view);
150 
151 #ifndef __VISUALC6__
152     wxViewVector GetViewsVector() const;
153 #endif // !__VISUALC6__
154 
GetViews()155     wxList& GetViews() { return m_documentViews; }
GetViews()156     const wxList& GetViews() const { return m_documentViews; }
157 
158     wxView *GetFirstView() const;
159 
160     virtual void UpdateAllViews(wxView *sender = NULL, wxObject *hint = NULL);
161     virtual void NotifyClosing();
162 
163     // Remove all views (because we're closing the document)
164     virtual bool DeleteAllViews();
165 
166     // Other stuff
167     virtual wxDocManager *GetDocumentManager() const;
GetDocumentTemplate()168     virtual wxDocTemplate *GetDocumentTemplate() const
169         { return m_documentTemplate; }
SetDocumentTemplate(wxDocTemplate * temp)170     virtual void SetDocumentTemplate(wxDocTemplate *temp)
171         { m_documentTemplate = temp; }
172 
173     // Get the document name to be shown to the user: the title if there is
174     // any, otherwise the filename if the document was saved and, finally,
175     // "unnamed" otherwise
176     virtual wxString GetUserReadableName() const;
177 
178 #if WXWIN_COMPATIBILITY_2_8
179     // use GetUserReadableName() instead
180     wxDEPRECATED_BUT_USED_INTERNALLY(
181         virtual bool GetPrintableName(wxString& buf) const
182     );
183 #endif // WXWIN_COMPATIBILITY_2_8
184 
185     // Returns a window that can be used as a parent for document-related
186     // dialogs. Override if necessary.
187     virtual wxWindow *GetDocumentWindow() const;
188 
189     // Returns true if this document is a child document corresponding to a
190     // part of the parent document and not a disk file as usual.
IsChildDocument()191     bool IsChildDocument() const { return m_documentParent != NULL; }
192 
193 protected:
194     wxList                m_documentViews;
195     wxString              m_documentFile;
196     wxString              m_documentTitle;
197     wxString              m_documentTypeName;
198     wxDocTemplate*        m_documentTemplate;
199     bool                  m_documentModified;
200 
201     // if the document parent is non-NULL, it's a pseudo-document corresponding
202     // to a part of the parent document which can't be saved or loaded
203     // independently of its parent and is always closed when its parent is
204     wxDocument*           m_documentParent;
205 
206     wxCommandProcessor*   m_commandProcessor;
207     bool                  m_savedYet;
208 
209     // Called by OnSaveDocument and OnOpenDocument to implement standard
210     // Save/Load behaviour. Re-implement in derived class for custom
211     // behaviour.
212     virtual bool DoSaveDocument(const wxString& file);
213     virtual bool DoOpenDocument(const wxString& file);
214 
215     // the default implementation of GetUserReadableName()
216     wxString DoGetUserReadableName() const;
217 
218 private:
219     // list of all documents whose m_documentParent is this one
220     typedef wxDList<wxDocument> DocsList;
221     DocsList m_childDocuments;
222 
223     DECLARE_ABSTRACT_CLASS(wxDocument)
224     wxDECLARE_NO_COPY_CLASS(wxDocument);
225 };
226 
227 class WXDLLIMPEXP_CORE wxView: public wxEvtHandler
228 {
229 public:
230     wxView();
231     virtual ~wxView();
232 
GetDocument()233     wxDocument *GetDocument() const { return m_viewDocument; }
234     virtual void SetDocument(wxDocument *doc);
235 
GetViewName()236     wxString GetViewName() const { return m_viewTypeName; }
SetViewName(const wxString & name)237     void SetViewName(const wxString& name) { m_viewTypeName = name; }
238 
GetFrame()239     wxWindow *GetFrame() const { return m_viewFrame ; }
SetFrame(wxWindow * frame)240     void SetFrame(wxWindow *frame) { m_viewFrame = frame; }
241 
242     virtual void OnActivateView(bool activate,
243                                 wxView *activeView,
244                                 wxView *deactiveView);
245     virtual void OnDraw(wxDC *dc) = 0;
246     virtual void OnPrint(wxDC *dc, wxObject *info);
247     virtual void OnUpdate(wxView *sender, wxObject *hint = NULL);
OnClosingDocument()248     virtual void OnClosingDocument() {}
249     virtual void OnChangeFilename();
250 
251     // Called by framework if created automatically by the default document
252     // manager class: gives view a chance to initialise
OnCreate(wxDocument * WXUNUSED (doc),long WXUNUSED (flags))253     virtual bool OnCreate(wxDocument *WXUNUSED(doc), long WXUNUSED(flags))
254         { return true; }
255 
256     // Checks if the view is the last one for the document; if so, asks user
257     // to confirm save data (if modified). If ok, deletes itself and returns
258     // true.
259     virtual bool Close(bool deleteWindow = true);
260 
261     // Override to do cleanup/veto close
262     virtual bool OnClose(bool deleteWindow);
263 
264     // A view's window can call this to notify the view it is (in)active.
265     // The function then notifies the document manager.
266     virtual void Activate(bool activate);
267 
GetDocumentManager()268     wxDocManager *GetDocumentManager() const
269         { return m_viewDocument->GetDocumentManager(); }
270 
271 #if wxUSE_PRINTING_ARCHITECTURE
272     virtual wxPrintout *OnCreatePrintout();
273 #endif
274 
275     // implementation only
276     // -------------------
277 
278     // set the associated frame, it is used to reset its view when we're
279     // destroyed
280     void SetDocChildFrame(wxDocChildFrameAnyBase *docChildFrame);
281 
282     // get the associated frame, may be NULL during destruction
GetDocChildFrame()283     wxDocChildFrameAnyBase* GetDocChildFrame() const { return m_docChildFrame; }
284 
285 protected:
286     // hook the document into event handlers chain here
287     virtual bool TryBefore(wxEvent& event);
288 
289     wxDocument*       m_viewDocument;
290     wxString          m_viewTypeName;
291     wxWindow*         m_viewFrame;
292 
293     wxDocChildFrameAnyBase *m_docChildFrame;
294 
295 private:
296     DECLARE_ABSTRACT_CLASS(wxView)
297     wxDECLARE_NO_COPY_CLASS(wxView);
298 };
299 
300 // Represents user interface (and other) properties of documents and views
301 class WXDLLIMPEXP_CORE wxDocTemplate: public wxObject
302 {
303 
304 friend class WXDLLIMPEXP_FWD_CORE wxDocManager;
305 
306 public:
307     // Associate document and view types. They're for identifying what view is
308     // associated with what template/document type
309     wxDocTemplate(wxDocManager *manager,
310                   const wxString& descr,
311                   const wxString& filter,
312                   const wxString& dir,
313                   const wxString& ext,
314                   const wxString& docTypeName,
315                   const wxString& viewTypeName,
316                   wxClassInfo *docClassInfo = NULL,
317                   wxClassInfo *viewClassInfo = NULL,
318                   long flags = wxDEFAULT_TEMPLATE_FLAGS);
319 
320     virtual ~wxDocTemplate();
321 
322     // By default, these two member functions dynamically creates document and
323     // view using dynamic instance construction. Override these if you need a
324     // different method of construction.
325     virtual wxDocument *CreateDocument(const wxString& path, long flags = 0);
326     virtual wxView *CreateView(wxDocument *doc, long flags = 0);
327 
328     // Helper method for CreateDocument; also allows you to do your own document
329     // creation
330     virtual bool InitDocument(wxDocument* doc,
331                               const wxString& path,
332                               long flags = 0);
333 
GetDefaultExtension()334     wxString GetDefaultExtension() const { return m_defaultExt; }
GetDescription()335     wxString GetDescription() const { return m_description; }
GetDirectory()336     wxString GetDirectory() const { return m_directory; }
GetDocumentManager()337     wxDocManager *GetDocumentManager() const { return m_documentManager; }
SetDocumentManager(wxDocManager * manager)338     void SetDocumentManager(wxDocManager *manager)
339         { m_documentManager = manager; }
GetFileFilter()340     wxString GetFileFilter() const { return m_fileFilter; }
GetFlags()341     long GetFlags() const { return m_flags; }
GetViewName()342     virtual wxString GetViewName() const { return m_viewTypeName; }
GetDocumentName()343     virtual wxString GetDocumentName() const { return m_docTypeName; }
344 
SetFileFilter(const wxString & filter)345     void SetFileFilter(const wxString& filter) { m_fileFilter = filter; }
SetDirectory(const wxString & dir)346     void SetDirectory(const wxString& dir) { m_directory = dir; }
SetDescription(const wxString & descr)347     void SetDescription(const wxString& descr) { m_description = descr; }
SetDefaultExtension(const wxString & ext)348     void SetDefaultExtension(const wxString& ext) { m_defaultExt = ext; }
SetFlags(long flags)349     void SetFlags(long flags) { m_flags = flags; }
350 
IsVisible()351     bool IsVisible() const { return (m_flags & wxTEMPLATE_VISIBLE) != 0; }
352 
GetDocClassInfo()353     wxClassInfo* GetDocClassInfo() const { return m_docClassInfo; }
GetViewClassInfo()354     wxClassInfo* GetViewClassInfo() const { return m_viewClassInfo; }
355 
356     virtual bool FileMatchesTemplate(const wxString& path);
357 
358 protected:
359     long              m_flags;
360     wxString          m_fileFilter;
361     wxString          m_directory;
362     wxString          m_description;
363     wxString          m_defaultExt;
364     wxString          m_docTypeName;
365     wxString          m_viewTypeName;
366     wxDocManager*     m_documentManager;
367 
368     // For dynamic creation of appropriate instances.
369     wxClassInfo*      m_docClassInfo;
370     wxClassInfo*      m_viewClassInfo;
371 
372     // Called by CreateDocument and CreateView to create the actual
373     // document/view object.
374     //
375     // By default uses the ClassInfo provided to the constructor. Override
376     // these functions to provide a different method of creation.
377     virtual wxDocument *DoCreateDocument();
378     virtual wxView *DoCreateView();
379 
380 private:
381     DECLARE_CLASS(wxDocTemplate)
382     wxDECLARE_NO_COPY_CLASS(wxDocTemplate);
383 };
384 
385 // One object of this class may be created in an application, to manage all
386 // the templates and documents.
387 class WXDLLIMPEXP_CORE wxDocManager: public wxEvtHandler
388 {
389 public:
390     // NB: flags are unused, don't pass wxDOC_XXX to this ctor
391     wxDocManager(long flags = 0, bool initialize = true);
392     virtual ~wxDocManager();
393 
394     virtual bool Initialize();
395 
396     // Handlers for common user commands
397     void OnFileClose(wxCommandEvent& event);
398     void OnFileCloseAll(wxCommandEvent& event);
399     void OnFileNew(wxCommandEvent& event);
400     void OnFileOpen(wxCommandEvent& event);
401     void OnFileRevert(wxCommandEvent& event);
402     void OnFileSave(wxCommandEvent& event);
403     void OnFileSaveAs(wxCommandEvent& event);
404     void OnMRUFile(wxCommandEvent& event);
405 #if wxUSE_PRINTING_ARCHITECTURE
406     void OnPrint(wxCommandEvent& event);
407     void OnPreview(wxCommandEvent& event);
408     void OnPageSetup(wxCommandEvent& event);
409 #endif // wxUSE_PRINTING_ARCHITECTURE
410     void OnUndo(wxCommandEvent& event);
411     void OnRedo(wxCommandEvent& event);
412 
413     // Handlers for UI update commands
414     void OnUpdateFileOpen(wxUpdateUIEvent& event);
415     void OnUpdateDisableIfNoDoc(wxUpdateUIEvent& event);
416     void OnUpdateFileRevert(wxUpdateUIEvent& event);
417     void OnUpdateFileNew(wxUpdateUIEvent& event);
418     void OnUpdateFileSave(wxUpdateUIEvent& event);
419     void OnUpdateFileSaveAs(wxUpdateUIEvent& event);
420     void OnUpdateUndo(wxUpdateUIEvent& event);
421     void OnUpdateRedo(wxUpdateUIEvent& event);
422 
423     // called when file format detection didn't work, can be overridden to do
424     // something in this case
OnOpenFileFailure()425     virtual void OnOpenFileFailure() { }
426 
427     virtual wxDocument *CreateDocument(const wxString& path, long flags = 0);
428 
429     // wrapper around CreateDocument() with a more clear name
CreateNewDocument()430     wxDocument *CreateNewDocument()
431         { return CreateDocument(wxString(), wxDOC_NEW); }
432 
433     virtual wxView *CreateView(wxDocument *doc, long flags = 0);
434     virtual void DeleteTemplate(wxDocTemplate *temp, long flags = 0);
435     virtual bool FlushDoc(wxDocument *doc);
436     virtual wxDocTemplate *MatchTemplate(const wxString& path);
437     virtual wxDocTemplate *SelectDocumentPath(wxDocTemplate **templates,
438             int noTemplates, wxString& path, long flags, bool save = false);
439     virtual wxDocTemplate *SelectDocumentType(wxDocTemplate **templates,
440             int noTemplates, bool sort = false);
441     virtual wxDocTemplate *SelectViewType(wxDocTemplate **templates,
442             int noTemplates, bool sort = false);
443     virtual wxDocTemplate *FindTemplateForPath(const wxString& path);
444 
445     void AssociateTemplate(wxDocTemplate *temp);
446     void DisassociateTemplate(wxDocTemplate *temp);
447 
448     // Find template from document class info, may return NULL.
449     wxDocTemplate* FindTemplate(const wxClassInfo* documentClassInfo);
450 
451     // Find document from file name, may return NULL.
452     wxDocument* FindDocumentByPath(const wxString& path) const;
453 
454     wxDocument *GetCurrentDocument() const;
455 
SetMaxDocsOpen(int n)456     void SetMaxDocsOpen(int n) { m_maxDocsOpen = n; }
GetMaxDocsOpen()457     int GetMaxDocsOpen() const { return m_maxDocsOpen; }
458 
459     // Add and remove a document from the manager's list
460     void AddDocument(wxDocument *doc);
461     void RemoveDocument(wxDocument *doc);
462 
463     // closes all currently open documents
464     bool CloseDocuments(bool force = true);
465 
466     // closes the specified document
467     bool CloseDocument(wxDocument* doc, bool force = false);
468 
469     // Clear remaining documents and templates
470     bool Clear(bool force = true);
471 
472     // Views or windows should inform the document manager
473     // when a view is going in or out of focus
474     virtual void ActivateView(wxView *view, bool activate = true);
GetCurrentView()475     virtual wxView *GetCurrentView() const { return m_currentView; }
476 
477     // This method tries to find an active view harder than GetCurrentView():
478     // if the latter is NULL, it also checks if we don't have just a single
479     // view and returns it then.
480     wxView *GetAnyUsableView() const;
481 
482 
483 #ifndef __VISUALC6__
484     wxDocVector GetDocumentsVector() const;
485     wxDocTemplateVector GetTemplatesVector() const;
486 #endif // !__VISUALC6__
487 
GetDocuments()488     wxList& GetDocuments() { return m_docs; }
GetTemplates()489     wxList& GetTemplates() { return m_templates; }
490 
491     // Return the default name for a new document (by default returns strings
492     // in the form "unnamed <counter>" but can be overridden)
493     virtual wxString MakeNewDocumentName();
494 
495     // Make a frame title (override this to do something different)
496     virtual wxString MakeFrameTitle(wxDocument* doc);
497 
498     virtual wxFileHistory *OnCreateFileHistory();
GetFileHistory()499     virtual wxFileHistory *GetFileHistory() const { return m_fileHistory; }
500 
501     // File history management
502     virtual void AddFileToHistory(const wxString& file);
503     virtual void RemoveFileFromHistory(size_t i);
504     virtual size_t GetHistoryFilesCount() const;
505     virtual wxString GetHistoryFile(size_t i) const;
506     virtual void FileHistoryUseMenu(wxMenu *menu);
507     virtual void FileHistoryRemoveMenu(wxMenu *menu);
508 #if wxUSE_CONFIG
509     virtual void FileHistoryLoad(const wxConfigBase& config);
510     virtual void FileHistorySave(wxConfigBase& config);
511 #endif // wxUSE_CONFIG
512 
513     virtual void FileHistoryAddFilesToMenu();
514     virtual void FileHistoryAddFilesToMenu(wxMenu* menu);
515 
516     wxString GetLastDirectory() const;
SetLastDirectory(const wxString & dir)517     void SetLastDirectory(const wxString& dir) { m_lastDirectory = dir; }
518 
519     // Get the current document manager
GetDocumentManager()520     static wxDocManager* GetDocumentManager() { return sm_docManager; }
521 
522 #if wxUSE_PRINTING_ARCHITECTURE
GetPageSetupDialogData()523     wxPageSetupDialogData& GetPageSetupDialogData()
524         { return m_pageSetupDialogData; }
GetPageSetupDialogData()525     const wxPageSetupDialogData& GetPageSetupDialogData() const
526         { return m_pageSetupDialogData; }
527 #endif // wxUSE_PRINTING_ARCHITECTURE
528 
529 #if WXWIN_COMPATIBILITY_2_8
530     // deprecated, override GetDefaultName() instead
531     wxDEPRECATED_BUT_USED_INTERNALLY(
532         virtual bool MakeDefaultName(wxString& buf)
533     );
534 #endif
535 
536 #if WXWIN_COMPATIBILITY_2_6
537     // deprecated, use GetHistoryFilesCount() instead
538     wxDEPRECATED( size_t GetNoHistoryFiles() const );
539 #endif // WXWIN_COMPATIBILITY_2_6
540 
541 
542 protected:
543     // Called when a file selected from the MRU list doesn't exist any more.
544     // The default behaviour is to remove the file from the MRU and notify the
545     // user about it but this method can be overridden to customize it.
546     virtual void OnMRUFileNotExist(unsigned n, const wxString& filename);
547 
548     // Open the MRU file with the given index in our associated file history.
549     void DoOpenMRUFile(unsigned n);
550 #if wxUSE_PRINTING_ARCHITECTURE
551     virtual wxPreviewFrame* CreatePreviewFrame(wxPrintPreviewBase* preview,
552                                                wxWindow *parent,
553                                                const wxString& title);
554 #endif // wxUSE_PRINTING_ARCHITECTURE
555 
556     // hook the currently active view into event handlers chain here
557     virtual bool TryBefore(wxEvent& event);
558 
559     // return the command processor for the current document, if any
560     wxCommandProcessor *GetCurrentCommandProcessor() const;
561 
562     int               m_defaultDocumentNameCounter;
563     int               m_maxDocsOpen;
564     wxList            m_docs;
565     wxList            m_templates;
566     wxView*           m_currentView;
567     wxFileHistory*    m_fileHistory;
568     wxString          m_lastDirectory;
569     static wxDocManager* sm_docManager;
570 
571 #if wxUSE_PRINTING_ARCHITECTURE
572     wxPageSetupDialogData m_pageSetupDialogData;
573 #endif // wxUSE_PRINTING_ARCHITECTURE
574 
575     DECLARE_EVENT_TABLE()
576     DECLARE_DYNAMIC_CLASS(wxDocManager)
577     wxDECLARE_NO_COPY_CLASS(wxDocManager);
578 };
579 
580 #if WXWIN_COMPATIBILITY_2_6
GetNoHistoryFiles()581 inline size_t wxDocManager::GetNoHistoryFiles() const
582 {
583     return GetHistoryFilesCount();
584 }
585 #endif // WXWIN_COMPATIBILITY_2_6
586 
587 // ----------------------------------------------------------------------------
588 // Base class for child frames -- this is what wxView renders itself into
589 //
590 // Notice that this is a mix-in class so it doesn't derive from wxWindow, only
591 // wxDocChildFrameAny does
592 // ----------------------------------------------------------------------------
593 
594 class WXDLLIMPEXP_CORE wxDocChildFrameAnyBase
595 {
596 public:
597     // default ctor, use Create() after it
wxDocChildFrameAnyBase()598     wxDocChildFrameAnyBase()
599     {
600         m_childDocument = NULL;
601         m_childView = NULL;
602         m_win = NULL;
603         m_lastEvent = NULL;
604     }
605 
606     // full ctor equivalent to using the default one and Create()
wxDocChildFrameAnyBase(wxDocument * doc,wxView * view,wxWindow * win)607     wxDocChildFrameAnyBase(wxDocument *doc, wxView *view, wxWindow *win)
608     {
609         Create(doc, view, win);
610     }
611 
612     // method which must be called for an object created using the default ctor
613     //
614     // note that it returns bool just for consistency with Create() methods in
615     // other classes, we never return false from here
Create(wxDocument * doc,wxView * view,wxWindow * win)616     bool Create(wxDocument *doc, wxView *view, wxWindow *win)
617     {
618         m_childDocument = doc;
619         m_childView = view;
620         m_win = win;
621 
622         if ( view )
623             view->SetDocChildFrame(this);
624 
625         return true;
626     }
627 
628     // dtor doesn't need to be virtual, an object should never be destroyed via
629     // a pointer to this class
~wxDocChildFrameAnyBase()630     ~wxDocChildFrameAnyBase()
631     {
632         // prevent the view from deleting us if we're being deleted directly
633         // (and not via Close() + Destroy())
634         if ( m_childView )
635             m_childView->SetDocChildFrame(NULL);
636     }
637 
GetDocument()638     wxDocument *GetDocument() const { return m_childDocument; }
GetView()639     wxView *GetView() const { return m_childView; }
SetDocument(wxDocument * doc)640     void SetDocument(wxDocument *doc) { m_childDocument = doc; }
SetView(wxView * view)641     void SetView(wxView *view) { m_childView = view; }
642 
GetWindow()643     wxWindow *GetWindow() const { return m_win; }
644 
645     // implementation only
646 
647     // Check if this event had been just processed in this frame.
HasAlreadyProcessed(wxEvent & event)648     bool HasAlreadyProcessed(wxEvent& event) const
649     {
650         return m_lastEvent == &event;
651     }
652 
653 protected:
654     // we're not a wxEvtHandler but we provide this wxEvtHandler-like function
655     // which is called from TryBefore() of the derived classes to give our view
656     // a chance to process the message before the frame event handlers are used
657     bool TryProcessEvent(wxEvent& event);
658 
659     // called from EVT_CLOSE handler in the frame: check if we can close and do
660     // cleanup if so; veto the event otherwise
661     bool CloseView(wxCloseEvent& event);
662 
663 
664     wxDocument*       m_childDocument;
665     wxView*           m_childView;
666 
667     // the associated window: having it here is not terribly elegant but it
668     // allows us to avoid having any virtual functions in this class
669     wxWindow* m_win;
670 
671 private:
672     // Pointer to the last processed event used to avoid sending the same event
673     // twice to wxDocManager, from here and from wxDocParentFrameAnyBase.
674     wxEvent* m_lastEvent;
675 
676     wxDECLARE_NO_COPY_CLASS(wxDocChildFrameAnyBase);
677 };
678 
679 // ----------------------------------------------------------------------------
680 // Template implementing child frame concept using the given wxFrame-like class
681 //
682 // This is used to define wxDocChildFrame and wxDocMDIChildFrame: ChildFrame is
683 // a wxFrame or wxMDIChildFrame (although in theory it could be any wxWindow-
684 // derived class as long as it provided a ctor with the same signature as
685 // wxFrame and OnActivate() method) and ParentFrame is either wxFrame or
686 // wxMDIParentFrame.
687 // ----------------------------------------------------------------------------
688 
689 template <class ChildFrame, class ParentFrame>
690 class WXDLLIMPEXP_CORE wxDocChildFrameAny : public ChildFrame,
691                                             public wxDocChildFrameAnyBase
692 {
693 public:
694     typedef ChildFrame BaseClass;
695 
696     // default ctor, use Create after it
wxDocChildFrameAny()697     wxDocChildFrameAny() { }
698 
699     // ctor for a frame showing the given view of the specified document
700     wxDocChildFrameAny(wxDocument *doc,
701                        wxView *view,
702                        ParentFrame *parent,
703                        wxWindowID id,
704                        const wxString& title,
705                        const wxPoint& pos = wxDefaultPosition,
706                        const wxSize& size = wxDefaultSize,
707                        long style = wxDEFAULT_FRAME_STYLE,
708                        const wxString& name = wxFrameNameStr)
709     {
710         Create(doc, view, parent, id, title, pos, size, style, name);
711     }
712 
713     bool Create(wxDocument *doc,
714                 wxView *view,
715                 ParentFrame *parent,
716                 wxWindowID id,
717                 const wxString& title,
718                 const wxPoint& pos = wxDefaultPosition,
719                 const wxSize& size = wxDefaultSize,
720                 long style = wxDEFAULT_FRAME_STYLE,
721                 const wxString& name = wxFrameNameStr)
722     {
723         if ( !wxDocChildFrameAnyBase::Create(doc, view, this) )
724             return false;
725 
726         if ( !BaseClass::Create(parent, id, title, pos, size, style, name) )
727             return false;
728 
729         this->Connect(wxEVT_ACTIVATE,
730                       wxActivateEventHandler(wxDocChildFrameAny::OnActivate));
731         this->Connect(wxEVT_CLOSE_WINDOW,
732                       wxCloseEventHandler(wxDocChildFrameAny::OnCloseWindow));
733 
734         return true;
735     }
736 
Destroy()737     virtual bool Destroy()
738     {
739         return BaseClass::Destroy();
740     }
741 
742 protected:
743     // hook the child view into event handlers chain here
TryBefore(wxEvent & event)744     virtual bool TryBefore(wxEvent& event)
745     {
746         return TryProcessEvent(event) || BaseClass::TryBefore(event);
747     }
748 
749 private:
OnActivate(wxActivateEvent & event)750     void OnActivate(wxActivateEvent& event)
751     {
752         BaseClass::OnActivate(event);
753 
754         if ( m_childView )
755             m_childView->Activate(event.GetActive());
756     }
757 
OnCloseWindow(wxCloseEvent & event)758     void OnCloseWindow(wxCloseEvent& event)
759     {
760         if ( CloseView(event) )
761             Destroy();
762         //else: vetoed
763     }
764 
765     wxDECLARE_NO_COPY_TEMPLATE_CLASS_2(wxDocChildFrameAny,
766                                         ChildFrame, ParentFrame);
767 };
768 
769 // ----------------------------------------------------------------------------
770 // A default child frame: we need to define it as a class just for wxRTTI,
771 // otherwise we could simply typedef it
772 // ----------------------------------------------------------------------------
773 
774 #ifdef __VISUALC6__
775     // "non dll-interface class 'wxDocChildFrameAny<>' used as base interface
776     // for dll-interface class 'wxDocChildFrame'" -- this is bogus as the
777     // template will be DLL-exported but only once it is used as base class
778     // here!
779     #pragma warning (push)
780     #pragma warning (disable:4275)
781 #endif
782 
783 typedef wxDocChildFrameAny<wxFrame, wxFrame> wxDocChildFrameBase;
784 
785 class WXDLLIMPEXP_CORE wxDocChildFrame : public wxDocChildFrameBase
786 {
787 public:
wxDocChildFrame()788     wxDocChildFrame()
789     {
790     }
791 
792     wxDocChildFrame(wxDocument *doc,
793                     wxView *view,
794                     wxFrame *parent,
795                     wxWindowID id,
796                     const wxString& title,
797                     const wxPoint& pos = wxDefaultPosition,
798                     const wxSize& size = wxDefaultSize,
799                     long style = wxDEFAULT_FRAME_STYLE,
800                     const wxString& name = wxFrameNameStr)
wxDocChildFrameBase(doc,view,parent,id,title,pos,size,style,name)801         : wxDocChildFrameBase(doc, view,
802                               parent, id, title, pos, size, style, name)
803     {
804     }
805 
806     bool Create(wxDocument *doc,
807                 wxView *view,
808                 wxFrame *parent,
809                 wxWindowID id,
810                 const wxString& title,
811                 const wxPoint& pos = wxDefaultPosition,
812                 const wxSize& size = wxDefaultSize,
813                 long style = wxDEFAULT_FRAME_STYLE,
814                 const wxString& name = wxFrameNameStr)
815     {
816         return wxDocChildFrameBase::Create
817                (
818                     doc, view,
819                     parent, id, title, pos, size, style, name
820                );
821     }
822 
823 private:
824     DECLARE_CLASS(wxDocChildFrame)
825     wxDECLARE_NO_COPY_CLASS(wxDocChildFrame);
826 };
827 
828 // ----------------------------------------------------------------------------
829 // wxDocParentFrame and related classes.
830 //
831 // As with wxDocChildFrame we define a template base class used by both normal
832 // and MDI versions
833 // ----------------------------------------------------------------------------
834 
835 // Base class containing type-independent code of wxDocParentFrameAny
836 //
837 // Similarly to wxDocChildFrameAnyBase, this class is a mix-in and doesn't
838 // derive from wxWindow.
839 class WXDLLIMPEXP_CORE wxDocParentFrameAnyBase
840 {
841 public:
wxDocParentFrameAnyBase(wxWindow * frame)842     wxDocParentFrameAnyBase(wxWindow* frame)
843         : m_frame(frame)
844     {
845         m_docManager = NULL;
846     }
847 
GetDocumentManager()848     wxDocManager *GetDocumentManager() const { return m_docManager; }
849 
850 protected:
851     // This is similar to wxDocChildFrameAnyBase method with the same name:
852     // while we're not an event handler ourselves and so can't override
853     // TryBefore(), we provide a helper that the derived template class can use
854     // from its TryBefore() implementation.
855     bool TryProcessEvent(wxEvent& event);
856 
857     wxWindow* const m_frame;
858     wxDocManager *m_docManager;
859 
860     wxDECLARE_NO_COPY_CLASS(wxDocParentFrameAnyBase);
861 };
862 
863 // This is similar to wxDocChildFrameAny and is used to provide common
864 // implementation for both wxDocParentFrame and wxDocMDIParentFrame
865 template <class BaseFrame>
866 class WXDLLIMPEXP_CORE wxDocParentFrameAny : public BaseFrame,
867                                              public wxDocParentFrameAnyBase
868 {
869 public:
wxDocParentFrameAny()870     wxDocParentFrameAny() : wxDocParentFrameAnyBase(this) { }
871     wxDocParentFrameAny(wxDocManager *manager,
872                         wxFrame *frame,
873                         wxWindowID id,
874                         const wxString& title,
875                         const wxPoint& pos = wxDefaultPosition,
876                         const wxSize& size = wxDefaultSize,
877                         long style = wxDEFAULT_FRAME_STYLE,
878                         const wxString& name = wxFrameNameStr)
wxDocParentFrameAnyBase(this)879         : wxDocParentFrameAnyBase(this)
880     {
881         Create(manager, frame, id, title, pos, size, style, name);
882     }
883 
884     bool Create(wxDocManager *manager,
885                 wxFrame *frame,
886                 wxWindowID id,
887                 const wxString& title,
888                 const wxPoint& pos = wxDefaultPosition,
889                 const wxSize& size = wxDefaultSize,
890                 long style = wxDEFAULT_FRAME_STYLE,
891                 const wxString& name = wxFrameNameStr)
892     {
893         m_docManager = manager;
894 
895         if ( !BaseFrame::Create(frame, id, title, pos, size, style, name) )
896             return false;
897 
898         this->Connect(wxID_EXIT, wxEVT_MENU,
899                       wxCommandEventHandler(wxDocParentFrameAny::OnExit));
900         this->Connect(wxEVT_CLOSE_WINDOW,
901                       wxCloseEventHandler(wxDocParentFrameAny::OnCloseWindow));
902 
903         return true;
904     }
905 
906 protected:
907     // hook the document manager into event handling chain here
TryBefore(wxEvent & event)908     virtual bool TryBefore(wxEvent& event)
909     {
910         // It is important to send the event to the base class first as
911         // wxMDIParentFrame overrides its TryBefore() to send the menu events
912         // to the currently active child frame and the child must get them
913         // before our own TryProcessEvent() is executed, not afterwards.
914         return BaseFrame::TryBefore(event) || TryProcessEvent(event);
915     }
916 
917 private:
OnExit(wxCommandEvent & WXUNUSED (event))918     void OnExit(wxCommandEvent& WXUNUSED(event))
919     {
920         this->Close();
921     }
922 
OnCloseWindow(wxCloseEvent & event)923     void OnCloseWindow(wxCloseEvent& event)
924     {
925         if ( m_docManager && !m_docManager->Clear(!event.CanVeto()) )
926         {
927             // The user decided not to close finally, abort.
928             event.Veto();
929         }
930         else
931         {
932             // Just skip the event, base class handler will destroy the window.
933             event.Skip();
934         }
935     }
936 
937 
938     wxDECLARE_NO_COPY_CLASS(wxDocParentFrameAny);
939 };
940 
941 typedef wxDocParentFrameAny<wxFrame> wxDocParentFrameBase;
942 
943 class WXDLLIMPEXP_CORE wxDocParentFrame : public wxDocParentFrameBase
944 {
945 public:
wxDocParentFrame()946     wxDocParentFrame() : wxDocParentFrameBase() { }
947 
948     wxDocParentFrame(wxDocManager *manager,
949                      wxFrame *parent,
950                      wxWindowID id,
951                      const wxString& title,
952                      const wxPoint& pos = wxDefaultPosition,
953                      const wxSize& size = wxDefaultSize,
954                      long style = wxDEFAULT_FRAME_STYLE,
955                      const wxString& name = wxFrameNameStr)
wxDocParentFrameBase(manager,parent,id,title,pos,size,style,name)956         : wxDocParentFrameBase(manager,
957                                parent, id, title, pos, size, style, name)
958     {
959     }
960 
961     bool Create(wxDocManager *manager,
962                 wxFrame *parent,
963                 wxWindowID id,
964                 const wxString& title,
965                 const wxPoint& pos = wxDefaultPosition,
966                 const wxSize& size = wxDefaultSize,
967                 long style = wxDEFAULT_FRAME_STYLE,
968                 const wxString& name = wxFrameNameStr)
969     {
970         return wxDocParentFrameBase::Create(manager,
971                                             parent, id, title,
972                                             pos, size, style, name);
973     }
974 
975 private:
976     DECLARE_CLASS(wxDocParentFrame)
977     wxDECLARE_NO_COPY_CLASS(wxDocParentFrame);
978 };
979 
980 #ifdef __VISUALC6__
981     // reenable warning 4275
982     #pragma warning (pop)
983 #endif
984 
985 // ----------------------------------------------------------------------------
986 // Provide simple default printing facilities
987 // ----------------------------------------------------------------------------
988 
989 #if wxUSE_PRINTING_ARCHITECTURE
990 class WXDLLIMPEXP_CORE wxDocPrintout : public wxPrintout
991 {
992 public:
993     wxDocPrintout(wxView *view = NULL, const wxString& title = wxString());
994 
995     // implement wxPrintout methods
996     virtual bool OnPrintPage(int page);
997     virtual bool HasPage(int page);
998     virtual bool OnBeginDocument(int startPage, int endPage);
999     virtual void GetPageInfo(int *minPage, int *maxPage,
1000                              int *selPageFrom, int *selPageTo);
1001 
GetView()1002     virtual wxView *GetView() { return m_printoutView; }
1003 
1004 protected:
1005     wxView*       m_printoutView;
1006 
1007 private:
1008     DECLARE_DYNAMIC_CLASS(wxDocPrintout)
1009     wxDECLARE_NO_COPY_CLASS(wxDocPrintout);
1010 };
1011 #endif // wxUSE_PRINTING_ARCHITECTURE
1012 
1013 // For compatibility with existing file formats:
1014 // converts from/to a stream to/from a temporary file.
1015 #if wxUSE_STD_IOSTREAM
1016 bool WXDLLIMPEXP_CORE
1017 wxTransferFileToStream(const wxString& filename, wxSTD ostream& stream);
1018 bool WXDLLIMPEXP_CORE
1019 wxTransferStreamToFile(wxSTD istream& stream, const wxString& filename);
1020 #else
1021 bool WXDLLIMPEXP_CORE
1022 wxTransferFileToStream(const wxString& filename, wxOutputStream& stream);
1023 bool WXDLLIMPEXP_CORE
1024 wxTransferStreamToFile(wxInputStream& stream, const wxString& filename);
1025 #endif // wxUSE_STD_IOSTREAM
1026 
1027 
1028 // these flags are not used anywhere by wxWidgets and kept only for an unlikely
1029 // case of existing user code using them for its own purposes
1030 #if WXWIN_COMPATIBILITY_2_8
1031 enum
1032 {
1033     wxDOC_SDI = 1,
1034     wxDOC_MDI,
1035     wxDEFAULT_DOCMAN_FLAGS = wxDOC_SDI
1036 };
1037 #endif // WXWIN_COMPATIBILITY_2_8
1038 
1039 #ifndef __VISUALC6__
GetViewsVector()1040 inline wxViewVector wxDocument::GetViewsVector() const
1041 {
1042     return m_documentViews.AsVector<wxView*>();
1043 }
1044 
GetDocumentsVector()1045 inline wxDocVector wxDocManager::GetDocumentsVector() const
1046 {
1047     return m_docs.AsVector<wxDocument*>();
1048 }
1049 
GetTemplatesVector()1050 inline wxDocTemplateVector wxDocManager::GetTemplatesVector() const
1051 {
1052     return m_templates.AsVector<wxDocTemplate*>();
1053 }
1054 #endif // !__VISUALC6__
1055 
1056 #endif // wxUSE_DOC_VIEW_ARCHITECTURE
1057 
1058 #endif // _WX_DOCH__
1059