1 #----------------------------------------------------------------------------
3 # Purpose: Port of the wxWindows docview classes
9 # Copyright: (c) 2003-2005 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
10 # License: wxWindows license
11 #----------------------------------------------------------------------------
21 #----------------------------------------------------------------------
23 #----------------------------------------------------------------------
30 DEFAULT_DOCMAN_FLAGS
= DOC_SDI
& DOC_OPEN_ONCE
33 TEMPLATE_INVISIBLE
= 2
34 DEFAULT_TEMPLATE_FLAGS
= TEMPLATE_VISIBLE
39 #----------------------------------------------------------------------
40 # Convenience functions from wxWindows used in docview
41 #----------------------------------------------------------------------
44 def FileNameFromPath(path
):
46 Returns the filename for a full path.
48 return os
.path
.split(path
)[1]
50 def FindExtension(path
):
52 Returns the extension of a filename for a full path.
54 return os
.path
.splitext(path
)[1].lower()
58 Returns True if the path exists.
60 return os
.path
.isfile(path
)
64 Returns the path of a full path without the filename.
66 return os
.path
.split(path
)[0]
69 #----------------------------------------------------------------------
70 # Document/View Classes
71 #----------------------------------------------------------------------
74 class Document(wx
.EvtHandler
):
76 The document class can be used to model an application's file-based data. It
77 is part of the document/view framework supported by wxWindows, and cooperates
78 with the wxView, wxDocTemplate and wxDocManager classes.
80 Note this wxPython version also keeps track of the modification date of the
81 document and if it changes on disk outside of the application, we will warn the
82 user before saving to avoid clobbering the file.
86 def __init__(self
, parent
= None):
88 Constructor. Define your own default constructor to initialize
89 application-specific data.
91 wx
.EvtHandler
.__init
__(self
)
93 self
._documentParent
= parent
94 self
._documentTemplate
= None
95 self
._commandProcessor
= None
96 self
._savedYet
= False
97 self
._writeable
= True
99 self
._documentTitle
= None
100 self
._documentFile
= None
101 self
._documentTypeName
= None
102 self
._documentModified
= False
103 self
._documentModificationDate
= None
104 self
._documentViews
= []
107 def ProcessEvent(self
, event
):
109 Processes an event, searching event tables and calling zero or more
110 suitable event handler function(s). Note that the ProcessEvent
111 method is called from the wxPython docview framework directly since
112 wxPython does not have a virtual ProcessEvent function.
117 def GetFilename(self
):
119 Gets the filename associated with this document, or "" if none is
122 return self
._documentFile
127 Gets the title for this document. The document title is used for an
128 associated frame (if any), and is usually constructed by the framework
131 return self
._documentTitle
134 def SetTitle(self
, title
):
136 Sets the title for this document. The document title is used for an
137 associated frame (if any), and is usually constructed by the framework
140 self
._documentTitle
= title
143 def GetDocumentName(self
):
145 The document type name given to the wxDocTemplate constructor,
146 copied to this document when the document is created. If several
147 document templates are created that use the same document type, this
148 variable is used in wxDocManager::CreateView to collate a list of
149 alternative view types that can be used on this kind of document.
151 return self
._documentTypeName
154 def SetDocumentName(self
, name
):
156 Sets he document type name given to the wxDocTemplate constructor,
157 copied to this document when the document is created. If several
158 document templates are created that use the same document type, this
159 variable is used in wxDocManager::CreateView to collate a list of
160 alternative view types that can be used on this kind of document. Do
161 not change the value of this variable.
163 self
._documentTypeName
= name
166 def GetDocumentSaved(self
):
168 Returns True if the document has been saved. This method has been
169 added to wxPython and is not in wxWindows.
171 return self
._savedYet
174 def SetDocumentSaved(self
, saved
= True):
176 Sets whether the document has been saved. This method has been
177 added to wxPython and is not in wxWindows.
179 self
._savedYet
= saved
182 def GetCommandProcessor(self
):
184 Returns the command processor associated with this document.
186 return self
._commandProcessor
189 def SetCommandProcessor(self
, processor
):
191 Sets the command processor to be used for this document. The document
192 will then be responsible for its deletion. Normally you should not
193 call this; override OnCreateCommandProcessor instead.
195 self
._commandProcessor
= processor
198 def IsModified(self
):
200 Returns true if the document has been modified since the last save,
201 false otherwise. You may need to override this if your document view
202 maintains its own record of being modified (for example if using
203 wxTextWindow to view and edit the document).
205 return self
._documentModified
208 def Modify(self
, modify
):
210 Call with true to mark the document as modified since the last save,
211 false otherwise. You may need to override this if your document view
212 maintains its own record of being modified (for example if using
213 xTextWindow to view and edit the document).
215 self
._documentModified
= modify
218 def SetDocumentModificationDate(self
, filename
=None):
220 Saves the file's last modification date.
221 This is used to check if the file has been modified outside of the application.
222 This method has been added to wxPython and is not in wxWindows.
225 filename
= self
.GetFilename()
226 self
._documentModificationDate
= os
.path
.getmtime(filename
)
227 print "debug print, file: %s set modification date to %s" % (filename
, self
._documentModificationDate
)
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 print "debug print, File %s: new mod date %s, original mod date %s" % (self
.GetFilename(), os
.path
.getmtime(self
.GetFilename()), self
.GetDocumentModificationDate())
369 msgTitle
= wx
.GetApp().GetAppName()
371 msgTitle
= _("Application")
372 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
374 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
375 self
.GetDocumentWindow())
381 else: # elif res == wx.CANCEL:
384 if not self
._documentFile
or not self
._savedYet
:
386 return self
.OnSaveDocument(self
._documentFile
)
391 Prompts the user for a file to save to, and then calls OnSaveDocument.
393 docTemplate
= self
.GetDocumentTemplate()
397 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
398 filename
= wx
.FileSelector(_("Save As"),
399 docTemplate
.GetDirectory(),
400 FileNameFromPath(self
.GetFilename()),
401 docTemplate
.GetDefaultExtension(),
403 flags
= wx
.SAVE | wx
.OVERWRITE_PROMPT
,
404 parent
= self
.GetDocumentWindow())
408 name
, ext
= os
.path
.splitext(filename
)
410 filename
+= '.' + docTemplate
.GetDefaultExtension()
412 self
.SetFilename(filename
)
413 self
.SetTitle(FileNameFromPath(filename
))
415 for view
in self
._documentViews
:
416 view
.OnChangeFilename()
418 if not self
.OnSaveDocument(filename
):
421 if docTemplate
.FileMatchesTemplate(filename
):
422 self
.GetDocumentManager().AddFileToHistory(filename
)
427 def OnSaveDocument(self
, filename
):
429 Constructs an output file for the given filename (which must
430 not be empty), and calls SaveObject. If SaveObject returns true, the
431 document is set to unmodified; otherwise, an error message box is
437 msgTitle
= wx
.GetApp().GetAppName()
439 msgTitle
= _("File Error")
441 backupFilename
= None
443 # if current file exists, move it to a safe place temporarily
444 if os
.path
.exists(filename
):
446 # Check if read-only.
447 if not os
.access(filename
, os
.W_OK
):
448 wx
.MessageBox("Could not save '%s'. No write permission to overwrite existing file." % FileNameFromPath(filename
),
450 wx
.OK | wx
.ICON_EXCLAMATION
,
451 self
.GetDocumentWindow())
455 backupFilename
= "%s.bak%s" % (filename
, i
)
456 while os
.path
.exists(backupFilename
):
458 backupFilename
= "%s.bak%s" % (filename
, i
)
459 os
.rename(filename
, backupFilename
)
461 fileObject
= file(filename
, 'w')
462 self
.SaveObject(fileObject
)
465 os
.remove(backupFilename
)
467 # save failed, restore old file
470 os
.rename(backupFilename
, filename
)
472 wx
.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
474 wx
.OK | wx
.ICON_EXCLAMATION
,
475 self
.GetDocumentWindow())
478 self
.SetFilename(filename
, True)
480 self
.SetDocumentModificationDate()
481 self
.SetDocumentSaved(True)
482 #if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
483 # wx.FileName(file).MacSetDefaultTypeAndCreator()
487 def OnOpenDocument(self
, filename
):
489 Constructs an input file for the given filename (which must not
490 be empty), and calls LoadObject. If LoadObject returns true, the
491 document is set to unmodified; otherwise, an error message box is
492 displayed. The document's views are notified that the filename has
493 changed, to give windows an opportunity to update their titles. All of
494 the document's views are then updated.
496 if not self
.OnSaveModified():
499 msgTitle
= wx
.GetApp().GetAppName()
501 msgTitle
= _("File Error")
503 fileObject
= file(filename
, 'r')
505 self
.LoadObject(fileObject
)
507 wx
.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
509 wx
.OK | wx
.ICON_EXCLAMATION
,
510 self
.GetDocumentWindow())
513 self
.SetFilename(filename
, True)
515 self
.SetDocumentModificationDate()
516 self
.SetDocumentSaved(True)
517 self
.UpdateAllViews()
521 def LoadObject(self
, file):
523 Override this function and call it from your own LoadObject before
524 loading your own data. LoadObject is called by the framework
525 automatically when the document contents need to be loaded.
527 Note that the wxPython version simply sends you a Python file object,
528 so you can use pickle.
533 def SaveObject(self
, file):
535 Override this function and call it from your own SaveObject before
536 saving your own data. SaveObject is called by the framework
537 automatically when the document contents need to be saved.
539 Note that the wxPython version simply sends you a Python file object,
540 so you can use pickle.
547 Override this function to revert the document to its last saved state.
552 def GetPrintableName(self
):
554 Copies a suitable document name into the supplied name buffer.
555 The default function uses the title, or if there is no title, uses the
556 filename; or if no filename, the string 'Untitled'.
558 if self
._documentTitle
:
559 return self
._documentTitle
560 elif self
._documentFile
:
561 return FileNameFromPath(self
._documentFile
)
566 def GetDocumentWindow(self
):
568 Intended to return a suitable window for using as a parent for
569 document-related dialog boxes. By default, uses the frame associated
572 if len(self
._documentViews
) > 0:
573 return self
._documentViews
[0].GetFrame()
575 return wx
.GetApp().GetTopWindow()
578 def OnCreateCommandProcessor(self
):
580 Override this function if you want a different (or no) command
581 processor to be created when the document is created. By default, it
582 returns an instance of wxCommandProcessor.
584 return CommandProcessor()
587 def OnSaveModified(self
):
589 If the document has been modified, prompts the user to ask if the
590 changes should be changed. If the user replies Yes, the Save function
591 is called. If No, the document is marked as unmodified and the
592 function succeeds. If Cancel, the function fails.
594 if not self
.IsModified():
597 """ check for file modification outside of application """
598 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
599 print "debug print, File %s: new mod date %s, original mod date %s" % (self
.GetFilename(), os
.path
.getmtime(self
.GetFilename()), self
.GetDocumentModificationDate())
600 msgTitle
= wx
.GetApp().GetAppName()
602 msgTitle
= _("Warning")
603 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
605 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
606 self
.GetDocumentWindow())
612 return wx
.lib
.docview
.Document
.Save(self
)
613 else: # elif res == wx.CANCEL:
616 msgTitle
= wx
.GetApp().GetAppName()
618 msgTitle
= _("Warning")
620 res
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(),
622 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
623 self
.GetDocumentWindow())
630 else: # elif res == wx.CANCEL:
636 Called by printing framework to draw the view.
641 def AddView(self
, view
):
643 If the view is not already in the list of views, adds the view and
644 calls OnChangedViewList.
646 if not view
in self
._documentViews
:
647 self
._documentViews
.append(view
)
648 self
.OnChangedViewList()
652 def RemoveView(self
, view
):
654 Removes the view from the document's list of views, and calls
657 if view
in self
._documentViews
:
658 self
._documentViews
.remove(view
)
659 self
.OnChangedViewList()
663 def OnCreate(self
, path
, flags
):
665 The default implementation calls DeleteContents (an empty
666 implementation) sets the modified flag to false. Override this to
667 supply additional behaviour when the document is closed with Close.
669 return self
.GetDocumentTemplate().CreateView(self
, flags
)
672 def OnChangedViewList(self
):
674 Called when a view is added to or deleted from this document. The
675 default implementation saves and deletes the document if no views
676 exist (the last one has just been removed).
678 if len(self
._documentViews
) == 0:
679 if self
.OnSaveModified():
680 pass # C version does a delete but Python will garbage collect
683 def UpdateAllViews(self
, sender
= None, hint
= None):
685 Updates all views. If sender is non-NULL, does not update this view.
686 hint represents optional information to allow a view to optimize its
689 for view
in self
._documentViews
:
691 view
.OnUpdate(sender
, hint
)
694 def NotifyClosing(self
):
696 Notifies the views that the document is going to close.
698 for view
in self
._documentViews
:
699 view
.OnClosingDocument()
702 def SetFilename(self
, filename
, notifyViews
= False):
704 Sets the filename for this document. Usually called by the framework.
705 If notifyViews is true, wxView.OnChangeFilename is called for all
708 self
._documentFile
= filename
710 for view
in self
._documentViews
:
711 view
.OnChangeFilename()
714 def GetWriteable(self
):
716 Returns true if the document can be written to its accociated file path.
717 This method has been added to wxPython and is not in wxWindows.
719 if not self
._writeable
:
721 if not self
._documentFile
: # Doesn't exist, do a save as
724 return os
.access(self
._documentFile
, os
.W_OK
)
727 def SetWriteable(self
, writeable
):
729 Set to False if the document can not be saved. This will disable the ID_SAVE_AS
730 event and is useful for custom documents that should not be saveable. The ID_SAVE
731 event can be disabled by never Modifying the document. This method has been added
732 to wxPython and is not in wxWindows.
734 self
._writeable
= writeable
737 class View(wx
.EvtHandler
):
739 The view class can be used to model the viewing and editing component of
740 an application's file-based data. It is part of the document/view
741 framework supported by wxWindows, and cooperates with the wxDocument,
742 wxDocTemplate and wxDocManager classes.
747 Constructor. Define your own default constructor to initialize
748 application-specific data.
750 wx
.EvtHandler
.__init
__(self
)
751 self
._viewDocument
= None
752 self
._viewFrame
= None
757 Destructor. Removes itself from the document's list of views.
759 if self
._viewDocument
:
760 self
._viewDocument
.RemoveView(self
)
761 wx
.EvtHandler
.Destroy(self
)
764 def ProcessEvent(self
, event
):
766 Processes an event, searching event tables and calling zero or more
767 suitable event handler function(s). Note that the ProcessEvent
768 method is called from the wxPython docview framework directly since
769 wxPython does not have a virtual ProcessEvent function.
771 if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
):
777 def ProcessUpdateUIEvent(self
, event
):
779 Processes a UI event, searching event tables and calling zero or more
780 suitable event handler function(s). Note that the ProcessEvent
781 method is called from the wxPython docview framework directly since
782 wxPython does not have a virtual ProcessEvent function.
787 def OnActivateView(self
, activate
, activeView
, deactiveView
):
789 Called when a view is activated by means of wxView::Activate. The
790 default implementation does nothing.
795 def OnClosingDocument(self
):
797 Override this to clean up the view when the document is being closed.
798 The default implementation does nothing.
803 def OnDraw(self
, dc
):
805 Override this to draw the view for the printing framework. The
806 default implementation does nothing.
811 def OnPrint(self
, dc
, info
):
813 Override this to print the view for the printing framework. The
814 default implementation calls View.OnDraw.
819 def OnUpdate(self
, sender
, hint
):
821 Called when the view should be updated. sender is a pointer to the
822 view that sent the update request, or NULL if no single view requested
823 the update (for instance, when the document is opened). hint is as yet
824 unused but may in future contain application-specific information for
825 making updating more efficient.
830 def OnChangeFilename(self
):
832 Called when the filename has changed. The default implementation
833 constructs a suitable title and sets the title of the view frame (if
837 appName
= wx
.GetApp().GetAppName()
838 if not self
.GetDocument():
844 if appName
and isinstance(self
.GetFrame(), DocChildFrame
): # Only need app name in title for SDI
845 title
= appName
+ _(" - ")
848 self
.GetFrame().SetTitle(title
+ self
.GetDocument().GetPrintableName())
851 def GetDocument(self
):
853 Returns the document associated with the view.
855 return self
._viewDocument
858 def SetDocument(self
, doc
):
860 Associates the given document with the view. Normally called by the
863 self
._viewDocument
= doc
868 def GetViewName(self
):
870 Gets the name associated with the view (passed to the wxDocTemplate
871 constructor). Not currently used by the framework.
873 return self
._viewTypeName
876 def SetViewName(self
, name
):
878 Sets the view type name. Should only be called by the framework.
880 self
._viewTypeName
= name
883 def Close(self
, deleteWindow
= True):
885 Closes the view by calling OnClose. If deleteWindow is true, this
886 function should delete the window associated with the view.
888 if self
.OnClose(deleteWindow
= deleteWindow
):
894 def Activate(self
, activate
= True):
896 Call this from your view frame's OnActivate member to tell the
897 framework which view is currently active. If your windowing system
898 doesn't call OnActivate, you may need to call this function from
899 OnMenuCommand or any place where you know the view must be active, and
900 the framework will need to get the current view.
902 The prepackaged view frame wxDocChildFrame calls wxView.Activate from
903 its OnActivate member and from its OnMenuCommand member.
905 if self
.GetDocument() and self
.GetDocumentManager():
906 self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView())
907 self
.GetDocumentManager().ActivateView(self
, activate
)
910 def OnClose(self
, deleteWindow
= True):
912 Implements closing behaviour. The default implementation calls
913 wxDocument.Close to close the associated document. Does not delete the
914 view. The application may wish to do some cleaning up operations in
915 this function, if a call to wxDocument::Close succeeded. For example,
916 if your application's all share the same window, you need to
917 disassociate the window from the view and perhaps clear the window. If
918 deleteWindow is true, delete the frame associated with the view.
920 if self
.GetDocument():
921 return self
.GetDocument().Close()
926 def OnCreate(self
, doc
, flags
):
928 wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just
929 after the wxDocTemplate creates the wxView, it calls wxView::OnCreate.
930 In its OnCreate member function, the wxView can create a
931 wxDocChildFrame or a derived class. This wxDocChildFrame provides user
932 interface elements to view and/or edit the contents of the wxDocument.
934 By default, simply returns true. If the function returns false, the
935 view will be deleted.
940 def OnCreatePrintout(self
):
942 Returns a wxPrintout object for the purposes of printing. It should
943 create a new object every time it is called; the framework will delete
946 By default, this function returns an instance of wxDocPrintout, which
947 prints and previews one page by calling wxView.OnDraw.
949 Override to return an instance of a class other than wxDocPrintout.
951 return DocPrintout(self
)
956 Gets the frame associated with the view (if any). Note that this
957 "frame" is not a wxFrame at all in the generic MDI implementation
958 which uses the notebook pages instead of the frames and this is why
959 this method returns a wxWindow and not a wxFrame.
961 return self
._viewFrame
964 def SetFrame(self
, frame
):
966 Sets the frame associated with this view. The application should call
967 this if possible, to tell the view about the frame. See GetFrame for
968 the explanation about the mismatch between the "Frame" in the method
969 name and the type of its parameter.
971 self
._viewFrame
= frame
974 def GetDocumentManager(self
):
976 Returns the document manager instance associated with this view.
978 if self
._viewDocument
:
979 return self
.GetDocument().GetDocumentManager()
984 class DocTemplate(wx
.Object
):
986 The wxDocTemplate class is used to model the relationship between a
987 document class and a view class.
991 def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
= DEFAULT_TEMPLATE_FLAGS
, icon
= None):
993 Constructor. Create instances dynamically near the start of your
994 application after creating a wxDocManager instance, and before doing
995 any document or view operations.
997 manager is the document manager object which manages this template.
999 description is a short description of what the template is for. This
1000 string will be displayed in the file filter list of Windows file
1003 filter is an appropriate file filter such as *.txt.
1005 dir is the default directory to use for file selectors.
1007 ext is the default file extension (such as txt).
1009 docTypeName is a name that should be unique for a given type of
1010 document, used for gathering a list of views relevant to a
1011 particular document.
1013 viewTypeName is a name that should be unique for a given view.
1015 docClass is a Python class. If this is not supplied, you will need to
1016 derive a new wxDocTemplate class and override the CreateDocument
1017 member to return a new document instance on demand.
1019 viewClass is a Python class. If this is not supplied, you will need to
1020 derive a new wxDocTemplate class and override the CreateView member to
1021 return a new view instance on demand.
1023 flags is a bit list of the following:
1024 wx.TEMPLATE_VISIBLE The template may be displayed to the user in
1027 wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in
1030 wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE.
1032 self
._docManager
= manager
1033 self
._description
= description
1034 self
._fileFilter
= filter
1035 self
._directory
= dir
1036 self
._defaultExt
= ext
1037 self
._docTypeName
= docTypeName
1038 self
._viewTypeName
= viewTypeName
1039 self
._docType
= docType
1040 self
._viewType
= viewType
1044 self
._docManager
.AssociateTemplate(self
)
1047 def GetDefaultExtension(self
):
1049 Returns the default file extension for the document data, as passed to
1050 the document template constructor.
1052 return self
._defaultExt
1055 def SetDefaultExtension(self
, defaultExt
):
1057 Sets the default file extension.
1059 self
._defaultExt
= defaultExt
1062 def GetDescription(self
):
1064 Returns the text description of this template, as passed to the
1065 document template constructor.
1067 return self
._description
1070 def SetDescription(self
, description
):
1072 Sets the template description.
1074 self
._description
= description
1077 def GetDirectory(self
):
1079 Returns the default directory, as passed to the document template
1082 return self
._directory
1085 def SetDirectory(self
, dir):
1087 Sets the default directory.
1089 self
._directory
= dir
1092 def GetDocumentManager(self
):
1094 Returns the document manager instance for which this template was
1097 return self
._docManager
1100 def SetDocumentManager(self
, manager
):
1102 Sets the document manager instance for which this template was
1103 created. Should not be called by the application.
1105 self
._docManager
= manager
1108 def GetFileFilter(self
):
1110 Returns the file filter, as passed to the document template
1113 return self
._fileFilter
1116 def SetFileFilter(self
, filter):
1118 Sets the file filter.
1120 self
._fileFilter
= filter
1125 Returns the flags, as passed to the document template constructor.
1126 (see the constructor description for more details).
1131 def SetFlags(self
, flags
):
1133 Sets the internal document template flags (see the constructor
1134 description for more details).
1141 Returns the icon, as passed to the document template
1142 constructor. This method has been added to wxPython and is
1148 def SetIcon(self
, flags
):
1150 Sets the icon. This method has been added to wxPython and is not
1156 def GetDocumentType(self
):
1158 Returns the Python document class, as passed to the document template
1161 return self
._docType
1164 def GetViewType(self
):
1166 Returns the Python view class, as passed to the document template
1169 return self
._viewType
1172 def IsVisible(self
):
1174 Returns true if the document template can be shown in user dialogs,
1177 return (self
._flags
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
1180 def GetDocumentName(self
):
1182 Returns the document type name, as passed to the document template
1185 return self
._docTypeName
1188 def GetViewName(self
):
1190 Returns the view type name, as passed to the document template
1193 return self
._viewTypeName
1196 def CreateDocument(self
, path
, flags
):
1198 Creates a new instance of the associated document class. If you have
1199 not supplied a class to the template constructor, you will need to
1200 override this function to return an appropriate document instance.
1202 doc
= self
._docType
()
1203 doc
.SetFilename(path
)
1204 doc
.SetDocumentTemplate(self
)
1205 self
.GetDocumentManager().AddDocument(doc
)
1206 doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor())
1207 if doc
.OnCreate(path
, flags
):
1210 if doc
in self
.GetDocumentManager().GetDocuments():
1211 doc
.DeleteAllViews()
1215 def CreateView(self
, doc
, flags
):
1217 Creates a new instance of the associated document view. If you have
1218 not supplied a class to the template constructor, you will need to
1219 override this function to return an appropriate view instance.
1221 view
= self
._viewType
()
1222 view
.SetDocument(doc
)
1223 if view
.OnCreate(doc
, flags
):
1230 def FileMatchesTemplate(self
, path
):
1232 Returns True if the path's extension matches one of this template's
1233 file filter extensions.
1235 ext
= FindExtension(path
)
1236 if not ext
: return False
1237 return ext
in self
.GetFileFilter()
1238 # return self.GetDefaultExtension() == FindExtension(path)
1241 class DocManager(wx
.EvtHandler
):
1243 The wxDocManager class is part of the document/view framework supported by
1244 wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate
1248 def __init__(self
, flags
= DEFAULT_DOCMAN_FLAGS
, initialize
= True):
1250 Constructor. Create a document manager instance dynamically near the
1251 start of your application before doing any document or view operations.
1253 flags is used in the Python version to indicate whether the document
1254 manager is in DOC_SDI or DOC_MDI mode.
1256 If initialize is true, the Initialize function will be called to
1257 create a default history list object. If you derive from wxDocManager,
1258 you may wish to call the base constructor with false, and then call
1259 Initialize in your own constructor, to allow your own Initialize or
1260 OnCreateFileHistory functions to be called.
1263 wx
.EvtHandler
.__init
__(self
)
1265 self
._defaultDocumentNameCounter
= 1
1267 self
._currentView
= None
1268 self
._lastActiveView
= None
1269 self
._maxDocsOpen
= 10000
1270 self
._fileHistory
= None
1271 self
._templates
= []
1273 self
._lastDirectory
= ""
1278 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
)
1279 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
)
1280 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
)
1281 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
)
1282 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
)
1283 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
)
1284 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
)
1285 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
1286 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
1287 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
)
1288 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
)
1289 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
)
1291 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
)
1292 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
)
1293 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
)
1294 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
)
1295 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
)
1296 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
)
1297 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
)
1298 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
)
1299 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
)
1300 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
)
1301 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
)
1302 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
)
1310 wx
.EvtHandler
.Destroy(self
)
1315 Returns the document manager's flags. This method has been
1316 added to wxPython and is not in wxWindows.
1321 def CloseDocument(self
, doc
, force
= True):
1323 Closes the specified document.
1325 if doc
.Close() or force
:
1326 doc
.DeleteAllViews()
1327 if doc
in self
._docs
:
1333 def CloseDocuments(self
, force
= True):
1335 Closes all currently opened documents.
1337 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
1338 if not self
.CloseDocument(document
, force
):
1340 document
.DeleteAllViews() # Implicitly delete the document when the last view is removed
1344 def Clear(self
, force
= True):
1346 Closes all currently opened document by callling CloseDocuments and
1347 clears the document manager's templates.
1349 if not self
.CloseDocuments(force
):
1351 self
._templates
= []
1355 def Initialize(self
):
1357 Initializes data; currently just calls OnCreateFileHistory. Some data
1358 cannot always be initialized in the constructor because the programmer
1359 must be given the opportunity to override functionality. In fact
1360 Initialize is called from the wxDocManager constructor, but this can
1361 be vetoed by passing false to the second argument, allowing the
1362 derived class's constructor to call Initialize, possibly calling a
1363 different OnCreateFileHistory from the default.
1365 The bottom line: if you're not deriving from Initialize, forget it and
1366 construct wxDocManager with no arguments.
1368 self
.OnCreateFileHistory()
1372 def OnCreateFileHistory(self
):
1374 A hook to allow a derived class to create a different type of file
1375 history. Called from Initialize.
1377 self
._fileHistory
= wx
.FileHistory()
1380 def OnFileClose(self
, event
):
1382 Closes and deletes the currently active document.
1384 doc
= self
.GetCurrentDocument()
1386 doc
.DeleteAllViews()
1387 if doc
in self
._docs
:
1388 self
._docs
.remove(doc
)
1391 def OnFileCloseAll(self
, event
):
1393 Closes and deletes all the currently opened documents.
1395 return self
.CloseDocuments(force
= False)
1398 def OnFileNew(self
, event
):
1400 Creates a new document and reads in the selected file.
1402 self
.CreateDocument('', DOC_NEW
)
1405 def OnFileOpen(self
, event
):
1407 Creates a new document and reads in the selected file.
1409 if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
):
1410 self
.OnOpenFileFailure()
1413 def OnFileRevert(self
, event
):
1415 Reverts the current document by calling wxDocument.Save for the current
1418 doc
= self
.GetCurrentDocument()
1424 def OnFileSave(self
, event
):
1426 Saves the current document by calling wxDocument.Save for the current
1429 doc
= self
.GetCurrentDocument()
1435 def OnFileSaveAs(self
, event
):
1437 Calls wxDocument.SaveAs for the current document.
1439 doc
= self
.GetCurrentDocument()
1445 def OnPrint(self
, event
):
1447 Prints the current document by calling its View's OnCreatePrintout
1450 view
= self
.GetCurrentView()
1454 printout
= view
.OnCreatePrintout()
1456 pdd
= wx
.PrintDialogData()
1457 printer
= wx
.Printer(pdd
)
1458 printer
.Print(view
.GetFrame(), printout
) # , True)
1461 def OnPrintSetup(self
, event
):
1463 Presents the print setup dialog.
1465 view
= self
.GetCurrentView()
1467 parentWin
= view
.GetFrame()
1469 parentWin
= wx
.GetApp().GetTopWindow()
1471 data
= wx
.PrintDialogData()
1472 printDialog
= wx
.PrintDialog(parentWin
, data
)
1473 printDialog
.GetPrintDialogData().SetSetupDialog(True)
1474 printDialog
.ShowModal()
1475 # TODO: Confirm that we don't have to remember PrintDialogData
1478 def OnPreview(self
, event
):
1480 Previews the current document by calling its View's OnCreatePrintout
1483 view
= self
.GetCurrentView()
1487 printout
= view
.OnCreatePrintout()
1489 # Pass two printout objects: for preview, and possible printing.
1490 preview
= wx
.PrintPreview(printout
, view
.OnCreatePrintout())
1491 # 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.
1492 mimicFrame
= wx
.GetApp().GetTopWindow()
1493 frame
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize())
1494 frame
.SetIcon(mimicFrame
.GetIcon())
1495 frame
.SetTitle(mimicFrame
.GetTitle() + _(" - Preview"))
1500 def OnUndo(self
, event
):
1502 Issues an Undo command to the current document's command processor.
1504 doc
= self
.GetCurrentDocument()
1507 if doc
.GetCommandProcessor():
1508 doc
.GetCommandProcessor().Undo()
1511 def OnRedo(self
, event
):
1513 Issues a Redo command to the current document's command processor.
1515 doc
= self
.GetCurrentDocument()
1518 if doc
.GetCommandProcessor():
1519 doc
.GetCommandProcessor().Redo()
1522 def OnUpdateFileOpen(self
, event
):
1524 Updates the user interface for the File Open command.
1529 def OnUpdateFileClose(self
, event
):
1531 Updates the user interface for the File Close command.
1533 event
.Enable(self
.GetCurrentDocument() != None)
1536 def OnUpdateFileCloseAll(self
, event
):
1538 Updates the user interface for the File Close All command.
1540 event
.Enable(self
.GetCurrentDocument() != None)
1543 def OnUpdateFileRevert(self
, event
):
1545 Updates the user interface for the File Revert command.
1547 event
.Enable(self
.GetCurrentDocument() != None)
1550 def OnUpdateFileNew(self
, event
):
1552 Updates the user interface for the File New command.
1557 def OnUpdateFileSave(self
, event
):
1559 Updates the user interface for the File Save command.
1561 doc
= self
.GetCurrentDocument()
1562 event
.Enable(doc
!= None and doc
.IsModified())
1565 def OnUpdateFileSaveAs(self
, event
):
1567 Updates the user interface for the File Save As command.
1569 event
.Enable(self
.GetCurrentDocument() != None and self
.GetCurrentDocument().GetWriteable())
1572 def OnUpdateUndo(self
, event
):
1574 Updates the user interface for the Undo command.
1576 doc
= self
.GetCurrentDocument()
1577 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo())
1578 if doc
and doc
.GetCommandProcessor():
1579 doc
.GetCommandProcessor().SetMenuStrings()
1581 event
.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
1584 def OnUpdateRedo(self
, event
):
1586 Updates the user interface for the Redo command.
1588 doc
= self
.GetCurrentDocument()
1589 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo())
1590 if doc
and doc
.GetCommandProcessor():
1591 doc
.GetCommandProcessor().SetMenuStrings()
1593 event
.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
1596 def OnUpdatePrint(self
, event
):
1598 Updates the user interface for the Print command.
1600 event
.Enable(self
.GetCurrentDocument() != None)
1603 def OnUpdatePrintSetup(self
, event
):
1605 Updates the user interface for the Print Setup command.
1610 def OnUpdatePreview(self
, event
):
1612 Updates the user interface for the Print Preview command.
1614 event
.Enable(self
.GetCurrentDocument() != None)
1617 def GetCurrentView(self
):
1619 Returns the currently active view.
1621 if self
._currentView
:
1622 return self
._currentView
1623 if len(self
._docs
) == 1:
1624 return self
._docs
[0].GetFirstView()
1628 def GetLastActiveView(self
):
1630 Returns the last active view. This is used in the SDI framework where dialogs can be mistaken for a view
1631 and causes the framework to deactivete the current view. This happens when something like a custom dialog box used
1632 to operate on the current view is shown.
1634 if len(self
._docs
) >= 1:
1635 return self
._lastActiveView
1640 def ProcessEvent(self
, event
):
1642 Processes an event, searching event tables and calling zero or more
1643 suitable event handler function(s). Note that the ProcessEvent
1644 method is called from the wxPython docview framework directly since
1645 wxPython does not have a virtual ProcessEvent function.
1647 view
= self
.GetCurrentView()
1649 if view
.ProcessEvent(event
):
1652 if id == wx
.ID_OPEN
:
1653 self
.OnFileOpen(event
)
1655 elif id == wx
.ID_CLOSE
:
1656 self
.OnFileClose(event
)
1658 elif id == wx
.ID_CLOSE_ALL
:
1659 self
.OnFileCloseAll(event
)
1661 elif id == wx
.ID_REVERT
:
1662 self
.OnFileRevert(event
)
1664 elif id == wx
.ID_NEW
:
1665 self
.OnFileNew(event
)
1667 elif id == wx
.ID_SAVE
:
1668 self
.OnFileSave(event
)
1670 elif id == wx
.ID_SAVEAS
:
1671 self
.OnFileSaveAs(event
)
1673 elif id == wx
.ID_UNDO
:
1676 elif id == wx
.ID_REDO
:
1679 elif id == wx
.ID_PRINT
:
1682 elif id == wx
.ID_PRINT_SETUP
:
1683 self
.OnPrintSetup(event
)
1685 elif id == wx
.ID_PREVIEW
:
1686 self
.OnPreview(event
)
1692 def ProcessUpdateUIEvent(self
, event
):
1694 Processes a UI event, searching event tables and calling zero or more
1695 suitable event handler function(s). Note that the ProcessEvent
1696 method is called from the wxPython docview framework directly since
1697 wxPython does not have a virtual ProcessEvent function.
1700 view
= self
.GetCurrentView()
1702 if view
.ProcessUpdateUIEvent(event
):
1704 if id == wx
.ID_OPEN
:
1705 self
.OnUpdateFileOpen(event
)
1707 elif id == wx
.ID_CLOSE
:
1708 self
.OnUpdateFileClose(event
)
1710 elif id == wx
.ID_CLOSE_ALL
:
1711 self
.OnUpdateFileCloseAll(event
)
1713 elif id == wx
.ID_REVERT
:
1714 self
.OnUpdateFileRevert(event
)
1716 elif id == wx
.ID_NEW
:
1717 self
.OnUpdateFileNew(event
)
1719 elif id == wx
.ID_SAVE
:
1720 self
.OnUpdateFileSave(event
)
1722 elif id == wx
.ID_SAVEAS
:
1723 self
.OnUpdateFileSaveAs(event
)
1725 elif id == wx
.ID_UNDO
:
1726 self
.OnUpdateUndo(event
)
1728 elif id == wx
.ID_REDO
:
1729 self
.OnUpdateRedo(event
)
1731 elif id == wx
.ID_PRINT
:
1732 self
.OnUpdatePrint(event
)
1734 elif id == wx
.ID_PRINT_SETUP
:
1735 self
.OnUpdatePrintSetup(event
)
1737 elif id == wx
.ID_PREVIEW
:
1738 self
.OnUpdatePreview(event
)
1744 def CreateDocument(self
, path
, flags
= 0):
1746 Creates a new document in a manner determined by the flags parameter,
1749 wx.lib.docview.DOC_NEW Creates a fresh document.
1750 wx.lib.docview.DOC_SILENT Silently loads the given document file.
1752 If wx.lib.docview.DOC_NEW is present, a new document will be created and returned,
1753 possibly after asking the user for a template to use if there is more
1754 than one document template. If wx.lib.docview.DOC_SILENT is present, a new document
1755 will be created and the given file loaded into it. If neither of these
1756 flags is present, the user will be presented with a file selector for
1757 the file to load, and the template to use will be determined by the
1758 extension (Windows) or by popping up a template choice list (other
1761 If the maximum number of documents has been reached, this function
1762 will delete the oldest currently loaded document before creating a new
1765 wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE flag.
1768 for temp
in self
._templates
:
1769 if temp
.IsVisible():
1770 templates
.append(temp
)
1771 if len(templates
) == 0:
1774 if len(self
.GetDocuments()) >= self
._maxDocsOpen
:
1775 doc
= self
.GetDocuments()[0]
1776 if not self
.CloseDocument(doc
, False):
1780 if len(templates
) == 1:
1782 newDoc
= temp
.CreateDocument(path
, flags
)
1784 newDoc
.SetDocumentName(temp
.GetDocumentName())
1785 newDoc
.SetDocumentTemplate(temp
)
1786 newDoc
.OnNewDocument()
1789 temp
= self
.SelectDocumentType(templates
)
1791 newDoc
= temp
.CreateDocument(path
, flags
)
1793 newDoc
.SetDocumentName(temp
.GetDocumentName())
1794 newDoc
.SetDocumentTemplate(temp
)
1795 newDoc
.OnNewDocument()
1800 if path
and flags
& DOC_SILENT
:
1801 temp
= self
.FindTemplateForPath(path
)
1803 temp
, path
= self
.SelectDocumentPath(templates
, path
, flags
)
1806 if self
.GetFlags() & DOC_OPEN_ONCE
:
1807 for document
in self
._docs
:
1808 if document
.GetFilename() == path
:
1809 firstView
= document
.GetFirstView()
1810 if firstView
and firstView
.GetFrame():
1811 firstView
.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
1812 if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
1813 firstView
.GetFrame().Iconize(False)
1817 newDoc
= temp
.CreateDocument(path
, flags
)
1819 newDoc
.SetDocumentName(temp
.GetDocumentName())
1820 newDoc
.SetDocumentTemplate(temp
)
1821 if not newDoc
.OnOpenDocument(path
):
1822 newDoc
.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1823 newDoc
.GetFirstView().GetFrame().Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
1825 self
.AddFileToHistory(path
)
1831 def CreateView(self
, document
, flags
= 0):
1833 Creates a new view for the given document. If more than one view is
1834 allowed for the document (by virtue of multiple templates mentioning
1835 the same document type), a choice of view is presented to the user.
1838 for temp
in self
._templates
:
1839 if temp
.IsVisible():
1840 if temp
.GetDocumentName() == doc
.GetDocumentName():
1841 templates
.append(temp
)
1842 if len(templates
) == 0:
1845 if len(templates
) == 1:
1847 view
= temp
.CreateView(doc
, flags
)
1849 view
.SetViewName(temp
.GetViewName())
1852 temp
= SelectViewType(templates
)
1854 view
= temp
.CreateView(doc
, flags
)
1856 view
.SetViewName(temp
.GetViewName())
1862 def DeleteTemplate(self
, template
, flags
):
1864 Placeholder, not yet implemented in wxWindows.
1869 def FlushDoc(self
, doc
):
1871 Placeholder, not yet implemented in wxWindows.
1876 def MatchTemplate(self
, path
):
1878 Placeholder, not yet implemented in wxWindows.
1883 def GetCurrentDocument(self
):
1885 Returns the document associated with the currently active view (if any).
1887 view
= self
.GetCurrentView()
1889 return view
.GetDocument()
1894 def MakeDefaultName(self
):
1896 Returns a suitable default name. This is implemented by appending an
1897 integer counter to the string "Untitled" and incrementing the counter.
1899 name
= _("Untitled %d") % self
._defaultDocumentNameCounter
1900 self
._defaultDocumentNameCounter
= self
._defaultDocumentNameCounter
+ 1
1904 def MakeFrameTitle(self
):
1906 Returns a suitable title for a document frame. This is implemented by
1907 appending the document name to the application name.
1909 appName
= wx
.GetApp().GetAppName()
1913 docName
= doc
.GetPrintableName()
1914 title
= docName
+ _(" - ") + appName
1918 def AddFileToHistory(self
, fileName
):
1920 Adds a file to the file history list, if we have a pointer to an
1921 appropriate file menu.
1923 if self
._fileHistory
:
1924 self
._fileHistory
.AddFileToHistory(fileName
)
1927 def RemoveFileFromHistory(self
, i
):
1929 Removes a file from the file history list, if we have a pointer to an
1930 appropriate file menu.
1932 if self
._fileHistory
:
1933 self
._fileHistory
.RemoveFileFromHistory(i
)
1936 def GetFileHistory(self
):
1938 Returns the file history.
1940 return self
._fileHistory
1943 def GetHistoryFile(self
, i
):
1945 Returns the file at index i from the file history.
1947 if self
._fileHistory
:
1948 return self
._fileHistory
.GetHistoryFile(i
)
1953 def FileHistoryUseMenu(self
, menu
):
1955 Use this menu for appending recently-visited document filenames, for
1956 convenient access. Calling this function with a valid menu enables the
1957 history list functionality.
1959 Note that you can add multiple menus using this function, to be
1960 managed by the file history object.
1962 if self
._fileHistory
:
1963 self
._fileHistory
.UseMenu(menu
)
1966 def FileHistoryRemoveMenu(self
, menu
):
1968 Removes the given menu from the list of menus managed by the file
1971 if self
._fileHistory
:
1972 self
._fileHistory
.RemoveMenu(menu
)
1975 def FileHistoryLoad(self
, config
):
1977 Loads the file history from a config object.
1979 if self
._fileHistory
:
1980 self
._fileHistory
.Load(config
)
1983 def FileHistorySave(self
, config
):
1985 Saves the file history into a config object. This must be called
1986 explicitly by the application.
1988 if self
._fileHistory
:
1989 self
._fileHistory
.Save(config
)
1992 def FileHistoryAddFilesToMenu(self
, menu
= None):
1994 Appends the files in the history list, to all menus managed by the
1995 file history object.
1997 If menu is specified, appends the files in the history list to the
2000 if self
._fileHistory
:
2002 self
._fileHistory
.AddFilesToThisMenu(menu
)
2004 self
._fileHistory
.AddFilesToMenu()
2007 def GetHistoryFilesCount(self
):
2009 Returns the number of files currently stored in the file history.
2011 if self
._fileHistory
:
2012 return self
._fileHistory
.GetNoHistoryFiles()
2017 def FindTemplateForPath(self
, path
):
2019 Given a path, try to find template that matches the extension. This is
2020 only an approximate method of finding a template for creating a
2023 for temp
in self
._templates
:
2024 if temp
.FileMatchesTemplate(path
):
2029 def FindSuitableParent(self
):
2031 Returns a parent frame or dialog, either the frame with the current
2032 focus or if there is no current focus the application's top frame.
2034 parent
= wx
.GetApp().GetTopWindow()
2035 focusWindow
= wx
.Window_FindFocus()
2037 while focusWindow
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
):
2038 focusWindow
= focusWindow
.GetParent()
2040 parent
= focusWindow
2044 def SelectDocumentPath(self
, templates
, flags
, save
):
2046 Under Windows, pops up a file selector with a list of filters
2047 corresponding to document templates. The wxDocTemplate corresponding
2048 to the selected file's extension is returned.
2050 On other platforms, if there is more than one document template a
2051 choice list is popped up, followed by a file selector.
2053 This function is used in wxDocManager.CreateDocument.
2055 if wx
.Platform
== "__WXMSW__" or wx
.Platform
== "__WXGTK__" or wx
.Platform
== "__WXMAC__":
2058 for temp
in templates
:
2059 if temp
.IsVisible():
2061 descr
= descr
+ _('|')
2062 allfilter
= allfilter
+ _(';')
2063 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
2064 allfilter
= allfilter
+ temp
.GetFileFilter()
2065 descr
= _("All") + _(" (") + allfilter
+ _(") |") + allfilter
+ _('|') + descr
# spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
2069 path
= wx
.FileSelector(_("Select a File"),
2070 self
._lastDirectory
,
2073 flags
= wx
.HIDE_READONLY
,
2074 parent
= self
.FindSuitableParent())
2076 if not FileExists(path
):
2077 msgTitle
= wx
.GetApp().GetAppName()
2079 msgTitle
= _("File Error")
2080 wx
.MessageBox("Could not open '%s'." % FileNameFromPath(path
),
2082 wx
.OK | wx
.ICON_EXCLAMATION
,
2085 self
._lastDirectory
= PathOnly(path
)
2087 theTemplate
= self
.FindTemplateForPath(path
)
2088 return (theTemplate
, path
)
2093 def OnOpenFileFailure(self
):
2095 Called when there is an error opening a file.
2100 def SelectDocumentType(self
, temps
, sort
= False):
2102 Returns a document template by asking the user (if there is more than
2103 one template). This function is used in wxDocManager.CreateDocument.
2107 templates - list of templates from which to choose a desired template.
2109 sort - If more than one template is passed in in templates, then this
2110 parameter indicates whether the list of templates that the user will
2111 have to choose from is sorted or not when shown the choice box dialog.
2116 if temp
.IsVisible():
2118 for temp2
in templates
:
2119 if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName():
2123 templates
.append(temp
)
2125 if len(templates
) == 0:
2127 elif len(templates
) == 1:
2132 return cmp(a
.GetDescription(), b
.GetDescription())
2133 templates
.sort(tempcmp
)
2136 for temp
in templates
:
2137 strings
.append(temp
.GetDescription())
2139 res
= wx
.GetSingleChoiceIndex(_("Select a document type:"),
2142 self
.FindSuitableParent())
2145 return templates
[res
]
2148 def SelectViewType(self
, temps
, sort
= False):
2150 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.
2155 if temp
.IsVisible() and temp
.GetViewTypeName():
2156 if temp
.GetViewName() not in strings
:
2157 templates
.append(temp
)
2158 strings
.append(temp
.GetViewTypeName())
2160 if len(templates
) == 0:
2162 elif len(templates
) == 1:
2167 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName())
2168 templates
.sort(tempcmp
)
2170 res
= wx
.GetSingleChoiceIndex(_("Select a document view:"),
2173 self
.FindSuitableParent())
2176 return templates
[res
]
2179 def GetTemplates(self
):
2181 Returns the document manager's template list. This method has been added to
2182 wxPython and is not in wxWindows.
2184 return self
._templates
2187 def AssociateTemplate(self
, docTemplate
):
2189 Adds the template to the document manager's template list.
2191 if docTemplate
not in self
._templates
:
2192 self
._templates
.append(docTemplate
)
2195 def DisassociateTemplate(self
, docTemplate
):
2197 Removes the template from the list of templates.
2199 self
._templates
.remove(docTemplate
)
2202 def AddDocument(self
, document
):
2204 Adds the document to the list of documents.
2206 if document
not in self
._docs
:
2207 self
._docs
.append(document
)
2210 def RemoveDocument(self
, doc
):
2212 Removes the document from the list of documents.
2214 if doc
in self
._docs
:
2215 self
._docs
.remove(doc
)
2218 def ActivateView(self
, view
, activate
= True, deleting
= False):
2220 Sets the current view.
2223 self
._currentView
= view
2224 self
._lastActiveView
= view
2226 self
._currentView
= None
2229 def GetMaxDocsOpen(self
):
2231 Returns the number of documents that can be open simultaneously.
2233 return self
._maxDocsOpen
2236 def SetMaxDocsOpen(self
, maxDocsOpen
):
2238 Sets the maximum number of documents that can be open at a time. By
2239 default, this is 10,000. If you set it to 1, existing documents will
2240 be saved and deleted when the user tries to open or create a new one
2241 (similar to the behaviour of Windows Write, for example). Allowing
2242 multiple documents gives behaviour more akin to MS Word and other
2243 Multiple Document Interface applications.
2245 self
._maxDocsOpen
= maxDocsOpen
2248 def GetDocuments(self
):
2250 Returns the list of documents.
2255 class DocParentFrame(wx
.Frame
):
2257 The wxDocParentFrame class provides a default top-level frame for
2258 applications using the document/view framework. This class can only be
2259 used for SDI (not MDI) parent frames.
2261 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates
2265 def __init__(self
, manager
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2267 Constructor. Note that the event table must be rebuilt for the
2268 frame since the EvtHandler is not virtual.
2270 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
)
2271 self
._docManager
= manager
2273 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2275 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2276 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2278 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2279 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2280 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2281 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2282 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2283 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2284 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2285 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2286 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2287 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2288 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2289 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2291 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2292 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2293 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2294 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2295 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2296 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2297 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2298 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2299 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2300 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2301 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2302 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2305 def ProcessEvent(self
, event
):
2307 Processes an event, searching event tables and calling zero or more
2308 suitable event handler function(s). Note that the ProcessEvent
2309 method is called from the wxPython docview framework directly since
2310 wxPython does not have a virtual ProcessEvent function.
2312 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2315 def ProcessUpdateUIEvent(self
, event
):
2317 Processes a UI event, searching event tables and calling zero or more
2318 suitable event handler function(s). Note that the ProcessEvent
2319 method is called from the wxPython docview framework directly since
2320 wxPython does not have a virtual ProcessEvent function.
2322 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2325 def OnExit(self
, event
):
2327 Called when File/Exit is chosen and closes the window.
2332 def OnMRUFile(self
, event
):
2334 Opens the appropriate file when it is selected from the file history
2337 n
= event
.GetId() - wx
.ID_FILE1
2338 filename
= self
._docManager
.GetHistoryFile(n
)
2340 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2342 self
._docManager
.RemoveFileFromHistory(n
)
2343 msgTitle
= wx
.GetApp().GetAppName()
2345 msgTitle
= _("File Error")
2346 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),
2348 wx
.OK | wx
.ICON_EXCLAMATION
,
2352 def OnCloseWindow(self
, event
):
2354 Deletes all views and documents. If no user input cancelled the
2355 operation, the frame will be destroyed and the application will exit.
2357 if self
._docManager
.Clear(not event
.CanVeto()):
2363 class DocChildFrame(wx
.Frame
):
2365 The wxDocChildFrame class provides a default frame for displaying
2366 documents on separate windows. This class can only be used for SDI (not
2369 The class is part of the document/view framework supported by wxWindows,
2370 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2375 def __init__(self
, doc
, view
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2377 Constructor. Note that the event table must be rebuilt for the
2378 frame since the EvtHandler is not virtual.
2380 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2381 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2382 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2383 self
._childDocument
= doc
2384 self
._childView
= view
2388 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2389 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2390 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2391 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2392 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2393 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2394 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2395 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2396 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2397 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2398 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2399 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2401 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2402 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2403 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2404 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2405 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2406 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2407 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2408 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2409 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2410 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2411 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2412 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2415 def ProcessEvent(self
, event
):
2417 Processes an event, searching event tables and calling zero or more
2418 suitable event handler function(s). Note that the ProcessEvent
2419 method is called from the wxPython docview framework directly since
2420 wxPython does not have a virtual ProcessEvent function.
2423 self
._childView
.Activate(True)
2424 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2425 # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows
2426 # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
2427 if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2435 def ProcessUpdateUIEvent(self
, event
):
2437 Processes a UI event, searching event tables and calling zero or more
2438 suitable event handler function(s). Note that the ProcessEvent
2439 method is called from the wxPython docview framework directly since
2440 wxPython does not have a virtual ProcessEvent function.
2442 if self
.GetParent():
2443 self
.GetParent().ProcessUpdateUIEvent(event
)
2448 def OnActivate(self
, event
):
2450 Activates the current view.
2452 # wx.Frame.OnActivate(event) This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead
2454 self
._childView
.Activate(event
.GetActive())
2457 def OnCloseWindow(self
, event
):
2459 Closes and deletes the current view and document.
2463 if not event
.CanVeto():
2466 ans
= self
._childView
.Close(deleteWindow
= False)
2469 self
._childView
.Activate(False)
2470 self
._childView
.Destroy()
2471 self
._childView
= None
2472 if self
._childDocument
:
2473 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2474 self
._childDocument
= None
2482 def GetDocument(self
):
2484 Returns the document associated with this frame.
2486 return self
._childDocument
2489 def SetDocument(self
, document
):
2491 Sets the document for this frame.
2493 self
._childDocument
= document
2498 Returns the view associated with this frame.
2500 return self
._childView
2503 def SetView(self
, view
):
2505 Sets the view for this frame.
2507 self
._childView
= view
2510 class DocMDIParentFrame(wx
.MDIParentFrame
):
2512 The wxDocMDIParentFrame class provides a default top-level frame for
2513 applications using the document/view framework. This class can only be
2514 used for MDI parent frames.
2516 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2521 def __init__(self
, manager
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2523 Constructor. Note that the event table must be rebuilt for the
2524 frame since the EvtHandler is not virtual.
2526 wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2527 self
._docManager
= manager
2529 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2531 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2532 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2534 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2535 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2536 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2537 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2538 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2539 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2540 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2541 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2542 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2543 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2544 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2545 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2547 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2548 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2549 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2550 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2551 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2552 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2553 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2554 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2555 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2556 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2557 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2558 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2561 def ProcessEvent(self
, event
):
2563 Processes an event, searching event tables and calling zero or more
2564 suitable event handler function(s). Note that the ProcessEvent
2565 method is called from the wxPython docview framework directly since
2566 wxPython does not have a virtual ProcessEvent function.
2568 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2571 def ProcessUpdateUIEvent(self
, event
):
2573 Processes a UI event, searching event tables and calling zero or more
2574 suitable event handler function(s). Note that the ProcessEvent
2575 method is called from the wxPython docview framework directly since
2576 wxPython does not have a virtual ProcessEvent function.
2578 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2581 def OnExit(self
, event
):
2583 Called when File/Exit is chosen and closes the window.
2588 def OnMRUFile(self
, event
):
2590 Opens the appropriate file when it is selected from the file history
2593 n
= event
.GetId() - wx
.ID_FILE1
2594 filename
= self
._docManager
.GetHistoryFile(n
)
2596 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2598 self
._docManager
.RemoveFileFromHistory(n
)
2599 msgTitle
= wx
.GetApp().GetAppName()
2601 msgTitle
= _("File Error")
2602 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),
2604 wx
.OK | wx
.ICON_EXCLAMATION
,
2608 def OnCloseWindow(self
, event
):
2610 Deletes all views and documents. If no user input cancelled the
2611 operation, the frame will be destroyed and the application will exit.
2613 if self
._docManager
.Clear(not event
.CanVeto()):
2619 class DocMDIChildFrame(wx
.MDIChildFrame
):
2621 The wxDocMDIChildFrame class provides a default frame for displaying
2622 documents on separate windows. This class can only be used for MDI child
2625 The class is part of the document/view framework supported by wxWindows,
2626 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2631 def __init__(self
, doc
, view
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2633 Constructor. Note that the event table must be rebuilt for the
2634 frame since the EvtHandler is not virtual.
2636 wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2637 self
._childDocument
= doc
2638 self
._childView
= view
2641 # self.Create(doc, view, frame, id, title, pos, size, style, name)
2642 self
._activeEvent
= None
2644 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2645 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2647 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
2648 mdiChildren
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren())
2649 if len(mdiChildren
) == 1:
2653 ## # Couldn't get this to work, but seems to work fine with single stage construction
2654 ## def Create(self, doc, view, frame, id, title, pos, size, style, name):
2655 ## self._childDocument = doc
2656 ## self._childView = view
2657 ## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
2659 ## view.SetFrame(self)
2665 def Activate(self
): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
2667 Activates the current view.
2670 self
._childView
.Activate(True)
2673 def ProcessEvent(event
):
2675 Processes an event, searching event tables and calling zero or more
2676 suitable event handler function(s). Note that the ProcessEvent
2677 method is called from the wxPython docview framework directly since
2678 wxPython does not have a virtual ProcessEvent function.
2680 if self
._activeEvent
== event
:
2683 self
._activeEvent
= event
# Break recursion loops
2686 self
._childView
.Activate(True)
2688 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2689 if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2696 self
._activeEvent
= None
2700 def OnActivate(self
, event
):
2702 Sets the currently active view to be the frame's view. You may need to
2703 override (but still call) this function in order to set the keyboard
2704 focus for your subwindow.
2706 if self
._activated
!= 0:
2708 self
._activated
+= 1
2709 wx
.MDIChildFrame
.Activate(self
)
2710 if event
.GetActive() and self
._childView
:
2711 self
._childView
.Activate(event
.GetActive())
2714 def OnCloseWindow(self
, event
):
2716 Closes and deletes the current view and document.
2720 if not event
.CanVeto():
2723 ans
= self
._childView
.Close(deleteWindow
= False)
2726 self
._childView
.Activate(False)
2727 self
._childView
.Destroy()
2728 self
._childView
= None
2729 if self
._childDocument
:
2730 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2731 self
._childDocument
= None
2739 def GetDocument(self
):
2741 Returns the document associated with this frame.
2743 return self
._childDocument
2746 def SetDocument(self
, document
):
2748 Sets the document for this frame.
2750 self
._childDocument
= document
2755 Returns the view associated with this frame.
2757 return self
._childView
2760 def SetView(self
, view
):
2762 Sets the view for this frame.
2764 self
._childView
= view
2767 class DocPrintout(wx
.Printout
):
2769 DocPrintout is a default Printout that prints the first page of a document
2774 def __init__(self
, view
, title
= "Printout"):
2778 wx
.Printout
.__init
__(self
)
2779 self
._printoutView
= view
2784 Returns the DocPrintout's view.
2786 return self
._printoutView
2789 def OnPrintPage(self
, page
):
2791 Prints the first page of the view.
2794 ppiScreenX
, ppiScreenY
= self
.GetPPIScreen()
2795 ppiPrinterX
, ppiPrinterY
= self
.GetPPIPrinter()
2796 scale
= ppiPrinterX
/ppiScreenX
2798 pageWidth
, pageHeight
= self
.GetPageSizePixels()
2799 overallScale
= scale
* w
/ pageWidth
2800 dc
.SetUserScale(overallScale
, overallScale
)
2801 if self
._printoutView
:
2802 self
._printoutView
.OnDraw(dc
)
2806 def HasPage(self
, pageNum
):
2808 Indicates that the DocPrintout only has a single page.
2813 def OnBeginDocument(self
, startPage
, endPage
):
2815 Not quite sure why this was overridden, but it was in wxWindows! :)
2817 if not wx
.Printout
.base_OnBeginDocument(self
, startPage
, endPage
):
2822 def GetPageInfo(self
):
2824 Indicates that the DocPrintout only has a single page.
2830 return (minPage
, maxPage
, selPageFrom
, selPageTo
)
2833 #----------------------------------------------------------------------
2835 #----------------------------------------------------------------------
2837 class Command(wx
.Object
):
2839 wxCommand is a base class for modelling an application command, which is
2840 an action usually performed by selecting a menu item, pressing a toolbar
2841 button or any other means provided by the application to change the data
2846 def __init__(self
, canUndo
= False, name
= None):
2848 Constructor. wxCommand is an abstract class, so you will need to
2849 derive a new class and call this constructor from your own constructor.
2851 canUndo tells the command processor whether this command is undo-able.
2852 You can achieve the same functionality by overriding the CanUndo member
2853 function (if for example the criteria for undoability is context-
2856 name must be supplied for the command processor to display the command
2857 name in the application's edit menu.
2859 self
._canUndo
= canUndo
2865 Returns true if the command can be undone, false otherwise.
2867 return self
._canUndo
2872 Returns the command name.
2879 Override this member function to execute the appropriate action when
2880 called. Return true to indicate that the action has taken place, false
2881 otherwise. Returning false will indicate to the command processor that
2882 the action is not undoable and should not be added to the command
2890 Override this member function to un-execute a previous Do. Return true
2891 to indicate that the action has taken place, false otherwise. Returning
2892 false will indicate to the command processor that the action is not
2893 redoable and no change should be made to the command history.
2895 How you implement this command is totally application dependent, but
2896 typical strategies include:
2898 Perform an inverse operation on the last modified piece of data in the
2899 document. When redone, a copy of data stored in command is pasted back
2900 or some operation reapplied. This relies on the fact that you know the
2901 ordering of Undos; the user can never Undo at an arbitrary position in
2904 Restore the entire document state (perhaps using document
2905 transactioning). Potentially very inefficient, but possibly easier to
2906 code if the user interface and data are complex, and an 'inverse
2907 execute' operation is hard to write.
2912 class CommandProcessor(wx
.Object
):
2914 wxCommandProcessor is a class that maintains a history of wxCommands, with
2915 undo/redo functionality built-in. Derive a new class from this if you want
2916 different behaviour.
2920 def __init__(self
, maxCommands
= -1):
2922 Constructor. maxCommands may be set to a positive integer to limit
2923 the number of commands stored to it, otherwise (and by default) the
2924 list of commands can grow arbitrarily.
2926 self
._maxCommands
= maxCommands
2927 self
._editMenu
= None
2928 self
._undoAccelerator
= _("Ctrl+Z")
2929 self
._redoAccelerator
= _("Ctrl+Y")
2930 self
.ClearCommands()
2933 def _GetCurrentCommand(self
):
2934 if len(self
._commands
) == 0:
2937 return self
._commands
[-1]
2940 def _GetCurrentRedoCommand(self
):
2941 if len(self
._redoCommands
) == 0:
2944 return self
._redoCommands
[-1]
2947 def GetMaxCommands(self
):
2949 Returns the maximum number of commands that the command processor
2953 return self
._maxCommands
2956 def GetCommands(self
):
2958 Returns the list of commands.
2960 return self
._commands
2963 def ClearCommands(self
):
2965 Deletes all the commands in the list and sets the current command
2969 self
._redoCommands
= []
2972 def GetEditMenu(self
):
2974 Returns the edit menu associated with the command processor.
2976 return self
._editMenu
2979 def SetEditMenu(self
, menu
):
2981 Tells the command processor to update the Undo and Redo items on this
2982 menu as appropriate. Set this to NULL if the menu is about to be
2983 destroyed and command operations may still be performed, or the
2984 command processor may try to access an invalid pointer.
2986 self
._editMenu
= menu
2989 def GetUndoAccelerator(self
):
2991 Returns the string that will be appended to the Undo menu item.
2993 return self
._undoAccelerator
2996 def SetUndoAccelerator(self
, accel
):
2998 Sets the string that will be appended to the Redo menu item.
3000 self
._undoAccelerator
= accel
3003 def GetRedoAccelerator(self
):
3005 Returns the string that will be appended to the Redo menu item.
3007 return self
._redoAccelerator
3010 def SetRedoAccelerator(self
, accel
):
3012 Sets the string that will be appended to the Redo menu item.
3014 self
._redoAccelerator
= accel
3017 def SetEditMenu(self
, menu
):
3019 Tells the command processor to update the Undo and Redo items on this
3020 menu as appropriate. Set this to NULL if the menu is about to be
3021 destroyed and command operations may still be performed, or the
3022 command processor may try to access an invalid pointer.
3024 self
._editMenu
= menu
3027 def SetMenuStrings(self
):
3029 Sets the menu labels according to the currently set menu and the
3030 current command state.
3032 if self
.GetEditMenu() != None:
3033 undoCommand
= self
._GetCurrentCommand
()
3034 redoCommand
= self
._GetCurrentRedoCommand
()
3035 undoItem
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
)
3036 redoItem
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
)
3037 if self
.GetUndoAccelerator():
3038 undoAccel
= '\t' + self
.GetUndoAccelerator()
3041 if self
.GetRedoAccelerator():
3042 redoAccel
= '\t' + self
.GetRedoAccelerator()
3045 if undoCommand
and undoItem
and undoCommand
.CanUndo():
3046 undoItem
.SetText(_("Undo ") + undoCommand
.GetName() + undoAccel
)
3047 #elif undoCommand and not undoCommand.CanUndo():
3048 # undoItem.SetText(_("Can't Undo") + undoAccel)
3050 undoItem
.SetText(_("Undo" + undoAccel
))
3051 if redoCommand
and redoItem
:
3052 redoItem
.SetText(_("Redo ") + redoCommand
.GetName() + redoAccel
)
3054 redoItem
.SetText(_("Redo") + redoAccel
)
3059 Returns true if the currently-active command can be undone, false
3062 if self
._GetCurrentCommand
() == None:
3064 return self
._GetCurrentCommand
().CanUndo()
3069 Returns true if the currently-active command can be redone, false
3072 return self
._GetCurrentRedoCommand
() != None
3075 def Submit(self
, command
, storeIt
= True):
3077 Submits a new command to the command processor. The command processor
3078 calls wxCommand::Do to execute the command; if it succeeds, the
3079 command is stored in the history list, and the associated edit menu
3080 (if any) updated appropriately. If it fails, the command is deleted
3081 immediately. Once Submit has been called, the passed command should
3082 not be deleted directly by the application.
3084 storeIt indicates whether the successful command should be stored in
3088 if done
and storeIt
:
3089 self
._commands
.append(command
)
3090 if self
._maxCommands
> -1:
3091 if len(self
._commands
) > self
._maxCommands
:
3092 del self
._commands
[0]
3098 Redoes the command just undone.
3100 cmd
= self
._GetCurrentRedoCommand
()
3105 self
._commands
.append(self
._redoCommands
.pop())
3111 Undoes the command just executed.
3113 cmd
= self
._GetCurrentCommand
()
3118 self
._redoCommands
.append(self
._commands
.pop())