1 #----------------------------------------------------------------------------
3 # Purpose: Port of the wxWindows docview classes
9 # Copyright: (c) 2003-2004 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.
82 def __init__(self
, parent
= None):
84 Constructor. Define your own default constructor to initialize
85 application-specific data.
87 wx
.EvtHandler
.__init
__(self
)
89 self
._documentModified
= False
90 self
._documentParent
= parent
91 self
._documentTemplate
= None
92 self
._commandProcessor
= None
93 self
._savedYet
= False
95 self
._documentTitle
= None
96 self
._documentFile
= None
97 self
._documentTypeName
= None
98 self
._documentModified
= False
99 self
._documentViews
= []
102 def ProcessEvent(self
, event
):
104 Processes an event, searching event tables and calling zero or more
105 suitable event handler function(s). Note that the ProcessEvent
106 method is called from the wxPython docview framework directly since
107 wxPython does not have a virtual ProcessEvent function.
112 def GetFilename(self
):
114 Gets the filename associated with this document, or "" if none is
117 return self
._documentFile
122 Gets the title for this document. The document title is used for an
123 associated frame (if any), and is usually constructed by the framework
126 return self
._documentTitle
129 def SetTitle(self
, title
):
131 Sets the title for this document. The document title is used for an
132 associated frame (if any), and is usually constructed by the framework
135 self
._documentTitle
= title
138 def GetDocumentName(self
):
140 The document type name given to the wxDocTemplate constructor,
141 copied to this document when the document is created. If several
142 document templates are created that use the same document type, this
143 variable is used in wxDocManager::CreateView to collate a list of
144 alternative view types that can be used on this kind of document.
146 return self
._documentTypeName
149 def SetDocumentName(self
, name
):
151 Sets he document type name given to the wxDocTemplate constructor,
152 copied to this document when the document is created. If several
153 document templates are created that use the same document type, this
154 variable is used in wxDocManager::CreateView to collate a list of
155 alternative view types that can be used on this kind of document. Do
156 not change the value of this variable.
158 self
._documentTypeName
= name
161 def GetDocumentSaved(self
):
163 Returns True if the document has been saved. This method has been
164 added to wxPython and is not in wxWindows.
166 return self
._savedYet
169 def SetDocumentSaved(self
, saved
= True):
171 Sets whether the document has been saved. This method has been
172 added to wxPython and is not in wxWindows.
174 self
._savedYet
= saved
177 def GetCommandProcessor(self
):
179 Returns the command processor associated with this document.
181 return self
._commandProcessor
184 def SetCommandProcessor(self
, processor
):
186 Sets the command processor to be used for this document. The document
187 will then be responsible for its deletion. Normally you should not
188 call this; override OnCreateCommandProcessor instead.
190 self
._commandProcessor
= processor
193 def IsModified(self
):
195 Returns true if the document has been modified since the last save,
196 false otherwise. You may need to override this if your document view
197 maintains its own record of being modified (for example if using
198 wxTextWindow to view and edit the document).
200 return self
._documentModified
203 def Modify(self
, modify
):
205 Call with true to mark the document as modified since the last save,
206 false otherwise. You may need to override this if your document view
207 maintains its own record of being modified (for example if using
208 xTextWindow to view and edit the document).
210 self
._documentModified
= modify
215 Returns the list whose elements are the views on the document.
217 return self
._documentViews
220 def GetDocumentTemplate(self
):
222 Returns the template that created the document.
224 return self
._documentTemplate
227 def SetDocumentTemplate(self
, template
):
229 Sets the template that created the document. Should only be called by
232 self
._documentTemplate
= template
235 def DeleteContents(self
):
237 Deletes the contents of the document. Override this method as
245 Destructor. Removes itself from the document manager.
247 self
.DeleteContents()
248 if self
.GetDocumentManager():
249 self
.GetDocumentManager().RemoveDocument(self
)
250 wx
.EvtHandler
.Destroy(self
)
255 Closes the document, by calling OnSaveModified and then (if this true)
256 OnCloseDocument. This does not normally delete the document object:
257 use DeleteAllViews to do this implicitly.
259 if self
.OnSaveModified():
260 if self
.OnCloseDocument():
268 def OnCloseDocument(self
):
270 The default implementation calls DeleteContents (an empty
271 implementation) sets the modified flag to false. Override this to
272 supply additional behaviour when the document is closed with Close.
275 self
.DeleteContents()
280 def DeleteAllViews(self
):
282 Calls wxView.Close and deletes each view. Deleting the final view will
283 implicitly delete the document itself, because the wxView destructor
284 calls RemoveView. This in turns calls wxDocument::OnChangedViewList,
285 whose default implemention is to save and delete the document if no
288 manager
= self
.GetDocumentManager()
289 for view
in self
._documentViews
:
292 if self
in manager
.GetDocuments():
297 def GetFirstView(self
):
299 A convenience function to get the first view for a document, because
300 in many cases a document will only have a single view.
302 if len(self
._documentViews
) == 0:
304 return self
._documentViews
[0]
307 def GetDocumentManager(self
):
309 Returns the associated document manager.
311 if self
._documentTemplate
:
312 return self
._documentTemplate
.GetDocumentManager()
316 def OnNewDocument(self
):
318 The default implementation calls OnSaveModified and DeleteContents,
319 makes a default title for the document, and notifies the views that
320 the filename (in fact, the title) has changed.
322 if not self
.OnSaveModified() or not self
.OnCloseDocument():
324 self
.DeleteContents()
326 self
.SetDocumentSaved(False)
327 name
= self
.GetDocumentManager().MakeDefaultName()
329 self
.SetFilename(name
, notifyViews
= True)
334 Saves the document by calling OnSaveDocument if there is an associated
335 filename, or SaveAs if there is no filename.
337 if not self
.IsModified() and self
._savedYet
:
340 if not self
._documentFile
or not self
._savedYet
:
342 return self
.OnSaveDocument(self
._documentFile
)
347 Prompts the user for a file to save to, and then calls OnSaveDocument.
349 docTemplate
= self
.GetDocumentTemplate()
353 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
354 filename
= wx
.FileSelector(_("Save As"),
355 docTemplate
.GetDirectory(),
356 FileNameFromPath(self
.GetFilename()),
357 docTemplate
.GetDefaultExtension(),
359 flags
= wx
.SAVE | wx
.OVERWRITE_PROMPT
,
360 parent
= self
.GetDocumentWindow())
364 name
, ext
= os
.path
.splitext(filename
)
366 filename
+= '.' + docTemplate
.GetDefaultExtension()
368 self
.SetFilename(filename
)
369 self
.SetTitle(FileNameFromPath(filename
))
371 for view
in self
._documentViews
:
372 view
.OnChangeFilename()
374 if not self
.OnSaveDocument(filename
):
377 if docTemplate
.FileMatchesTemplate(filename
):
378 self
.GetDocumentManager().AddFileToHistory(filename
)
383 def OnSaveDocument(self
, filename
):
385 Constructs an output file for the given filename (which must
386 not be empty), and calls SaveObject. If SaveObject returns true, the
387 document is set to unmodified; otherwise, an error message box is
393 msgTitle
= wx
.GetApp().GetAppName()
395 msgTitle
= _("File Error")
397 backupFilename
= None
399 # if current file exists, move it to a safe place temporarily
400 if os
.path
.exists(filename
):
402 # Check if read-only.
403 if not os
.access(filename
, os
.W_OK
):
404 wx
.MessageBox("Could not save '%s'. No write permission to overwrite existing file." % FileNameFromPath(filename
),
406 wx
.OK | wx
.ICON_EXCLAMATION
,
407 self
.GetDocumentWindow())
411 backupFilename
= "%s.bak%s" % (filename
, i
)
412 while os
.path
.exists(backupFilename
):
414 backupFilename
= "%s.bak%s" % (filename
, i
)
415 os
.rename(filename
, backupFilename
)
417 fileObject
= file(filename
, 'w')
418 self
.SaveObject(fileObject
)
421 os
.remove(backupFilename
)
423 # save failed, restore old file
426 os
.rename(backupFilename
, filename
)
428 wx
.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
430 wx
.OK | wx
.ICON_EXCLAMATION
,
431 self
.GetDocumentWindow())
434 self
.SetFilename(filename
, True)
436 self
.SetDocumentSaved(True)
437 #if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
438 # wx.FileName(file).MacSetDefaultTypeAndCreator()
442 def OnOpenDocument(self
, filename
):
444 Constructs an input file for the given filename (which must not
445 be empty), and calls LoadObject. If LoadObject returns true, the
446 document is set to unmodified; otherwise, an error message box is
447 displayed. The document's views are notified that the filename has
448 changed, to give windows an opportunity to update their titles. All of
449 the document's views are then updated.
451 if not self
.OnSaveModified():
454 msgTitle
= wx
.GetApp().GetAppName()
456 msgTitle
= _("File Error")
458 fileObject
= file(filename
, 'r')
460 self
.LoadObject(fileObject
)
462 wx
.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
464 wx
.OK | wx
.ICON_EXCLAMATION
,
465 self
.GetDocumentWindow())
468 self
.SetFilename(filename
, True)
470 self
.SetDocumentSaved(True)
471 self
.UpdateAllViews()
475 def LoadObject(self
, file):
477 Override this function and call it from your own LoadObject before
478 loading your own data. LoadObject is called by the framework
479 automatically when the document contents need to be loaded.
481 Note that the wxPython version simply sends you a Python file object,
482 so you can use pickle.
487 def SaveObject(self
, file):
489 Override this function and call it from your own SaveObject before
490 saving your own data. SaveObject is called by the framework
491 automatically when the document contents need to be saved.
493 Note that the wxPython version simply sends you a Python file object,
494 so you can use pickle.
501 Override this function to revert the document to its last saved state.
506 def GetPrintableName(self
):
508 Copies a suitable document name into the supplied name buffer.
509 The default function uses the title, or if there is no title, uses the
510 filename; or if no filename, the string 'Untitled'.
512 if self
._documentTitle
:
513 return self
._documentTitle
514 elif self
._documentFile
:
515 return FileNameFromPath(self
._documentFile
)
520 def GetDocumentWindow(self
):
522 Intended to return a suitable window for using as a parent for
523 document-related dialog boxes. By default, uses the frame associated
526 if len(self
._documentViews
) > 0:
527 return self
._documentViews
[0].GetFrame()
529 return wx
.GetApp().GetTopWindow()
532 def OnCreateCommandProcessor(self
):
534 Override this function if you want a different (or no) command
535 processor to be created when the document is created. By default, it
536 returns an instance of wxCommandProcessor.
538 return CommandProcessor()
541 def OnSaveModified(self
):
543 If the document has been modified, prompts the user to ask if the
544 changes should be changed. If the user replies Yes, the Save function
545 is called. If No, the document is marked as unmodified and the
546 function succeeds. If Cancel, the function fails.
548 if not self
.IsModified():
551 msgTitle
= wx
.GetApp().GetAppName()
553 msgTitle
= _("Warning")
555 res
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(),
557 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
558 self
.GetDocumentWindow())
565 else: # elif res == wx.CANCEL:
571 Called by printing framework to draw the view.
576 def AddView(self
, view
):
578 If the view is not already in the list of views, adds the view and
579 calls OnChangedViewList.
581 if not view
in self
._documentViews
:
582 self
._documentViews
.append(view
)
583 self
.OnChangedViewList()
587 def RemoveView(self
, view
):
589 Removes the view from the document's list of views, and calls
592 if view
in self
._documentViews
:
593 self
._documentViews
.remove(view
)
594 self
.OnChangedViewList()
598 def OnCreate(self
, path
, flags
):
600 The default implementation calls DeleteContents (an empty
601 implementation) sets the modified flag to false. Override this to
602 supply additional behaviour when the document is closed with Close.
604 return self
.GetDocumentTemplate().CreateView(self
, flags
)
607 def OnChangedViewList(self
):
609 Called when a view is added to or deleted from this document. The
610 default implementation saves and deletes the document if no views
611 exist (the last one has just been removed).
613 if len(self
._documentViews
) == 0:
614 if self
.OnSaveModified():
615 pass # C version does a delete but Python will garbage collect
618 def UpdateAllViews(self
, sender
= None, hint
= None):
620 Updates all views. If sender is non-NULL, does not update this view.
621 hint represents optional information to allow a view to optimize its
624 for view
in self
._documentViews
:
626 view
.OnUpdate(sender
, hint
)
629 def NotifyClosing(self
):
631 Notifies the views that the document is going to close.
633 for view
in self
._documentViews
:
634 view
.OnClosingDocument()
637 def SetFilename(self
, filename
, notifyViews
= False):
639 Sets the filename for this document. Usually called by the framework.
640 If notifyViews is true, wxView.OnChangeFilename is called for all
643 self
._documentFile
= filename
645 for view
in self
._documentViews
:
646 view
.OnChangeFilename()
649 class View(wx
.EvtHandler
):
651 The view class can be used to model the viewing and editing component of
652 an application's file-based data. It is part of the document/view
653 framework supported by wxWindows, and cooperates with the wxDocument,
654 wxDocTemplate and wxDocManager classes.
659 Constructor. Define your own default constructor to initialize
660 application-specific data.
662 wx
.EvtHandler
.__init
__(self
)
663 self
._viewDocument
= None
664 self
._viewFrame
= None
669 Destructor. Removes itself from the document's list of views.
671 if self
._viewDocument
:
672 self
._viewDocument
.RemoveView(self
)
673 wx
.EvtHandler
.Destroy(self
)
676 def ProcessEvent(self
, event
):
678 Processes an event, searching event tables and calling zero or more
679 suitable event handler function(s). Note that the ProcessEvent
680 method is called from the wxPython docview framework directly since
681 wxPython does not have a virtual ProcessEvent function.
683 if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
):
689 def ProcessUpdateUIEvent(self
, event
):
691 Processes a UI event, searching event tables and calling zero or more
692 suitable event handler function(s). Note that the ProcessEvent
693 method is called from the wxPython docview framework directly since
694 wxPython does not have a virtual ProcessEvent function.
699 def OnActivateView(self
, activate
, activeView
, deactiveView
):
701 Called when a view is activated by means of wxView::Activate. The
702 default implementation does nothing.
707 def OnClosingDocument(self
):
709 Override this to clean up the view when the document is being closed.
710 The default implementation does nothing.
715 def OnDraw(self
, dc
):
717 Override this to draw the view for the printing framework. The
718 default implementation does nothing.
723 def OnPrint(self
, dc
, info
):
725 Override this to print the view for the printing framework. The
726 default implementation calls View.OnDraw.
731 def OnUpdate(self
, sender
, hint
):
733 Called when the view should be updated. sender is a pointer to the
734 view that sent the update request, or NULL if no single view requested
735 the update (for instance, when the document is opened). hint is as yet
736 unused but may in future contain application-specific information for
737 making updating more efficient.
742 def OnChangeFilename(self
):
744 Called when the filename has changed. The default implementation
745 constructs a suitable title and sets the title of the view frame (if
749 appName
= wx
.GetApp().GetAppName()
750 if not self
.GetDocument():
756 if appName
and not isinstance(self
.GetFrame(), DocMDIChildFrame
): # Don't need appname in title for MDI
757 title
= appName
+ _(" - ")
760 self
.GetFrame().SetTitle(title
+ self
.GetDocument().GetPrintableName())
763 def GetDocument(self
):
765 Returns the document associated with the view.
767 return self
._viewDocument
770 def SetDocument(self
, doc
):
772 Associates the given document with the view. Normally called by the
775 self
._viewDocument
= doc
780 def GetViewName(self
):
782 Gets the name associated with the view (passed to the wxDocTemplate
783 constructor). Not currently used by the framework.
785 return self
._viewTypeName
788 def SetViewName(self
, name
):
790 Sets the view type name. Should only be called by the framework.
792 self
._viewTypeName
= name
795 def Close(self
, deleteWindow
= True):
797 Closes the view by calling OnClose. If deleteWindow is true, this
798 function should delete the window associated with the view.
800 if self
.OnClose(deleteWindow
= deleteWindow
):
806 def Activate(self
, activate
= True):
808 Call this from your view frame's OnActivate member to tell the
809 framework which view is currently active. If your windowing system
810 doesn't call OnActivate, you may need to call this function from
811 OnMenuCommand or any place where you know the view must be active, and
812 the framework will need to get the current view.
814 The prepackaged view frame wxDocChildFrame calls wxView.Activate from
815 its OnActivate member and from its OnMenuCommand member.
817 if self
.GetDocument() and self
.GetDocumentManager():
818 self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView())
819 self
.GetDocumentManager().ActivateView(self
, activate
)
822 def OnClose(self
, deleteWindow
= True):
824 Implements closing behaviour. The default implementation calls
825 wxDocument.Close to close the associated document. Does not delete the
826 view. The application may wish to do some cleaning up operations in
827 this function, if a call to wxDocument::Close succeeded. For example,
828 if your application's all share the same window, you need to
829 disassociate the window from the view and perhaps clear the window. If
830 deleteWindow is true, delete the frame associated with the view.
832 if self
.GetDocument():
833 return self
.GetDocument().Close()
838 def OnCreate(self
, doc
, flags
):
840 wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just
841 after the wxDocTemplate creates the wxView, it calls wxView::OnCreate.
842 In its OnCreate member function, the wxView can create a
843 wxDocChildFrame or a derived class. This wxDocChildFrame provides user
844 interface elements to view and/or edit the contents of the wxDocument.
846 By default, simply returns true. If the function returns false, the
847 view will be deleted.
852 def OnCreatePrintout(self
):
854 Returns a wxPrintout object for the purposes of printing. It should
855 create a new object every time it is called; the framework will delete
858 By default, this function returns an instance of wxDocPrintout, which
859 prints and previews one page by calling wxView.OnDraw.
861 Override to return an instance of a class other than wxDocPrintout.
863 return DocPrintout(self
)
868 Gets the frame associated with the view (if any). Note that this
869 "frame" is not a wxFrame at all in the generic MDI implementation
870 which uses the notebook pages instead of the frames and this is why
871 this method returns a wxWindow and not a wxFrame.
873 return self
._viewFrame
876 def SetFrame(self
, frame
):
878 Sets the frame associated with this view. The application should call
879 this if possible, to tell the view about the frame. See GetFrame for
880 the explanation about the mismatch between the "Frame" in the method
881 name and the type of its parameter.
883 self
._viewFrame
= frame
886 def GetDocumentManager(self
):
888 Returns the document manager instance associated with this view.
890 if self
._viewDocument
:
891 return self
.GetDocument().GetDocumentManager()
896 class DocTemplate(wx
.Object
):
898 The wxDocTemplate class is used to model the relationship between a
899 document class and a view class.
903 def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
= DEFAULT_TEMPLATE_FLAGS
, icon
= None):
905 Constructor. Create instances dynamically near the start of your
906 application after creating a wxDocManager instance, and before doing
907 any document or view operations.
909 manager is the document manager object which manages this template.
911 description is a short description of what the template is for. This
912 string will be displayed in the file filter list of Windows file
915 filter is an appropriate file filter such as *.txt.
917 dir is the default directory to use for file selectors.
919 ext is the default file extension (such as txt).
921 docTypeName is a name that should be unique for a given type of
922 document, used for gathering a list of views relevant to a
925 viewTypeName is a name that should be unique for a given view.
927 docClass is a Python class. If this is not supplied, you will need to
928 derive a new wxDocTemplate class and override the CreateDocument
929 member to return a new document instance on demand.
931 viewClass is a Python class. If this is not supplied, you will need to
932 derive a new wxDocTemplate class and override the CreateView member to
933 return a new view instance on demand.
935 flags is a bit list of the following:
936 wx.TEMPLATE_VISIBLE The template may be displayed to the user in
939 wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in
942 wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE.
944 self
._docManager
= manager
945 self
._description
= description
946 self
._fileFilter
= filter
947 self
._directory
= dir
948 self
._defaultExt
= ext
949 self
._docTypeName
= docTypeName
950 self
._viewTypeName
= viewTypeName
951 self
._docType
= docType
952 self
._viewType
= viewType
956 self
._docManager
.AssociateTemplate(self
)
959 def GetDefaultExtension(self
):
961 Returns the default file extension for the document data, as passed to
962 the document template constructor.
964 return self
._defaultExt
967 def SetDefaultExtension(self
, defaultExt
):
969 Sets the default file extension.
971 self
._defaultExt
= defaultExt
974 def GetDescription(self
):
976 Returns the text description of this template, as passed to the
977 document template constructor.
979 return self
._description
982 def SetDescription(self
, description
):
984 Sets the template description.
986 self
._description
= description
989 def GetDirectory(self
):
991 Returns the default directory, as passed to the document template
994 return self
._directory
997 def SetDirectory(self
, dir):
999 Sets the default directory.
1001 self
._directory
= dir
1004 def GetDocumentManager(self
):
1006 Returns the document manager instance for which this template was
1009 return self
._docManager
1012 def SetDocumentManager(self
, manager
):
1014 Sets the document manager instance for which this template was
1015 created. Should not be called by the application.
1017 self
._docManager
= manager
1020 def GetFileFilter(self
):
1022 Returns the file filter, as passed to the document template
1025 return self
._fileFilter
1028 def SetFileFilter(self
, filter):
1030 Sets the file filter.
1032 self
._fileFilter
= filter
1037 Returns the flags, as passed to the document template constructor.
1038 (see the constructor description for more details).
1043 def SetFlags(self
, flags
):
1045 Sets the internal document template flags (see the constructor
1046 description for more details).
1053 Returns the icon, as passed to the document template
1054 constructor. This method has been added to wxPython and is
1060 def SetIcon(self
, flags
):
1062 Sets the icon. This method has been added to wxPython and is not
1068 def GetDocumentType(self
):
1070 Returns the Python document class, as passed to the document template
1073 return self
._docType
1076 def GetViewType(self
):
1078 Returns the Python view class, as passed to the document template
1081 return self
._viewType
1084 def IsVisible(self
):
1086 Returns true if the document template can be shown in user dialogs,
1089 return (self
._flags
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
1092 def GetDocumentName(self
):
1094 Returns the document type name, as passed to the document template
1097 return self
._docTypeName
1100 def GetViewName(self
):
1102 Returns the view type name, as passed to the document template
1105 return self
._viewTypeName
1108 def CreateDocument(self
, path
, flags
):
1110 Creates a new instance of the associated document class. If you have
1111 not supplied a class to the template constructor, you will need to
1112 override this function to return an appropriate document instance.
1114 doc
= self
._docType
()
1115 doc
.SetFilename(path
)
1116 doc
.SetDocumentTemplate(self
)
1117 self
.GetDocumentManager().AddDocument(doc
)
1118 doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor())
1119 if doc
.OnCreate(path
, flags
):
1122 if doc
in self
.GetDocumentManager().GetDocuments():
1123 doc
.DeleteAllViews()
1127 def CreateView(self
, doc
, flags
):
1129 Creates a new instance of the associated document view. If you have
1130 not supplied a class to the template constructor, you will need to
1131 override this function to return an appropriate view instance.
1133 view
= self
._viewType
()
1134 view
.SetDocument(doc
)
1135 if view
.OnCreate(doc
, flags
):
1142 def FileMatchesTemplate(self
, path
):
1144 Returns True if the path's extension matches one of this template's
1145 file filter extensions.
1147 ext
= FindExtension(path
)
1148 if not ext
: return False
1149 return ext
in self
.GetFileFilter()
1150 # return self.GetDefaultExtension() == FindExtension(path)
1153 class DocManager(wx
.EvtHandler
):
1155 The wxDocManager class is part of the document/view framework supported by
1156 wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate
1160 def __init__(self
, flags
= DEFAULT_DOCMAN_FLAGS
, initialize
= True):
1162 Constructor. Create a document manager instance dynamically near the
1163 start of your application before doing any document or view operations.
1165 flags is used in the Python version to indicate whether the document
1166 manager is in DOC_SDI or DOC_MDI mode.
1168 If initialize is true, the Initialize function will be called to
1169 create a default history list object. If you derive from wxDocManager,
1170 you may wish to call the base constructor with false, and then call
1171 Initialize in your own constructor, to allow your own Initialize or
1172 OnCreateFileHistory functions to be called.
1175 wx
.EvtHandler
.__init
__(self
)
1177 self
._defaultDocumentNameCounter
= 1
1179 self
._currentView
= None
1180 self
._lastActiveView
= None
1181 self
._maxDocsOpen
= 10000
1182 self
._fileHistory
= None
1183 self
._templates
= []
1185 self
._lastDirectory
= ""
1190 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
)
1191 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
)
1192 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
)
1193 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
)
1194 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
)
1195 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
)
1196 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
)
1197 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
1198 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
1199 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
)
1200 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
)
1201 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
)
1203 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
)
1204 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
)
1205 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
)
1206 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
)
1207 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
)
1208 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
)
1209 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
)
1210 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
)
1211 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
)
1212 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
)
1213 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
)
1214 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
)
1222 wx
.EvtHandler
.Destroy(self
)
1227 Returns the document manager's flags. This method has been
1228 added to wxPython and is not in wxWindows.
1233 def CloseDocument(self
, doc
, force
= True):
1235 Closes the specified document.
1237 if doc
.Close() or force
:
1238 doc
.DeleteAllViews()
1239 if doc
in self
._docs
:
1245 def CloseDocuments(self
, force
= True):
1247 Closes all currently opened documents.
1249 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
1250 if not self
.CloseDocument(document
, force
):
1252 document
.DeleteAllViews() # Implicitly delete the document when the last view is removed
1256 def Clear(self
, force
= True):
1258 Closes all currently opened document by callling CloseDocuments and
1259 clears the document manager's templates.
1261 if not self
.CloseDocuments(force
):
1263 self
._templates
= []
1267 def Initialize(self
):
1269 Initializes data; currently just calls OnCreateFileHistory. Some data
1270 cannot always be initialized in the constructor because the programmer
1271 must be given the opportunity to override functionality. In fact
1272 Initialize is called from the wxDocManager constructor, but this can
1273 be vetoed by passing false to the second argument, allowing the
1274 derived class's constructor to call Initialize, possibly calling a
1275 different OnCreateFileHistory from the default.
1277 The bottom line: if you're not deriving from Initialize, forget it and
1278 construct wxDocManager with no arguments.
1280 self
.OnCreateFileHistory()
1284 def OnCreateFileHistory(self
):
1286 A hook to allow a derived class to create a different type of file
1287 history. Called from Initialize.
1289 self
._fileHistory
= wx
.FileHistory()
1292 def OnFileClose(self
, event
):
1294 Closes and deletes the currently active document.
1296 doc
= self
.GetCurrentDocument()
1298 doc
.DeleteAllViews()
1299 if doc
in self
._docs
:
1300 self
._docs
.remove(doc
)
1303 def OnFileCloseAll(self
, event
):
1305 Closes and deletes all the currently opened documents.
1307 return self
.CloseDocuments(force
= False)
1310 def OnFileNew(self
, event
):
1312 Creates a new document and reads in the selected file.
1314 self
.CreateDocument('', DOC_NEW
)
1317 def OnFileOpen(self
, event
):
1319 Creates a new document and reads in the selected file.
1321 if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
):
1322 self
.OnOpenFileFailure()
1325 def OnFileRevert(self
, event
):
1327 Reverts the current document by calling wxDocument.Save for the current
1330 doc
= self
.GetCurrentDocument()
1336 def OnFileSave(self
, event
):
1338 Saves the current document by calling wxDocument.Save for the current
1341 doc
= self
.GetCurrentDocument()
1347 def OnFileSaveAs(self
, event
):
1349 Calls wxDocument.SaveAs for the current document.
1351 doc
= self
.GetCurrentDocument()
1357 def OnPrint(self
, event
):
1359 Prints the current document by calling its View's OnCreatePrintout
1362 view
= self
.GetCurrentView()
1366 printout
= view
.OnCreatePrintout()
1368 pdd
= wx
.PrintDialogData()
1369 printer
= wx
.Printer(pdd
)
1370 printer
.Print(view
.GetFrame(), printout
) # , True)
1373 def OnPrintSetup(self
, event
):
1375 Presents the print setup dialog.
1377 view
= self
.GetCurrentView()
1379 parentWin
= view
.GetFrame()
1381 parentWin
= wx
.GetApp().GetTopWindow()
1383 data
= wx
.PrintDialogData()
1384 printDialog
= wx
.PrintDialog(parentWin
, data
)
1385 printDialog
.GetPrintDialogData().SetSetupDialog(True)
1386 printDialog
.ShowModal()
1387 # TODO: Confirm that we don't have to remember PrintDialogData
1390 def OnPreview(self
, event
):
1392 Previews the current document by calling its View's OnCreatePrintout
1395 view
= self
.GetCurrentView()
1399 printout
= view
.OnCreatePrintout()
1401 # Pass two printout objects: for preview, and possible printing.
1402 preview
= wx
.PrintPreview(printout
, view
.OnCreatePrintout())
1403 # 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.
1404 mimicFrame
= wx
.GetApp().GetTopWindow()
1405 frame
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize())
1406 frame
.SetIcon(mimicFrame
.GetIcon())
1407 frame
.SetTitle(mimicFrame
.GetTitle() + _(" - Preview"))
1412 def OnUndo(self
, event
):
1414 Issues an Undo command to the current document's command processor.
1416 doc
= self
.GetCurrentDocument()
1419 if doc
.GetCommandProcessor():
1420 doc
.GetCommandProcessor().Undo()
1423 def OnRedo(self
, event
):
1425 Issues a Redo command to the current document's command processor.
1427 doc
= self
.GetCurrentDocument()
1430 if doc
.GetCommandProcessor():
1431 doc
.GetCommandProcessor().Redo()
1434 def OnUpdateFileOpen(self
, event
):
1436 Updates the user interface for the File Open command.
1441 def OnUpdateFileClose(self
, event
):
1443 Updates the user interface for the File Close command.
1445 event
.Enable(self
.GetCurrentDocument() != None)
1448 def OnUpdateFileCloseAll(self
, event
):
1450 Updates the user interface for the File Close All command.
1452 event
.Enable(self
.GetCurrentDocument() != None)
1455 def OnUpdateFileRevert(self
, event
):
1457 Updates the user interface for the File Revert command.
1459 event
.Enable(self
.GetCurrentDocument() != None)
1462 def OnUpdateFileNew(self
, event
):
1464 Updates the user interface for the File New command.
1469 def OnUpdateFileSave(self
, event
):
1471 Updates the user interface for the File Save command.
1473 doc
= self
.GetCurrentDocument()
1474 event
.Enable(doc
!= None and doc
.IsModified())
1477 def OnUpdateFileSaveAs(self
, event
):
1479 Updates the user interface for the File Save As command.
1481 event
.Enable(self
.GetCurrentDocument() != None)
1484 def OnUpdateUndo(self
, event
):
1486 Updates the user interface for the Undo command.
1488 doc
= self
.GetCurrentDocument()
1489 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo())
1490 if doc
and doc
.GetCommandProcessor():
1491 doc
.GetCommandProcessor().SetMenuStrings()
1493 event
.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
1496 def OnUpdateRedo(self
, event
):
1498 Updates the user interface for the Redo command.
1500 doc
= self
.GetCurrentDocument()
1501 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo())
1502 if doc
and doc
.GetCommandProcessor():
1503 doc
.GetCommandProcessor().SetMenuStrings()
1505 event
.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
1508 def OnUpdatePrint(self
, event
):
1510 Updates the user interface for the Print command.
1512 event
.Enable(self
.GetCurrentDocument() != None)
1515 def OnUpdatePrintSetup(self
, event
):
1517 Updates the user interface for the Print Setup command.
1522 def OnUpdatePreview(self
, event
):
1524 Updates the user interface for the Print Preview command.
1526 event
.Enable(self
.GetCurrentDocument() != None)
1529 def GetCurrentView(self
):
1531 Returns the currently active view.
1533 if self
._currentView
:
1534 return self
._currentView
1535 if len(self
._docs
) == 1:
1536 return self
._docs
[0].GetFirstView()
1540 def GetLastActiveView(self
):
1542 Returns the last active view. This is used in the SDI framework where dialogs can be mistaken for a view
1543 and causes the framework to deactivete the current view. This happens when something like a custom dialog box used
1544 to operate on the current view is shown.
1546 if len(self
._docs
) >= 1:
1547 return self
._lastActiveView
1552 def ProcessEvent(self
, event
):
1554 Processes an event, searching event tables and calling zero or more
1555 suitable event handler function(s). Note that the ProcessEvent
1556 method is called from the wxPython docview framework directly since
1557 wxPython does not have a virtual ProcessEvent function.
1559 view
= self
.GetCurrentView()
1561 if view
.ProcessEvent(event
):
1564 if id == wx
.ID_OPEN
:
1565 self
.OnFileOpen(event
)
1567 elif id == wx
.ID_CLOSE
:
1568 self
.OnFileClose(event
)
1570 elif id == wx
.ID_CLOSE_ALL
:
1571 self
.OnFileCloseAll(event
)
1573 elif id == wx
.ID_REVERT
:
1574 self
.OnFileRevert(event
)
1576 elif id == wx
.ID_NEW
:
1577 self
.OnFileNew(event
)
1579 elif id == wx
.ID_SAVE
:
1580 self
.OnFileSave(event
)
1582 elif id == wx
.ID_SAVEAS
:
1583 self
.OnFileSaveAs(event
)
1585 elif id == wx
.ID_UNDO
:
1588 elif id == wx
.ID_REDO
:
1591 elif id == wx
.ID_PRINT
:
1594 elif id == wx
.ID_PRINT_SETUP
:
1595 self
.OnPrintSetup(event
)
1597 elif id == wx
.ID_PREVIEW
:
1598 self
.OnPreview(event
)
1604 def ProcessUpdateUIEvent(self
, event
):
1606 Processes a UI event, searching event tables and calling zero or more
1607 suitable event handler function(s). Note that the ProcessEvent
1608 method is called from the wxPython docview framework directly since
1609 wxPython does not have a virtual ProcessEvent function.
1612 view
= self
.GetCurrentView()
1614 if view
.ProcessUpdateUIEvent(event
):
1616 if id == wx
.ID_OPEN
:
1617 self
.OnUpdateFileOpen(event
)
1619 elif id == wx
.ID_CLOSE
:
1620 self
.OnUpdateFileClose(event
)
1622 elif id == wx
.ID_CLOSE_ALL
:
1623 self
.OnUpdateFileCloseAll(event
)
1625 elif id == wx
.ID_REVERT
:
1626 self
.OnUpdateFileRevert(event
)
1628 elif id == wx
.ID_NEW
:
1629 self
.OnUpdateFileNew(event
)
1631 elif id == wx
.ID_SAVE
:
1632 self
.OnUpdateFileSave(event
)
1634 elif id == wx
.ID_SAVEAS
:
1635 self
.OnUpdateFileSaveAs(event
)
1637 elif id == wx
.ID_UNDO
:
1638 self
.OnUpdateUndo(event
)
1640 elif id == wx
.ID_REDO
:
1641 self
.OnUpdateRedo(event
)
1643 elif id == wx
.ID_PRINT
:
1644 self
.OnUpdatePrint(event
)
1646 elif id == wx
.ID_PRINT_SETUP
:
1647 self
.OnUpdatePrintSetup(event
)
1649 elif id == wx
.ID_PREVIEW
:
1650 self
.OnUpdatePreview(event
)
1656 def CreateDocument(self
, path
, flags
= 0):
1658 Creates a new document in a manner determined by the flags parameter,
1661 wx.lib.docview.DOC_NEW Creates a fresh document.
1662 wx.lib.docview.DOC_SILENT Silently loads the given document file.
1664 If wx.lib.docview.DOC_NEW is present, a new document will be created and returned,
1665 possibly after asking the user for a template to use if there is more
1666 than one document template. If wx.lib.docview.DOC_SILENT is present, a new document
1667 will be created and the given file loaded into it. If neither of these
1668 flags is present, the user will be presented with a file selector for
1669 the file to load, and the template to use will be determined by the
1670 extension (Windows) or by popping up a template choice list (other
1673 If the maximum number of documents has been reached, this function
1674 will delete the oldest currently loaded document before creating a new
1677 wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE flag.
1680 for temp
in self
._templates
:
1681 if temp
.IsVisible():
1682 templates
.append(temp
)
1683 if len(templates
) == 0:
1686 if len(self
.GetDocuments()) >= self
._maxDocsOpen
:
1687 doc
= self
.GetDocuments()[0]
1688 if not self
.CloseDocument(doc
, False):
1692 if len(templates
) == 1:
1694 newDoc
= temp
.CreateDocument(path
, flags
)
1696 newDoc
.SetDocumentName(temp
.GetDocumentName())
1697 newDoc
.SetDocumentTemplate(temp
)
1698 newDoc
.OnNewDocument()
1701 temp
= self
.SelectDocumentType(templates
)
1703 newDoc
= temp
.CreateDocument(path
, flags
)
1705 newDoc
.SetDocumentName(temp
.GetDocumentName())
1706 newDoc
.SetDocumentTemplate(temp
)
1707 newDoc
.OnNewDocument()
1712 if path
and flags
& DOC_SILENT
:
1713 temp
= self
.FindTemplateForPath(path
)
1715 temp
, path
= self
.SelectDocumentPath(templates
, path
, flags
)
1718 if self
.GetFlags() & DOC_OPEN_ONCE
:
1719 for document
in self
._docs
:
1720 if document
.GetFilename() == path
:
1721 firstView
= document
.GetFirstView()
1722 if firstView
and firstView
.GetFrame():
1723 firstView
.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
1724 if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
1725 firstView
.GetFrame().Iconize(False)
1729 newDoc
= temp
.CreateDocument(path
, flags
)
1731 newDoc
.SetDocumentName(temp
.GetDocumentName())
1732 newDoc
.SetDocumentTemplate(temp
)
1733 if not newDoc
.OnOpenDocument(path
):
1734 newDoc
.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1735 newDoc
.GetFirstView().GetFrame().Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
1737 self
.AddFileToHistory(path
)
1743 def CreateView(self
, document
, flags
= 0):
1745 Creates a new view for the given document. If more than one view is
1746 allowed for the document (by virtue of multiple templates mentioning
1747 the same document type), a choice of view is presented to the user.
1750 for temp
in self
._templates
:
1751 if temp
.IsVisible():
1752 if temp
.GetDocumentName() == doc
.GetDocumentName():
1753 templates
.append(temp
)
1754 if len(templates
) == 0:
1757 if len(templates
) == 1:
1759 view
= temp
.CreateView(doc
, flags
)
1761 view
.SetViewName(temp
.GetViewName())
1764 temp
= SelectViewType(templates
)
1766 view
= temp
.CreateView(doc
, flags
)
1768 view
.SetViewName(temp
.GetViewName())
1774 def DeleteTemplate(self
, template
, flags
):
1776 Placeholder, not yet implemented in wxWindows.
1781 def FlushDoc(self
, doc
):
1783 Placeholder, not yet implemented in wxWindows.
1788 def MatchTemplate(self
, path
):
1790 Placeholder, not yet implemented in wxWindows.
1795 def GetCurrentDocument(self
):
1797 Returns the document associated with the currently active view (if any).
1799 view
= self
.GetCurrentView()
1801 return view
.GetDocument()
1806 def MakeDefaultName(self
):
1808 Returns a suitable default name. This is implemented by appending an
1809 integer counter to the string "Untitled" and incrementing the counter.
1811 name
= _("Untitled %d") % self
._defaultDocumentNameCounter
1812 self
._defaultDocumentNameCounter
= self
._defaultDocumentNameCounter
+ 1
1816 def MakeFrameTitle(self
):
1818 Returns a suitable title for a document frame. This is implemented by
1819 appending the document name to the application name.
1821 appName
= wx
.GetApp().GetAppName()
1825 docName
= doc
.GetPrintableName()
1826 title
= docName
+ _(" - ") + appName
1830 def AddFileToHistory(self
, fileName
):
1832 Adds a file to the file history list, if we have a pointer to an
1833 appropriate file menu.
1835 if self
._fileHistory
:
1836 self
._fileHistory
.AddFileToHistory(fileName
)
1839 def RemoveFileFromHistory(self
, i
):
1841 Removes a file from the file history list, if we have a pointer to an
1842 appropriate file menu.
1844 if self
._fileHistory
:
1845 self
._fileHistory
.RemoveFileFromHistory(i
)
1848 def GetFileHistory(self
):
1850 Returns the file history.
1852 return self
._fileHistory
1855 def GetHistoryFile(self
, i
):
1857 Returns the file at index i from the file history.
1859 if self
._fileHistory
:
1860 return self
._fileHistory
.GetHistoryFile(i
)
1865 def FileHistoryUseMenu(self
, menu
):
1867 Use this menu for appending recently-visited document filenames, for
1868 convenient access. Calling this function with a valid menu enables the
1869 history list functionality.
1871 Note that you can add multiple menus using this function, to be
1872 managed by the file history object.
1874 if self
._fileHistory
:
1875 self
._fileHistory
.UseMenu(menu
)
1878 def FileHistoryRemoveMenu(self
, menu
):
1880 Removes the given menu from the list of menus managed by the file
1883 if self
._fileHistory
:
1884 self
._fileHistory
.RemoveMenu(menu
)
1887 def FileHistoryLoad(self
, config
):
1889 Loads the file history from a config object.
1891 if self
._fileHistory
:
1892 self
._fileHistory
.Load(config
)
1895 def FileHistorySave(self
, config
):
1897 Saves the file history into a config object. This must be called
1898 explicitly by the application.
1900 if self
._fileHistory
:
1901 self
._fileHistory
.Save(config
)
1904 def FileHistoryAddFilesToMenu(self
, menu
= None):
1906 Appends the files in the history list, to all menus managed by the
1907 file history object.
1909 If menu is specified, appends the files in the history list to the
1912 if self
._fileHistory
:
1914 self
._fileHistory
.AddFilesToThisMenu(menu
)
1916 self
._fileHistory
.AddFilesToMenu()
1919 def GetHistoryFilesCount(self
):
1921 Returns the number of files currently stored in the file history.
1923 if self
._fileHistory
:
1924 return self
._fileHistory
.GetNoHistoryFiles()
1929 def FindTemplateForPath(self
, path
):
1931 Given a path, try to find template that matches the extension. This is
1932 only an approximate method of finding a template for creating a
1935 for temp
in self
._templates
:
1936 if temp
.FileMatchesTemplate(path
):
1941 def FindSuitableParent(self
):
1943 Returns a parent frame or dialog, either the frame with the current
1944 focus or if there is no current focus the application's top frame.
1946 parent
= wx
.GetApp().GetTopWindow()
1947 focusWindow
= wx
.Window_FindFocus()
1949 while focusWindow
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
):
1950 focusWindow
= focusWindow
.GetParent()
1952 parent
= focusWindow
1956 def SelectDocumentPath(self
, templates
, flags
, save
):
1958 Under Windows, pops up a file selector with a list of filters
1959 corresponding to document templates. The wxDocTemplate corresponding
1960 to the selected file's extension is returned.
1962 On other platforms, if there is more than one document template a
1963 choice list is popped up, followed by a file selector.
1965 This function is used in wxDocManager.CreateDocument.
1967 if wx
.Platform
== "__WXMSW__" or wx
.Platform
== "__WXGTK__" or wx
.Platform
== "__WXMAC__":
1970 for temp
in templates
:
1971 if temp
.IsVisible():
1973 descr
= descr
+ _('|')
1974 allfilter
= allfilter
+ _(';')
1975 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
1976 allfilter
= allfilter
+ temp
.GetFileFilter()
1977 descr
= _("All") + _(" (") + allfilter
+ _(") |") + allfilter
+ _('|') + descr
# spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
1981 path
= wx
.FileSelector(_("Select a File"),
1982 self
._lastDirectory
,
1985 flags
= wx
.HIDE_READONLY
,
1986 parent
= self
.FindSuitableParent())
1988 if not FileExists(path
):
1989 msgTitle
= wx
.GetApp().GetAppName()
1991 msgTitle
= _("File Error")
1992 wx
.MessageBox("Could not open '%s'." % FileNameFromPath(path
),
1994 wx
.OK | wx
.ICON_EXCLAMATION
,
1997 self
._lastDirectory
= PathOnly(path
)
1999 theTemplate
= self
.FindTemplateForPath(path
)
2000 return (theTemplate
, path
)
2005 def OnOpenFileFailure(self
):
2007 Called when there is an error opening a file.
2012 def SelectDocumentType(self
, temps
, sort
= False):
2014 Returns a document template by asking the user (if there is more than
2015 one template). This function is used in wxDocManager.CreateDocument.
2019 templates - list of templates from which to choose a desired template.
2021 sort - If more than one template is passed in in templates, then this
2022 parameter indicates whether the list of templates that the user will
2023 have to choose from is sorted or not when shown the choice box dialog.
2028 if temp
.IsVisible():
2030 for temp2
in templates
:
2031 if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName():
2035 templates
.append(temp
)
2037 if len(templates
) == 0:
2039 elif len(templates
) == 1:
2044 return cmp(a
.GetDescription(), b
.GetDescription())
2045 templates
.sort(tempcmp
)
2048 for temp
in templates
:
2049 strings
.append(temp
.GetDescription())
2051 res
= wx
.GetSingleChoiceIndex(_("Select a document type:"),
2054 self
.FindSuitableParent())
2057 return templates
[res
]
2060 def SelectViewType(self
, temps
, sort
= False):
2062 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.
2067 if temp
.IsVisible() and temp
.GetViewTypeName():
2068 if temp
.GetViewName() not in strings
:
2069 templates
.append(temp
)
2070 strings
.append(temp
.GetViewTypeName())
2072 if len(templates
) == 0:
2074 elif len(templates
) == 1:
2079 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName())
2080 templates
.sort(tempcmp
)
2082 res
= wx
.GetSingleChoiceIndex(_("Select a document view:"),
2085 self
.FindSuitableParent())
2088 return templates
[res
]
2091 def GetTemplates(self
):
2093 Returns the document manager's template list. This method has been added to
2094 wxPython and is not in wxWindows.
2096 return self
._templates
2099 def AssociateTemplate(self
, docTemplate
):
2101 Adds the template to the document manager's template list.
2103 if docTemplate
not in self
._templates
:
2104 self
._templates
.append(docTemplate
)
2107 def DisassociateTemplate(self
, docTemplate
):
2109 Removes the template from the list of templates.
2111 self
._templates
.remove(docTemplate
)
2114 def AddDocument(self
, document
):
2116 Adds the document to the list of documents.
2118 if document
not in self
._docs
:
2119 self
._docs
.append(document
)
2122 def RemoveDocument(self
, doc
):
2124 Removes the document from the list of documents.
2126 if doc
in self
._docs
:
2127 self
._docs
.remove(doc
)
2130 def ActivateView(self
, view
, activate
= True, deleting
= False):
2132 Sets the current view.
2135 self
._currentView
= view
2136 self
._lastActiveView
= view
2138 self
._currentView
= None
2141 def GetMaxDocsOpen(self
):
2143 Returns the number of documents that can be open simultaneously.
2145 return self
._maxDocsOpen
2148 def SetMaxDocsOpen(self
, maxDocsOpen
):
2150 Sets the maximum number of documents that can be open at a time. By
2151 default, this is 10,000. If you set it to 1, existing documents will
2152 be saved and deleted when the user tries to open or create a new one
2153 (similar to the behaviour of Windows Write, for example). Allowing
2154 multiple documents gives behaviour more akin to MS Word and other
2155 Multiple Document Interface applications.
2157 self
._maxDocsOpen
= maxDocsOpen
2160 def GetDocuments(self
):
2162 Returns the list of documents.
2167 class DocParentFrame(wx
.Frame
):
2169 The wxDocParentFrame class provides a default top-level frame for
2170 applications using the document/view framework. This class can only be
2171 used for SDI (not MDI) parent frames.
2173 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates
2177 def __init__(self
, manager
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2179 Constructor. Note that the event table must be rebuilt for the
2180 frame since the EvtHandler is not virtual.
2182 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
)
2183 self
._docManager
= manager
2185 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2187 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2188 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2190 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2191 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2192 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2193 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2194 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2195 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2196 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2197 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2198 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2199 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2200 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2201 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2203 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2204 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2205 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2206 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2207 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2208 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2209 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2210 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2211 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2212 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2213 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2214 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2217 def ProcessEvent(self
, event
):
2219 Processes an event, searching event tables and calling zero or more
2220 suitable event handler function(s). Note that the ProcessEvent
2221 method is called from the wxPython docview framework directly since
2222 wxPython does not have a virtual ProcessEvent function.
2224 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2227 def ProcessUpdateUIEvent(self
, event
):
2229 Processes a UI event, searching event tables and calling zero or more
2230 suitable event handler function(s). Note that the ProcessEvent
2231 method is called from the wxPython docview framework directly since
2232 wxPython does not have a virtual ProcessEvent function.
2234 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2237 def OnExit(self
, event
):
2239 Called when File/Exit is chosen and closes the window.
2244 def OnMRUFile(self
, event
):
2246 Opens the appropriate file when it is selected from the file history
2249 n
= event
.GetId() - wx
.ID_FILE1
2250 filename
= self
._docManager
.GetHistoryFile(n
)
2252 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2254 self
._docManager
.RemoveFileFromHistory(n
)
2255 msgTitle
= wx
.GetApp().GetAppName()
2257 msgTitle
= _("File Error")
2258 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),
2260 wx
.OK | wx
.ICON_EXCLAMATION
,
2264 def OnCloseWindow(self
, event
):
2266 Deletes all views and documents. If no user input cancelled the
2267 operation, the frame will be destroyed and the application will exit.
2269 if self
._docManager
.Clear(not event
.CanVeto()):
2275 class DocChildFrame(wx
.Frame
):
2277 The wxDocChildFrame class provides a default frame for displaying
2278 documents on separate windows. This class can only be used for SDI (not
2281 The class is part of the document/view framework supported by wxWindows,
2282 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2287 def __init__(self
, doc
, view
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2289 Constructor. Note that the event table must be rebuilt for the
2290 frame since the EvtHandler is not virtual.
2292 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2293 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2294 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2295 self
._childDocument
= doc
2296 self
._childView
= view
2300 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2301 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2302 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2303 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2304 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2305 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2306 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2307 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2308 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2309 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2310 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2311 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2313 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2314 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2315 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2316 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2317 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2318 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2319 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2320 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2321 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2322 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2323 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2324 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2327 def ProcessEvent(self
, event
):
2329 Processes an event, searching event tables and calling zero or more
2330 suitable event handler function(s). Note that the ProcessEvent
2331 method is called from the wxPython docview framework directly since
2332 wxPython does not have a virtual ProcessEvent function.
2335 self
._childView
.Activate(True)
2336 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2337 # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows
2338 # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
2339 if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2347 def ProcessUpdateUIEvent(self
, event
):
2349 Processes a UI event, searching event tables and calling zero or more
2350 suitable event handler function(s). Note that the ProcessEvent
2351 method is called from the wxPython docview framework directly since
2352 wxPython does not have a virtual ProcessEvent function.
2354 if self
.GetParent():
2355 self
.GetParent().ProcessUpdateUIEvent(event
)
2360 def OnActivate(self
, event
):
2362 Activates the current view.
2364 # wx.Frame.OnActivate(event) This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead
2366 self
._childView
.Activate(event
.GetActive())
2369 def OnCloseWindow(self
, event
):
2371 Closes and deletes the current view and document.
2375 if not event
.CanVeto():
2378 ans
= self
._childView
.Close(deleteWindow
= False)
2381 self
._childView
.Activate(False)
2382 self
._childView
.Destroy()
2383 self
._childView
= None
2384 if self
._childDocument
:
2385 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2386 self
._childDocument
= None
2394 def GetDocument(self
):
2396 Returns the document associated with this frame.
2398 return self
._childDocument
2401 def SetDocument(self
, document
):
2403 Sets the document for this frame.
2405 self
._childDocument
= document
2410 Returns the view associated with this frame.
2412 return self
._childView
2415 def SetView(self
, view
):
2417 Sets the view for this frame.
2419 self
._childView
= view
2422 class DocMDIParentFrame(wx
.MDIParentFrame
):
2424 The wxDocMDIParentFrame class provides a default top-level frame for
2425 applications using the document/view framework. This class can only be
2426 used for MDI parent frames.
2428 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2433 def __init__(self
, manager
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2435 Constructor. Note that the event table must be rebuilt for the
2436 frame since the EvtHandler is not virtual.
2438 wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2439 self
._docManager
= manager
2441 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2443 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2444 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2446 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2447 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2448 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2449 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2450 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2451 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2452 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2453 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2454 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2455 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2456 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2457 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2459 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2460 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2461 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2462 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2463 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2464 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2465 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2466 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2467 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2468 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2469 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2470 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2473 def ProcessEvent(self
, event
):
2475 Processes an event, searching event tables and calling zero or more
2476 suitable event handler function(s). Note that the ProcessEvent
2477 method is called from the wxPython docview framework directly since
2478 wxPython does not have a virtual ProcessEvent function.
2480 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2483 def ProcessUpdateUIEvent(self
, event
):
2485 Processes a UI event, searching event tables and calling zero or more
2486 suitable event handler function(s). Note that the ProcessEvent
2487 method is called from the wxPython docview framework directly since
2488 wxPython does not have a virtual ProcessEvent function.
2490 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2493 def OnExit(self
, event
):
2495 Called when File/Exit is chosen and closes the window.
2500 def OnMRUFile(self
, event
):
2502 Opens the appropriate file when it is selected from the file history
2505 n
= event
.GetId() - wx
.ID_FILE1
2506 filename
= self
._docManager
.GetHistoryFile(n
)
2508 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2510 self
._docManager
.RemoveFileFromHistory(n
)
2511 msgTitle
= wx
.GetApp().GetAppName()
2513 msgTitle
= _("File Error")
2514 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),
2516 wx
.OK | wx
.ICON_EXCLAMATION
,
2520 def OnCloseWindow(self
, event
):
2522 Deletes all views and documents. If no user input cancelled the
2523 operation, the frame will be destroyed and the application will exit.
2525 if self
._docManager
.Clear(not event
.CanVeto()):
2531 class DocMDIChildFrame(wx
.MDIChildFrame
):
2533 The wxDocMDIChildFrame class provides a default frame for displaying
2534 documents on separate windows. This class can only be used for MDI child
2537 The class is part of the document/view framework supported by wxWindows,
2538 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2543 def __init__(self
, doc
, view
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2545 Constructor. Note that the event table must be rebuilt for the
2546 frame since the EvtHandler is not virtual.
2548 wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2549 self
._childDocument
= doc
2550 self
._childView
= view
2553 # self.Create(doc, view, frame, id, title, pos, size, style, name)
2554 self
._activeEvent
= None
2556 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2557 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2559 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
2560 mdiChildren
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren())
2561 if len(mdiChildren
) == 1:
2565 ## # Couldn't get this to work, but seems to work fine with single stage construction
2566 ## def Create(self, doc, view, frame, id, title, pos, size, style, name):
2567 ## self._childDocument = doc
2568 ## self._childView = view
2569 ## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
2571 ## view.SetFrame(self)
2577 def Activate(self
): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
2579 Activates the current view.
2582 self
._childView
.Activate(True)
2585 def ProcessEvent(event
):
2587 Processes an event, searching event tables and calling zero or more
2588 suitable event handler function(s). Note that the ProcessEvent
2589 method is called from the wxPython docview framework directly since
2590 wxPython does not have a virtual ProcessEvent function.
2592 if self
._activeEvent
== event
:
2595 self
._activeEvent
= event
# Break recursion loops
2598 self
._childView
.Activate(True)
2600 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2601 if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2608 self
._activeEvent
= None
2612 def OnActivate(self
, event
):
2614 Sets the currently active view to be the frame's view. You may need to
2615 override (but still call) this function in order to set the keyboard
2616 focus for your subwindow.
2618 if self
._activated
!= 0:
2620 self
._activated
+= 1
2621 wx
.MDIChildFrame
.Activate(self
)
2622 if event
.GetActive() and self
._childView
:
2623 self
._childView
.Activate(event
.GetActive())
2626 def OnCloseWindow(self
, event
):
2628 Closes and deletes the current view and document.
2632 if not event
.CanVeto():
2635 ans
= self
._childView
.Close(deleteWindow
= False)
2638 self
._childView
.Activate(False)
2639 self
._childView
.Destroy()
2640 self
._childView
= None
2641 if self
._childDocument
:
2642 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2643 self
._childDocument
= None
2651 def GetDocument(self
):
2653 Returns the document associated with this frame.
2655 return self
._childDocument
2658 def SetDocument(self
, document
):
2660 Sets the document for this frame.
2662 self
._childDocument
= document
2667 Returns the view associated with this frame.
2669 return self
._childView
2672 def SetView(self
, view
):
2674 Sets the view for this frame.
2676 self
._childView
= view
2679 class DocPrintout(wx
.Printout
):
2681 DocPrintout is a default Printout that prints the first page of a document
2686 def __init__(self
, view
, title
= "Printout"):
2690 wx
.Printout
.__init
__(self
)
2691 self
._printoutView
= view
2696 Returns the DocPrintout's view.
2698 return self
._printoutView
2701 def OnPrintPage(self
, page
):
2703 Prints the first page of the view.
2706 ppiScreenX
, ppiScreenY
= self
.GetPPIScreen()
2707 ppiPrinterX
, ppiPrinterY
= self
.GetPPIPrinter()
2708 scale
= ppiPrinterX
/ppiScreenX
2710 pageWidth
, pageHeight
= self
.GetPageSizePixels()
2711 overallScale
= scale
* w
/ pageWidth
2712 dc
.SetUserScale(overallScale
, overallScale
)
2713 if self
._printoutView
:
2714 self
._printoutView
.OnDraw(dc
)
2718 def HasPage(self
, pageNum
):
2720 Indicates that the DocPrintout only has a single page.
2725 def OnBeginDocument(self
, startPage
, endPage
):
2727 Not quite sure why this was overridden, but it was in wxWindows! :)
2729 if not wx
.Printout
.base_OnBeginDocument(self
, startPage
, endPage
):
2734 def GetPageInfo(self
):
2736 Indicates that the DocPrintout only has a single page.
2742 return (minPage
, maxPage
, selPageFrom
, selPageTo
)
2745 #----------------------------------------------------------------------
2747 #----------------------------------------------------------------------
2749 class Command(wx
.Object
):
2751 wxCommand is a base class for modelling an application command, which is
2752 an action usually performed by selecting a menu item, pressing a toolbar
2753 button or any other means provided by the application to change the data
2758 def __init__(self
, canUndo
= False, name
= None):
2760 Constructor. wxCommand is an abstract class, so you will need to
2761 derive a new class and call this constructor from your own constructor.
2763 canUndo tells the command processor whether this command is undo-able.
2764 You can achieve the same functionality by overriding the CanUndo member
2765 function (if for example the criteria for undoability is context-
2768 name must be supplied for the command processor to display the command
2769 name in the application's edit menu.
2771 self
._canUndo
= canUndo
2777 Returns true if the command can be undone, false otherwise.
2779 return self
._canUndo
2784 Returns the command name.
2791 Override this member function to execute the appropriate action when
2792 called. Return true to indicate that the action has taken place, false
2793 otherwise. Returning false will indicate to the command processor that
2794 the action is not undoable and should not be added to the command
2802 Override this member function to un-execute a previous Do. Return true
2803 to indicate that the action has taken place, false otherwise. Returning
2804 false will indicate to the command processor that the action is not
2805 redoable and no change should be made to the command history.
2807 How you implement this command is totally application dependent, but
2808 typical strategies include:
2810 Perform an inverse operation on the last modified piece of data in the
2811 document. When redone, a copy of data stored in command is pasted back
2812 or some operation reapplied. This relies on the fact that you know the
2813 ordering of Undos; the user can never Undo at an arbitrary position in
2816 Restore the entire document state (perhaps using document
2817 transactioning). Potentially very inefficient, but possibly easier to
2818 code if the user interface and data are complex, and an 'inverse
2819 execute' operation is hard to write.
2824 class CommandProcessor(wx
.Object
):
2826 wxCommandProcessor is a class that maintains a history of wxCommands, with
2827 undo/redo functionality built-in. Derive a new class from this if you want
2828 different behaviour.
2832 def __init__(self
, maxCommands
= -1):
2834 Constructor. maxCommands may be set to a positive integer to limit
2835 the number of commands stored to it, otherwise (and by default) the
2836 list of commands can grow arbitrarily.
2838 self
._maxCommands
= maxCommands
2839 self
._editMenu
= None
2840 self
._undoAccelerator
= _("Ctrl+Z")
2841 self
._redoAccelerator
= _("Ctrl+Y")
2842 self
.ClearCommands()
2845 def _GetCurrentCommand(self
):
2846 if len(self
._commands
) == 0:
2849 return self
._commands
[-1]
2852 def _GetCurrentRedoCommand(self
):
2853 if len(self
._redoCommands
) == 0:
2856 return self
._redoCommands
[-1]
2859 def GetMaxCommands(self
):
2861 Returns the maximum number of commands that the command processor
2865 return self
._maxCommands
2868 def GetCommands(self
):
2870 Returns the list of commands.
2872 return self
._commands
2875 def ClearCommands(self
):
2877 Deletes all the commands in the list and sets the current command
2881 self
._redoCommands
= []
2884 def GetEditMenu(self
):
2886 Returns the edit menu associated with the command processor.
2888 return self
._editMenu
2891 def SetEditMenu(self
, menu
):
2893 Tells the command processor to update the Undo and Redo items on this
2894 menu as appropriate. Set this to NULL if the menu is about to be
2895 destroyed and command operations may still be performed, or the
2896 command processor may try to access an invalid pointer.
2898 self
._editMenu
= menu
2901 def GetUndoAccelerator(self
):
2903 Returns the string that will be appended to the Undo menu item.
2905 return self
._undoAccelerator
2908 def SetUndoAccelerator(self
, accel
):
2910 Sets the string that will be appended to the Redo menu item.
2912 self
._undoAccelerator
= accel
2915 def GetRedoAccelerator(self
):
2917 Returns the string that will be appended to the Redo menu item.
2919 return self
._redoAccelerator
2922 def SetRedoAccelerator(self
, accel
):
2924 Sets the string that will be appended to the Redo menu item.
2926 self
._redoAccelerator
= accel
2929 def SetEditMenu(self
, menu
):
2931 Tells the command processor to update the Undo and Redo items on this
2932 menu as appropriate. Set this to NULL if the menu is about to be
2933 destroyed and command operations may still be performed, or the
2934 command processor may try to access an invalid pointer.
2936 self
._editMenu
= menu
2939 def SetMenuStrings(self
):
2941 Sets the menu labels according to the currently set menu and the
2942 current command state.
2944 if self
.GetEditMenu() != None:
2945 undoCommand
= self
._GetCurrentCommand
()
2946 redoCommand
= self
._GetCurrentRedoCommand
()
2947 undoItem
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
)
2948 redoItem
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
)
2949 if self
.GetUndoAccelerator():
2950 undoAccel
= '\t' + self
.GetUndoAccelerator()
2953 if self
.GetRedoAccelerator():
2954 redoAccel
= '\t' + self
.GetRedoAccelerator()
2957 if undoCommand
and undoItem
and undoCommand
.CanUndo():
2958 undoItem
.SetText(_("Undo ") + undoCommand
.GetName() + undoAccel
)
2959 #elif undoCommand and not undoCommand.CanUndo():
2960 # undoItem.SetText(_("Can't Undo") + undoAccel)
2962 undoItem
.SetText(_("Undo" + undoAccel
))
2963 if redoCommand
and redoItem
:
2964 redoItem
.SetText(_("Redo ") + redoCommand
.GetName() + redoAccel
)
2966 redoItem
.SetText(_("Redo") + redoAccel
)
2971 Returns true if the currently-active command can be undone, false
2974 if self
._GetCurrentCommand
() == None:
2976 return self
._GetCurrentCommand
().CanUndo()
2981 Returns true if the currently-active command can be redone, false
2984 return self
._GetCurrentRedoCommand
() != None
2987 def Submit(self
, command
, storeIt
= True):
2989 Submits a new command to the command processor. The command processor
2990 calls wxCommand::Do to execute the command; if it succeeds, the
2991 command is stored in the history list, and the associated edit menu
2992 (if any) updated appropriately. If it fails, the command is deleted
2993 immediately. Once Submit has been called, the passed command should
2994 not be deleted directly by the application.
2996 storeIt indicates whether the successful command should be stored in
3000 if done
and storeIt
:
3001 self
._commands
.append(command
)
3002 if self
._maxCommands
> -1:
3003 if len(self
._commands
) > self
._maxCommands
:
3004 del self
._commands
[0]
3010 Redoes the command just undone.
3012 cmd
= self
._GetCurrentRedoCommand
()
3017 self
._commands
.append(self
._redoCommands
.pop())
3023 Undoes the command just executed.
3025 cmd
= self
._GetCurrentCommand
()
3030 self
._redoCommands
.append(self
._commands
.pop())