1 #----------------------------------------------------------------------------
3 # Purpose: Port of the wxWindows docview classes
9 # Copyright: (c) 2003-2005 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
10 # License: wxWindows license
11 #----------------------------------------------------------------------------
21 #----------------------------------------------------------------------
23 #----------------------------------------------------------------------
30 DEFAULT_DOCMAN_FLAGS
= DOC_SDI
& DOC_OPEN_ONCE
33 TEMPLATE_INVISIBLE
= 2
34 DEFAULT_TEMPLATE_FLAGS
= TEMPLATE_VISIBLE
39 #----------------------------------------------------------------------
40 # Convenience functions from wxWindows used in docview
41 #----------------------------------------------------------------------
44 def FileNameFromPath(path
):
46 Returns the filename for a full path.
48 return os
.path
.split(path
)[1]
50 def FindExtension(path
):
52 Returns the extension of a filename for a full path.
54 return os
.path
.splitext(path
)[1].lower()
58 Returns True if the path exists.
60 return os
.path
.isfile(path
)
64 Returns the path of a full path without the filename.
66 return os
.path
.split(path
)[0]
69 #----------------------------------------------------------------------
70 # Document/View Classes
71 #----------------------------------------------------------------------
74 class Document(wx
.EvtHandler
):
76 The document class can be used to model an application's file-based data. It
77 is part of the document/view framework supported by wxWindows, and cooperates
78 with the wxView, wxDocTemplate and wxDocManager classes.
80 Note this wxPython version also keeps track of the modification date of the
81 document and if it changes on disk outside of the application, we will warn the
82 user before saving to avoid clobbering the file.
86 def __init__(self
, parent
=None):
88 Constructor. Define your own default constructor to initialize
89 application-specific data.
91 wx
.EvtHandler
.__init
__(self
)
93 self
._documentParent
= parent
94 self
._documentTemplate
= None
95 self
._commandProcessor
= None
96 self
._savedYet
= False
97 self
._writeable
= True
99 self
._documentTitle
= None
100 self
._documentFile
= None
101 self
._documentTypeName
= None
102 self
._documentModified
= False
103 self
._documentModificationDate
= None
104 self
._documentViews
= []
107 def ProcessEvent(self
, event
):
109 Processes an event, searching event tables and calling zero or more
110 suitable event handler function(s). Note that the ProcessEvent
111 method is called from the wxPython docview framework directly since
112 wxPython does not have a virtual ProcessEvent function.
117 def GetFilename(self
):
119 Gets the filename associated with this document, or "" if none is
122 return self
._documentFile
127 Gets the title for this document. The document title is used for an
128 associated frame (if any), and is usually constructed by the framework
131 return self
._documentTitle
134 def SetTitle(self
, title
):
136 Sets the title for this document. The document title is used for an
137 associated frame (if any), and is usually constructed by the framework
140 self
._documentTitle
= title
143 def GetDocumentName(self
):
145 The document type name given to the wxDocTemplate constructor,
146 copied to this document when the document is created. If several
147 document templates are created that use the same document type, this
148 variable is used in wxDocManager::CreateView to collate a list of
149 alternative view types that can be used on this kind of document.
151 return self
._documentTypeName
154 def SetDocumentName(self
, name
):
156 Sets he document type name given to the wxDocTemplate constructor,
157 copied to this document when the document is created. If several
158 document templates are created that use the same document type, this
159 variable is used in wxDocManager::CreateView to collate a list of
160 alternative view types that can be used on this kind of document. Do
161 not change the value of this variable.
163 self
._documentTypeName
= name
166 def GetDocumentSaved(self
):
168 Returns True if the document has been saved. This method has been
169 added to wxPython and is not in wxWindows.
171 return self
._savedYet
174 def SetDocumentSaved(self
, saved
=True):
176 Sets whether the document has been saved. This method has been
177 added to wxPython and is not in wxWindows.
179 self
._savedYet
= saved
182 def GetCommandProcessor(self
):
184 Returns the command processor associated with this document.
186 return self
._commandProcessor
189 def SetCommandProcessor(self
, processor
):
191 Sets the command processor to be used for this document. The document
192 will then be responsible for its deletion. Normally you should not
193 call this; override OnCreateCommandProcessor instead.
195 self
._commandProcessor
= processor
198 def IsModified(self
):
200 Returns true if the document has been modified since the last save,
201 false otherwise. You may need to override this if your document view
202 maintains its own record of being modified (for example if using
203 wxTextWindow to view and edit the document).
205 return self
._documentModified
208 def Modify(self
, modify
):
210 Call with true to mark the document as modified since the last save,
211 false otherwise. You may need to override this if your document view
212 maintains its own record of being modified (for example if using
213 xTextWindow to view and edit the document).
215 self
._documentModified
= modify
218 def SetDocumentModificationDate(self
):
220 Saves the file's last modification date.
221 This is used to check if the file has been modified outside of the application.
222 This method has been added to wxPython and is not in wxWindows.
224 self
._documentModificationDate
= os
.path
.getmtime(self
.GetFilename())
227 def GetDocumentModificationDate(self
):
229 Returns the file's modification date when it was loaded from disk.
230 This is used to check if the file has been modified outside of the application.
231 This method has been added to wxPython and is not in wxWindows.
233 return self
._documentModificationDate
238 Returns the list whose elements are the views on the document.
240 return self
._documentViews
243 def GetDocumentTemplate(self
):
245 Returns the template that created the document.
247 return self
._documentTemplate
250 def SetDocumentTemplate(self
, template
):
252 Sets the template that created the document. Should only be called by
255 self
._documentTemplate
= template
258 def DeleteContents(self
):
260 Deletes the contents of the document. Override this method as
268 Destructor. Removes itself from the document manager.
270 self
.DeleteContents()
271 if self
.GetDocumentManager():
272 self
.GetDocumentManager().RemoveDocument(self
)
273 wx
.EvtHandler
.Destroy(self
)
278 Closes the document, by calling OnSaveModified and then (if this true)
279 OnCloseDocument. This does not normally delete the document object:
280 use DeleteAllViews to do this implicitly.
282 if self
.OnSaveModified():
283 if self
.OnCloseDocument():
291 def OnCloseDocument(self
):
293 The default implementation calls DeleteContents (an empty
294 implementation) sets the modified flag to false. Override this to
295 supply additional behaviour when the document is closed with Close.
298 self
.DeleteContents()
303 def DeleteAllViews(self
):
305 Calls wxView.Close and deletes each view. Deleting the final view will
306 implicitly delete the document itself, because the wxView destructor
307 calls RemoveView. This in turns calls wxDocument::OnChangedViewList,
308 whose default implemention is to save and delete the document if no
311 manager
= self
.GetDocumentManager()
312 for view
in self
._documentViews
:
315 if self
in manager
.GetDocuments():
320 def GetFirstView(self
):
322 A convenience function to get the first view for a document, because
323 in many cases a document will only have a single view.
325 if len(self
._documentViews
) == 0:
327 return self
._documentViews
[0]
330 def GetDocumentManager(self
):
332 Returns the associated document manager.
334 if self
._documentTemplate
:
335 return self
._documentTemplate
.GetDocumentManager()
339 def OnNewDocument(self
):
341 The default implementation calls OnSaveModified and DeleteContents,
342 makes a default title for the document, and notifies the views that
343 the filename (in fact, the title) has changed.
345 if not self
.OnSaveModified() or not self
.OnCloseDocument():
347 self
.DeleteContents()
349 self
.SetDocumentSaved(False)
350 name
= self
.GetDocumentManager().MakeDefaultName()
352 self
.SetFilename(name
, notifyViews
= True)
357 Saves the document by calling OnSaveDocument if there is an associated
358 filename, or SaveAs if there is no filename.
360 if not self
.IsModified(): # and self._savedYet: This was here, but if it is not modified who cares if it hasn't been saved yet?
363 """ check for file modification outside of application """
364 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
365 msgTitle
= wx
.GetApp().GetAppName()
367 msgTitle
= _("Application")
368 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
370 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
371 self
.GetDocumentWindow())
377 else: # elif res == wx.CANCEL:
380 if not self
._documentFile
or not self
._savedYet
:
382 return self
.OnSaveDocument(self
._documentFile
)
387 Prompts the user for a file to save to, and then calls OnSaveDocument.
389 docTemplate
= self
.GetDocumentTemplate()
393 descr
= docTemplate
.GetDescription() + _(" (") + docTemplate
.GetFileFilter() + _(") |") + docTemplate
.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
394 filename
= wx
.FileSelector(_("Save As"),
395 docTemplate
.GetDirectory(),
396 FileNameFromPath(self
.GetFilename()),
397 docTemplate
.GetDefaultExtension(),
399 flags
= wx
.SAVE | wx
.OVERWRITE_PROMPT
,
400 parent
= self
.GetDocumentWindow())
404 name
, ext
= os
.path
.splitext(filename
)
406 filename
+= '.' + docTemplate
.GetDefaultExtension()
408 self
.SetFilename(filename
)
409 self
.SetTitle(FileNameFromPath(filename
))
411 for view
in self
._documentViews
:
412 view
.OnChangeFilename()
414 if not self
.OnSaveDocument(filename
):
417 if docTemplate
.FileMatchesTemplate(filename
):
418 self
.GetDocumentManager().AddFileToHistory(filename
)
423 def OnSaveDocument(self
, filename
):
425 Constructs an output file for the given filename (which must
426 not be empty), and calls SaveObject. If SaveObject returns true, the
427 document is set to unmodified; otherwise, an error message box is
433 msgTitle
= wx
.GetApp().GetAppName()
435 msgTitle
= _("File Error")
437 backupFilename
= None
440 # if current file exists, move it to a safe place temporarily
441 if os
.path
.exists(filename
):
443 # Check if read-only.
444 if not os
.access(filename
, os
.W_OK
):
445 wx
.MessageBox("Could not save '%s'. No write permission to overwrite existing file." % FileNameFromPath(filename
),
447 wx
.OK | wx
.ICON_EXCLAMATION
,
448 self
.GetDocumentWindow())
452 backupFilename
= "%s.bak%s" % (filename
, i
)
453 while os
.path
.exists(backupFilename
):
455 backupFilename
= "%s.bak%s" % (filename
, i
)
456 os
.rename(filename
, backupFilename
)
458 fileObject
= file(filename
, 'w')
459 self
.SaveObject(fileObject
)
464 os
.remove(backupFilename
)
466 # for debugging purposes
468 traceback
.print_exc()
471 fileObject
.close() # file is still open, close it, need to do this before removal
473 # save failed, restore old file
476 os
.rename(backupFilename
, filename
)
477 self
.SetDocumentModificationDate()
479 wx
.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
481 wx
.OK | wx
.ICON_EXCLAMATION
,
482 self
.GetDocumentWindow())
485 self
.SetFilename(filename
, True)
487 self
.SetDocumentModificationDate()
488 self
.SetDocumentSaved(True)
489 #if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
490 # wx.FileName(file).MacSetDefaultTypeAndCreator()
494 def OnOpenDocument(self
, filename
):
496 Constructs an input file for the given filename (which must not
497 be empty), and calls LoadObject. If LoadObject returns true, the
498 document is set to unmodified; otherwise, an error message box is
499 displayed. The document's views are notified that the filename has
500 changed, to give windows an opportunity to update their titles. All of
501 the document's views are then updated.
503 if not self
.OnSaveModified():
506 msgTitle
= wx
.GetApp().GetAppName()
508 msgTitle
= _("File Error")
510 fileObject
= file(filename
, 'r')
512 self
.LoadObject(fileObject
)
516 # for debugging purposes
518 traceback
.print_exc()
521 fileObject
.close() # file is still open, close it
523 wx
.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
525 wx
.OK | wx
.ICON_EXCLAMATION
,
526 self
.GetDocumentWindow())
529 self
.SetFilename(filename
, True)
531 self
.SetDocumentModificationDate()
532 self
.SetDocumentSaved(True)
533 self
.UpdateAllViews()
537 def LoadObject(self
, file):
539 Override this function and call it from your own LoadObject before
540 loading your own data. LoadObject is called by the framework
541 automatically when the document contents need to be loaded.
543 Note that the wxPython version simply sends you a Python file object,
544 so you can use pickle.
549 def SaveObject(self
, file):
551 Override this function and call it from your own SaveObject before
552 saving your own data. SaveObject is called by the framework
553 automatically when the document contents need to be saved.
555 Note that the wxPython version simply sends you a Python file object,
556 so you can use pickle.
563 Override this function to revert the document to its last saved state.
568 def GetPrintableName(self
):
570 Copies a suitable document name into the supplied name buffer.
571 The default function uses the title, or if there is no title, uses the
572 filename; or if no filename, the string 'Untitled'.
574 if self
._documentTitle
:
575 return self
._documentTitle
576 elif self
._documentFile
:
577 return FileNameFromPath(self
._documentFile
)
582 def GetDocumentWindow(self
):
584 Intended to return a suitable window for using as a parent for
585 document-related dialog boxes. By default, uses the frame associated
588 if len(self
._documentViews
) > 0:
589 return self
._documentViews
[0].GetFrame()
591 return wx
.GetApp().GetTopWindow()
594 def OnCreateCommandProcessor(self
):
596 Override this function if you want a different (or no) command
597 processor to be created when the document is created. By default, it
598 returns an instance of wxCommandProcessor.
600 return CommandProcessor()
603 def OnSaveModified(self
):
605 If the document has been modified, prompts the user to ask if the
606 changes should be changed. If the user replies Yes, the Save function
607 is called. If No, the document is marked as unmodified and the
608 function succeeds. If Cancel, the function fails.
610 if not self
.IsModified():
613 """ check for file modification outside of application """
614 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
615 msgTitle
= wx
.GetApp().GetAppName()
617 msgTitle
= _("Warning")
618 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
620 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
621 self
.GetDocumentWindow())
627 return wx
.lib
.docview
.Document
.Save(self
)
628 else: # elif res == wx.CANCEL:
631 msgTitle
= wx
.GetApp().GetAppName()
633 msgTitle
= _("Warning")
635 res
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(),
637 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
638 self
.GetDocumentWindow())
645 else: # elif res == wx.CANCEL:
651 Called by printing framework to draw the view.
656 def AddView(self
, view
):
658 If the view is not already in the list of views, adds the view and
659 calls OnChangedViewList.
661 if not view
in self
._documentViews
:
662 self
._documentViews
.append(view
)
663 self
.OnChangedViewList()
667 def RemoveView(self
, view
):
669 Removes the view from the document's list of views, and calls
672 if view
in self
._documentViews
:
673 self
._documentViews
.remove(view
)
674 self
.OnChangedViewList()
678 def OnCreate(self
, path
, flags
):
680 The default implementation calls DeleteContents (an empty
681 implementation) sets the modified flag to false. Override this to
682 supply additional behaviour when the document is closed with Close.
684 return self
.GetDocumentTemplate().CreateView(self
, flags
)
687 def OnChangedViewList(self
):
689 Called when a view is added to or deleted from this document. The
690 default implementation saves and deletes the document if no views
691 exist (the last one has just been removed).
693 if len(self
._documentViews
) == 0:
694 if self
.OnSaveModified():
695 pass # C version does a delete but Python will garbage collect
698 def UpdateAllViews(self
, sender
= None, hint
= None):
700 Updates all views. If sender is non-NULL, does not update this view.
701 hint represents optional information to allow a view to optimize its
704 for view
in self
._documentViews
:
706 view
.OnUpdate(sender
, hint
)
709 def NotifyClosing(self
):
711 Notifies the views that the document is going to close.
713 for view
in self
._documentViews
:
714 view
.OnClosingDocument()
717 def SetFilename(self
, filename
, notifyViews
= False):
719 Sets the filename for this document. Usually called by the framework.
720 If notifyViews is true, wxView.OnChangeFilename is called for all
723 self
._documentFile
= filename
725 for view
in self
._documentViews
:
726 view
.OnChangeFilename()
729 def GetWriteable(self
):
731 Returns true if the document can be written to its accociated file path.
732 This method has been added to wxPython and is not in wxWindows.
734 if not self
._writeable
:
736 if not self
._documentFile
: # Doesn't exist, do a save as
739 return os
.access(self
._documentFile
, os
.W_OK
)
742 def SetWriteable(self
, writeable
):
744 Set to False if the document can not be saved. This will disable the ID_SAVE_AS
745 event and is useful for custom documents that should not be saveable. The ID_SAVE
746 event can be disabled by never Modifying the document. This method has been added
747 to wxPython and is not in wxWindows.
749 self
._writeable
= writeable
752 class View(wx
.EvtHandler
):
754 The view class can be used to model the viewing and editing component of
755 an application's file-based data. It is part of the document/view
756 framework supported by wxWindows, and cooperates with the wxDocument,
757 wxDocTemplate and wxDocManager classes.
762 Constructor. Define your own default constructor to initialize
763 application-specific data.
765 wx
.EvtHandler
.__init
__(self
)
766 self
._viewDocument
= None
767 self
._viewFrame
= None
772 Destructor. Removes itself from the document's list of views.
774 if self
._viewDocument
:
775 self
._viewDocument
.RemoveView(self
)
776 wx
.EvtHandler
.Destroy(self
)
779 def ProcessEvent(self
, event
):
781 Processes an event, searching event tables and calling zero or more
782 suitable event handler function(s). Note that the ProcessEvent
783 method is called from the wxPython docview framework directly since
784 wxPython does not have a virtual ProcessEvent function.
786 if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
):
792 def ProcessUpdateUIEvent(self
, event
):
794 Processes a UI event, searching event tables and calling zero or more
795 suitable event handler function(s). Note that the ProcessEvent
796 method is called from the wxPython docview framework directly since
797 wxPython does not have a virtual ProcessEvent function.
802 def OnActivateView(self
, activate
, activeView
, deactiveView
):
804 Called when a view is activated by means of wxView::Activate. The
805 default implementation does nothing.
810 def OnClosingDocument(self
):
812 Override this to clean up the view when the document is being closed.
813 The default implementation does nothing.
818 def OnDraw(self
, dc
):
820 Override this to draw the view for the printing framework. The
821 default implementation does nothing.
826 def OnPrint(self
, dc
, info
):
828 Override this to print the view for the printing framework. The
829 default implementation calls View.OnDraw.
834 def OnUpdate(self
, sender
, hint
):
836 Called when the view should be updated. sender is a pointer to the
837 view that sent the update request, or NULL if no single view requested
838 the update (for instance, when the document is opened). hint is as yet
839 unused but may in future contain application-specific information for
840 making updating more efficient.
845 def OnChangeFilename(self
):
847 Called when the filename has changed. The default implementation
848 constructs a suitable title and sets the title of the view frame (if
852 appName
= wx
.GetApp().GetAppName()
853 if not self
.GetDocument():
859 if appName
and isinstance(self
.GetFrame(), DocChildFrame
): # Only need app name in title for SDI
860 title
= appName
+ _(" - ")
863 self
.GetFrame().SetTitle(title
+ self
.GetDocument().GetPrintableName())
866 def GetDocument(self
):
868 Returns the document associated with the view.
870 return self
._viewDocument
873 def SetDocument(self
, doc
):
875 Associates the given document with the view. Normally called by the
878 self
._viewDocument
= doc
883 def GetViewName(self
):
885 Gets the name associated with the view (passed to the wxDocTemplate
886 constructor). Not currently used by the framework.
888 return self
._viewTypeName
891 def SetViewName(self
, name
):
893 Sets the view type name. Should only be called by the framework.
895 self
._viewTypeName
= name
898 def Close(self
, deleteWindow
=True):
900 Closes the view by calling OnClose. If deleteWindow is true, this
901 function should delete the window associated with the view.
903 if self
.OnClose(deleteWindow
= deleteWindow
):
909 def Activate(self
, activate
=True):
911 Call this from your view frame's OnActivate member to tell the
912 framework which view is currently active. If your windowing system
913 doesn't call OnActivate, you may need to call this function from
914 OnMenuCommand or any place where you know the view must be active, and
915 the framework will need to get the current view.
917 The prepackaged view frame wxDocChildFrame calls wxView.Activate from
918 its OnActivate member and from its OnMenuCommand member.
920 if self
.GetDocument() and self
.GetDocumentManager():
921 self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView())
922 self
.GetDocumentManager().ActivateView(self
, activate
)
925 def OnClose(self
, deleteWindow
=True):
927 Implements closing behaviour. The default implementation calls
928 wxDocument.Close to close the associated document. Does not delete the
929 view. The application may wish to do some cleaning up operations in
930 this function, if a call to wxDocument::Close succeeded. For example,
931 if your application's all share the same window, you need to
932 disassociate the window from the view and perhaps clear the window. If
933 deleteWindow is true, delete the frame associated with the view.
935 if self
.GetDocument():
936 return self
.GetDocument().Close()
941 def OnCreate(self
, doc
, flags
):
943 wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just
944 after the wxDocTemplate creates the wxView, it calls wxView::OnCreate.
945 In its OnCreate member function, the wxView can create a
946 wxDocChildFrame or a derived class. This wxDocChildFrame provides user
947 interface elements to view and/or edit the contents of the wxDocument.
949 By default, simply returns true. If the function returns false, the
950 view will be deleted.
955 def OnCreatePrintout(self
):
957 Returns a wxPrintout object for the purposes of printing. It should
958 create a new object every time it is called; the framework will delete
961 By default, this function returns an instance of wxDocPrintout, which
962 prints and previews one page by calling wxView.OnDraw.
964 Override to return an instance of a class other than wxDocPrintout.
966 return DocPrintout(self
, self
.GetDocument().GetPrintableName())
971 Gets the frame associated with the view (if any). Note that this
972 "frame" is not a wxFrame at all in the generic MDI implementation
973 which uses the notebook pages instead of the frames and this is why
974 this method returns a wxWindow and not a wxFrame.
976 return self
._viewFrame
979 def SetFrame(self
, frame
):
981 Sets the frame associated with this view. The application should call
982 this if possible, to tell the view about the frame. See GetFrame for
983 the explanation about the mismatch between the "Frame" in the method
984 name and the type of its parameter.
986 self
._viewFrame
= frame
989 def GetDocumentManager(self
):
991 Returns the document manager instance associated with this view.
993 if self
._viewDocument
:
994 return self
.GetDocument().GetDocumentManager()
999 class DocTemplate(wx
.Object
):
1001 The wxDocTemplate class is used to model the relationship between a
1002 document class and a view class.
1006 def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
=DEFAULT_TEMPLATE_FLAGS
, icon
=None):
1008 Constructor. Create instances dynamically near the start of your
1009 application after creating a wxDocManager instance, and before doing
1010 any document or view operations.
1012 manager is the document manager object which manages this template.
1014 description is a short description of what the template is for. This
1015 string will be displayed in the file filter list of Windows file
1018 filter is an appropriate file filter such as *.txt.
1020 dir is the default directory to use for file selectors.
1022 ext is the default file extension (such as txt).
1024 docTypeName is a name that should be unique for a given type of
1025 document, used for gathering a list of views relevant to a
1026 particular document.
1028 viewTypeName is a name that should be unique for a given view.
1030 docClass is a Python class. If this is not supplied, you will need to
1031 derive a new wxDocTemplate class and override the CreateDocument
1032 member to return a new document instance on demand.
1034 viewClass is a Python class. If this is not supplied, you will need to
1035 derive a new wxDocTemplate class and override the CreateView member to
1036 return a new view instance on demand.
1038 flags is a bit list of the following:
1039 wx.TEMPLATE_VISIBLE The template may be displayed to the user in
1042 wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in
1045 wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE.
1047 self
._docManager
= manager
1048 self
._description
= description
1049 self
._fileFilter
= filter
1050 self
._directory
= dir
1051 self
._defaultExt
= ext
1052 self
._docTypeName
= docTypeName
1053 self
._viewTypeName
= viewTypeName
1054 self
._docType
= docType
1055 self
._viewType
= viewType
1059 self
._docManager
.AssociateTemplate(self
)
1062 def GetDefaultExtension(self
):
1064 Returns the default file extension for the document data, as passed to
1065 the document template constructor.
1067 return self
._defaultExt
1070 def SetDefaultExtension(self
, defaultExt
):
1072 Sets the default file extension.
1074 self
._defaultExt
= defaultExt
1077 def GetDescription(self
):
1079 Returns the text description of this template, as passed to the
1080 document template constructor.
1082 return self
._description
1085 def SetDescription(self
, description
):
1087 Sets the template description.
1089 self
._description
= description
1092 def GetDirectory(self
):
1094 Returns the default directory, as passed to the document template
1097 return self
._directory
1100 def SetDirectory(self
, dir):
1102 Sets the default directory.
1104 self
._directory
= dir
1107 def GetDocumentManager(self
):
1109 Returns the document manager instance for which this template was
1112 return self
._docManager
1115 def SetDocumentManager(self
, manager
):
1117 Sets the document manager instance for which this template was
1118 created. Should not be called by the application.
1120 self
._docManager
= manager
1123 def GetFileFilter(self
):
1125 Returns the file filter, as passed to the document template
1128 return self
._fileFilter
1131 def SetFileFilter(self
, filter):
1133 Sets the file filter.
1135 self
._fileFilter
= filter
1140 Returns the flags, as passed to the document template constructor.
1141 (see the constructor description for more details).
1146 def SetFlags(self
, flags
):
1148 Sets the internal document template flags (see the constructor
1149 description for more details).
1156 Returns the icon, as passed to the document template
1157 constructor. This method has been added to wxPython and is
1163 def SetIcon(self
, flags
):
1165 Sets the icon. This method has been added to wxPython and is not
1171 def GetDocumentType(self
):
1173 Returns the Python document class, as passed to the document template
1176 return self
._docType
1179 def GetViewType(self
):
1181 Returns the Python view class, as passed to the document template
1184 return self
._viewType
1187 def IsVisible(self
):
1189 Returns true if the document template can be shown in user dialogs,
1192 return (self
._flags
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
1195 def GetDocumentName(self
):
1197 Returns the document type name, as passed to the document template
1200 return self
._docTypeName
1203 def GetViewName(self
):
1205 Returns the view type name, as passed to the document template
1208 return self
._viewTypeName
1211 def CreateDocument(self
, path
, flags
):
1213 Creates a new instance of the associated document class. If you have
1214 not supplied a class to the template constructor, you will need to
1215 override this function to return an appropriate document instance.
1217 doc
= self
._docType
()
1218 doc
.SetFilename(path
)
1219 doc
.SetDocumentTemplate(self
)
1220 self
.GetDocumentManager().AddDocument(doc
)
1221 doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor())
1222 if doc
.OnCreate(path
, flags
):
1225 if doc
in self
.GetDocumentManager().GetDocuments():
1226 doc
.DeleteAllViews()
1230 def CreateView(self
, doc
, flags
):
1232 Creates a new instance of the associated document view. If you have
1233 not supplied a class to the template constructor, you will need to
1234 override this function to return an appropriate view instance.
1236 view
= self
._viewType
()
1237 view
.SetDocument(doc
)
1238 if view
.OnCreate(doc
, flags
):
1245 def FileMatchesTemplate(self
, path
):
1247 Returns True if the path's extension matches one of this template's
1248 file filter extensions.
1250 ## print "*** path", path
1251 ## if "*.*" in self.GetFileFilter():
1254 ext
= FindExtension(path
)
1255 if not ext
: return False
1256 return ext
in self
.GetFileFilter()
1257 # return self.GetDefaultExtension() == FindExtension(path)
1260 class DocManager(wx
.EvtHandler
):
1262 The wxDocManager class is part of the document/view framework supported by
1263 wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate
1267 def __init__(self
, flags
=DEFAULT_DOCMAN_FLAGS
, initialize
=True):
1269 Constructor. Create a document manager instance dynamically near the
1270 start of your application before doing any document or view operations.
1272 flags is used in the Python version to indicate whether the document
1273 manager is in DOC_SDI or DOC_MDI mode.
1275 If initialize is true, the Initialize function will be called to
1276 create a default history list object. If you derive from wxDocManager,
1277 you may wish to call the base constructor with false, and then call
1278 Initialize in your own constructor, to allow your own Initialize or
1279 OnCreateFileHistory functions to be called.
1282 wx
.EvtHandler
.__init
__(self
)
1284 self
._defaultDocumentNameCounter
= 1
1286 self
._currentView
= None
1287 self
._lastActiveView
= None
1288 self
._maxDocsOpen
= 10000
1289 self
._fileHistory
= None
1290 self
._templates
= []
1292 self
._lastDirectory
= ""
1297 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
)
1298 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
)
1299 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
)
1300 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
)
1301 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
)
1302 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
)
1303 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
)
1304 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
1305 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
1306 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
)
1307 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
)
1308 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
)
1310 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
)
1311 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
)
1312 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
)
1313 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
)
1314 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
)
1315 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
)
1316 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
)
1317 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
)
1318 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
)
1319 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
)
1320 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
)
1321 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
)
1329 wx
.EvtHandler
.Destroy(self
)
1334 Returns the document manager's flags. This method has been
1335 added to wxPython and is not in wxWindows.
1340 def CloseDocument(self
, doc
, force
=True):
1342 Closes the specified document.
1344 if doc
.Close() or force
:
1345 doc
.DeleteAllViews()
1346 if doc
in self
._docs
:
1352 def CloseDocuments(self
, force
=True):
1354 Closes all currently opened documents.
1356 for document
in self
._docs
[::-1]: # Close in lifo (reverse) order. We clone the list to make sure we go through all docs even as they are deleted
1357 if not self
.CloseDocument(document
, force
):
1359 document
.DeleteAllViews() # Implicitly delete the document when the last view is removed
1363 def Clear(self
, force
=True):
1365 Closes all currently opened document by callling CloseDocuments and
1366 clears the document manager's templates.
1368 if not self
.CloseDocuments(force
):
1370 self
._templates
= []
1374 def Initialize(self
):
1376 Initializes data; currently just calls OnCreateFileHistory. Some data
1377 cannot always be initialized in the constructor because the programmer
1378 must be given the opportunity to override functionality. In fact
1379 Initialize is called from the wxDocManager constructor, but this can
1380 be vetoed by passing false to the second argument, allowing the
1381 derived class's constructor to call Initialize, possibly calling a
1382 different OnCreateFileHistory from the default.
1384 The bottom line: if you're not deriving from Initialize, forget it and
1385 construct wxDocManager with no arguments.
1387 self
.OnCreateFileHistory()
1391 def OnCreateFileHistory(self
):
1393 A hook to allow a derived class to create a different type of file
1394 history. Called from Initialize.
1396 self
._fileHistory
= wx
.FileHistory()
1399 def OnFileClose(self
, event
):
1401 Closes and deletes the currently active document.
1403 doc
= self
.GetCurrentDocument()
1405 doc
.DeleteAllViews()
1406 if doc
in self
._docs
:
1407 self
._docs
.remove(doc
)
1410 def OnFileCloseAll(self
, event
):
1412 Closes and deletes all the currently opened documents.
1414 return self
.CloseDocuments(force
= False)
1417 def OnFileNew(self
, event
):
1419 Creates a new document and reads in the selected file.
1421 self
.CreateDocument('', DOC_NEW
)
1424 def OnFileOpen(self
, event
):
1426 Creates a new document and reads in the selected file.
1428 if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
):
1429 self
.OnOpenFileFailure()
1432 def OnFileRevert(self
, event
):
1434 Reverts the current document by calling wxDocument.Save for the current
1437 doc
= self
.GetCurrentDocument()
1443 def OnFileSave(self
, event
):
1445 Saves the current document by calling wxDocument.Save for the current
1448 doc
= self
.GetCurrentDocument()
1454 def OnFileSaveAs(self
, event
):
1456 Calls wxDocument.SaveAs for the current document.
1458 doc
= self
.GetCurrentDocument()
1464 def OnPrint(self
, event
):
1466 Prints the current document by calling its View's OnCreatePrintout
1469 view
= self
.GetCurrentView()
1473 printout
= view
.OnCreatePrintout()
1475 if not hasattr(self
, "printData"):
1476 self
.printData
= wx
.PrintData()
1477 self
.printData
.SetPaperId(wx
.PAPER_LETTER
)
1478 self
.printData
.SetPrintMode(wx
.PRINT_MODE_PRINTER
)
1480 pdd
= wx
.PrintDialogData(self
.printData
)
1481 printer
= wx
.Printer(pdd
)
1482 printer
.Print(view
.GetFrame(), printout
)
1485 def OnPrintSetup(self
, event
):
1487 Presents the print setup dialog.
1489 view
= self
.GetCurrentView()
1491 parentWin
= view
.GetFrame()
1493 parentWin
= wx
.GetApp().GetTopWindow()
1495 if not hasattr(self
, "printData"):
1496 self
.printData
= wx
.PrintData()
1497 self
.printData
.SetPaperId(wx
.PAPER_LETTER
)
1499 data
= wx
.PrintDialogData(self
.printData
)
1500 printDialog
= wx
.PrintDialog(parentWin
, data
)
1501 printDialog
.GetPrintDialogData().SetSetupDialog(True)
1502 printDialog
.ShowModal()
1504 # this makes a copy of the wx.PrintData instead of just saving
1505 # a reference to the one inside the PrintDialogData that will
1506 # be destroyed when the dialog is destroyed
1507 self
.printData
= wx
.PrintData(printDialog
.GetPrintDialogData().GetPrintData())
1509 printDialog
.Destroy()
1512 def OnPreview(self
, event
):
1514 Previews the current document by calling its View's OnCreatePrintout
1517 view
= self
.GetCurrentView()
1521 printout
= view
.OnCreatePrintout()
1523 if not hasattr(self
, "printData"):
1524 self
.printData
= wx
.PrintData()
1525 self
.printData
.SetPaperId(wx
.PAPER_LETTER
)
1526 self
.printData
.SetPrintMode(wx
.PRINT_MODE_PREVIEW
)
1528 data
= wx
.PrintDialogData(self
.printData
)
1529 # Pass two printout objects: for preview, and possible printing.
1530 preview
= wx
.PrintPreview(printout
, view
.OnCreatePrintout(), data
)
1531 if not preview
.Ok():
1532 wx
.MessageBox(_("Unable to display print preview."))
1534 # wxWindows source doesn't use base frame's pos, size, and icon, but did it this way so it would work like MS Office etc.
1535 mimicFrame
= wx
.GetApp().GetTopWindow()
1536 frame
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize())
1537 frame
.SetIcon(mimicFrame
.GetIcon())
1538 frame
.SetTitle(_("%s - %s - Preview") % (mimicFrame
.GetTitle(), view
.GetDocument().GetPrintableName()))
1543 def OnUndo(self
, event
):
1545 Issues an Undo command to the current document's command processor.
1547 doc
= self
.GetCurrentDocument()
1550 if doc
.GetCommandProcessor():
1551 doc
.GetCommandProcessor().Undo()
1554 def OnRedo(self
, event
):
1556 Issues a Redo command to the current document's command processor.
1558 doc
= self
.GetCurrentDocument()
1561 if doc
.GetCommandProcessor():
1562 doc
.GetCommandProcessor().Redo()
1565 def OnUpdateFileOpen(self
, event
):
1567 Updates the user interface for the File Open command.
1572 def OnUpdateFileClose(self
, event
):
1574 Updates the user interface for the File Close command.
1576 event
.Enable(self
.GetCurrentDocument() != None)
1579 def OnUpdateFileCloseAll(self
, event
):
1581 Updates the user interface for the File Close All command.
1583 event
.Enable(self
.GetCurrentDocument() != None)
1586 def OnUpdateFileRevert(self
, event
):
1588 Updates the user interface for the File Revert command.
1590 event
.Enable(self
.GetCurrentDocument() != None)
1593 def OnUpdateFileNew(self
, event
):
1595 Updates the user interface for the File New command.
1600 def OnUpdateFileSave(self
, event
):
1602 Updates the user interface for the File Save command.
1604 doc
= self
.GetCurrentDocument()
1605 event
.Enable(doc
!= None and doc
.IsModified())
1608 def OnUpdateFileSaveAs(self
, event
):
1610 Updates the user interface for the File Save As command.
1612 event
.Enable(self
.GetCurrentDocument() != None and self
.GetCurrentDocument().GetWriteable())
1615 def OnUpdateUndo(self
, event
):
1617 Updates the user interface for the Undo command.
1619 doc
= self
.GetCurrentDocument()
1620 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo())
1621 if doc
and doc
.GetCommandProcessor():
1622 doc
.GetCommandProcessor().SetMenuStrings()
1624 event
.SetText(_("&Undo\tCtrl+Z"))
1627 def OnUpdateRedo(self
, event
):
1629 Updates the user interface for the Redo command.
1631 doc
= self
.GetCurrentDocument()
1632 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo())
1633 if doc
and doc
.GetCommandProcessor():
1634 doc
.GetCommandProcessor().SetMenuStrings()
1636 event
.SetText(_("&Redo\tCtrl+Y"))
1639 def OnUpdatePrint(self
, event
):
1641 Updates the user interface for the Print command.
1643 event
.Enable(self
.GetCurrentDocument() != None)
1646 def OnUpdatePrintSetup(self
, event
):
1648 Updates the user interface for the Print Setup command.
1653 def OnUpdatePreview(self
, event
):
1655 Updates the user interface for the Print Preview command.
1657 event
.Enable(self
.GetCurrentDocument() != None)
1660 def GetCurrentView(self
):
1662 Returns the currently active view.
1664 if self
._currentView
:
1665 return self
._currentView
1666 if len(self
._docs
) == 1:
1667 return self
._docs
[0].GetFirstView()
1671 def GetLastActiveView(self
):
1673 Returns the last active view. This is used in the SDI framework where dialogs can be mistaken for a view
1674 and causes the framework to deactivete the current view. This happens when something like a custom dialog box used
1675 to operate on the current view is shown.
1677 if len(self
._docs
) >= 1:
1678 return self
._lastActiveView
1683 def ProcessEvent(self
, event
):
1685 Processes an event, searching event tables and calling zero or more
1686 suitable event handler function(s). Note that the ProcessEvent
1687 method is called from the wxPython docview framework directly since
1688 wxPython does not have a virtual ProcessEvent function.
1690 view
= self
.GetCurrentView()
1692 if view
.ProcessEvent(event
):
1695 if id == wx
.ID_OPEN
:
1696 self
.OnFileOpen(event
)
1698 elif id == wx
.ID_CLOSE
:
1699 self
.OnFileClose(event
)
1701 elif id == wx
.ID_CLOSE_ALL
:
1702 self
.OnFileCloseAll(event
)
1704 elif id == wx
.ID_REVERT
:
1705 self
.OnFileRevert(event
)
1707 elif id == wx
.ID_NEW
:
1708 self
.OnFileNew(event
)
1710 elif id == wx
.ID_SAVE
:
1711 self
.OnFileSave(event
)
1713 elif id == wx
.ID_SAVEAS
:
1714 self
.OnFileSaveAs(event
)
1716 elif id == wx
.ID_UNDO
:
1719 elif id == wx
.ID_REDO
:
1722 elif id == wx
.ID_PRINT
:
1725 elif id == wx
.ID_PRINT_SETUP
:
1726 self
.OnPrintSetup(event
)
1728 elif id == wx
.ID_PREVIEW
:
1729 self
.OnPreview(event
)
1735 def ProcessUpdateUIEvent(self
, event
):
1737 Processes a UI event, searching event tables and calling zero or more
1738 suitable event handler function(s). Note that the ProcessEvent
1739 method is called from the wxPython docview framework directly since
1740 wxPython does not have a virtual ProcessEvent function.
1743 view
= self
.GetCurrentView()
1745 if view
.ProcessUpdateUIEvent(event
):
1747 if id == wx
.ID_OPEN
:
1748 self
.OnUpdateFileOpen(event
)
1750 elif id == wx
.ID_CLOSE
:
1751 self
.OnUpdateFileClose(event
)
1753 elif id == wx
.ID_CLOSE_ALL
:
1754 self
.OnUpdateFileCloseAll(event
)
1756 elif id == wx
.ID_REVERT
:
1757 self
.OnUpdateFileRevert(event
)
1759 elif id == wx
.ID_NEW
:
1760 self
.OnUpdateFileNew(event
)
1762 elif id == wx
.ID_SAVE
:
1763 self
.OnUpdateFileSave(event
)
1765 elif id == wx
.ID_SAVEAS
:
1766 self
.OnUpdateFileSaveAs(event
)
1768 elif id == wx
.ID_UNDO
:
1769 self
.OnUpdateUndo(event
)
1771 elif id == wx
.ID_REDO
:
1772 self
.OnUpdateRedo(event
)
1774 elif id == wx
.ID_PRINT
:
1775 self
.OnUpdatePrint(event
)
1777 elif id == wx
.ID_PRINT_SETUP
:
1778 self
.OnUpdatePrintSetup(event
)
1780 elif id == wx
.ID_PREVIEW
:
1781 self
.OnUpdatePreview(event
)
1787 def CreateDocument(self
, path
, flags
=0):
1789 Creates a new document in a manner determined by the flags parameter,
1792 wx.lib.docview.DOC_NEW Creates a fresh document.
1793 wx.lib.docview.DOC_SILENT Silently loads the given document file.
1795 If wx.lib.docview.DOC_NEW is present, a new document will be created and returned,
1796 possibly after asking the user for a template to use if there is more
1797 than one document template. If wx.lib.docview.DOC_SILENT is present, a new document
1798 will be created and the given file loaded into it. If neither of these
1799 flags is present, the user will be presented with a file selector for
1800 the file to load, and the template to use will be determined by the
1801 extension (Windows) or by popping up a template choice list (other
1804 If the maximum number of documents has been reached, this function
1805 will delete the oldest currently loaded document before creating a new
1808 wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE flag.
1811 for temp
in self
._templates
:
1812 if temp
.IsVisible():
1813 templates
.append(temp
)
1814 if len(templates
) == 0:
1817 if len(self
.GetDocuments()) >= self
._maxDocsOpen
:
1818 doc
= self
.GetDocuments()[0]
1819 if not self
.CloseDocument(doc
, False):
1823 if len(templates
) == 1:
1825 newDoc
= temp
.CreateDocument(path
, flags
)
1827 newDoc
.SetDocumentName(temp
.GetDocumentName())
1828 newDoc
.SetDocumentTemplate(temp
)
1829 newDoc
.OnNewDocument()
1832 temp
= self
.SelectDocumentType(templates
)
1834 newDoc
= temp
.CreateDocument(path
, flags
)
1836 newDoc
.SetDocumentName(temp
.GetDocumentName())
1837 newDoc
.SetDocumentTemplate(temp
)
1838 newDoc
.OnNewDocument()
1843 if path
and flags
& DOC_SILENT
:
1844 temp
= self
.FindTemplateForPath(path
)
1846 temp
, path
= self
.SelectDocumentPath(templates
, path
, flags
)
1849 if path
and self
.GetFlags() & DOC_OPEN_ONCE
:
1850 for document
in self
._docs
:
1851 if document
.GetFilename() and os
.path
.normcase(document
.GetFilename()) == os
.path
.normcase(path
):
1852 """ check for file modification outside of application """
1853 if os
.path
.exists(path
) and os
.path
.getmtime(path
) != document
.GetDocumentModificationDate():
1854 msgTitle
= wx
.GetApp().GetAppName()
1856 msgTitle
= _("Warning")
1857 shortName
= document
.GetPrintableName()
1858 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Reload '%s' from file system?") % (shortName
, msgTitle
, shortName
),
1860 wx
.YES_NO | wx
.ICON_QUESTION
,
1861 self
.FindSuitableParent())
1863 if not self
.CloseDocument(document
, False):
1864 wx
.MessageBox(_("Couldn't reload '%s'. Unable to close current '%s'.") % (shortName
, shortName
))
1866 return self
.CreateDocument(path
, flags
)
1867 elif res
== wx
.NO
: # don't ask again
1868 document
.SetDocumentModificationDate()
1870 firstView
= document
.GetFirstView()
1871 if firstView
and firstView
.GetFrame():
1872 firstView
.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
1873 if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
1874 firstView
.GetFrame().Iconize(False)
1878 newDoc
= temp
.CreateDocument(path
, flags
)
1880 newDoc
.SetDocumentName(temp
.GetDocumentName())
1881 newDoc
.SetDocumentTemplate(temp
)
1882 if not newDoc
.OnOpenDocument(path
):
1883 newDoc
.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1884 newDoc
.GetFirstView().GetFrame().Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
1886 self
.AddFileToHistory(path
)
1892 def CreateView(self
, doc
, flags
=0):
1894 Creates a new view for the given document. If more than one view is
1895 allowed for the document (by virtue of multiple templates mentioning
1896 the same document type), a choice of view is presented to the user.
1899 for temp
in self
._templates
:
1900 if temp
.IsVisible():
1901 if temp
.GetDocumentName() == doc
.GetDocumentName():
1902 templates
.append(temp
)
1903 if len(templates
) == 0:
1906 if len(templates
) == 1:
1908 view
= temp
.CreateView(doc
, flags
)
1910 view
.SetViewName(temp
.GetViewName())
1913 temp
= SelectViewType(templates
)
1915 view
= temp
.CreateView(doc
, flags
)
1917 view
.SetViewName(temp
.GetViewName())
1923 def DeleteTemplate(self
, template
, flags
):
1925 Placeholder, not yet implemented in wxWindows.
1930 def FlushDoc(self
, doc
):
1932 Placeholder, not yet implemented in wxWindows.
1937 def MatchTemplate(self
, path
):
1939 Placeholder, not yet implemented in wxWindows.
1944 def GetCurrentDocument(self
):
1946 Returns the document associated with the currently active view (if any).
1948 view
= self
.GetCurrentView()
1950 return view
.GetDocument()
1955 def MakeDefaultName(self
):
1957 Returns a suitable default name. This is implemented by appending an
1958 integer counter to the string "Untitled" and incrementing the counter.
1960 name
= _("Untitled %d") % self
._defaultDocumentNameCounter
1961 self
._defaultDocumentNameCounter
= self
._defaultDocumentNameCounter
+ 1
1965 def MakeFrameTitle(self
):
1967 Returns a suitable title for a document frame. This is implemented by
1968 appending the document name to the application name.
1970 appName
= wx
.GetApp().GetAppName()
1974 docName
= doc
.GetPrintableName()
1975 title
= docName
+ _(" - ") + appName
1979 def AddFileToHistory(self
, fileName
):
1981 Adds a file to the file history list, if we have a pointer to an
1982 appropriate file menu.
1984 if self
._fileHistory
:
1985 self
._fileHistory
.AddFileToHistory(fileName
)
1988 def RemoveFileFromHistory(self
, i
):
1990 Removes a file from the file history list, if we have a pointer to an
1991 appropriate file menu.
1993 if self
._fileHistory
:
1994 self
._fileHistory
.RemoveFileFromHistory(i
)
1997 def GetFileHistory(self
):
1999 Returns the file history.
2001 return self
._fileHistory
2004 def GetHistoryFile(self
, i
):
2006 Returns the file at index i from the file history.
2008 if self
._fileHistory
:
2009 return self
._fileHistory
.GetHistoryFile(i
)
2014 def FileHistoryUseMenu(self
, menu
):
2016 Use this menu for appending recently-visited document filenames, for
2017 convenient access. Calling this function with a valid menu enables the
2018 history list functionality.
2020 Note that you can add multiple menus using this function, to be
2021 managed by the file history object.
2023 if self
._fileHistory
:
2024 self
._fileHistory
.UseMenu(menu
)
2027 def FileHistoryRemoveMenu(self
, menu
):
2029 Removes the given menu from the list of menus managed by the file
2032 if self
._fileHistory
:
2033 self
._fileHistory
.RemoveMenu(menu
)
2036 def FileHistoryLoad(self
, config
):
2038 Loads the file history from a config object.
2040 if self
._fileHistory
:
2041 self
._fileHistory
.Load(config
)
2044 def FileHistorySave(self
, config
):
2046 Saves the file history into a config object. This must be called
2047 explicitly by the application.
2049 if self
._fileHistory
:
2050 self
._fileHistory
.Save(config
)
2053 def FileHistoryAddFilesToMenu(self
, menu
=None):
2055 Appends the files in the history list, to all menus managed by the
2056 file history object.
2058 If menu is specified, appends the files in the history list to the
2061 if self
._fileHistory
:
2063 self
._fileHistory
.AddFilesToThisMenu(menu
)
2065 self
._fileHistory
.AddFilesToMenu()
2068 def GetHistoryFilesCount(self
):
2070 Returns the number of files currently stored in the file history.
2072 if self
._fileHistory
:
2073 return self
._fileHistory
.GetNoHistoryFiles()
2078 def FindTemplateForPath(self
, path
):
2080 Given a path, try to find template that matches the extension. This is
2081 only an approximate method of finding a template for creating a
2084 Note this wxPython verson looks for and returns a default template if no specific template is found.
2087 for temp
in self
._templates
:
2088 if temp
.FileMatchesTemplate(path
):
2091 if "*.*" in temp
.GetFileFilter():
2096 def FindSuitableParent(self
):
2098 Returns a parent frame or dialog, either the frame with the current
2099 focus or if there is no current focus the application's top frame.
2101 parent
= wx
.GetApp().GetTopWindow()
2102 focusWindow
= wx
.Window_FindFocus()
2104 while focusWindow
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
):
2105 focusWindow
= focusWindow
.GetParent()
2107 parent
= focusWindow
2111 def SelectDocumentPath(self
, templates
, flags
, save
):
2113 Under Windows, pops up a file selector with a list of filters
2114 corresponding to document templates. The wxDocTemplate corresponding
2115 to the selected file's extension is returned.
2117 On other platforms, if there is more than one document template a
2118 choice list is popped up, followed by a file selector.
2120 This function is used in wxDocManager.CreateDocument.
2122 if wx
.Platform
== "__WXMSW__" or wx
.Platform
== "__WXGTK__" or wx
.Platform
== "__WXMAC__":
2125 for temp
in templates
:
2126 if temp
.IsVisible():
2128 descr
= descr
+ _('|')
2129 allfilter
= allfilter
+ _(';')
2130 descr
= descr
+ temp
.GetDescription() + _(" (") + temp
.GetFileFilter() + _(") |") + temp
.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
2131 allfilter
= allfilter
+ temp
.GetFileFilter()
2132 descr
= _("All (%s)|%s|%s|Any (*.*) | *.*") % (allfilter
, allfilter
, descr
) # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
2136 path
= wx
.FileSelector(_("Select a File"),
2137 self
._lastDirectory
,
2140 flags
= wx
.HIDE_READONLY
,
2141 parent
= self
.FindSuitableParent())
2143 if not FileExists(path
):
2144 msgTitle
= wx
.GetApp().GetAppName()
2146 msgTitle
= _("File Error")
2147 wx
.MessageBox("Could not open '%s'." % FileNameFromPath(path
),
2149 wx
.OK | wx
.ICON_EXCLAMATION
,
2152 self
._lastDirectory
= PathOnly(path
)
2154 theTemplate
= self
.FindTemplateForPath(path
)
2155 return (theTemplate
, path
)
2160 def OnOpenFileFailure(self
):
2162 Called when there is an error opening a file.
2167 def SelectDocumentType(self
, temps
, sort
=False):
2169 Returns a document template by asking the user (if there is more than
2170 one template). This function is used in wxDocManager.CreateDocument.
2174 templates - list of templates from which to choose a desired template.
2176 sort - If more than one template is passed in in templates, then this
2177 parameter indicates whether the list of templates that the user will
2178 have to choose from is sorted or not when shown the choice box dialog.
2183 if temp
.IsVisible():
2185 for temp2
in templates
:
2186 if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName():
2190 templates
.append(temp
)
2192 if len(templates
) == 0:
2194 elif len(templates
) == 1:
2199 return cmp(a
.GetDescription(), b
.GetDescription())
2200 templates
.sort(tempcmp
)
2203 for temp
in templates
:
2204 strings
.append(temp
.GetDescription())
2206 res
= wx
.GetSingleChoiceIndex(_("Select a document type:"),
2209 self
.FindSuitableParent())
2212 return templates
[res
]
2215 def SelectViewType(self
, temps
, sort
=False):
2217 Returns a document template by asking the user (if there is more than one template), displaying a list of valid views. This function is used in wxDocManager::CreateView. The dialog normally will not appear because the array of templates only contains those relevant to the document in question, and often there will only be one such.
2222 if temp
.IsVisible() and temp
.GetViewTypeName():
2223 if temp
.GetViewName() not in strings
:
2224 templates
.append(temp
)
2225 strings
.append(temp
.GetViewTypeName())
2227 if len(templates
) == 0:
2229 elif len(templates
) == 1:
2234 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName())
2235 templates
.sort(tempcmp
)
2237 res
= wx
.GetSingleChoiceIndex(_("Select a document view:"),
2240 self
.FindSuitableParent())
2243 return templates
[res
]
2246 def GetTemplates(self
):
2248 Returns the document manager's template list. This method has been added to
2249 wxPython and is not in wxWindows.
2251 return self
._templates
2254 def AssociateTemplate(self
, docTemplate
):
2256 Adds the template to the document manager's template list.
2258 if docTemplate
not in self
._templates
:
2259 self
._templates
.append(docTemplate
)
2262 def DisassociateTemplate(self
, docTemplate
):
2264 Removes the template from the list of templates.
2266 self
._templates
.remove(docTemplate
)
2269 def AddDocument(self
, document
):
2271 Adds the document to the list of documents.
2273 if document
not in self
._docs
:
2274 self
._docs
.append(document
)
2277 def RemoveDocument(self
, doc
):
2279 Removes the document from the list of documents.
2281 if doc
in self
._docs
:
2282 self
._docs
.remove(doc
)
2285 def ActivateView(self
, view
, activate
=True, deleting
=False):
2287 Sets the current view.
2290 self
._currentView
= view
2291 self
._lastActiveView
= view
2293 self
._currentView
= None
2296 def GetMaxDocsOpen(self
):
2298 Returns the number of documents that can be open simultaneously.
2300 return self
._maxDocsOpen
2303 def SetMaxDocsOpen(self
, maxDocsOpen
):
2305 Sets the maximum number of documents that can be open at a time. By
2306 default, this is 10,000. If you set it to 1, existing documents will
2307 be saved and deleted when the user tries to open or create a new one
2308 (similar to the behaviour of Windows Write, for example). Allowing
2309 multiple documents gives behaviour more akin to MS Word and other
2310 Multiple Document Interface applications.
2312 self
._maxDocsOpen
= maxDocsOpen
2315 def GetDocuments(self
):
2317 Returns the list of documents.
2322 class DocParentFrame(wx
.Frame
):
2324 The wxDocParentFrame class provides a default top-level frame for
2325 applications using the document/view framework. This class can only be
2326 used for SDI (not MDI) parent frames.
2328 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates
2332 def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2334 Constructor. Note that the event table must be rebuilt for the
2335 frame since the EvtHandler is not virtual.
2337 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
)
2338 self
._docManager
= manager
2340 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2342 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2343 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2345 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2346 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2347 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2348 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2349 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2350 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2351 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2352 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2353 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2354 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2355 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2356 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2358 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2359 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2360 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2361 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2362 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2363 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2364 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2365 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2366 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2367 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2368 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2369 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2372 def ProcessEvent(self
, event
):
2374 Processes an event, searching event tables and calling zero or more
2375 suitable event handler function(s). Note that the ProcessEvent
2376 method is called from the wxPython docview framework directly since
2377 wxPython does not have a virtual ProcessEvent function.
2379 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2382 def ProcessUpdateUIEvent(self
, event
):
2384 Processes a UI event, searching event tables and calling zero or more
2385 suitable event handler function(s). Note that the ProcessEvent
2386 method is called from the wxPython docview framework directly since
2387 wxPython does not have a virtual ProcessEvent function.
2389 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2392 def OnExit(self
, event
):
2394 Called when File/Exit is chosen and closes the window.
2399 def OnMRUFile(self
, event
):
2401 Opens the appropriate file when it is selected from the file history
2404 n
= event
.GetId() - wx
.ID_FILE1
2405 filename
= self
._docManager
.GetHistoryFile(n
)
2407 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2409 self
._docManager
.RemoveFileFromHistory(n
)
2410 msgTitle
= wx
.GetApp().GetAppName()
2412 msgTitle
= _("File Error")
2413 wx
.MessageBox("The file '%s' doesn't exist and couldn't be opened.\nIt has been removed from the most recently used files list" % FileNameFromPath(file),
2415 wx
.OK | wx
.ICON_EXCLAMATION
,
2419 def OnCloseWindow(self
, event
):
2421 Deletes all views and documents. If no user input cancelled the
2422 operation, the frame will be destroyed and the application will exit.
2424 if self
._docManager
.Clear(not event
.CanVeto()):
2430 class DocChildFrame(wx
.Frame
):
2432 The wxDocChildFrame class provides a default frame for displaying
2433 documents on separate windows. This class can only be used for SDI (not
2436 The class is part of the document/view framework supported by wxWindows,
2437 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2442 def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2444 Constructor. Note that the event table must be rebuilt for the
2445 frame since the EvtHandler is not virtual.
2447 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2448 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2449 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2450 self
._childDocument
= doc
2451 self
._childView
= view
2455 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2456 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2457 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2458 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2459 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2460 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2461 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2462 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2463 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2464 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2465 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2466 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2468 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2469 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2470 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2471 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2472 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2473 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2474 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2475 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2476 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2477 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2478 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2479 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2482 def ProcessEvent(self
, event
):
2484 Processes an event, searching event tables and calling zero or more
2485 suitable event handler function(s). Note that the ProcessEvent
2486 method is called from the wxPython docview framework directly since
2487 wxPython does not have a virtual ProcessEvent function.
2490 self
._childView
.Activate(True)
2491 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2492 # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows
2493 # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
2494 if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2502 def ProcessUpdateUIEvent(self
, event
):
2504 Processes a UI event, searching event tables and calling zero or more
2505 suitable event handler function(s). Note that the ProcessEvent
2506 method is called from the wxPython docview framework directly since
2507 wxPython does not have a virtual ProcessEvent function.
2509 if self
.GetParent():
2510 self
.GetParent().ProcessUpdateUIEvent(event
)
2515 def OnActivate(self
, event
):
2517 Activates the current view.
2519 # wx.Frame.OnActivate(event) This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead
2521 self
._childView
.Activate(event
.GetActive())
2524 def OnCloseWindow(self
, event
):
2526 Closes and deletes the current view and document.
2530 if not event
.CanVeto():
2533 ans
= self
._childView
.Close(deleteWindow
= False)
2536 self
._childView
.Activate(False)
2537 self
._childView
.Destroy()
2538 self
._childView
= None
2539 if self
._childDocument
:
2540 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2541 self
._childDocument
= None
2549 def GetDocument(self
):
2551 Returns the document associated with this frame.
2553 return self
._childDocument
2556 def SetDocument(self
, document
):
2558 Sets the document for this frame.
2560 self
._childDocument
= document
2565 Returns the view associated with this frame.
2567 return self
._childView
2570 def SetView(self
, view
):
2572 Sets the view for this frame.
2574 self
._childView
= view
2577 class DocMDIParentFrame(wx
.MDIParentFrame
):
2579 The wxDocMDIParentFrame class provides a default top-level frame for
2580 applications using the document/view framework. This class can only be
2581 used for MDI parent frames.
2583 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2588 def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2590 Constructor. Note that the event table must be rebuilt for the
2591 frame since the EvtHandler is not virtual.
2593 wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2594 self
._docManager
= manager
2596 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2598 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2599 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2601 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2602 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2603 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2604 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2605 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2606 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2607 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2608 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2609 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2610 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2611 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2612 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2614 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2615 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2616 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2617 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2618 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2619 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2620 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2621 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2622 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2623 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2624 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2625 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2628 def ProcessEvent(self
, event
):
2630 Processes an event, searching event tables and calling zero or more
2631 suitable event handler function(s). Note that the ProcessEvent
2632 method is called from the wxPython docview framework directly since
2633 wxPython does not have a virtual ProcessEvent function.
2635 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2638 def ProcessUpdateUIEvent(self
, event
):
2640 Processes a UI event, searching event tables and calling zero or more
2641 suitable event handler function(s). Note that the ProcessEvent
2642 method is called from the wxPython docview framework directly since
2643 wxPython does not have a virtual ProcessEvent function.
2645 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2648 def OnExit(self
, event
):
2650 Called when File/Exit is chosen and closes the window.
2655 def OnMRUFile(self
, event
):
2657 Opens the appropriate file when it is selected from the file history
2660 n
= event
.GetId() - wx
.ID_FILE1
2661 filename
= self
._docManager
.GetHistoryFile(n
)
2663 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2665 self
._docManager
.RemoveFileFromHistory(n
)
2666 msgTitle
= wx
.GetApp().GetAppName()
2668 msgTitle
= _("File Error")
2669 wx
.MessageBox("The file '%s' doesn't exist and couldn't be opened.\nIt has been removed from the most recently used files list" % FileNameFromPath(file),
2671 wx
.OK | wx
.ICON_EXCLAMATION
,
2675 def OnCloseWindow(self
, event
):
2677 Deletes all views and documents. If no user input cancelled the
2678 operation, the frame will be destroyed and the application will exit.
2680 if self
._docManager
.Clear(not event
.CanVeto()):
2686 class DocMDIChildFrame(wx
.MDIChildFrame
):
2688 The wxDocMDIChildFrame class provides a default frame for displaying
2689 documents on separate windows. This class can only be used for MDI child
2692 The class is part of the document/view framework supported by wxWindows,
2693 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2698 def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2700 Constructor. Note that the event table must be rebuilt for the
2701 frame since the EvtHandler is not virtual.
2703 wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2704 self
._childDocument
= doc
2705 self
._childView
= view
2708 # self.Create(doc, view, frame, id, title, pos, size, style, name)
2709 self
._activeEvent
= None
2711 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2712 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2714 if frame
: # wxBug: For some reason the EVT_ACTIVATE event is not getting triggered for the first mdi client window that is opened so we have to do it manually
2715 mdiChildren
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren())
2716 if len(mdiChildren
) == 1:
2720 ## # Couldn't get this to work, but seems to work fine with single stage construction
2721 ## def Create(self, doc, view, frame, id, title, pos, size, style, name):
2722 ## self._childDocument = doc
2723 ## self._childView = view
2724 ## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
2726 ## view.SetFrame(self)
2732 def Activate(self
): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
2734 Activates the current view.
2737 self
._childView
.Activate(True)
2740 def ProcessEvent(event
):
2742 Processes an event, searching event tables and calling zero or more
2743 suitable event handler function(s). Note that the ProcessEvent
2744 method is called from the wxPython docview framework directly since
2745 wxPython does not have a virtual ProcessEvent function.
2747 if self
._activeEvent
== event
:
2750 self
._activeEvent
= event
# Break recursion loops
2753 self
._childView
.Activate(True)
2755 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2756 if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2763 self
._activeEvent
= None
2767 def OnActivate(self
, event
):
2769 Sets the currently active view to be the frame's view. You may need to
2770 override (but still call) this function in order to set the keyboard
2771 focus for your subwindow.
2773 if self
._activated
!= 0:
2775 self
._activated
+= 1
2776 wx
.MDIChildFrame
.Activate(self
)
2777 if event
.GetActive() and self
._childView
:
2778 self
._childView
.Activate(event
.GetActive())
2781 def OnCloseWindow(self
, event
):
2783 Closes and deletes the current view and document.
2787 if not event
.CanVeto():
2790 ans
= self
._childView
.Close(deleteWindow
= False)
2793 self
._childView
.Activate(False)
2794 self
._childView
.Destroy()
2795 self
._childView
= None
2796 if self
._childDocument
:
2797 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2798 self
._childDocument
= None
2806 def GetDocument(self
):
2808 Returns the document associated with this frame.
2810 return self
._childDocument
2813 def SetDocument(self
, document
):
2815 Sets the document for this frame.
2817 self
._childDocument
= document
2822 Returns the view associated with this frame.
2824 return self
._childView
2827 def SetView(self
, view
):
2829 Sets the view for this frame.
2831 self
._childView
= view
2834 class DocPrintout(wx
.Printout
):
2836 DocPrintout is a default Printout that prints the first page of a document
2841 def __init__(self
, view
, title
="Printout"):
2845 wx
.Printout
.__init
__(self
, title
)
2846 self
._printoutView
= view
2851 Returns the DocPrintout's view.
2853 return self
._printoutView
2856 def OnPrintPage(self
, page
):
2858 Prints the first page of the view.
2861 ppiScreenX
, ppiScreenY
= self
.GetPPIScreen()
2862 ppiPrinterX
, ppiPrinterY
= self
.GetPPIPrinter()
2863 scale
= ppiPrinterX
/ppiScreenX
2865 pageWidth
, pageHeight
= self
.GetPageSizePixels()
2866 overallScale
= scale
* w
/ pageWidth
2867 dc
.SetUserScale(overallScale
, overallScale
)
2868 if self
._printoutView
:
2869 self
._printoutView
.OnDraw(dc
)
2873 def HasPage(self
, pageNum
):
2875 Indicates that the DocPrintout only has a single page.
2880 def OnBeginDocument(self
, startPage
, endPage
):
2882 Not quite sure why this was overridden, but it was in wxWindows! :)
2884 if not wx
.Printout
.base_OnBeginDocument(self
, startPage
, endPage
):
2889 def GetPageInfo(self
):
2891 Indicates that the DocPrintout only has a single page.
2897 return (minPage
, maxPage
, selPageFrom
, selPageTo
)
2900 #----------------------------------------------------------------------
2902 #----------------------------------------------------------------------
2904 class Command(wx
.Object
):
2906 wxCommand is a base class for modelling an application command, which is
2907 an action usually performed by selecting a menu item, pressing a toolbar
2908 button or any other means provided by the application to change the data
2913 def __init__(self
, canUndo
= False, name
= None):
2915 Constructor. wxCommand is an abstract class, so you will need to
2916 derive a new class and call this constructor from your own constructor.
2918 canUndo tells the command processor whether this command is undo-able.
2919 You can achieve the same functionality by overriding the CanUndo member
2920 function (if for example the criteria for undoability is context-
2923 name must be supplied for the command processor to display the command
2924 name in the application's edit menu.
2926 self
._canUndo
= canUndo
2932 Returns true if the command can be undone, false otherwise.
2934 return self
._canUndo
2939 Returns the command name.
2946 Override this member function to execute the appropriate action when
2947 called. Return true to indicate that the action has taken place, false
2948 otherwise. Returning false will indicate to the command processor that
2949 the action is not undoable and should not be added to the command
2957 Override this member function to un-execute a previous Do. Return true
2958 to indicate that the action has taken place, false otherwise. Returning
2959 false will indicate to the command processor that the action is not
2960 redoable and no change should be made to the command history.
2962 How you implement this command is totally application dependent, but
2963 typical strategies include:
2965 Perform an inverse operation on the last modified piece of data in the
2966 document. When redone, a copy of data stored in command is pasted back
2967 or some operation reapplied. This relies on the fact that you know the
2968 ordering of Undos; the user can never Undo at an arbitrary position in
2971 Restore the entire document state (perhaps using document
2972 transactioning). Potentially very inefficient, but possibly easier to
2973 code if the user interface and data are complex, and an 'inverse
2974 execute' operation is hard to write.
2979 class CommandProcessor(wx
.Object
):
2981 wxCommandProcessor is a class that maintains a history of wxCommands, with
2982 undo/redo functionality built-in. Derive a new class from this if you want
2983 different behaviour.
2987 def __init__(self
, maxCommands
=-1):
2989 Constructor. maxCommands may be set to a positive integer to limit
2990 the number of commands stored to it, otherwise (and by default) the
2991 list of commands can grow arbitrarily.
2993 self
._maxCommands
= maxCommands
2994 self
._editMenu
= None
2995 self
._undoAccelerator
= _("Ctrl+Z")
2996 self
._redoAccelerator
= _("Ctrl+Y")
2997 self
.ClearCommands()
3000 def _GetCurrentCommand(self
):
3001 if len(self
._commands
) == 0:
3004 return self
._commands
[-1]
3007 def _GetCurrentRedoCommand(self
):
3008 if len(self
._redoCommands
) == 0:
3011 return self
._redoCommands
[-1]
3014 def GetMaxCommands(self
):
3016 Returns the maximum number of commands that the command processor
3020 return self
._maxCommands
3023 def GetCommands(self
):
3025 Returns the list of commands.
3027 return self
._commands
3030 def ClearCommands(self
):
3032 Deletes all the commands in the list and sets the current command
3036 self
._redoCommands
= []
3039 def GetEditMenu(self
):
3041 Returns the edit menu associated with the command processor.
3043 return self
._editMenu
3046 def SetEditMenu(self
, menu
):
3048 Tells the command processor to update the Undo and Redo items on this
3049 menu as appropriate. Set this to NULL if the menu is about to be
3050 destroyed and command operations may still be performed, or the
3051 command processor may try to access an invalid pointer.
3053 self
._editMenu
= menu
3056 def GetUndoAccelerator(self
):
3058 Returns the string that will be appended to the Undo menu item.
3060 return self
._undoAccelerator
3063 def SetUndoAccelerator(self
, accel
):
3065 Sets the string that will be appended to the Redo menu item.
3067 self
._undoAccelerator
= accel
3070 def GetRedoAccelerator(self
):
3072 Returns the string that will be appended to the Redo menu item.
3074 return self
._redoAccelerator
3077 def SetRedoAccelerator(self
, accel
):
3079 Sets the string that will be appended to the Redo menu item.
3081 self
._redoAccelerator
= accel
3084 def SetEditMenu(self
, menu
):
3086 Tells the command processor to update the Undo and Redo items on this
3087 menu as appropriate. Set this to NULL if the menu is about to be
3088 destroyed and command operations may still be performed, or the
3089 command processor may try to access an invalid pointer.
3091 self
._editMenu
= menu
3094 def SetMenuStrings(self
):
3096 Sets the menu labels according to the currently set menu and the
3097 current command state.
3099 if self
.GetEditMenu() != None:
3100 undoCommand
= self
._GetCurrentCommand
()
3101 redoCommand
= self
._GetCurrentRedoCommand
()
3102 undoItem
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
)
3103 redoItem
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
)
3104 if self
.GetUndoAccelerator():
3105 undoAccel
= '\t' + self
.GetUndoAccelerator()
3108 if self
.GetRedoAccelerator():
3109 redoAccel
= '\t' + self
.GetRedoAccelerator()
3112 if undoCommand
and undoItem
and undoCommand
.CanUndo():
3113 undoItem
.SetText(_("&Undo ") + undoCommand
.GetName() + undoAccel
)
3114 #elif undoCommand and not undoCommand.CanUndo():
3115 # undoItem.SetText(_("Can't Undo") + undoAccel)
3117 undoItem
.SetText(_("&Undo" + undoAccel
))
3118 if redoCommand
and redoItem
:
3119 redoItem
.SetText(_("&Redo ") + redoCommand
.GetName() + redoAccel
)
3121 redoItem
.SetText(_("&Redo") + redoAccel
)
3126 Returns true if the currently-active command can be undone, false
3129 if self
._GetCurrentCommand
() == None:
3131 return self
._GetCurrentCommand
().CanUndo()
3136 Returns true if the currently-active command can be redone, false
3139 return self
._GetCurrentRedoCommand
() != None
3142 def Submit(self
, command
, storeIt
=True):
3144 Submits a new command to the command processor. The command processor
3145 calls wxCommand::Do to execute the command; if it succeeds, the
3146 command is stored in the history list, and the associated edit menu
3147 (if any) updated appropriately. If it fails, the command is deleted
3148 immediately. Once Submit has been called, the passed command should
3149 not be deleted directly by the application.
3151 storeIt indicates whether the successful command should be stored in
3155 if done
and storeIt
:
3156 self
._commands
.append(command
)
3157 if self
._maxCommands
> -1:
3158 if len(self
._commands
) > self
._maxCommands
:
3159 del self
._commands
[0]
3165 Redoes the command just undone.
3167 cmd
= self
._GetCurrentRedoCommand
()
3172 self
._commands
.append(self
._redoCommands
.pop())
3178 Undoes the command just executed.
3180 cmd
= self
._GetCurrentCommand
()
3185 self
._redoCommands
.append(self
._commands
.pop())