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 #----------------------------------------------------------------------------
22 #----------------------------------------------------------------------
24 #----------------------------------------------------------------------
32 DEFAULT_DOCMAN_FLAGS
= DOC_SDI
& DOC_OPEN_ONCE
35 TEMPLATE_INVISIBLE
= 2
36 TEMPLATE_NO_CREATE
= (4 | TEMPLATE_VISIBLE
)
37 DEFAULT_TEMPLATE_FLAGS
= TEMPLATE_VISIBLE
42 #----------------------------------------------------------------------
43 # Convenience functions from wxWindows used in docview
44 #----------------------------------------------------------------------
47 def FileNameFromPath(path
):
49 Returns the filename for a full path.
51 return os
.path
.split(path
)[1]
53 def FindExtension(path
):
55 Returns the extension of a filename for a full path.
57 return os
.path
.splitext(path
)[1].lower()
61 Returns True if the path exists.
63 return os
.path
.isfile(path
)
67 Returns the path of a full path without the filename.
69 return os
.path
.split(path
)[0]
72 #----------------------------------------------------------------------
73 # Document/View Classes
74 #----------------------------------------------------------------------
77 class Document(wx
.EvtHandler
):
79 The document class can be used to model an application's file-based data. It
80 is part of the document/view framework supported by wxWindows, and cooperates
81 with the wxView, wxDocTemplate and wxDocManager classes.
83 Note this wxPython version also keeps track of the modification date of the
84 document and if it changes on disk outside of the application, we will warn the
85 user before saving to avoid clobbering the file.
89 def __init__(self
, parent
=None):
91 Constructor. Define your own default constructor to initialize
92 application-specific data.
94 wx
.EvtHandler
.__init
__(self
)
96 self
._documentParent
= parent
97 self
._documentTemplate
= None
98 self
._commandProcessor
= None
99 self
._savedYet
= False
100 self
._writeable
= True
102 self
._documentTitle
= None
103 self
._documentFile
= None
104 self
._documentTypeName
= None
105 self
._documentModified
= False
106 self
._documentModificationDate
= None
107 self
._documentViews
= []
110 def ProcessEvent(self
, event
):
112 Processes an event, searching event tables and calling zero or more
113 suitable event handler function(s). Note that the ProcessEvent
114 method is called from the wxPython docview framework directly since
115 wxPython does not have a virtual ProcessEvent function.
120 def GetFilename(self
):
122 Gets the filename associated with this document, or "" if none is
125 return self
._documentFile
130 Gets the title for this document. The document title is used for an
131 associated frame (if any), and is usually constructed by the framework
134 return self
._documentTitle
137 def SetTitle(self
, title
):
139 Sets the title for this document. The document title is used for an
140 associated frame (if any), and is usually constructed by the framework
143 self
._documentTitle
= title
146 def GetDocumentName(self
):
148 The document type name given to the wxDocTemplate constructor,
149 copied to this document when the document is created. If several
150 document templates are created that use the same document type, this
151 variable is used in wxDocManager::CreateView to collate a list of
152 alternative view types that can be used on this kind of document.
154 return self
._documentTypeName
157 def SetDocumentName(self
, name
):
159 Sets he document type name given to the wxDocTemplate constructor,
160 copied to this document when the document is created. If several
161 document templates are created that use the same document type, this
162 variable is used in wxDocManager::CreateView to collate a list of
163 alternative view types that can be used on this kind of document. Do
164 not change the value of this variable.
166 self
._documentTypeName
= name
169 def GetDocumentSaved(self
):
171 Returns True if the document has been saved. This method has been
172 added to wxPython and is not in wxWindows.
174 return self
._savedYet
177 def SetDocumentSaved(self
, saved
=True):
179 Sets whether the document has been saved. This method has been
180 added to wxPython and is not in wxWindows.
182 self
._savedYet
= saved
185 def GetCommandProcessor(self
):
187 Returns the command processor associated with this document.
189 return self
._commandProcessor
192 def SetCommandProcessor(self
, processor
):
194 Sets the command processor to be used for this document. The document
195 will then be responsible for its deletion. Normally you should not
196 call this; override OnCreateCommandProcessor instead.
198 self
._commandProcessor
= processor
201 def IsModified(self
):
203 Returns true if the document has been modified since the last save,
204 false otherwise. You may need to override this if your document view
205 maintains its own record of being modified (for example if using
206 wxTextWindow to view and edit the document).
208 return self
._documentModified
211 def Modify(self
, modify
):
213 Call with true to mark the document as modified since the last save,
214 false otherwise. You may need to override this if your document view
215 maintains its own record of being modified (for example if using
216 xTextWindow to view and edit the document).
218 self
._documentModified
= modify
221 def SetDocumentModificationDate(self
):
223 Saves the file's last modification date.
224 This is used to check if the file has been modified outside of the application.
225 This method has been added to wxPython and is not in wxWindows.
227 self
._documentModificationDate
= os
.path
.getmtime(self
.GetFilename())
230 def GetDocumentModificationDate(self
):
232 Returns the file's modification date when it was loaded from disk.
233 This is used to check if the file has been modified outside of the application.
234 This method has been added to wxPython and is not in wxWindows.
236 return self
._documentModificationDate
241 Returns the list whose elements are the views on the document.
243 return self
._documentViews
246 def GetDocumentTemplate(self
):
248 Returns the template that created the document.
250 return self
._documentTemplate
253 def SetDocumentTemplate(self
, template
):
255 Sets the template that created the document. Should only be called by
258 self
._documentTemplate
= template
261 def DeleteContents(self
):
263 Deletes the contents of the document. Override this method as
271 Destructor. Removes itself from the document manager.
273 self
.DeleteContents()
274 if self
.GetDocumentManager():
275 self
.GetDocumentManager().RemoveDocument(self
)
276 wx
.EvtHandler
.Destroy(self
)
281 Closes the document, by calling OnSaveModified and then (if this true)
282 OnCloseDocument. This does not normally delete the document object:
283 use DeleteAllViews to do this implicitly.
285 if self
.OnSaveModified():
286 if self
.OnCloseDocument():
294 def OnCloseDocument(self
):
296 The default implementation calls DeleteContents (an empty
297 implementation) sets the modified flag to false. Override this to
298 supply additional behaviour when the document is closed with Close.
301 self
.DeleteContents()
306 def DeleteAllViews(self
):
308 Calls wxView.Close and deletes each view. Deleting the final view will
309 implicitly delete the document itself, because the wxView destructor
310 calls RemoveView. This in turns calls wxDocument::OnChangedViewList,
311 whose default implemention is to save and delete the document if no
314 manager
= self
.GetDocumentManager()
315 for view
in self
._documentViews
:
318 if self
in manager
.GetDocuments():
323 def GetFirstView(self
):
325 A convenience function to get the first view for a document, because
326 in many cases a document will only have a single view.
328 if len(self
._documentViews
) == 0:
330 return self
._documentViews
[0]
333 def GetDocumentManager(self
):
335 Returns the associated document manager.
337 if self
._documentTemplate
:
338 return self
._documentTemplate
.GetDocumentManager()
342 def OnNewDocument(self
):
344 The default implementation calls OnSaveModified and DeleteContents,
345 makes a default title for the document, and notifies the views that
346 the filename (in fact, the title) has changed.
348 if not self
.OnSaveModified() or not self
.OnCloseDocument():
350 self
.DeleteContents()
352 self
.SetDocumentSaved(False)
353 name
= self
.GetDocumentManager().MakeDefaultName()
355 self
.SetFilename(name
, notifyViews
= True)
360 Saves the document by calling OnSaveDocument if there is an associated
361 filename, or SaveAs if there is no filename.
363 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?
366 """ check for file modification outside of application """
367 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
368 msgTitle
= wx
.GetApp().GetAppName()
370 msgTitle
= _("Application")
371 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
373 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
374 self
.GetDocumentWindow())
380 else: # elif res == wx.CANCEL:
383 if not self
._documentFile
or not self
._savedYet
:
385 return self
.OnSaveDocument(self
._documentFile
)
390 Prompts the user for a file to save to, and then calls OnSaveDocument.
392 docTemplate
= self
.GetDocumentTemplate()
396 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
397 filename
= wx
.FileSelector(_("Save As"),
398 docTemplate
.GetDirectory(),
399 FileNameFromPath(self
.GetFilename()),
400 docTemplate
.GetDefaultExtension(),
402 flags
= wx
.SAVE | wx
.OVERWRITE_PROMPT
,
403 parent
= self
.GetDocumentWindow())
407 name
, ext
= os
.path
.splitext(filename
)
409 filename
+= '.' + docTemplate
.GetDefaultExtension()
411 self
.SetFilename(filename
)
412 self
.SetTitle(FileNameFromPath(filename
))
414 for view
in self
._documentViews
:
415 view
.OnChangeFilename()
417 if not self
.OnSaveDocument(filename
):
420 if docTemplate
.FileMatchesTemplate(filename
):
421 self
.GetDocumentManager().AddFileToHistory(filename
)
426 def OnSaveDocument(self
, filename
):
428 Constructs an output file for the given filename (which must
429 not be empty), and calls SaveObject. If SaveObject returns true, the
430 document is set to unmodified; otherwise, an error message box is
436 msgTitle
= wx
.GetApp().GetAppName()
438 msgTitle
= _("File Error")
440 backupFilename
= None
444 # if current file exists, move it to a safe place temporarily
445 if os
.path
.exists(filename
):
447 # Check if read-only.
448 if not os
.access(filename
, os
.W_OK
):
449 wx
.MessageBox("Could not save '%s'. No write permission to overwrite existing file." % FileNameFromPath(filename
),
451 wx
.OK | wx
.ICON_EXCLAMATION
,
452 self
.GetDocumentWindow())
456 backupFilename
= "%s.bak%s" % (filename
, i
)
457 while os
.path
.exists(backupFilename
):
459 backupFilename
= "%s.bak%s" % (filename
, i
)
460 shutil
.copy(filename
, backupFilename
)
463 fileObject
= file(filename
, 'w')
464 self
.SaveObject(fileObject
)
469 os
.remove(backupFilename
)
471 # for debugging purposes
473 traceback
.print_exc()
476 fileObject
.close() # file is still open, close it, need to do this before removal
478 # save failed, remove copied file
479 if backupFilename
and copied
:
480 os
.remove(backupFilename
)
482 wx
.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
484 wx
.OK | wx
.ICON_EXCLAMATION
,
485 self
.GetDocumentWindow())
488 self
.SetFilename(filename
, True)
490 self
.SetDocumentModificationDate()
491 self
.SetDocumentSaved(True)
492 #if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
493 # wx.FileName(file).MacSetDefaultTypeAndCreator()
497 def OnOpenDocument(self
, filename
):
499 Constructs an input file for the given filename (which must not
500 be empty), and calls LoadObject. If LoadObject returns true, the
501 document is set to unmodified; otherwise, an error message box is
502 displayed. The document's views are notified that the filename has
503 changed, to give windows an opportunity to update their titles. All of
504 the document's views are then updated.
506 if not self
.OnSaveModified():
509 msgTitle
= wx
.GetApp().GetAppName()
511 msgTitle
= _("File Error")
513 fileObject
= file(filename
, 'r')
515 self
.LoadObject(fileObject
)
519 # for debugging purposes
521 traceback
.print_exc()
524 fileObject
.close() # file is still open, close it
526 wx
.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
528 wx
.OK | wx
.ICON_EXCLAMATION
,
529 self
.GetDocumentWindow())
532 self
.SetFilename(filename
, True)
534 self
.SetDocumentModificationDate()
535 self
.SetDocumentSaved(True)
536 self
.UpdateAllViews()
540 def LoadObject(self
, file):
542 Override this function and call it from your own LoadObject before
543 loading your own data. LoadObject is called by the framework
544 automatically when the document contents need to be loaded.
546 Note that the wxPython version simply sends you a Python file object,
547 so you can use pickle.
552 def SaveObject(self
, file):
554 Override this function and call it from your own SaveObject before
555 saving your own data. SaveObject is called by the framework
556 automatically when the document contents need to be saved.
558 Note that the wxPython version simply sends you a Python file object,
559 so you can use pickle.
566 Override this function to revert the document to its last saved state.
571 def GetPrintableName(self
):
573 Copies a suitable document name into the supplied name buffer.
574 The default function uses the title, or if there is no title, uses the
575 filename; or if no filename, the string 'Untitled'.
577 if self
._documentTitle
:
578 return self
._documentTitle
579 elif self
._documentFile
:
580 return FileNameFromPath(self
._documentFile
)
585 def GetDocumentWindow(self
):
587 Intended to return a suitable window for using as a parent for
588 document-related dialog boxes. By default, uses the frame associated
591 if len(self
._documentViews
) > 0:
592 return self
._documentViews
[0].GetFrame()
594 return wx
.GetApp().GetTopWindow()
597 def OnCreateCommandProcessor(self
):
599 Override this function if you want a different (or no) command
600 processor to be created when the document is created. By default, it
601 returns an instance of wxCommandProcessor.
603 return CommandProcessor()
606 def OnSaveModified(self
):
608 If the document has been modified, prompts the user to ask if the
609 changes should be changed. If the user replies Yes, the Save function
610 is called. If No, the document is marked as unmodified and the
611 function succeeds. If Cancel, the function fails.
613 if not self
.IsModified():
616 """ check for file modification outside of application """
617 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
618 msgTitle
= wx
.GetApp().GetAppName()
620 msgTitle
= _("Warning")
621 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
623 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
624 self
.GetDocumentWindow())
630 return wx
.lib
.docview
.Document
.Save(self
)
631 else: # elif res == wx.CANCEL:
634 msgTitle
= wx
.GetApp().GetAppName()
636 msgTitle
= _("Warning")
638 res
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(),
640 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
641 self
.GetDocumentWindow())
648 else: # elif res == wx.CANCEL:
654 Called by printing framework to draw the view.
659 def AddView(self
, view
):
661 If the view is not already in the list of views, adds the view and
662 calls OnChangedViewList.
664 if not view
in self
._documentViews
:
665 self
._documentViews
.append(view
)
666 self
.OnChangedViewList()
670 def RemoveView(self
, view
):
672 Removes the view from the document's list of views, and calls
675 if view
in self
._documentViews
:
676 self
._documentViews
.remove(view
)
677 self
.OnChangedViewList()
681 def OnCreate(self
, path
, flags
):
683 The default implementation calls DeleteContents (an empty
684 implementation) sets the modified flag to false. Override this to
685 supply additional behaviour when the document is opened with Open.
687 if flags
& DOC_NO_VIEW
:
689 return self
.GetDocumentTemplate().CreateView(self
, flags
)
692 def OnChangedViewList(self
):
694 Called when a view is added to or deleted from this document. The
695 default implementation saves and deletes the document if no views
696 exist (the last one has just been removed).
698 if len(self
._documentViews
) == 0:
699 if self
.OnSaveModified():
700 pass # C version does a delete but Python will garbage collect
703 def UpdateAllViews(self
, sender
= None, hint
= None):
705 Updates all views. If sender is non-NULL, does not update this view.
706 hint represents optional information to allow a view to optimize its
709 for view
in self
._documentViews
:
711 view
.OnUpdate(sender
, hint
)
714 def NotifyClosing(self
):
716 Notifies the views that the document is going to close.
718 for view
in self
._documentViews
:
719 view
.OnClosingDocument()
722 def SetFilename(self
, filename
, notifyViews
= False):
724 Sets the filename for this document. Usually called by the framework.
725 If notifyViews is true, wxView.OnChangeFilename is called for all
728 self
._documentFile
= filename
730 for view
in self
._documentViews
:
731 view
.OnChangeFilename()
734 def GetWriteable(self
):
736 Returns true if the document can be written to its accociated file path.
737 This method has been added to wxPython and is not in wxWindows.
739 if not self
._writeable
:
741 if not self
._documentFile
: # Doesn't exist, do a save as
744 return os
.access(self
._documentFile
, os
.W_OK
)
747 def SetWriteable(self
, writeable
):
749 Set to False if the document can not be saved. This will disable the ID_SAVE_AS
750 event and is useful for custom documents that should not be saveable. The ID_SAVE
751 event can be disabled by never Modifying the document. This method has been added
752 to wxPython and is not in wxWindows.
754 self
._writeable
= writeable
757 class View(wx
.EvtHandler
):
759 The view class can be used to model the viewing and editing component of
760 an application's file-based data. It is part of the document/view
761 framework supported by wxWindows, and cooperates with the wxDocument,
762 wxDocTemplate and wxDocManager classes.
767 Constructor. Define your own default constructor to initialize
768 application-specific data.
770 wx
.EvtHandler
.__init
__(self
)
771 self
._viewDocument
= None
772 self
._viewFrame
= None
777 Destructor. Removes itself from the document's list of views.
779 if self
._viewDocument
:
780 self
._viewDocument
.RemoveView(self
)
781 wx
.EvtHandler
.Destroy(self
)
784 def ProcessEvent(self
, event
):
786 Processes an event, searching event tables and calling zero or more
787 suitable event handler function(s). Note that the ProcessEvent
788 method is called from the wxPython docview framework directly since
789 wxPython does not have a virtual ProcessEvent function.
791 if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
):
797 def ProcessUpdateUIEvent(self
, event
):
799 Processes a UI event, searching event tables and calling zero or more
800 suitable event handler function(s). Note that the ProcessEvent
801 method is called from the wxPython docview framework directly since
802 wxPython does not have a virtual ProcessEvent function.
807 def OnActivateView(self
, activate
, activeView
, deactiveView
):
809 Called when a view is activated by means of wxView::Activate. The
810 default implementation does nothing.
815 def OnClosingDocument(self
):
817 Override this to clean up the view when the document is being closed.
818 The default implementation does nothing.
823 def OnDraw(self
, dc
):
825 Override this to draw the view for the printing framework. The
826 default implementation does nothing.
831 def OnPrint(self
, dc
, info
):
833 Override this to print the view for the printing framework. The
834 default implementation calls View.OnDraw.
839 def OnUpdate(self
, sender
, hint
):
841 Called when the view should be updated. sender is a pointer to the
842 view that sent the update request, or NULL if no single view requested
843 the update (for instance, when the document is opened). hint is as yet
844 unused but may in future contain application-specific information for
845 making updating more efficient.
850 def OnChangeFilename(self
):
852 Called when the filename has changed. The default implementation
853 constructs a suitable title and sets the title of the view frame (if
857 appName
= wx
.GetApp().GetAppName()
858 if not self
.GetDocument():
864 if appName
and isinstance(self
.GetFrame(), DocChildFrame
): # Only need app name in title for SDI
865 title
= appName
+ _(" - ")
868 self
.GetFrame().SetTitle(title
+ self
.GetDocument().GetPrintableName())
871 def GetDocument(self
):
873 Returns the document associated with the view.
875 return self
._viewDocument
878 def SetDocument(self
, doc
):
880 Associates the given document with the view. Normally called by the
883 self
._viewDocument
= doc
888 def GetViewName(self
):
890 Gets the name associated with the view (passed to the wxDocTemplate
891 constructor). Not currently used by the framework.
893 return self
._viewTypeName
896 def SetViewName(self
, name
):
898 Sets the view type name. Should only be called by the framework.
900 self
._viewTypeName
= name
903 def Close(self
, deleteWindow
=True):
905 Closes the view by calling OnClose. If deleteWindow is true, this
906 function should delete the window associated with the view.
908 if self
.OnClose(deleteWindow
= deleteWindow
):
914 def Activate(self
, activate
=True):
916 Call this from your view frame's OnActivate member to tell the
917 framework which view is currently active. If your windowing system
918 doesn't call OnActivate, you may need to call this function from
919 any place where you know the view must be active, and
920 the framework will need to get the current view.
922 The prepackaged view frame wxDocChildFrame calls wxView.Activate from
923 its OnActivate member.
925 if self
.GetDocument() and self
.GetDocumentManager():
926 self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView())
927 self
.GetDocumentManager().ActivateView(self
, activate
)
930 def OnClose(self
, deleteWindow
=True):
932 Implements closing behaviour. The default implementation calls
933 wxDocument.Close to close the associated document. Does not delete the
934 view. The application may wish to do some cleaning up operations in
935 this function, if a call to wxDocument::Close succeeded. For example,
936 if your application's all share the same window, you need to
937 disassociate the window from the view and perhaps clear the window. If
938 deleteWindow is true, delete the frame associated with the view.
940 if self
.GetDocument():
941 return self
.GetDocument().Close()
946 def OnCreate(self
, doc
, flags
):
948 wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just
949 after the wxDocTemplate creates the wxView, it calls wxView::OnCreate.
950 In its OnCreate member function, the wxView can create a
951 wxDocChildFrame or a derived class. This wxDocChildFrame provides user
952 interface elements to view and/or edit the contents of the wxDocument.
954 By default, simply returns true. If the function returns false, the
955 view will be deleted.
960 def OnCreatePrintout(self
):
962 Returns a wxPrintout object for the purposes of printing. It should
963 create a new object every time it is called; the framework will delete
966 By default, this function returns an instance of wxDocPrintout, which
967 prints and previews one page by calling wxView.OnDraw.
969 Override to return an instance of a class other than wxDocPrintout.
971 return DocPrintout(self
, self
.GetDocument().GetPrintableName())
976 Gets the frame associated with the view (if any). Note that this
977 "frame" is not a wxFrame at all in the generic MDI implementation
978 which uses the notebook pages instead of the frames and this is why
979 this method returns a wxWindow and not a wxFrame.
981 return self
._viewFrame
984 def SetFrame(self
, frame
):
986 Sets the frame associated with this view. The application should call
987 this if possible, to tell the view about the frame. See GetFrame for
988 the explanation about the mismatch between the "Frame" in the method
989 name and the type of its parameter.
991 self
._viewFrame
= frame
994 def GetDocumentManager(self
):
996 Returns the document manager instance associated with this view.
998 if self
._viewDocument
:
999 return self
.GetDocument().GetDocumentManager()
1004 class DocTemplate(wx
.Object
):
1006 The wxDocTemplate class is used to model the relationship between a
1007 document class and a view class.
1011 def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
=DEFAULT_TEMPLATE_FLAGS
, icon
=None):
1013 Constructor. Create instances dynamically near the start of your
1014 application after creating a wxDocManager instance, and before doing
1015 any document or view operations.
1017 manager is the document manager object which manages this template.
1019 description is a short description of what the template is for. This
1020 string will be displayed in the file filter list of Windows file
1023 filter is an appropriate file filter such as *.txt.
1025 dir is the default directory to use for file selectors.
1027 ext is the default file extension (such as txt).
1029 docTypeName is a name that should be unique for a given type of
1030 document, used for gathering a list of views relevant to a
1031 particular document.
1033 viewTypeName is a name that should be unique for a given view.
1035 docClass is a Python class. If this is not supplied, you will need to
1036 derive a new wxDocTemplate class and override the CreateDocument
1037 member to return a new document instance on demand.
1039 viewClass is a Python class. If this is not supplied, you will need to
1040 derive a new wxDocTemplate class and override the CreateView member to
1041 return a new view instance on demand.
1043 flags is a bit list of the following:
1044 wx.TEMPLATE_VISIBLE The template may be displayed to the user in
1047 wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in
1050 wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE.
1052 self
._docManager
= manager
1053 self
._description
= description
1054 self
._fileFilter
= filter
1055 self
._directory
= dir
1056 self
._defaultExt
= ext
1057 self
._docTypeName
= docTypeName
1058 self
._viewTypeName
= viewTypeName
1059 self
._docType
= docType
1060 self
._viewType
= viewType
1064 self
._docManager
.AssociateTemplate(self
)
1067 def GetDefaultExtension(self
):
1069 Returns the default file extension for the document data, as passed to
1070 the document template constructor.
1072 return self
._defaultExt
1075 def SetDefaultExtension(self
, defaultExt
):
1077 Sets the default file extension.
1079 self
._defaultExt
= defaultExt
1082 def GetDescription(self
):
1084 Returns the text description of this template, as passed to the
1085 document template constructor.
1087 return self
._description
1090 def SetDescription(self
, description
):
1092 Sets the template description.
1094 self
._description
= description
1097 def GetDirectory(self
):
1099 Returns the default directory, as passed to the document template
1102 return self
._directory
1105 def SetDirectory(self
, dir):
1107 Sets the default directory.
1109 self
._directory
= dir
1112 def GetDocumentManager(self
):
1114 Returns the document manager instance for which this template was
1117 return self
._docManager
1120 def SetDocumentManager(self
, manager
):
1122 Sets the document manager instance for which this template was
1123 created. Should not be called by the application.
1125 self
._docManager
= manager
1128 def GetFileFilter(self
):
1130 Returns the file filter, as passed to the document template
1133 return self
._fileFilter
1136 def SetFileFilter(self
, filter):
1138 Sets the file filter.
1140 self
._fileFilter
= filter
1145 Returns the flags, as passed to the document template constructor.
1146 (see the constructor description for more details).
1151 def SetFlags(self
, flags
):
1153 Sets the internal document template flags (see the constructor
1154 description for more details).
1161 Returns the icon, as passed to the document template
1162 constructor. This method has been added to wxPython and is
1168 def SetIcon(self
, flags
):
1170 Sets the icon. This method has been added to wxPython and is not
1176 def GetDocumentType(self
):
1178 Returns the Python document class, as passed to the document template
1181 return self
._docType
1184 def GetViewType(self
):
1186 Returns the Python view class, as passed to the document template
1189 return self
._viewType
1192 def IsVisible(self
):
1194 Returns true if the document template can be shown in user dialogs,
1197 return (self
._flags
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
1200 def IsNewable(self
):
1202 Returns true if the document template can be shown in "New" dialogs,
1205 This method has been added to wxPython and is not in wxWindows.
1207 return (self
._flags
& TEMPLATE_NO_CREATE
) != TEMPLATE_NO_CREATE
1210 def GetDocumentName(self
):
1212 Returns the document type name, as passed to the document template
1215 return self
._docTypeName
1218 def GetViewName(self
):
1220 Returns the view type name, as passed to the document template
1223 return self
._viewTypeName
1226 def CreateDocument(self
, path
, flags
):
1228 Creates a new instance of the associated document class. If you have
1229 not supplied a class to the template constructor, you will need to
1230 override this function to return an appropriate document instance.
1232 doc
= self
._docType
()
1233 doc
.SetFilename(path
)
1234 doc
.SetDocumentTemplate(self
)
1235 self
.GetDocumentManager().AddDocument(doc
)
1236 doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor())
1237 if doc
.OnCreate(path
, flags
):
1240 if doc
in self
.GetDocumentManager().GetDocuments():
1241 doc
.DeleteAllViews()
1245 def CreateView(self
, doc
, flags
):
1247 Creates a new instance of the associated document view. If you have
1248 not supplied a class to the template constructor, you will need to
1249 override this function to return an appropriate view instance.
1251 view
= self
._viewType
()
1252 view
.SetDocument(doc
)
1253 if view
.OnCreate(doc
, flags
):
1260 def FileMatchesTemplate(self
, path
):
1262 Returns True if the path's extension matches one of this template's
1263 file filter extensions.
1265 ext
= FindExtension(path
)
1266 if not ext
: return False
1268 extList
= self
.GetFileFilter().replace('*','').split(';')
1269 return ext
in extList
1272 class DocManager(wx
.EvtHandler
):
1274 The wxDocManager class is part of the document/view framework supported by
1275 wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate
1279 def __init__(self
, flags
=DEFAULT_DOCMAN_FLAGS
, initialize
=True):
1281 Constructor. Create a document manager instance dynamically near the
1282 start of your application before doing any document or view operations.
1284 flags is used in the Python version to indicate whether the document
1285 manager is in DOC_SDI or DOC_MDI mode.
1287 If initialize is true, the Initialize function will be called to
1288 create a default history list object. If you derive from wxDocManager,
1289 you may wish to call the base constructor with false, and then call
1290 Initialize in your own constructor, to allow your own Initialize or
1291 OnCreateFileHistory functions to be called.
1294 wx
.EvtHandler
.__init
__(self
)
1296 self
._defaultDocumentNameCounter
= 1
1298 self
._currentView
= None
1299 self
._lastActiveView
= None
1300 self
._maxDocsOpen
= 10000
1301 self
._fileHistory
= None
1302 self
._templates
= []
1304 self
._lastDirectory
= ""
1309 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
)
1310 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
)
1311 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
)
1312 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
)
1313 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
)
1314 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
)
1315 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
)
1316 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
1317 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
1318 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
)
1319 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
)
1320 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
)
1322 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
)
1323 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
)
1324 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
)
1325 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
)
1326 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
)
1327 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
)
1328 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
)
1329 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
)
1330 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
)
1331 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
)
1332 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
)
1333 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
)
1341 wx
.EvtHandler
.Destroy(self
)
1346 Returns the document manager's flags. This method has been
1347 added to wxPython and is not in wxWindows.
1352 def CloseDocument(self
, doc
, force
=True):
1354 Closes the specified document.
1356 if doc
.Close() or force
:
1357 doc
.DeleteAllViews()
1358 if doc
in self
._docs
:
1364 def CloseDocuments(self
, force
=True):
1366 Closes all currently opened documents.
1368 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
1369 if not self
.CloseDocument(document
, force
):
1371 document
.DeleteAllViews() # Implicitly delete the document when the last view is removed
1375 def Clear(self
, force
=True):
1377 Closes all currently opened document by callling CloseDocuments and
1378 clears the document manager's templates.
1380 if not self
.CloseDocuments(force
):
1382 self
._templates
= []
1386 def Initialize(self
):
1388 Initializes data; currently just calls OnCreateFileHistory. Some data
1389 cannot always be initialized in the constructor because the programmer
1390 must be given the opportunity to override functionality. In fact
1391 Initialize is called from the wxDocManager constructor, but this can
1392 be vetoed by passing false to the second argument, allowing the
1393 derived class's constructor to call Initialize, possibly calling a
1394 different OnCreateFileHistory from the default.
1396 The bottom line: if you're not deriving from Initialize, forget it and
1397 construct wxDocManager with no arguments.
1399 self
.OnCreateFileHistory()
1403 def OnCreateFileHistory(self
):
1405 A hook to allow a derived class to create a different type of file
1406 history. Called from Initialize.
1408 self
._fileHistory
= wx
.FileHistory()
1411 def OnFileClose(self
, event
):
1413 Closes and deletes the currently active document.
1415 doc
= self
.GetCurrentDocument()
1417 doc
.DeleteAllViews()
1418 if doc
in self
._docs
:
1419 self
._docs
.remove(doc
)
1422 def OnFileCloseAll(self
, event
):
1424 Closes and deletes all the currently opened documents.
1426 return self
.CloseDocuments(force
= False)
1429 def OnFileNew(self
, event
):
1431 Creates a new document and reads in the selected file.
1433 self
.CreateDocument('', DOC_NEW
)
1436 def OnFileOpen(self
, event
):
1438 Creates a new document and reads in the selected file.
1440 if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
):
1441 self
.OnOpenFileFailure()
1444 def OnFileRevert(self
, event
):
1446 Reverts the current document by calling wxDocument.Save for the current
1449 doc
= self
.GetCurrentDocument()
1455 def OnFileSave(self
, event
):
1457 Saves the current document by calling wxDocument.Save for the current
1460 doc
= self
.GetCurrentDocument()
1466 def OnFileSaveAs(self
, event
):
1468 Calls wxDocument.SaveAs for the current document.
1470 doc
= self
.GetCurrentDocument()
1476 def OnPrint(self
, event
):
1478 Prints the current document by calling its View's OnCreatePrintout
1481 view
= self
.GetCurrentView()
1485 printout
= view
.OnCreatePrintout()
1487 if not hasattr(self
, "printData"):
1488 self
.printData
= wx
.PrintData()
1489 self
.printData
.SetPaperId(wx
.PAPER_LETTER
)
1490 self
.printData
.SetPrintMode(wx
.PRINT_MODE_PRINTER
)
1492 pdd
= wx
.PrintDialogData(self
.printData
)
1493 printer
= wx
.Printer(pdd
)
1494 printer
.Print(view
.GetFrame(), printout
)
1497 def OnPrintSetup(self
, event
):
1499 Presents the print setup dialog.
1501 view
= self
.GetCurrentView()
1503 parentWin
= view
.GetFrame()
1505 parentWin
= wx
.GetApp().GetTopWindow()
1507 if not hasattr(self
, "printData"):
1508 self
.printData
= wx
.PrintData()
1509 self
.printData
.SetPaperId(wx
.PAPER_LETTER
)
1511 data
= wx
.PrintDialogData(self
.printData
)
1512 printDialog
= wx
.PrintDialog(parentWin
, data
)
1513 printDialog
.GetPrintDialogData().SetSetupDialog(True)
1514 printDialog
.ShowModal()
1516 # this makes a copy of the wx.PrintData instead of just saving
1517 # a reference to the one inside the PrintDialogData that will
1518 # be destroyed when the dialog is destroyed
1519 self
.printData
= wx
.PrintData(printDialog
.GetPrintDialogData().GetPrintData())
1521 printDialog
.Destroy()
1524 def OnPreview(self
, event
):
1526 Previews the current document by calling its View's OnCreatePrintout
1529 view
= self
.GetCurrentView()
1533 printout
= view
.OnCreatePrintout()
1535 if not hasattr(self
, "printData"):
1536 self
.printData
= wx
.PrintData()
1537 self
.printData
.SetPaperId(wx
.PAPER_LETTER
)
1538 self
.printData
.SetPrintMode(wx
.PRINT_MODE_PREVIEW
)
1540 data
= wx
.PrintDialogData(self
.printData
)
1541 # Pass two printout objects: for preview, and possible printing.
1542 preview
= wx
.PrintPreview(printout
, view
.OnCreatePrintout(), data
)
1543 if not preview
.Ok():
1544 wx
.MessageBox(_("Unable to display print preview."))
1546 # 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.
1547 mimicFrame
= wx
.GetApp().GetTopWindow()
1548 frame
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize())
1549 frame
.SetIcon(mimicFrame
.GetIcon())
1550 frame
.SetTitle(_("%s - %s - Preview") % (mimicFrame
.GetTitle(), view
.GetDocument().GetPrintableName()))
1555 def OnUndo(self
, event
):
1557 Issues an Undo command to the current document's command processor.
1559 doc
= self
.GetCurrentDocument()
1562 if doc
.GetCommandProcessor():
1563 doc
.GetCommandProcessor().Undo()
1566 def OnRedo(self
, event
):
1568 Issues a Redo command to the current document's command processor.
1570 doc
= self
.GetCurrentDocument()
1573 if doc
.GetCommandProcessor():
1574 doc
.GetCommandProcessor().Redo()
1577 def OnUpdateFileOpen(self
, event
):
1579 Updates the user interface for the File Open command.
1584 def OnUpdateFileClose(self
, event
):
1586 Updates the user interface for the File Close command.
1588 event
.Enable(self
.GetCurrentDocument() != None)
1591 def OnUpdateFileCloseAll(self
, event
):
1593 Updates the user interface for the File Close All command.
1595 event
.Enable(self
.GetCurrentDocument() != None)
1598 def OnUpdateFileRevert(self
, event
):
1600 Updates the user interface for the File Revert command.
1602 event
.Enable(self
.GetCurrentDocument() != None)
1605 def OnUpdateFileNew(self
, event
):
1607 Updates the user interface for the File New command.
1612 def OnUpdateFileSave(self
, event
):
1614 Updates the user interface for the File Save command.
1616 doc
= self
.GetCurrentDocument()
1617 event
.Enable(doc
!= None and doc
.IsModified())
1620 def OnUpdateFileSaveAs(self
, event
):
1622 Updates the user interface for the File Save As command.
1624 event
.Enable(self
.GetCurrentDocument() != None and self
.GetCurrentDocument().GetWriteable())
1627 def OnUpdateUndo(self
, event
):
1629 Updates the user interface for the Undo command.
1631 doc
= self
.GetCurrentDocument()
1632 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo())
1633 if doc
and doc
.GetCommandProcessor():
1634 doc
.GetCommandProcessor().SetMenuStrings()
1636 event
.SetText(_("&Undo\tCtrl+Z"))
1639 def OnUpdateRedo(self
, event
):
1641 Updates the user interface for the Redo command.
1643 doc
= self
.GetCurrentDocument()
1644 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo())
1645 if doc
and doc
.GetCommandProcessor():
1646 doc
.GetCommandProcessor().SetMenuStrings()
1648 event
.SetText(_("&Redo\tCtrl+Y"))
1651 def OnUpdatePrint(self
, event
):
1653 Updates the user interface for the Print command.
1655 event
.Enable(self
.GetCurrentDocument() != None)
1658 def OnUpdatePrintSetup(self
, event
):
1660 Updates the user interface for the Print Setup command.
1665 def OnUpdatePreview(self
, event
):
1667 Updates the user interface for the Print Preview command.
1669 event
.Enable(self
.GetCurrentDocument() != None)
1672 def GetCurrentView(self
):
1674 Returns the currently active view.
1676 if self
._currentView
:
1677 return self
._currentView
1678 if len(self
._docs
) == 1:
1679 return self
._docs
[0].GetFirstView()
1683 def GetLastActiveView(self
):
1685 Returns the last active view. This is used in the SDI framework where dialogs can be mistaken for a view
1686 and causes the framework to deactivete the current view. This happens when something like a custom dialog box used
1687 to operate on the current view is shown.
1689 if len(self
._docs
) >= 1:
1690 return self
._lastActiveView
1695 def ProcessEvent(self
, event
):
1697 Processes an event, searching event tables and calling zero or more
1698 suitable event handler function(s). Note that the ProcessEvent
1699 method is called from the wxPython docview framework directly since
1700 wxPython does not have a virtual ProcessEvent function.
1702 view
= self
.GetCurrentView()
1704 if view
.ProcessEvent(event
):
1707 if id == wx
.ID_OPEN
:
1708 self
.OnFileOpen(event
)
1710 elif id == wx
.ID_CLOSE
:
1711 self
.OnFileClose(event
)
1713 elif id == wx
.ID_CLOSE_ALL
:
1714 self
.OnFileCloseAll(event
)
1716 elif id == wx
.ID_REVERT
:
1717 self
.OnFileRevert(event
)
1719 elif id == wx
.ID_NEW
:
1720 self
.OnFileNew(event
)
1722 elif id == wx
.ID_SAVE
:
1723 self
.OnFileSave(event
)
1725 elif id == wx
.ID_SAVEAS
:
1726 self
.OnFileSaveAs(event
)
1728 elif id == wx
.ID_UNDO
:
1731 elif id == wx
.ID_REDO
:
1734 elif id == wx
.ID_PRINT
:
1737 elif id == wx
.ID_PRINT_SETUP
:
1738 self
.OnPrintSetup(event
)
1740 elif id == wx
.ID_PREVIEW
:
1741 self
.OnPreview(event
)
1747 def ProcessUpdateUIEvent(self
, event
):
1749 Processes a UI event, searching event tables and calling zero or more
1750 suitable event handler function(s). Note that the ProcessEvent
1751 method is called from the wxPython docview framework directly since
1752 wxPython does not have a virtual ProcessEvent function.
1755 view
= self
.GetCurrentView()
1757 if view
.ProcessUpdateUIEvent(event
):
1759 if id == wx
.ID_OPEN
:
1760 self
.OnUpdateFileOpen(event
)
1762 elif id == wx
.ID_CLOSE
:
1763 self
.OnUpdateFileClose(event
)
1765 elif id == wx
.ID_CLOSE_ALL
:
1766 self
.OnUpdateFileCloseAll(event
)
1768 elif id == wx
.ID_REVERT
:
1769 self
.OnUpdateFileRevert(event
)
1771 elif id == wx
.ID_NEW
:
1772 self
.OnUpdateFileNew(event
)
1774 elif id == wx
.ID_SAVE
:
1775 self
.OnUpdateFileSave(event
)
1777 elif id == wx
.ID_SAVEAS
:
1778 self
.OnUpdateFileSaveAs(event
)
1780 elif id == wx
.ID_UNDO
:
1781 self
.OnUpdateUndo(event
)
1783 elif id == wx
.ID_REDO
:
1784 self
.OnUpdateRedo(event
)
1786 elif id == wx
.ID_PRINT
:
1787 self
.OnUpdatePrint(event
)
1789 elif id == wx
.ID_PRINT_SETUP
:
1790 self
.OnUpdatePrintSetup(event
)
1792 elif id == wx
.ID_PREVIEW
:
1793 self
.OnUpdatePreview(event
)
1799 def CreateDocument(self
, path
, flags
=0):
1801 Creates a new document in a manner determined by the flags parameter,
1804 wx.lib.docview.DOC_NEW Creates a fresh document.
1805 wx.lib.docview.DOC_SILENT Silently loads the given document file.
1807 If wx.lib.docview.DOC_NEW is present, a new document will be created and returned,
1808 possibly after asking the user for a template to use if there is more
1809 than one document template. If wx.lib.docview.DOC_SILENT is present, a new document
1810 will be created and the given file loaded into it. If neither of these
1811 flags is present, the user will be presented with a file selector for
1812 the file to load, and the template to use will be determined by the
1813 extension (Windows) or by popping up a template choice list (other
1816 If the maximum number of documents has been reached, this function
1817 will delete the oldest currently loaded document before creating a new
1820 wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE
1821 and wx.lib.docview.DOC_NO_VIEW flag.
1823 if wx.lib.docview.DOC_OPEN_ONCE is present, trying to open the same file multiple
1824 times will just return the same document.
1825 if wx.lib.docview.DOC_NO_VIEW is present, opening a file will generate the document,
1826 but not generate a corresponding view.
1829 for temp
in self
._templates
:
1830 if temp
.IsVisible():
1831 templates
.append(temp
)
1832 if len(templates
) == 0:
1835 if len(self
.GetDocuments()) >= self
._maxDocsOpen
:
1836 doc
= self
.GetDocuments()[0]
1837 if not self
.CloseDocument(doc
, False):
1841 for temp
in templates
[:]:
1842 if not temp
.IsNewable():
1843 templates
.remove(temp
)
1844 if len(templates
) == 1:
1847 temp
= self
.SelectDocumentType(templates
)
1849 newDoc
= temp
.CreateDocument(path
, flags
)
1851 newDoc
.SetDocumentName(temp
.GetDocumentName())
1852 newDoc
.SetDocumentTemplate(temp
)
1853 newDoc
.OnNewDocument()
1858 if path
and flags
& DOC_SILENT
:
1859 temp
= self
.FindTemplateForPath(path
)
1861 temp
, path
= self
.SelectDocumentPath(templates
, path
, flags
)
1864 if path
and self
.GetFlags() & DOC_OPEN_ONCE
:
1865 for document
in self
._docs
:
1866 if document
.GetFilename() and os
.path
.normcase(document
.GetFilename()) == os
.path
.normcase(path
):
1867 """ check for file modification outside of application """
1868 if os
.path
.exists(path
) and os
.path
.getmtime(path
) != document
.GetDocumentModificationDate():
1869 msgTitle
= wx
.GetApp().GetAppName()
1871 msgTitle
= _("Warning")
1872 shortName
= document
.GetPrintableName()
1873 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Reload '%s' from file system?") % (shortName
, msgTitle
, shortName
),
1875 wx
.YES_NO | wx
.ICON_QUESTION
,
1876 self
.FindSuitableParent())
1878 if not self
.CloseDocument(document
, False):
1879 wx
.MessageBox(_("Couldn't reload '%s'. Unable to close current '%s'.") % (shortName
, shortName
))
1881 return self
.CreateDocument(path
, flags
)
1882 elif res
== wx
.NO
: # don't ask again
1883 document
.SetDocumentModificationDate()
1885 firstView
= document
.GetFirstView()
1886 if not firstView
and not (flags
& DOC_NO_VIEW
):
1887 document
.GetDocumentTemplate().CreateView(document
, flags
)
1888 document
.UpdateAllViews()
1889 firstView
= document
.GetFirstView()
1891 if firstView
and firstView
.GetFrame() and not (flags
& DOC_NO_VIEW
):
1892 firstView
.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
1893 if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
1894 firstView
.GetFrame().Iconize(False)
1898 newDoc
= temp
.CreateDocument(path
, flags
)
1900 newDoc
.SetDocumentName(temp
.GetDocumentName())
1901 newDoc
.SetDocumentTemplate(temp
)
1902 if not newDoc
.OnOpenDocument(path
):
1903 newDoc
.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1904 frame
= newDoc
.GetFirstView().GetFrame()
1906 frame
.Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
1908 self
.AddFileToHistory(path
)
1914 def CreateView(self
, doc
, flags
=0):
1916 Creates a new view for the given document. If more than one view is
1917 allowed for the document (by virtue of multiple templates mentioning
1918 the same document type), a choice of view is presented to the user.
1921 for temp
in self
._templates
:
1922 if temp
.IsVisible():
1923 if temp
.GetDocumentName() == doc
.GetDocumentName():
1924 templates
.append(temp
)
1925 if len(templates
) == 0:
1928 if len(templates
) == 1:
1930 view
= temp
.CreateView(doc
, flags
)
1932 view
.SetViewName(temp
.GetViewName())
1935 temp
= SelectViewType(templates
)
1937 view
= temp
.CreateView(doc
, flags
)
1939 view
.SetViewName(temp
.GetViewName())
1945 def DeleteTemplate(self
, template
, flags
):
1947 Placeholder, not yet implemented in wxWindows.
1952 def FlushDoc(self
, doc
):
1954 Placeholder, not yet implemented in wxWindows.
1959 def MatchTemplate(self
, path
):
1961 Placeholder, not yet implemented in wxWindows.
1966 def GetCurrentDocument(self
):
1968 Returns the document associated with the currently active view (if any).
1970 view
= self
.GetCurrentView()
1972 return view
.GetDocument()
1977 def MakeDefaultName(self
):
1979 Returns a suitable default name. This is implemented by appending an
1980 integer counter to the string "Untitled" and incrementing the counter.
1982 name
= _("Untitled %d") % self
._defaultDocumentNameCounter
1983 self
._defaultDocumentNameCounter
= self
._defaultDocumentNameCounter
+ 1
1987 def MakeFrameTitle(self
):
1989 Returns a suitable title for a document frame. This is implemented by
1990 appending the document name to the application name.
1992 appName
= wx
.GetApp().GetAppName()
1996 docName
= doc
.GetPrintableName()
1997 title
= docName
+ _(" - ") + appName
2001 def AddFileToHistory(self
, fileName
):
2003 Adds a file to the file history list, if we have a pointer to an
2004 appropriate file menu.
2006 if self
._fileHistory
:
2007 self
._fileHistory
.AddFileToHistory(fileName
)
2010 def RemoveFileFromHistory(self
, i
):
2012 Removes a file from the file history list, if we have a pointer to an
2013 appropriate file menu.
2015 if self
._fileHistory
:
2016 self
._fileHistory
.RemoveFileFromHistory(i
)
2019 def GetFileHistory(self
):
2021 Returns the file history.
2023 return self
._fileHistory
2026 def GetHistoryFile(self
, i
):
2028 Returns the file at index i from the file history.
2030 if self
._fileHistory
:
2031 return self
._fileHistory
.GetHistoryFile(i
)
2036 def FileHistoryUseMenu(self
, menu
):
2038 Use this menu for appending recently-visited document filenames, for
2039 convenient access. Calling this function with a valid menu enables the
2040 history list functionality.
2042 Note that you can add multiple menus using this function, to be
2043 managed by the file history object.
2045 if self
._fileHistory
:
2046 self
._fileHistory
.UseMenu(menu
)
2049 def FileHistoryRemoveMenu(self
, menu
):
2051 Removes the given menu from the list of menus managed by the file
2054 if self
._fileHistory
:
2055 self
._fileHistory
.RemoveMenu(menu
)
2058 def FileHistoryLoad(self
, config
):
2060 Loads the file history from a config object.
2062 if self
._fileHistory
:
2063 self
._fileHistory
.Load(config
)
2066 def FileHistorySave(self
, config
):
2068 Saves the file history into a config object. This must be called
2069 explicitly by the application.
2071 if self
._fileHistory
:
2072 self
._fileHistory
.Save(config
)
2075 def FileHistoryAddFilesToMenu(self
, menu
=None):
2077 Appends the files in the history list, to all menus managed by the
2078 file history object.
2080 If menu is specified, appends the files in the history list to the
2083 if self
._fileHistory
:
2085 self
._fileHistory
.AddFilesToThisMenu(menu
)
2087 self
._fileHistory
.AddFilesToMenu()
2090 def GetHistoryFilesCount(self
):
2092 Returns the number of files currently stored in the file history.
2094 if self
._fileHistory
:
2095 return self
._fileHistory
.GetNoHistoryFiles()
2100 def FindTemplateForPath(self
, path
):
2102 Given a path, try to find template that matches the extension. This is
2103 only an approximate method of finding a template for creating a
2106 Note this wxPython verson looks for and returns a default template if no specific template is found.
2109 for temp
in self
._templates
:
2110 if temp
.FileMatchesTemplate(path
):
2113 if "*.*" in temp
.GetFileFilter():
2118 def FindSuitableParent(self
):
2120 Returns a parent frame or dialog, either the frame with the current
2121 focus or if there is no current focus the application's top frame.
2123 parent
= wx
.GetApp().GetTopWindow()
2124 focusWindow
= wx
.Window_FindFocus()
2126 while focusWindow
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
):
2127 focusWindow
= focusWindow
.GetParent()
2129 parent
= focusWindow
2133 def SelectDocumentPath(self
, templates
, flags
, save
):
2135 Under Windows, pops up a file selector with a list of filters
2136 corresponding to document templates. The wxDocTemplate corresponding
2137 to the selected file's extension is returned.
2139 On other platforms, if there is more than one document template a
2140 choice list is popped up, followed by a file selector.
2142 This function is used in wxDocManager.CreateDocument.
2144 if wx
.Platform
== "__WXMSW__" or wx
.Platform
== "__WXGTK__" or wx
.Platform
== "__WXMAC__":
2146 for temp
in templates
:
2147 if temp
.IsVisible():
2149 descr
= descr
+ _('|')
2150 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
2151 descr
= _("All (*.*)|*.*|%s") % descr
# spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
2155 dlg
= wx
.FileDialog(self
.FindSuitableParent(),
2158 style
=wx
.OPEN|wx
.FILE_MUST_EXIST|wx
.CHANGE_DIR
)
2159 # dlg.CenterOnParent() # wxBug: caused crash with wx.FileDialog
2160 if dlg
.ShowModal() == wx
.ID_OK
:
2161 path
= dlg
.GetPath()
2167 theTemplate
= self
.FindTemplateForPath(path
)
2168 return (theTemplate
, path
)
2173 def OnOpenFileFailure(self
):
2175 Called when there is an error opening a file.
2180 def SelectDocumentType(self
, temps
, sort
=False):
2182 Returns a document template by asking the user (if there is more than
2183 one template). This function is used in wxDocManager.CreateDocument.
2187 templates - list of templates from which to choose a desired template.
2189 sort - If more than one template is passed in in templates, then this
2190 parameter indicates whether the list of templates that the user will
2191 have to choose from is sorted or not when shown the choice box dialog.
2196 if temp
.IsVisible():
2198 for temp2
in templates
:
2199 if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName():
2203 templates
.append(temp
)
2205 if len(templates
) == 0:
2207 elif len(templates
) == 1:
2212 return cmp(a
.GetDescription(), b
.GetDescription())
2213 templates
.sort(tempcmp
)
2216 for temp
in templates
:
2217 strings
.append(temp
.GetDescription())
2219 res
= wx
.GetSingleChoiceIndex(_("Select a document type:"),
2222 self
.FindSuitableParent())
2225 return templates
[res
]
2228 def SelectViewType(self
, temps
, sort
=False):
2230 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.
2235 if temp
.IsVisible() and temp
.GetViewTypeName():
2236 if temp
.GetViewName() not in strings
:
2237 templates
.append(temp
)
2238 strings
.append(temp
.GetViewTypeName())
2240 if len(templates
) == 0:
2242 elif len(templates
) == 1:
2247 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName())
2248 templates
.sort(tempcmp
)
2250 res
= wx
.GetSingleChoiceIndex(_("Select a document view:"),
2253 self
.FindSuitableParent())
2256 return templates
[res
]
2259 def GetTemplates(self
):
2261 Returns the document manager's template list. This method has been added to
2262 wxPython and is not in wxWindows.
2264 return self
._templates
2267 def AssociateTemplate(self
, docTemplate
):
2269 Adds the template to the document manager's template list.
2271 if docTemplate
not in self
._templates
:
2272 self
._templates
.append(docTemplate
)
2275 def DisassociateTemplate(self
, docTemplate
):
2277 Removes the template from the list of templates.
2279 self
._templates
.remove(docTemplate
)
2282 def AddDocument(self
, document
):
2284 Adds the document to the list of documents.
2286 if document
not in self
._docs
:
2287 self
._docs
.append(document
)
2290 def RemoveDocument(self
, doc
):
2292 Removes the document from the list of documents.
2294 if doc
in self
._docs
:
2295 self
._docs
.remove(doc
)
2298 def ActivateView(self
, view
, activate
=True, deleting
=False):
2300 Sets the current view.
2303 self
._currentView
= view
2304 self
._lastActiveView
= view
2306 self
._currentView
= None
2309 def GetMaxDocsOpen(self
):
2311 Returns the number of documents that can be open simultaneously.
2313 return self
._maxDocsOpen
2316 def SetMaxDocsOpen(self
, maxDocsOpen
):
2318 Sets the maximum number of documents that can be open at a time. By
2319 default, this is 10,000. If you set it to 1, existing documents will
2320 be saved and deleted when the user tries to open or create a new one
2321 (similar to the behaviour of Windows Write, for example). Allowing
2322 multiple documents gives behaviour more akin to MS Word and other
2323 Multiple Document Interface applications.
2325 self
._maxDocsOpen
= maxDocsOpen
2328 def GetDocuments(self
):
2330 Returns the list of documents.
2335 class DocParentFrame(wx
.Frame
):
2337 The wxDocParentFrame class provides a default top-level frame for
2338 applications using the document/view framework. This class can only be
2339 used for SDI (not MDI) parent frames.
2341 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates
2345 def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2347 Constructor. Note that the event table must be rebuilt for the
2348 frame since the EvtHandler is not virtual.
2350 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
)
2351 self
._docManager
= manager
2353 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2355 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2356 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2358 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2359 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2360 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2361 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2362 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2363 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2364 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2365 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2366 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2367 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2368 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2369 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2371 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2372 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2373 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2374 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2375 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2376 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2377 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2378 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2379 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2380 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2381 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2382 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2385 def ProcessEvent(self
, event
):
2387 Processes an event, searching event tables and calling zero or more
2388 suitable event handler function(s). Note that the ProcessEvent
2389 method is called from the wxPython docview framework directly since
2390 wxPython does not have a virtual ProcessEvent function.
2392 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2395 def ProcessUpdateUIEvent(self
, event
):
2397 Processes a UI event, searching event tables and calling zero or more
2398 suitable event handler function(s). Note that the ProcessEvent
2399 method is called from the wxPython docview framework directly since
2400 wxPython does not have a virtual ProcessEvent function.
2402 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2405 def OnExit(self
, event
):
2407 Called when File/Exit is chosen and closes the window.
2412 def OnMRUFile(self
, event
):
2414 Opens the appropriate file when it is selected from the file history
2417 n
= event
.GetId() - wx
.ID_FILE1
2418 filename
= self
._docManager
.GetHistoryFile(n
)
2420 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2422 self
._docManager
.RemoveFileFromHistory(n
)
2423 msgTitle
= wx
.GetApp().GetAppName()
2425 msgTitle
= _("File Error")
2426 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),
2428 wx
.OK | wx
.ICON_EXCLAMATION
,
2432 def OnCloseWindow(self
, event
):
2434 Deletes all views and documents. If no user input cancelled the
2435 operation, the frame will be destroyed and the application will exit.
2437 if self
._docManager
.Clear(not event
.CanVeto()):
2443 class DocChildFrame(wx
.Frame
):
2445 The wxDocChildFrame class provides a default frame for displaying
2446 documents on separate windows. This class can only be used for SDI (not
2449 The class is part of the document/view framework supported by wxWindows,
2450 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2455 def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2457 Constructor. Note that the event table must be rebuilt for the
2458 frame since the EvtHandler is not virtual.
2460 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2461 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2462 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2463 self
._childDocument
= doc
2464 self
._childView
= view
2468 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2469 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2470 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2471 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2472 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2473 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2474 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2475 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2476 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2477 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2478 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2479 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2481 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2482 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2483 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2484 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2485 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2486 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2487 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2488 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2489 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2490 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2491 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2492 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2495 def ProcessEvent(self
, event
):
2497 Processes an event, searching event tables and calling zero or more
2498 suitable event handler function(s). Note that the ProcessEvent
2499 method is called from the wxPython docview framework directly since
2500 wxPython does not have a virtual ProcessEvent function.
2503 self
._childView
.Activate(True)
2504 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2505 # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows
2506 # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
2507 if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2515 def ProcessUpdateUIEvent(self
, event
):
2517 Processes a UI event, searching event tables and calling zero or more
2518 suitable event handler function(s). Note that the ProcessEvent
2519 method is called from the wxPython docview framework directly since
2520 wxPython does not have a virtual ProcessEvent function.
2522 if self
.GetParent():
2523 self
.GetParent().ProcessUpdateUIEvent(event
)
2528 def OnActivate(self
, event
):
2530 Activates the current view.
2532 # wx.Frame.OnActivate(event) This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead
2534 self
._childView
.Activate(event
.GetActive())
2537 def OnCloseWindow(self
, event
):
2539 Closes and deletes the current view and document.
2543 if not event
.CanVeto():
2546 ans
= self
._childView
.Close(deleteWindow
= False)
2549 self
._childView
.Activate(False)
2550 self
._childView
.Destroy()
2551 self
._childView
= None
2552 if self
._childDocument
:
2553 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2554 self
._childDocument
= None
2562 def GetDocument(self
):
2564 Returns the document associated with this frame.
2566 return self
._childDocument
2569 def SetDocument(self
, document
):
2571 Sets the document for this frame.
2573 self
._childDocument
= document
2578 Returns the view associated with this frame.
2580 return self
._childView
2583 def SetView(self
, view
):
2585 Sets the view for this frame.
2587 self
._childView
= view
2590 class DocMDIParentFrame(wx
.MDIParentFrame
):
2592 The wxDocMDIParentFrame class provides a default top-level frame for
2593 applications using the document/view framework. This class can only be
2594 used for MDI parent frames.
2596 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2601 def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2603 Constructor. Note that the event table must be rebuilt for the
2604 frame since the EvtHandler is not virtual.
2606 wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2607 self
._docManager
= manager
2609 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2611 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2612 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2614 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2615 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2616 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2617 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2618 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2619 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2620 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2621 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2622 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2623 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2624 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2625 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2627 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2628 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2629 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2630 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2631 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2632 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2633 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2634 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2635 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2636 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2637 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2638 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2641 def ProcessEvent(self
, event
):
2643 Processes an event, searching event tables and calling zero or more
2644 suitable event handler function(s). Note that the ProcessEvent
2645 method is called from the wxPython docview framework directly since
2646 wxPython does not have a virtual ProcessEvent function.
2648 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2651 def ProcessUpdateUIEvent(self
, event
):
2653 Processes a UI event, searching event tables and calling zero or more
2654 suitable event handler function(s). Note that the ProcessEvent
2655 method is called from the wxPython docview framework directly since
2656 wxPython does not have a virtual ProcessEvent function.
2658 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2661 def OnExit(self
, event
):
2663 Called when File/Exit is chosen and closes the window.
2668 def OnMRUFile(self
, event
):
2670 Opens the appropriate file when it is selected from the file history
2673 n
= event
.GetId() - wx
.ID_FILE1
2674 filename
= self
._docManager
.GetHistoryFile(n
)
2676 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2678 self
._docManager
.RemoveFileFromHistory(n
)
2679 msgTitle
= wx
.GetApp().GetAppName()
2681 msgTitle
= _("File Error")
2682 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),
2684 wx
.OK | wx
.ICON_EXCLAMATION
,
2688 def OnCloseWindow(self
, event
):
2690 Deletes all views and documents. If no user input cancelled the
2691 operation, the frame will be destroyed and the application will exit.
2693 if self
._docManager
.Clear(not event
.CanVeto()):
2699 class DocMDIChildFrame(wx
.MDIChildFrame
):
2701 The wxDocMDIChildFrame class provides a default frame for displaying
2702 documents on separate windows. This class can only be used for MDI child
2705 The class is part of the document/view framework supported by wxWindows,
2706 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2711 def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2713 Constructor. Note that the event table must be rebuilt for the
2714 frame since the EvtHandler is not virtual.
2716 wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2717 self
._childDocument
= doc
2718 self
._childView
= view
2721 # self.Create(doc, view, frame, id, title, pos, size, style, name)
2722 self
._activeEvent
= None
2724 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2725 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2727 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
2728 mdiChildren
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren())
2729 if len(mdiChildren
) == 1:
2733 ## # Couldn't get this to work, but seems to work fine with single stage construction
2734 ## def Create(self, doc, view, frame, id, title, pos, size, style, name):
2735 ## self._childDocument = doc
2736 ## self._childView = view
2737 ## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
2739 ## view.SetFrame(self)
2745 def Activate(self
): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
2747 Activates the current view.
2750 self
._childView
.Activate(True)
2753 def ProcessEvent(event
):
2755 Processes an event, searching event tables and calling zero or more
2756 suitable event handler function(s). Note that the ProcessEvent
2757 method is called from the wxPython docview framework directly since
2758 wxPython does not have a virtual ProcessEvent function.
2760 if self
._activeEvent
== event
:
2763 self
._activeEvent
= event
# Break recursion loops
2766 self
._childView
.Activate(True)
2768 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2769 if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2776 self
._activeEvent
= None
2780 def OnActivate(self
, event
):
2782 Sets the currently active view to be the frame's view. You may need to
2783 override (but still call) this function in order to set the keyboard
2784 focus for your subwindow.
2786 if self
._activated
!= 0:
2788 self
._activated
+= 1
2789 wx
.MDIChildFrame
.Activate(self
)
2790 if event
.GetActive() and self
._childView
:
2791 self
._childView
.Activate(event
.GetActive())
2794 def OnCloseWindow(self
, event
):
2796 Closes and deletes the current view and document.
2800 if not event
.CanVeto():
2803 ans
= self
._childView
.Close(deleteWindow
= False)
2806 self
._childView
.Activate(False)
2807 self
._childView
.Destroy()
2808 self
._childView
= None
2809 if self
._childDocument
: # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2810 self
._childDocument
.DeleteContents()
2811 if self
._childDocument
.GetDocumentManager():
2812 self
._childDocument
.GetDocumentManager().RemoveDocument(self
._childDocument
)
2813 self
._childDocument
= None
2821 def GetDocument(self
):
2823 Returns the document associated with this frame.
2825 return self
._childDocument
2828 def SetDocument(self
, document
):
2830 Sets the document for this frame.
2832 self
._childDocument
= document
2837 Returns the view associated with this frame.
2839 return self
._childView
2842 def SetView(self
, view
):
2844 Sets the view for this frame.
2846 self
._childView
= view
2849 class DocPrintout(wx
.Printout
):
2851 DocPrintout is a default Printout that prints the first page of a document
2856 def __init__(self
, view
, title
="Printout"):
2860 wx
.Printout
.__init
__(self
, title
)
2861 self
._printoutView
= view
2866 Returns the DocPrintout's view.
2868 return self
._printoutView
2871 def OnPrintPage(self
, page
):
2873 Prints the first page of the view.
2876 ppiScreenX
, ppiScreenY
= self
.GetPPIScreen()
2877 ppiPrinterX
, ppiPrinterY
= self
.GetPPIPrinter()
2878 scale
= ppiPrinterX
/ppiScreenX
2880 pageWidth
, pageHeight
= self
.GetPageSizePixels()
2881 overallScale
= scale
* w
/ pageWidth
2882 dc
.SetUserScale(overallScale
, overallScale
)
2883 if self
._printoutView
:
2884 self
._printoutView
.OnDraw(dc
)
2888 def HasPage(self
, pageNum
):
2890 Indicates that the DocPrintout only has a single page.
2895 def OnBeginDocument(self
, startPage
, endPage
):
2897 Not quite sure why this was overridden, but it was in wxWindows! :)
2899 if not wx
.Printout
.OnBeginDocument(self
, startPage
, endPage
):
2904 def GetPageInfo(self
):
2906 Indicates that the DocPrintout only has a single page.
2912 return (minPage
, maxPage
, selPageFrom
, selPageTo
)
2915 #----------------------------------------------------------------------
2917 #----------------------------------------------------------------------
2919 class Command(wx
.Object
):
2921 wxCommand is a base class for modelling an application command, which is
2922 an action usually performed by selecting a menu item, pressing a toolbar
2923 button or any other means provided by the application to change the data
2928 def __init__(self
, canUndo
= False, name
= None):
2930 Constructor. wxCommand is an abstract class, so you will need to
2931 derive a new class and call this constructor from your own constructor.
2933 canUndo tells the command processor whether this command is undo-able.
2934 You can achieve the same functionality by overriding the CanUndo member
2935 function (if for example the criteria for undoability is context-
2938 name must be supplied for the command processor to display the command
2939 name in the application's edit menu.
2941 self
._canUndo
= canUndo
2947 Returns true if the command can be undone, false otherwise.
2949 return self
._canUndo
2954 Returns the command name.
2961 Override this member function to execute the appropriate action when
2962 called. Return true to indicate that the action has taken place, false
2963 otherwise. Returning false will indicate to the command processor that
2964 the action is not undoable and should not be added to the command
2972 Override this member function to un-execute a previous Do. Return true
2973 to indicate that the action has taken place, false otherwise. Returning
2974 false will indicate to the command processor that the action is not
2975 redoable and no change should be made to the command history.
2977 How you implement this command is totally application dependent, but
2978 typical strategies include:
2980 Perform an inverse operation on the last modified piece of data in the
2981 document. When redone, a copy of data stored in command is pasted back
2982 or some operation reapplied. This relies on the fact that you know the
2983 ordering of Undos; the user can never Undo at an arbitrary position in
2986 Restore the entire document state (perhaps using document
2987 transactioning). Potentially very inefficient, but possibly easier to
2988 code if the user interface and data are complex, and an 'inverse
2989 execute' operation is hard to write.
2994 class CommandProcessor(wx
.Object
):
2996 wxCommandProcessor is a class that maintains a history of wxCommands, with
2997 undo/redo functionality built-in. Derive a new class from this if you want
2998 different behaviour.
3002 def __init__(self
, maxCommands
=-1):
3004 Constructor. maxCommands may be set to a positive integer to limit
3005 the number of commands stored to it, otherwise (and by default) the
3006 list of commands can grow arbitrarily.
3008 self
._maxCommands
= maxCommands
3009 self
._editMenu
= None
3010 self
._undoAccelerator
= _("Ctrl+Z")
3011 self
._redoAccelerator
= _("Ctrl+Y")
3012 self
.ClearCommands()
3015 def _GetCurrentCommand(self
):
3016 if len(self
._commands
) == 0:
3019 return self
._commands
[-1]
3022 def _GetCurrentRedoCommand(self
):
3023 if len(self
._redoCommands
) == 0:
3026 return self
._redoCommands
[-1]
3029 def GetMaxCommands(self
):
3031 Returns the maximum number of commands that the command processor
3035 return self
._maxCommands
3038 def GetCommands(self
):
3040 Returns the list of commands.
3042 return self
._commands
3045 def ClearCommands(self
):
3047 Deletes all the commands in the list and sets the current command
3051 self
._redoCommands
= []
3054 def GetEditMenu(self
):
3056 Returns the edit menu associated with the command processor.
3058 return self
._editMenu
3061 def SetEditMenu(self
, menu
):
3063 Tells the command processor to update the Undo and Redo items on this
3064 menu as appropriate. Set this to NULL if the menu is about to be
3065 destroyed and command operations may still be performed, or the
3066 command processor may try to access an invalid pointer.
3068 self
._editMenu
= menu
3071 def GetUndoAccelerator(self
):
3073 Returns the string that will be appended to the Undo menu item.
3075 return self
._undoAccelerator
3078 def SetUndoAccelerator(self
, accel
):
3080 Sets the string that will be appended to the Redo menu item.
3082 self
._undoAccelerator
= accel
3085 def GetRedoAccelerator(self
):
3087 Returns the string that will be appended to the Redo menu item.
3089 return self
._redoAccelerator
3092 def SetRedoAccelerator(self
, accel
):
3094 Sets the string that will be appended to the Redo menu item.
3096 self
._redoAccelerator
= accel
3099 def SetEditMenu(self
, menu
):
3101 Tells the command processor to update the Undo and Redo items on this
3102 menu as appropriate. Set this to NULL if the menu is about to be
3103 destroyed and command operations may still be performed, or the
3104 command processor may try to access an invalid pointer.
3106 self
._editMenu
= menu
3109 def SetMenuStrings(self
):
3111 Sets the menu labels according to the currently set menu and the
3112 current command state.
3114 if self
.GetEditMenu() != None:
3115 undoCommand
= self
._GetCurrentCommand
()
3116 redoCommand
= self
._GetCurrentRedoCommand
()
3117 undoItem
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
)
3118 redoItem
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
)
3119 if self
.GetUndoAccelerator():
3120 undoAccel
= '\t' + self
.GetUndoAccelerator()
3123 if self
.GetRedoAccelerator():
3124 redoAccel
= '\t' + self
.GetRedoAccelerator()
3127 if undoCommand
and undoItem
and undoCommand
.CanUndo():
3128 undoItem
.SetText(_("&Undo ") + undoCommand
.GetName() + undoAccel
)
3129 #elif undoCommand and not undoCommand.CanUndo():
3130 # undoItem.SetText(_("Can't Undo") + undoAccel)
3132 undoItem
.SetText(_("&Undo" + undoAccel
))
3133 if redoCommand
and redoItem
:
3134 redoItem
.SetText(_("&Redo ") + redoCommand
.GetName() + redoAccel
)
3136 redoItem
.SetText(_("&Redo") + redoAccel
)
3141 Returns true if the currently-active command can be undone, false
3144 if self
._GetCurrentCommand
() == None:
3146 return self
._GetCurrentCommand
().CanUndo()
3151 Returns true if the currently-active command can be redone, false
3154 return self
._GetCurrentRedoCommand
() != None
3157 def Submit(self
, command
, storeIt
=True):
3159 Submits a new command to the command processor. The command processor
3160 calls wxCommand::Do to execute the command; if it succeeds, the
3161 command is stored in the history list, and the associated edit menu
3162 (if any) updated appropriately. If it fails, the command is deleted
3163 immediately. Once Submit has been called, the passed command should
3164 not be deleted directly by the application.
3166 storeIt indicates whether the successful command should be stored in
3171 del self
._redoCommands
[:]
3173 self
._commands
.append(command
)
3174 if self
._maxCommands
> -1:
3175 if len(self
._commands
) > self
._maxCommands
:
3176 del self
._commands
[0]
3182 Redoes the command just undone.
3184 cmd
= self
._GetCurrentRedoCommand
()
3189 self
._commands
.append(self
._redoCommands
.pop())
3195 Undoes the command just executed.
3197 cmd
= self
._GetCurrentCommand
()
3202 self
._redoCommands
.append(self
._commands
.pop())