1 #----------------------------------------------------------------------------
3 # Purpose: Port of the wxWindows docview classes
9 # Copyright: (c) 2003-2005 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
10 # License: wxWindows license
11 #----------------------------------------------------------------------------
21 #----------------------------------------------------------------------
23 #----------------------------------------------------------------------
30 DEFAULT_DOCMAN_FLAGS
= DOC_SDI
& DOC_OPEN_ONCE
33 TEMPLATE_INVISIBLE
= 2
34 DEFAULT_TEMPLATE_FLAGS
= TEMPLATE_VISIBLE
39 #----------------------------------------------------------------------
40 # Convenience functions from wxWindows used in docview
41 #----------------------------------------------------------------------
44 def FileNameFromPath(path
):
46 Returns the filename for a full path.
48 return os
.path
.split(path
)[1]
50 def FindExtension(path
):
52 Returns the extension of a filename for a full path.
54 return os
.path
.splitext(path
)[1].lower()
58 Returns True if the path exists.
60 return os
.path
.isfile(path
)
64 Returns the path of a full path without the filename.
66 return os
.path
.split(path
)[0]
69 #----------------------------------------------------------------------
70 # Document/View Classes
71 #----------------------------------------------------------------------
74 class Document(wx
.EvtHandler
):
76 The document class can be used to model an application's file-based data. It
77 is part of the document/view framework supported by wxWindows, and cooperates
78 with the wxView, wxDocTemplate and wxDocManager classes.
80 Note this wxPython version also keeps track of the modification date of the
81 document and if it changes on disk outside of the application, we will warn the
82 user before saving to avoid clobbering the file.
86 def __init__(self
, parent
= None):
88 Constructor. Define your own default constructor to initialize
89 application-specific data.
91 wx
.EvtHandler
.__init
__(self
)
93 self
._documentParent
= parent
94 self
._documentTemplate
= None
95 self
._commandProcessor
= None
96 self
._savedYet
= False
97 self
._writeable
= True
99 self
._documentTitle
= None
100 self
._documentFile
= None
101 self
._documentTypeName
= None
102 self
._documentModified
= False
103 self
._documentModificationDate
= None
104 self
._documentViews
= []
107 def ProcessEvent(self
, event
):
109 Processes an event, searching event tables and calling zero or more
110 suitable event handler function(s). Note that the ProcessEvent
111 method is called from the wxPython docview framework directly since
112 wxPython does not have a virtual ProcessEvent function.
117 def GetFilename(self
):
119 Gets the filename associated with this document, or "" if none is
122 return self
._documentFile
127 Gets the title for this document. The document title is used for an
128 associated frame (if any), and is usually constructed by the framework
131 return self
._documentTitle
134 def SetTitle(self
, title
):
136 Sets the title for this document. The document title is used for an
137 associated frame (if any), and is usually constructed by the framework
140 self
._documentTitle
= title
143 def GetDocumentName(self
):
145 The document type name given to the wxDocTemplate constructor,
146 copied to this document when the document is created. If several
147 document templates are created that use the same document type, this
148 variable is used in wxDocManager::CreateView to collate a list of
149 alternative view types that can be used on this kind of document.
151 return self
._documentTypeName
154 def SetDocumentName(self
, name
):
156 Sets he document type name given to the wxDocTemplate constructor,
157 copied to this document when the document is created. If several
158 document templates are created that use the same document type, this
159 variable is used in wxDocManager::CreateView to collate a list of
160 alternative view types that can be used on this kind of document. Do
161 not change the value of this variable.
163 self
._documentTypeName
= name
166 def GetDocumentSaved(self
):
168 Returns True if the document has been saved. This method has been
169 added to wxPython and is not in wxWindows.
171 return self
._savedYet
174 def SetDocumentSaved(self
, saved
= True):
176 Sets whether the document has been saved. This method has been
177 added to wxPython and is not in wxWindows.
179 self
._savedYet
= saved
182 def GetCommandProcessor(self
):
184 Returns the command processor associated with this document.
186 return self
._commandProcessor
189 def SetCommandProcessor(self
, processor
):
191 Sets the command processor to be used for this document. The document
192 will then be responsible for its deletion. Normally you should not
193 call this; override OnCreateCommandProcessor instead.
195 self
._commandProcessor
= processor
198 def IsModified(self
):
200 Returns true if the document has been modified since the last save,
201 false otherwise. You may need to override this if your document view
202 maintains its own record of being modified (for example if using
203 wxTextWindow to view and edit the document).
205 return self
._documentModified
208 def Modify(self
, modify
):
210 Call with true to mark the document as modified since the last save,
211 false otherwise. You may need to override this if your document view
212 maintains its own record of being modified (for example if using
213 xTextWindow to view and edit the document).
215 self
._documentModified
= modify
218 def SetDocumentModificationDate(self
):
220 Saves the file's last modification date.
221 This is used to check if the file has been modified outside of the application.
222 This method has been added to wxPython and is not in wxWindows.
224 self
._documentModificationDate
= os
.path
.getmtime(self
.GetFilename())
227 def GetDocumentModificationDate(self
):
229 Returns the file's modification date when it was loaded from disk.
230 This is used to check if the file has been modified outside of the application.
231 This method has been added to wxPython and is not in wxWindows.
233 return self
._documentModificationDate
238 Returns the list whose elements are the views on the document.
240 return self
._documentViews
243 def GetDocumentTemplate(self
):
245 Returns the template that created the document.
247 return self
._documentTemplate
250 def SetDocumentTemplate(self
, template
):
252 Sets the template that created the document. Should only be called by
255 self
._documentTemplate
= template
258 def DeleteContents(self
):
260 Deletes the contents of the document. Override this method as
268 Destructor. Removes itself from the document manager.
270 self
.DeleteContents()
271 if self
.GetDocumentManager():
272 self
.GetDocumentManager().RemoveDocument(self
)
273 wx
.EvtHandler
.Destroy(self
)
278 Closes the document, by calling OnSaveModified and then (if this true)
279 OnCloseDocument. This does not normally delete the document object:
280 use DeleteAllViews to do this implicitly.
282 if self
.OnSaveModified():
283 if self
.OnCloseDocument():
291 def OnCloseDocument(self
):
293 The default implementation calls DeleteContents (an empty
294 implementation) sets the modified flag to false. Override this to
295 supply additional behaviour when the document is closed with Close.
298 self
.DeleteContents()
303 def DeleteAllViews(self
):
305 Calls wxView.Close and deletes each view. Deleting the final view will
306 implicitly delete the document itself, because the wxView destructor
307 calls RemoveView. This in turns calls wxDocument::OnChangedViewList,
308 whose default implemention is to save and delete the document if no
311 manager
= self
.GetDocumentManager()
312 for view
in self
._documentViews
:
315 if self
in manager
.GetDocuments():
320 def GetFirstView(self
):
322 A convenience function to get the first view for a document, because
323 in many cases a document will only have a single view.
325 if len(self
._documentViews
) == 0:
327 return self
._documentViews
[0]
330 def GetDocumentManager(self
):
332 Returns the associated document manager.
334 if self
._documentTemplate
:
335 return self
._documentTemplate
.GetDocumentManager()
339 def OnNewDocument(self
):
341 The default implementation calls OnSaveModified and DeleteContents,
342 makes a default title for the document, and notifies the views that
343 the filename (in fact, the title) has changed.
345 if not self
.OnSaveModified() or not self
.OnCloseDocument():
347 self
.DeleteContents()
349 self
.SetDocumentSaved(False)
350 name
= self
.GetDocumentManager().MakeDefaultName()
352 self
.SetFilename(name
, notifyViews
= True)
357 Saves the document by calling OnSaveDocument if there is an associated
358 filename, or SaveAs if there is no filename.
360 if not self
.IsModified(): # and self._savedYet: This was here, but if it is not modified who cares if it hasn't been saved yet?
363 """ check for file modification outside of application """
364 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
365 msgTitle
= wx
.GetApp().GetAppName()
367 msgTitle
= _("Application")
368 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
370 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
371 self
.GetDocumentWindow())
377 else: # elif res == wx.CANCEL:
380 if not self
._documentFile
or not self
._savedYet
:
382 return self
.OnSaveDocument(self
._documentFile
)
387 Prompts the user for a file to save to, and then calls OnSaveDocument.
389 docTemplate
= self
.GetDocumentTemplate()
393 descr
= docTemplate
.GetDescription() + _(" (") + docTemplate
.GetFileFilter() + _(") |") + docTemplate
.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
394 filename
= wx
.FileSelector(_("Save As"),
395 docTemplate
.GetDirectory(),
396 FileNameFromPath(self
.GetFilename()),
397 docTemplate
.GetDefaultExtension(),
399 flags
= wx
.SAVE | wx
.OVERWRITE_PROMPT
,
400 parent
= self
.GetDocumentWindow())
404 name
, ext
= os
.path
.splitext(filename
)
406 filename
+= '.' + docTemplate
.GetDefaultExtension()
408 self
.SetFilename(filename
)
409 self
.SetTitle(FileNameFromPath(filename
))
411 for view
in self
._documentViews
:
412 view
.OnChangeFilename()
414 if not self
.OnSaveDocument(filename
):
417 if docTemplate
.FileMatchesTemplate(filename
):
418 self
.GetDocumentManager().AddFileToHistory(filename
)
423 def OnSaveDocument(self
, filename
):
425 Constructs an output file for the given filename (which must
426 not be empty), and calls SaveObject. If SaveObject returns true, the
427 document is set to unmodified; otherwise, an error message box is
433 msgTitle
= wx
.GetApp().GetAppName()
435 msgTitle
= _("File Error")
437 backupFilename
= None
439 # if current file exists, move it to a safe place temporarily
440 if os
.path
.exists(filename
):
442 # Check if read-only.
443 if not os
.access(filename
, os
.W_OK
):
444 wx
.MessageBox("Could not save '%s'. No write permission to overwrite existing file." % FileNameFromPath(filename
),
446 wx
.OK | wx
.ICON_EXCLAMATION
,
447 self
.GetDocumentWindow())
451 backupFilename
= "%s.bak%s" % (filename
, i
)
452 while os
.path
.exists(backupFilename
):
454 backupFilename
= "%s.bak%s" % (filename
, i
)
455 os
.rename(filename
, backupFilename
)
457 fileObject
= file(filename
, 'w')
458 self
.SaveObject(fileObject
)
461 os
.remove(backupFilename
)
463 # save failed, restore old file
466 os
.rename(backupFilename
, filename
)
467 self
.SetDocumentModificationDate()
469 wx
.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
471 wx
.OK | wx
.ICON_EXCLAMATION
,
472 self
.GetDocumentWindow())
475 self
.SetFilename(filename
, True)
477 self
.SetDocumentModificationDate()
478 self
.SetDocumentSaved(True)
479 #if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
480 # wx.FileName(file).MacSetDefaultTypeAndCreator()
484 def OnOpenDocument(self
, filename
):
486 Constructs an input file for the given filename (which must not
487 be empty), and calls LoadObject. If LoadObject returns true, the
488 document is set to unmodified; otherwise, an error message box is
489 displayed. The document's views are notified that the filename has
490 changed, to give windows an opportunity to update their titles. All of
491 the document's views are then updated.
493 if not self
.OnSaveModified():
496 msgTitle
= wx
.GetApp().GetAppName()
498 msgTitle
= _("File Error")
500 fileObject
= file(filename
, 'r')
502 self
.LoadObject(fileObject
)
504 wx
.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
506 wx
.OK | wx
.ICON_EXCLAMATION
,
507 self
.GetDocumentWindow())
510 self
.SetFilename(filename
, True)
512 self
.SetDocumentModificationDate()
513 self
.SetDocumentSaved(True)
514 self
.UpdateAllViews()
518 def LoadObject(self
, file):
520 Override this function and call it from your own LoadObject before
521 loading your own data. LoadObject is called by the framework
522 automatically when the document contents need to be loaded.
524 Note that the wxPython version simply sends you a Python file object,
525 so you can use pickle.
530 def SaveObject(self
, file):
532 Override this function and call it from your own SaveObject before
533 saving your own data. SaveObject is called by the framework
534 automatically when the document contents need to be saved.
536 Note that the wxPython version simply sends you a Python file object,
537 so you can use pickle.
544 Override this function to revert the document to its last saved state.
549 def GetPrintableName(self
):
551 Copies a suitable document name into the supplied name buffer.
552 The default function uses the title, or if there is no title, uses the
553 filename; or if no filename, the string 'Untitled'.
555 if self
._documentTitle
:
556 return self
._documentTitle
557 elif self
._documentFile
:
558 return FileNameFromPath(self
._documentFile
)
563 def GetDocumentWindow(self
):
565 Intended to return a suitable window for using as a parent for
566 document-related dialog boxes. By default, uses the frame associated
569 if len(self
._documentViews
) > 0:
570 return self
._documentViews
[0].GetFrame()
572 return wx
.GetApp().GetTopWindow()
575 def OnCreateCommandProcessor(self
):
577 Override this function if you want a different (or no) command
578 processor to be created when the document is created. By default, it
579 returns an instance of wxCommandProcessor.
581 return CommandProcessor()
584 def OnSaveModified(self
):
586 If the document has been modified, prompts the user to ask if the
587 changes should be changed. If the user replies Yes, the Save function
588 is called. If No, the document is marked as unmodified and the
589 function succeeds. If Cancel, the function fails.
591 if not self
.IsModified():
594 """ check for file modification outside of application """
595 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
596 msgTitle
= wx
.GetApp().GetAppName()
598 msgTitle
= _("Warning")
599 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
601 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
602 self
.GetDocumentWindow())
608 return wx
.lib
.docview
.Document
.Save(self
)
609 else: # elif res == wx.CANCEL:
612 msgTitle
= wx
.GetApp().GetAppName()
614 msgTitle
= _("Warning")
616 res
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(),
618 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
619 self
.GetDocumentWindow())
626 else: # elif res == wx.CANCEL:
632 Called by printing framework to draw the view.
637 def AddView(self
, view
):
639 If the view is not already in the list of views, adds the view and
640 calls OnChangedViewList.
642 if not view
in self
._documentViews
:
643 self
._documentViews
.append(view
)
644 self
.OnChangedViewList()
648 def RemoveView(self
, view
):
650 Removes the view from the document's list of views, and calls
653 if view
in self
._documentViews
:
654 self
._documentViews
.remove(view
)
655 self
.OnChangedViewList()
659 def OnCreate(self
, path
, flags
):
661 The default implementation calls DeleteContents (an empty
662 implementation) sets the modified flag to false. Override this to
663 supply additional behaviour when the document is closed with Close.
665 return self
.GetDocumentTemplate().CreateView(self
, flags
)
668 def OnChangedViewList(self
):
670 Called when a view is added to or deleted from this document. The
671 default implementation saves and deletes the document if no views
672 exist (the last one has just been removed).
674 if len(self
._documentViews
) == 0:
675 if self
.OnSaveModified():
676 pass # C version does a delete but Python will garbage collect
679 def UpdateAllViews(self
, sender
= None, hint
= None):
681 Updates all views. If sender is non-NULL, does not update this view.
682 hint represents optional information to allow a view to optimize its
685 for view
in self
._documentViews
:
687 view
.OnUpdate(sender
, hint
)
690 def NotifyClosing(self
):
692 Notifies the views that the document is going to close.
694 for view
in self
._documentViews
:
695 view
.OnClosingDocument()
698 def SetFilename(self
, filename
, notifyViews
= False):
700 Sets the filename for this document. Usually called by the framework.
701 If notifyViews is true, wxView.OnChangeFilename is called for all
704 self
._documentFile
= filename
706 for view
in self
._documentViews
:
707 view
.OnChangeFilename()
710 def GetWriteable(self
):
712 Returns true if the document can be written to its accociated file path.
713 This method has been added to wxPython and is not in wxWindows.
715 if not self
._writeable
:
717 if not self
._documentFile
: # Doesn't exist, do a save as
720 return os
.access(self
._documentFile
, os
.W_OK
)
723 def SetWriteable(self
, writeable
):
725 Set to False if the document can not be saved. This will disable the ID_SAVE_AS
726 event and is useful for custom documents that should not be saveable. The ID_SAVE
727 event can be disabled by never Modifying the document. This method has been added
728 to wxPython and is not in wxWindows.
730 self
._writeable
= writeable
733 class View(wx
.EvtHandler
):
735 The view class can be used to model the viewing and editing component of
736 an application's file-based data. It is part of the document/view
737 framework supported by wxWindows, and cooperates with the wxDocument,
738 wxDocTemplate and wxDocManager classes.
743 Constructor. Define your own default constructor to initialize
744 application-specific data.
746 wx
.EvtHandler
.__init
__(self
)
747 self
._viewDocument
= None
748 self
._viewFrame
= None
753 Destructor. Removes itself from the document's list of views.
755 if self
._viewDocument
:
756 self
._viewDocument
.RemoveView(self
)
757 wx
.EvtHandler
.Destroy(self
)
760 def ProcessEvent(self
, event
):
762 Processes an event, searching event tables and calling zero or more
763 suitable event handler function(s). Note that the ProcessEvent
764 method is called from the wxPython docview framework directly since
765 wxPython does not have a virtual ProcessEvent function.
767 if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
):
773 def ProcessUpdateUIEvent(self
, event
):
775 Processes a UI event, searching event tables and calling zero or more
776 suitable event handler function(s). Note that the ProcessEvent
777 method is called from the wxPython docview framework directly since
778 wxPython does not have a virtual ProcessEvent function.
783 def OnActivateView(self
, activate
, activeView
, deactiveView
):
785 Called when a view is activated by means of wxView::Activate. The
786 default implementation does nothing.
791 def OnClosingDocument(self
):
793 Override this to clean up the view when the document is being closed.
794 The default implementation does nothing.
799 def OnDraw(self
, dc
):
801 Override this to draw the view for the printing framework. The
802 default implementation does nothing.
807 def OnPrint(self
, dc
, info
):
809 Override this to print the view for the printing framework. The
810 default implementation calls View.OnDraw.
815 def OnUpdate(self
, sender
, hint
):
817 Called when the view should be updated. sender is a pointer to the
818 view that sent the update request, or NULL if no single view requested
819 the update (for instance, when the document is opened). hint is as yet
820 unused but may in future contain application-specific information for
821 making updating more efficient.
826 def OnChangeFilename(self
):
828 Called when the filename has changed. The default implementation
829 constructs a suitable title and sets the title of the view frame (if
833 appName
= wx
.GetApp().GetAppName()
834 if not self
.GetDocument():
840 if appName
and isinstance(self
.GetFrame(), DocChildFrame
): # Only need app name in title for SDI
841 title
= appName
+ _(" - ")
844 self
.GetFrame().SetTitle(title
+ self
.GetDocument().GetPrintableName())
847 def GetDocument(self
):
849 Returns the document associated with the view.
851 return self
._viewDocument
854 def SetDocument(self
, doc
):
856 Associates the given document with the view. Normally called by the
859 self
._viewDocument
= doc
864 def GetViewName(self
):
866 Gets the name associated with the view (passed to the wxDocTemplate
867 constructor). Not currently used by the framework.
869 return self
._viewTypeName
872 def SetViewName(self
, name
):
874 Sets the view type name. Should only be called by the framework.
876 self
._viewTypeName
= name
879 def Close(self
, deleteWindow
= True):
881 Closes the view by calling OnClose. If deleteWindow is true, this
882 function should delete the window associated with the view.
884 if self
.OnClose(deleteWindow
= deleteWindow
):
890 def Activate(self
, activate
= True):
892 Call this from your view frame's OnActivate member to tell the
893 framework which view is currently active. If your windowing system
894 doesn't call OnActivate, you may need to call this function from
895 OnMenuCommand or any place where you know the view must be active, and
896 the framework will need to get the current view.
898 The prepackaged view frame wxDocChildFrame calls wxView.Activate from
899 its OnActivate member and from its OnMenuCommand member.
901 if self
.GetDocument() and self
.GetDocumentManager():
902 self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView())
903 self
.GetDocumentManager().ActivateView(self
, activate
)
906 def OnClose(self
, deleteWindow
= True):
908 Implements closing behaviour. The default implementation calls
909 wxDocument.Close to close the associated document. Does not delete the
910 view. The application may wish to do some cleaning up operations in
911 this function, if a call to wxDocument::Close succeeded. For example,
912 if your application's all share the same window, you need to
913 disassociate the window from the view and perhaps clear the window. If
914 deleteWindow is true, delete the frame associated with the view.
916 if self
.GetDocument():
917 return self
.GetDocument().Close()
922 def OnCreate(self
, doc
, flags
):
924 wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just
925 after the wxDocTemplate creates the wxView, it calls wxView::OnCreate.
926 In its OnCreate member function, the wxView can create a
927 wxDocChildFrame or a derived class. This wxDocChildFrame provides user
928 interface elements to view and/or edit the contents of the wxDocument.
930 By default, simply returns true. If the function returns false, the
931 view will be deleted.
936 def OnCreatePrintout(self
):
938 Returns a wxPrintout object for the purposes of printing. It should
939 create a new object every time it is called; the framework will delete
942 By default, this function returns an instance of wxDocPrintout, which
943 prints and previews one page by calling wxView.OnDraw.
945 Override to return an instance of a class other than wxDocPrintout.
947 return DocPrintout(self
)
952 Gets the frame associated with the view (if any). Note that this
953 "frame" is not a wxFrame at all in the generic MDI implementation
954 which uses the notebook pages instead of the frames and this is why
955 this method returns a wxWindow and not a wxFrame.
957 return self
._viewFrame
960 def SetFrame(self
, frame
):
962 Sets the frame associated with this view. The application should call
963 this if possible, to tell the view about the frame. See GetFrame for
964 the explanation about the mismatch between the "Frame" in the method
965 name and the type of its parameter.
967 self
._viewFrame
= frame
970 def GetDocumentManager(self
):
972 Returns the document manager instance associated with this view.
974 if self
._viewDocument
:
975 return self
.GetDocument().GetDocumentManager()
980 class DocTemplate(wx
.Object
):
982 The wxDocTemplate class is used to model the relationship between a
983 document class and a view class.
987 def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
= DEFAULT_TEMPLATE_FLAGS
, icon
= None):
989 Constructor. Create instances dynamically near the start of your
990 application after creating a wxDocManager instance, and before doing
991 any document or view operations.
993 manager is the document manager object which manages this template.
995 description is a short description of what the template is for. This
996 string will be displayed in the file filter list of Windows file
999 filter is an appropriate file filter such as *.txt.
1001 dir is the default directory to use for file selectors.
1003 ext is the default file extension (such as txt).
1005 docTypeName is a name that should be unique for a given type of
1006 document, used for gathering a list of views relevant to a
1007 particular document.
1009 viewTypeName is a name that should be unique for a given view.
1011 docClass is a Python class. If this is not supplied, you will need to
1012 derive a new wxDocTemplate class and override the CreateDocument
1013 member to return a new document instance on demand.
1015 viewClass is a Python class. If this is not supplied, you will need to
1016 derive a new wxDocTemplate class and override the CreateView member to
1017 return a new view instance on demand.
1019 flags is a bit list of the following:
1020 wx.TEMPLATE_VISIBLE The template may be displayed to the user in
1023 wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in
1026 wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE.
1028 self
._docManager
= manager
1029 self
._description
= description
1030 self
._fileFilter
= filter
1031 self
._directory
= dir
1032 self
._defaultExt
= ext
1033 self
._docTypeName
= docTypeName
1034 self
._viewTypeName
= viewTypeName
1035 self
._docType
= docType
1036 self
._viewType
= viewType
1040 self
._docManager
.AssociateTemplate(self
)
1043 def GetDefaultExtension(self
):
1045 Returns the default file extension for the document data, as passed to
1046 the document template constructor.
1048 return self
._defaultExt
1051 def SetDefaultExtension(self
, defaultExt
):
1053 Sets the default file extension.
1055 self
._defaultExt
= defaultExt
1058 def GetDescription(self
):
1060 Returns the text description of this template, as passed to the
1061 document template constructor.
1063 return self
._description
1066 def SetDescription(self
, description
):
1068 Sets the template description.
1070 self
._description
= description
1073 def GetDirectory(self
):
1075 Returns the default directory, as passed to the document template
1078 return self
._directory
1081 def SetDirectory(self
, dir):
1083 Sets the default directory.
1085 self
._directory
= dir
1088 def GetDocumentManager(self
):
1090 Returns the document manager instance for which this template was
1093 return self
._docManager
1096 def SetDocumentManager(self
, manager
):
1098 Sets the document manager instance for which this template was
1099 created. Should not be called by the application.
1101 self
._docManager
= manager
1104 def GetFileFilter(self
):
1106 Returns the file filter, as passed to the document template
1109 return self
._fileFilter
1112 def SetFileFilter(self
, filter):
1114 Sets the file filter.
1116 self
._fileFilter
= filter
1121 Returns the flags, as passed to the document template constructor.
1122 (see the constructor description for more details).
1127 def SetFlags(self
, flags
):
1129 Sets the internal document template flags (see the constructor
1130 description for more details).
1137 Returns the icon, as passed to the document template
1138 constructor. This method has been added to wxPython and is
1144 def SetIcon(self
, flags
):
1146 Sets the icon. This method has been added to wxPython and is not
1152 def GetDocumentType(self
):
1154 Returns the Python document class, as passed to the document template
1157 return self
._docType
1160 def GetViewType(self
):
1162 Returns the Python view class, as passed to the document template
1165 return self
._viewType
1168 def IsVisible(self
):
1170 Returns true if the document template can be shown in user dialogs,
1173 return (self
._flags
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
1176 def GetDocumentName(self
):
1178 Returns the document type name, as passed to the document template
1181 return self
._docTypeName
1184 def GetViewName(self
):
1186 Returns the view type name, as passed to the document template
1189 return self
._viewTypeName
1192 def CreateDocument(self
, path
, flags
):
1194 Creates a new instance of the associated document class. If you have
1195 not supplied a class to the template constructor, you will need to
1196 override this function to return an appropriate document instance.
1198 doc
= self
._docType
()
1199 doc
.SetFilename(path
)
1200 doc
.SetDocumentTemplate(self
)
1201 self
.GetDocumentManager().AddDocument(doc
)
1202 doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor())
1203 if doc
.OnCreate(path
, flags
):
1206 if doc
in self
.GetDocumentManager().GetDocuments():
1207 doc
.DeleteAllViews()
1211 def CreateView(self
, doc
, flags
):
1213 Creates a new instance of the associated document view. If you have
1214 not supplied a class to the template constructor, you will need to
1215 override this function to return an appropriate view instance.
1217 view
= self
._viewType
()
1218 view
.SetDocument(doc
)
1219 if view
.OnCreate(doc
, flags
):
1226 def FileMatchesTemplate(self
, path
):
1228 Returns True if the path's extension matches one of this template's
1229 file filter extensions.
1231 ext
= FindExtension(path
)
1232 if not ext
: return False
1233 return ext
in self
.GetFileFilter()
1234 # return self.GetDefaultExtension() == FindExtension(path)
1237 class DocManager(wx
.EvtHandler
):
1239 The wxDocManager class is part of the document/view framework supported by
1240 wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate
1244 def __init__(self
, flags
= DEFAULT_DOCMAN_FLAGS
, initialize
= True):
1246 Constructor. Create a document manager instance dynamically near the
1247 start of your application before doing any document or view operations.
1249 flags is used in the Python version to indicate whether the document
1250 manager is in DOC_SDI or DOC_MDI mode.
1252 If initialize is true, the Initialize function will be called to
1253 create a default history list object. If you derive from wxDocManager,
1254 you may wish to call the base constructor with false, and then call
1255 Initialize in your own constructor, to allow your own Initialize or
1256 OnCreateFileHistory functions to be called.
1259 wx
.EvtHandler
.__init
__(self
)
1261 self
._defaultDocumentNameCounter
= 1
1263 self
._currentView
= None
1264 self
._lastActiveView
= None
1265 self
._maxDocsOpen
= 10000
1266 self
._fileHistory
= None
1267 self
._templates
= []
1269 self
._lastDirectory
= ""
1274 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
)
1275 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
)
1276 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
)
1277 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
)
1278 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
)
1279 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
)
1280 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
)
1281 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
1282 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
1283 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
)
1284 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
)
1285 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
)
1287 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
)
1288 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
)
1289 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
)
1290 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
)
1291 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
)
1292 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
)
1293 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
)
1294 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
)
1295 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
)
1296 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
)
1297 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
)
1298 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
)
1306 wx
.EvtHandler
.Destroy(self
)
1311 Returns the document manager's flags. This method has been
1312 added to wxPython and is not in wxWindows.
1317 def CloseDocument(self
, doc
, force
= True):
1319 Closes the specified document.
1321 if doc
.Close() or force
:
1322 doc
.DeleteAllViews()
1323 if doc
in self
._docs
:
1329 def CloseDocuments(self
, force
= True):
1331 Closes all currently opened documents.
1333 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
1334 if not self
.CloseDocument(document
, force
):
1336 document
.DeleteAllViews() # Implicitly delete the document when the last view is removed
1340 def Clear(self
, force
= True):
1342 Closes all currently opened document by callling CloseDocuments and
1343 clears the document manager's templates.
1345 if not self
.CloseDocuments(force
):
1347 self
._templates
= []
1351 def Initialize(self
):
1353 Initializes data; currently just calls OnCreateFileHistory. Some data
1354 cannot always be initialized in the constructor because the programmer
1355 must be given the opportunity to override functionality. In fact
1356 Initialize is called from the wxDocManager constructor, but this can
1357 be vetoed by passing false to the second argument, allowing the
1358 derived class's constructor to call Initialize, possibly calling a
1359 different OnCreateFileHistory from the default.
1361 The bottom line: if you're not deriving from Initialize, forget it and
1362 construct wxDocManager with no arguments.
1364 self
.OnCreateFileHistory()
1368 def OnCreateFileHistory(self
):
1370 A hook to allow a derived class to create a different type of file
1371 history. Called from Initialize.
1373 self
._fileHistory
= wx
.FileHistory()
1376 def OnFileClose(self
, event
):
1378 Closes and deletes the currently active document.
1380 doc
= self
.GetCurrentDocument()
1382 doc
.DeleteAllViews()
1383 if doc
in self
._docs
:
1384 self
._docs
.remove(doc
)
1387 def OnFileCloseAll(self
, event
):
1389 Closes and deletes all the currently opened documents.
1391 return self
.CloseDocuments(force
= False)
1394 def OnFileNew(self
, event
):
1396 Creates a new document and reads in the selected file.
1398 self
.CreateDocument('', DOC_NEW
)
1401 def OnFileOpen(self
, event
):
1403 Creates a new document and reads in the selected file.
1405 if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
):
1406 self
.OnOpenFileFailure()
1409 def OnFileRevert(self
, event
):
1411 Reverts the current document by calling wxDocument.Save for the current
1414 doc
= self
.GetCurrentDocument()
1420 def OnFileSave(self
, event
):
1422 Saves the current document by calling wxDocument.Save for the current
1425 doc
= self
.GetCurrentDocument()
1431 def OnFileSaveAs(self
, event
):
1433 Calls wxDocument.SaveAs for the current document.
1435 doc
= self
.GetCurrentDocument()
1441 def OnPrint(self
, event
):
1443 Prints the current document by calling its View's OnCreatePrintout
1446 view
= self
.GetCurrentView()
1450 printout
= view
.OnCreatePrintout()
1452 pdd
= wx
.PrintDialogData()
1453 printer
= wx
.Printer(pdd
)
1454 printer
.Print(view
.GetFrame(), printout
) # , True)
1457 def OnPrintSetup(self
, event
):
1459 Presents the print setup dialog.
1461 view
= self
.GetCurrentView()
1463 parentWin
= view
.GetFrame()
1465 parentWin
= wx
.GetApp().GetTopWindow()
1467 data
= wx
.PrintDialogData()
1468 printDialog
= wx
.PrintDialog(parentWin
, data
)
1469 printDialog
.GetPrintDialogData().SetSetupDialog(True)
1470 printDialog
.ShowModal()
1471 # TODO: Confirm that we don't have to remember PrintDialogData
1474 def OnPreview(self
, event
):
1476 Previews the current document by calling its View's OnCreatePrintout
1479 view
= self
.GetCurrentView()
1483 printout
= view
.OnCreatePrintout()
1485 # Pass two printout objects: for preview, and possible printing.
1486 preview
= wx
.PrintPreview(printout
, view
.OnCreatePrintout())
1487 # 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.
1488 mimicFrame
= wx
.GetApp().GetTopWindow()
1489 frame
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize())
1490 frame
.SetIcon(mimicFrame
.GetIcon())
1491 frame
.SetTitle(mimicFrame
.GetTitle() + _(" - Preview"))
1496 def OnUndo(self
, event
):
1498 Issues an Undo command to the current document's command processor.
1500 doc
= self
.GetCurrentDocument()
1503 if doc
.GetCommandProcessor():
1504 doc
.GetCommandProcessor().Undo()
1507 def OnRedo(self
, event
):
1509 Issues a Redo command to the current document's command processor.
1511 doc
= self
.GetCurrentDocument()
1514 if doc
.GetCommandProcessor():
1515 doc
.GetCommandProcessor().Redo()
1518 def OnUpdateFileOpen(self
, event
):
1520 Updates the user interface for the File Open command.
1525 def OnUpdateFileClose(self
, event
):
1527 Updates the user interface for the File Close command.
1529 event
.Enable(self
.GetCurrentDocument() != None)
1532 def OnUpdateFileCloseAll(self
, event
):
1534 Updates the user interface for the File Close All command.
1536 event
.Enable(self
.GetCurrentDocument() != None)
1539 def OnUpdateFileRevert(self
, event
):
1541 Updates the user interface for the File Revert command.
1543 event
.Enable(self
.GetCurrentDocument() != None)
1546 def OnUpdateFileNew(self
, event
):
1548 Updates the user interface for the File New command.
1553 def OnUpdateFileSave(self
, event
):
1555 Updates the user interface for the File Save command.
1557 doc
= self
.GetCurrentDocument()
1558 event
.Enable(doc
!= None and doc
.IsModified())
1561 def OnUpdateFileSaveAs(self
, event
):
1563 Updates the user interface for the File Save As command.
1565 event
.Enable(self
.GetCurrentDocument() != None and self
.GetCurrentDocument().GetWriteable())
1568 def OnUpdateUndo(self
, event
):
1570 Updates the user interface for the Undo command.
1572 doc
= self
.GetCurrentDocument()
1573 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo())
1574 if doc
and doc
.GetCommandProcessor():
1575 doc
.GetCommandProcessor().SetMenuStrings()
1577 event
.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
1580 def OnUpdateRedo(self
, event
):
1582 Updates the user interface for the Redo command.
1584 doc
= self
.GetCurrentDocument()
1585 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo())
1586 if doc
and doc
.GetCommandProcessor():
1587 doc
.GetCommandProcessor().SetMenuStrings()
1589 event
.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
1592 def OnUpdatePrint(self
, event
):
1594 Updates the user interface for the Print command.
1596 event
.Enable(self
.GetCurrentDocument() != None)
1599 def OnUpdatePrintSetup(self
, event
):
1601 Updates the user interface for the Print Setup command.
1606 def OnUpdatePreview(self
, event
):
1608 Updates the user interface for the Print Preview command.
1610 event
.Enable(self
.GetCurrentDocument() != None)
1613 def GetCurrentView(self
):
1615 Returns the currently active view.
1617 if self
._currentView
:
1618 return self
._currentView
1619 if len(self
._docs
) == 1:
1620 return self
._docs
[0].GetFirstView()
1624 def GetLastActiveView(self
):
1626 Returns the last active view. This is used in the SDI framework where dialogs can be mistaken for a view
1627 and causes the framework to deactivete the current view. This happens when something like a custom dialog box used
1628 to operate on the current view is shown.
1630 if len(self
._docs
) >= 1:
1631 return self
._lastActiveView
1636 def ProcessEvent(self
, event
):
1638 Processes an event, searching event tables and calling zero or more
1639 suitable event handler function(s). Note that the ProcessEvent
1640 method is called from the wxPython docview framework directly since
1641 wxPython does not have a virtual ProcessEvent function.
1643 view
= self
.GetCurrentView()
1645 if view
.ProcessEvent(event
):
1648 if id == wx
.ID_OPEN
:
1649 self
.OnFileOpen(event
)
1651 elif id == wx
.ID_CLOSE
:
1652 self
.OnFileClose(event
)
1654 elif id == wx
.ID_CLOSE_ALL
:
1655 self
.OnFileCloseAll(event
)
1657 elif id == wx
.ID_REVERT
:
1658 self
.OnFileRevert(event
)
1660 elif id == wx
.ID_NEW
:
1661 self
.OnFileNew(event
)
1663 elif id == wx
.ID_SAVE
:
1664 self
.OnFileSave(event
)
1666 elif id == wx
.ID_SAVEAS
:
1667 self
.OnFileSaveAs(event
)
1669 elif id == wx
.ID_UNDO
:
1672 elif id == wx
.ID_REDO
:
1675 elif id == wx
.ID_PRINT
:
1678 elif id == wx
.ID_PRINT_SETUP
:
1679 self
.OnPrintSetup(event
)
1681 elif id == wx
.ID_PREVIEW
:
1682 self
.OnPreview(event
)
1688 def ProcessUpdateUIEvent(self
, event
):
1690 Processes a UI event, searching event tables and calling zero or more
1691 suitable event handler function(s). Note that the ProcessEvent
1692 method is called from the wxPython docview framework directly since
1693 wxPython does not have a virtual ProcessEvent function.
1696 view
= self
.GetCurrentView()
1698 if view
.ProcessUpdateUIEvent(event
):
1700 if id == wx
.ID_OPEN
:
1701 self
.OnUpdateFileOpen(event
)
1703 elif id == wx
.ID_CLOSE
:
1704 self
.OnUpdateFileClose(event
)
1706 elif id == wx
.ID_CLOSE_ALL
:
1707 self
.OnUpdateFileCloseAll(event
)
1709 elif id == wx
.ID_REVERT
:
1710 self
.OnUpdateFileRevert(event
)
1712 elif id == wx
.ID_NEW
:
1713 self
.OnUpdateFileNew(event
)
1715 elif id == wx
.ID_SAVE
:
1716 self
.OnUpdateFileSave(event
)
1718 elif id == wx
.ID_SAVEAS
:
1719 self
.OnUpdateFileSaveAs(event
)
1721 elif id == wx
.ID_UNDO
:
1722 self
.OnUpdateUndo(event
)
1724 elif id == wx
.ID_REDO
:
1725 self
.OnUpdateRedo(event
)
1727 elif id == wx
.ID_PRINT
:
1728 self
.OnUpdatePrint(event
)
1730 elif id == wx
.ID_PRINT_SETUP
:
1731 self
.OnUpdatePrintSetup(event
)
1733 elif id == wx
.ID_PREVIEW
:
1734 self
.OnUpdatePreview(event
)
1740 def CreateDocument(self
, path
, flags
= 0):
1742 Creates a new document in a manner determined by the flags parameter,
1745 wx.lib.docview.DOC_NEW Creates a fresh document.
1746 wx.lib.docview.DOC_SILENT Silently loads the given document file.
1748 If wx.lib.docview.DOC_NEW is present, a new document will be created and returned,
1749 possibly after asking the user for a template to use if there is more
1750 than one document template. If wx.lib.docview.DOC_SILENT is present, a new document
1751 will be created and the given file loaded into it. If neither of these
1752 flags is present, the user will be presented with a file selector for
1753 the file to load, and the template to use will be determined by the
1754 extension (Windows) or by popping up a template choice list (other
1757 If the maximum number of documents has been reached, this function
1758 will delete the oldest currently loaded document before creating a new
1761 wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE flag.
1764 for temp
in self
._templates
:
1765 if temp
.IsVisible():
1766 templates
.append(temp
)
1767 if len(templates
) == 0:
1770 if len(self
.GetDocuments()) >= self
._maxDocsOpen
:
1771 doc
= self
.GetDocuments()[0]
1772 if not self
.CloseDocument(doc
, False):
1776 if len(templates
) == 1:
1778 newDoc
= temp
.CreateDocument(path
, flags
)
1780 newDoc
.SetDocumentName(temp
.GetDocumentName())
1781 newDoc
.SetDocumentTemplate(temp
)
1782 newDoc
.OnNewDocument()
1785 temp
= self
.SelectDocumentType(templates
)
1787 newDoc
= temp
.CreateDocument(path
, flags
)
1789 newDoc
.SetDocumentName(temp
.GetDocumentName())
1790 newDoc
.SetDocumentTemplate(temp
)
1791 newDoc
.OnNewDocument()
1796 if path
and flags
& DOC_SILENT
:
1797 temp
= self
.FindTemplateForPath(path
)
1799 temp
, path
= self
.SelectDocumentPath(templates
, path
, flags
)
1802 if self
.GetFlags() & DOC_OPEN_ONCE
:
1803 for document
in self
._docs
:
1804 if document
.GetFilename() == path
:
1805 firstView
= document
.GetFirstView()
1806 if firstView
and firstView
.GetFrame():
1807 firstView
.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
1808 if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
1809 firstView
.GetFrame().Iconize(False)
1813 newDoc
= temp
.CreateDocument(path
, flags
)
1815 newDoc
.SetDocumentName(temp
.GetDocumentName())
1816 newDoc
.SetDocumentTemplate(temp
)
1817 if not newDoc
.OnOpenDocument(path
):
1818 newDoc
.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1819 newDoc
.GetFirstView().GetFrame().Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
1821 self
.AddFileToHistory(path
)
1827 def CreateView(self
, document
, flags
= 0):
1829 Creates a new view for the given document. If more than one view is
1830 allowed for the document (by virtue of multiple templates mentioning
1831 the same document type), a choice of view is presented to the user.
1834 for temp
in self
._templates
:
1835 if temp
.IsVisible():
1836 if temp
.GetDocumentName() == doc
.GetDocumentName():
1837 templates
.append(temp
)
1838 if len(templates
) == 0:
1841 if len(templates
) == 1:
1843 view
= temp
.CreateView(doc
, flags
)
1845 view
.SetViewName(temp
.GetViewName())
1848 temp
= SelectViewType(templates
)
1850 view
= temp
.CreateView(doc
, flags
)
1852 view
.SetViewName(temp
.GetViewName())
1858 def DeleteTemplate(self
, template
, flags
):
1860 Placeholder, not yet implemented in wxWindows.
1865 def FlushDoc(self
, doc
):
1867 Placeholder, not yet implemented in wxWindows.
1872 def MatchTemplate(self
, path
):
1874 Placeholder, not yet implemented in wxWindows.
1879 def GetCurrentDocument(self
):
1881 Returns the document associated with the currently active view (if any).
1883 view
= self
.GetCurrentView()
1885 return view
.GetDocument()
1890 def MakeDefaultName(self
):
1892 Returns a suitable default name. This is implemented by appending an
1893 integer counter to the string "Untitled" and incrementing the counter.
1895 name
= _("Untitled %d") % self
._defaultDocumentNameCounter
1896 self
._defaultDocumentNameCounter
= self
._defaultDocumentNameCounter
+ 1
1900 def MakeFrameTitle(self
):
1902 Returns a suitable title for a document frame. This is implemented by
1903 appending the document name to the application name.
1905 appName
= wx
.GetApp().GetAppName()
1909 docName
= doc
.GetPrintableName()
1910 title
= docName
+ _(" - ") + appName
1914 def AddFileToHistory(self
, fileName
):
1916 Adds a file to the file history list, if we have a pointer to an
1917 appropriate file menu.
1919 if self
._fileHistory
:
1920 self
._fileHistory
.AddFileToHistory(fileName
)
1923 def RemoveFileFromHistory(self
, i
):
1925 Removes a file from the file history list, if we have a pointer to an
1926 appropriate file menu.
1928 if self
._fileHistory
:
1929 self
._fileHistory
.RemoveFileFromHistory(i
)
1932 def GetFileHistory(self
):
1934 Returns the file history.
1936 return self
._fileHistory
1939 def GetHistoryFile(self
, i
):
1941 Returns the file at index i from the file history.
1943 if self
._fileHistory
:
1944 return self
._fileHistory
.GetHistoryFile(i
)
1949 def FileHistoryUseMenu(self
, menu
):
1951 Use this menu for appending recently-visited document filenames, for
1952 convenient access. Calling this function with a valid menu enables the
1953 history list functionality.
1955 Note that you can add multiple menus using this function, to be
1956 managed by the file history object.
1958 if self
._fileHistory
:
1959 self
._fileHistory
.UseMenu(menu
)
1962 def FileHistoryRemoveMenu(self
, menu
):
1964 Removes the given menu from the list of menus managed by the file
1967 if self
._fileHistory
:
1968 self
._fileHistory
.RemoveMenu(menu
)
1971 def FileHistoryLoad(self
, config
):
1973 Loads the file history from a config object.
1975 if self
._fileHistory
:
1976 self
._fileHistory
.Load(config
)
1979 def FileHistorySave(self
, config
):
1981 Saves the file history into a config object. This must be called
1982 explicitly by the application.
1984 if self
._fileHistory
:
1985 self
._fileHistory
.Save(config
)
1988 def FileHistoryAddFilesToMenu(self
, menu
= None):
1990 Appends the files in the history list, to all menus managed by the
1991 file history object.
1993 If menu is specified, appends the files in the history list to the
1996 if self
._fileHistory
:
1998 self
._fileHistory
.AddFilesToThisMenu(menu
)
2000 self
._fileHistory
.AddFilesToMenu()
2003 def GetHistoryFilesCount(self
):
2005 Returns the number of files currently stored in the file history.
2007 if self
._fileHistory
:
2008 return self
._fileHistory
.GetNoHistoryFiles()
2013 def FindTemplateForPath(self
, path
):
2015 Given a path, try to find template that matches the extension. This is
2016 only an approximate method of finding a template for creating a
2019 for temp
in self
._templates
:
2020 if temp
.FileMatchesTemplate(path
):
2025 def FindSuitableParent(self
):
2027 Returns a parent frame or dialog, either the frame with the current
2028 focus or if there is no current focus the application's top frame.
2030 parent
= wx
.GetApp().GetTopWindow()
2031 focusWindow
= wx
.Window_FindFocus()
2033 while focusWindow
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
):
2034 focusWindow
= focusWindow
.GetParent()
2036 parent
= focusWindow
2040 def SelectDocumentPath(self
, templates
, flags
, save
):
2042 Under Windows, pops up a file selector with a list of filters
2043 corresponding to document templates. The wxDocTemplate corresponding
2044 to the selected file's extension is returned.
2046 On other platforms, if there is more than one document template a
2047 choice list is popped up, followed by a file selector.
2049 This function is used in wxDocManager.CreateDocument.
2051 if wx
.Platform
== "__WXMSW__" or wx
.Platform
== "__WXGTK__" or wx
.Platform
== "__WXMAC__":
2054 for temp
in templates
:
2055 if temp
.IsVisible():
2057 descr
= descr
+ _('|')
2058 allfilter
= allfilter
+ _(';')
2059 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
2060 allfilter
= allfilter
+ temp
.GetFileFilter()
2061 descr
= _("All") + _(" (") + allfilter
+ _(") |") + allfilter
+ _('|') + descr
# spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
2065 path
= wx
.FileSelector(_("Select a File"),
2066 self
._lastDirectory
,
2069 flags
= wx
.HIDE_READONLY
,
2070 parent
= self
.FindSuitableParent())
2072 if not FileExists(path
):
2073 msgTitle
= wx
.GetApp().GetAppName()
2075 msgTitle
= _("File Error")
2076 wx
.MessageBox("Could not open '%s'." % FileNameFromPath(path
),
2078 wx
.OK | wx
.ICON_EXCLAMATION
,
2081 self
._lastDirectory
= PathOnly(path
)
2083 theTemplate
= self
.FindTemplateForPath(path
)
2084 return (theTemplate
, path
)
2089 def OnOpenFileFailure(self
):
2091 Called when there is an error opening a file.
2096 def SelectDocumentType(self
, temps
, sort
= False):
2098 Returns a document template by asking the user (if there is more than
2099 one template). This function is used in wxDocManager.CreateDocument.
2103 templates - list of templates from which to choose a desired template.
2105 sort - If more than one template is passed in in templates, then this
2106 parameter indicates whether the list of templates that the user will
2107 have to choose from is sorted or not when shown the choice box dialog.
2112 if temp
.IsVisible():
2114 for temp2
in templates
:
2115 if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName():
2119 templates
.append(temp
)
2121 if len(templates
) == 0:
2123 elif len(templates
) == 1:
2128 return cmp(a
.GetDescription(), b
.GetDescription())
2129 templates
.sort(tempcmp
)
2132 for temp
in templates
:
2133 strings
.append(temp
.GetDescription())
2135 res
= wx
.GetSingleChoiceIndex(_("Select a document type:"),
2138 self
.FindSuitableParent())
2141 return templates
[res
]
2144 def SelectViewType(self
, temps
, sort
= False):
2146 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.
2151 if temp
.IsVisible() and temp
.GetViewTypeName():
2152 if temp
.GetViewName() not in strings
:
2153 templates
.append(temp
)
2154 strings
.append(temp
.GetViewTypeName())
2156 if len(templates
) == 0:
2158 elif len(templates
) == 1:
2163 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName())
2164 templates
.sort(tempcmp
)
2166 res
= wx
.GetSingleChoiceIndex(_("Select a document view:"),
2169 self
.FindSuitableParent())
2172 return templates
[res
]
2175 def GetTemplates(self
):
2177 Returns the document manager's template list. This method has been added to
2178 wxPython and is not in wxWindows.
2180 return self
._templates
2183 def AssociateTemplate(self
, docTemplate
):
2185 Adds the template to the document manager's template list.
2187 if docTemplate
not in self
._templates
:
2188 self
._templates
.append(docTemplate
)
2191 def DisassociateTemplate(self
, docTemplate
):
2193 Removes the template from the list of templates.
2195 self
._templates
.remove(docTemplate
)
2198 def AddDocument(self
, document
):
2200 Adds the document to the list of documents.
2202 if document
not in self
._docs
:
2203 self
._docs
.append(document
)
2206 def RemoveDocument(self
, doc
):
2208 Removes the document from the list of documents.
2210 if doc
in self
._docs
:
2211 self
._docs
.remove(doc
)
2214 def ActivateView(self
, view
, activate
= True, deleting
= False):
2216 Sets the current view.
2219 self
._currentView
= view
2220 self
._lastActiveView
= view
2222 self
._currentView
= None
2225 def GetMaxDocsOpen(self
):
2227 Returns the number of documents that can be open simultaneously.
2229 return self
._maxDocsOpen
2232 def SetMaxDocsOpen(self
, maxDocsOpen
):
2234 Sets the maximum number of documents that can be open at a time. By
2235 default, this is 10,000. If you set it to 1, existing documents will
2236 be saved and deleted when the user tries to open or create a new one
2237 (similar to the behaviour of Windows Write, for example). Allowing
2238 multiple documents gives behaviour more akin to MS Word and other
2239 Multiple Document Interface applications.
2241 self
._maxDocsOpen
= maxDocsOpen
2244 def GetDocuments(self
):
2246 Returns the list of documents.
2251 class DocParentFrame(wx
.Frame
):
2253 The wxDocParentFrame class provides a default top-level frame for
2254 applications using the document/view framework. This class can only be
2255 used for SDI (not MDI) parent frames.
2257 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates
2261 def __init__(self
, manager
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2263 Constructor. Note that the event table must be rebuilt for the
2264 frame since the EvtHandler is not virtual.
2266 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
)
2267 self
._docManager
= manager
2269 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2271 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2272 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2274 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2275 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2276 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2277 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2278 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2279 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2280 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2281 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2282 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2283 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2284 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2285 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2287 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2288 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2289 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2290 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2291 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2292 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2293 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2294 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2295 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2296 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2297 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2298 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2301 def ProcessEvent(self
, event
):
2303 Processes an event, searching event tables and calling zero or more
2304 suitable event handler function(s). Note that the ProcessEvent
2305 method is called from the wxPython docview framework directly since
2306 wxPython does not have a virtual ProcessEvent function.
2308 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2311 def ProcessUpdateUIEvent(self
, event
):
2313 Processes a UI event, searching event tables and calling zero or more
2314 suitable event handler function(s). Note that the ProcessEvent
2315 method is called from the wxPython docview framework directly since
2316 wxPython does not have a virtual ProcessEvent function.
2318 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2321 def OnExit(self
, event
):
2323 Called when File/Exit is chosen and closes the window.
2328 def OnMRUFile(self
, event
):
2330 Opens the appropriate file when it is selected from the file history
2333 n
= event
.GetId() - wx
.ID_FILE1
2334 filename
= self
._docManager
.GetHistoryFile(n
)
2336 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2338 self
._docManager
.RemoveFileFromHistory(n
)
2339 msgTitle
= wx
.GetApp().GetAppName()
2341 msgTitle
= _("File Error")
2342 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),
2344 wx
.OK | wx
.ICON_EXCLAMATION
,
2348 def OnCloseWindow(self
, event
):
2350 Deletes all views and documents. If no user input cancelled the
2351 operation, the frame will be destroyed and the application will exit.
2353 if self
._docManager
.Clear(not event
.CanVeto()):
2359 class DocChildFrame(wx
.Frame
):
2361 The wxDocChildFrame class provides a default frame for displaying
2362 documents on separate windows. This class can only be used for SDI (not
2365 The class is part of the document/view framework supported by wxWindows,
2366 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2371 def __init__(self
, doc
, view
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2373 Constructor. Note that the event table must be rebuilt for the
2374 frame since the EvtHandler is not virtual.
2376 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2377 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2378 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2379 self
._childDocument
= doc
2380 self
._childView
= view
2384 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2385 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2386 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2387 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2388 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2389 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2390 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2391 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2392 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2393 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2394 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2395 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2397 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2398 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2399 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2400 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2401 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2402 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2403 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2404 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2405 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2406 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2407 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2408 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2411 def ProcessEvent(self
, event
):
2413 Processes an event, searching event tables and calling zero or more
2414 suitable event handler function(s). Note that the ProcessEvent
2415 method is called from the wxPython docview framework directly since
2416 wxPython does not have a virtual ProcessEvent function.
2419 self
._childView
.Activate(True)
2420 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2421 # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows
2422 # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
2423 if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2431 def ProcessUpdateUIEvent(self
, event
):
2433 Processes a UI event, searching event tables and calling zero or more
2434 suitable event handler function(s). Note that the ProcessEvent
2435 method is called from the wxPython docview framework directly since
2436 wxPython does not have a virtual ProcessEvent function.
2438 if self
.GetParent():
2439 self
.GetParent().ProcessUpdateUIEvent(event
)
2444 def OnActivate(self
, event
):
2446 Activates the current view.
2448 # wx.Frame.OnActivate(event) This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead
2450 self
._childView
.Activate(event
.GetActive())
2453 def OnCloseWindow(self
, event
):
2455 Closes and deletes the current view and document.
2459 if not event
.CanVeto():
2462 ans
= self
._childView
.Close(deleteWindow
= False)
2465 self
._childView
.Activate(False)
2466 self
._childView
.Destroy()
2467 self
._childView
= None
2468 if self
._childDocument
:
2469 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2470 self
._childDocument
= None
2478 def GetDocument(self
):
2480 Returns the document associated with this frame.
2482 return self
._childDocument
2485 def SetDocument(self
, document
):
2487 Sets the document for this frame.
2489 self
._childDocument
= document
2494 Returns the view associated with this frame.
2496 return self
._childView
2499 def SetView(self
, view
):
2501 Sets the view for this frame.
2503 self
._childView
= view
2506 class DocMDIParentFrame(wx
.MDIParentFrame
):
2508 The wxDocMDIParentFrame class provides a default top-level frame for
2509 applications using the document/view framework. This class can only be
2510 used for MDI parent frames.
2512 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2517 def __init__(self
, manager
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2519 Constructor. Note that the event table must be rebuilt for the
2520 frame since the EvtHandler is not virtual.
2522 wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2523 self
._docManager
= manager
2525 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2527 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2528 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2530 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2531 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2532 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2533 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2534 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2535 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2536 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2537 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2538 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2539 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2540 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2541 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2543 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2544 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2545 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2546 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2547 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2548 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2549 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2550 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2551 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2552 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2553 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2554 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2557 def ProcessEvent(self
, event
):
2559 Processes an event, searching event tables and calling zero or more
2560 suitable event handler function(s). Note that the ProcessEvent
2561 method is called from the wxPython docview framework directly since
2562 wxPython does not have a virtual ProcessEvent function.
2564 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2567 def ProcessUpdateUIEvent(self
, event
):
2569 Processes a UI event, searching event tables and calling zero or more
2570 suitable event handler function(s). Note that the ProcessEvent
2571 method is called from the wxPython docview framework directly since
2572 wxPython does not have a virtual ProcessEvent function.
2574 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2577 def OnExit(self
, event
):
2579 Called when File/Exit is chosen and closes the window.
2584 def OnMRUFile(self
, event
):
2586 Opens the appropriate file when it is selected from the file history
2589 n
= event
.GetId() - wx
.ID_FILE1
2590 filename
= self
._docManager
.GetHistoryFile(n
)
2592 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2594 self
._docManager
.RemoveFileFromHistory(n
)
2595 msgTitle
= wx
.GetApp().GetAppName()
2597 msgTitle
= _("File Error")
2598 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),
2600 wx
.OK | wx
.ICON_EXCLAMATION
,
2604 def OnCloseWindow(self
, event
):
2606 Deletes all views and documents. If no user input cancelled the
2607 operation, the frame will be destroyed and the application will exit.
2609 if self
._docManager
.Clear(not event
.CanVeto()):
2615 class DocMDIChildFrame(wx
.MDIChildFrame
):
2617 The wxDocMDIChildFrame class provides a default frame for displaying
2618 documents on separate windows. This class can only be used for MDI child
2621 The class is part of the document/view framework supported by wxWindows,
2622 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2627 def __init__(self
, doc
, view
, frame
, id, title
, pos
= wx
.DefaultPosition
, size
= wx
.DefaultSize
, style
= wx
.DEFAULT_FRAME_STYLE
, name
= "frame"):
2629 Constructor. Note that the event table must be rebuilt for the
2630 frame since the EvtHandler is not virtual.
2632 wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2633 self
._childDocument
= doc
2634 self
._childView
= view
2637 # self.Create(doc, view, frame, id, title, pos, size, style, name)
2638 self
._activeEvent
= None
2640 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2641 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2643 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
2644 mdiChildren
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren())
2645 if len(mdiChildren
) == 1:
2649 ## # Couldn't get this to work, but seems to work fine with single stage construction
2650 ## def Create(self, doc, view, frame, id, title, pos, size, style, name):
2651 ## self._childDocument = doc
2652 ## self._childView = view
2653 ## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
2655 ## view.SetFrame(self)
2661 def Activate(self
): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
2663 Activates the current view.
2666 self
._childView
.Activate(True)
2669 def ProcessEvent(event
):
2671 Processes an event, searching event tables and calling zero or more
2672 suitable event handler function(s). Note that the ProcessEvent
2673 method is called from the wxPython docview framework directly since
2674 wxPython does not have a virtual ProcessEvent function.
2676 if self
._activeEvent
== event
:
2679 self
._activeEvent
= event
# Break recursion loops
2682 self
._childView
.Activate(True)
2684 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2685 if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2692 self
._activeEvent
= None
2696 def OnActivate(self
, event
):
2698 Sets the currently active view to be the frame's view. You may need to
2699 override (but still call) this function in order to set the keyboard
2700 focus for your subwindow.
2702 if self
._activated
!= 0:
2704 self
._activated
+= 1
2705 wx
.MDIChildFrame
.Activate(self
)
2706 if event
.GetActive() and self
._childView
:
2707 self
._childView
.Activate(event
.GetActive())
2710 def OnCloseWindow(self
, event
):
2712 Closes and deletes the current view and document.
2716 if not event
.CanVeto():
2719 ans
= self
._childView
.Close(deleteWindow
= False)
2722 self
._childView
.Activate(False)
2723 self
._childView
.Destroy()
2724 self
._childView
= None
2725 if self
._childDocument
:
2726 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2727 self
._childDocument
= None
2735 def GetDocument(self
):
2737 Returns the document associated with this frame.
2739 return self
._childDocument
2742 def SetDocument(self
, document
):
2744 Sets the document for this frame.
2746 self
._childDocument
= document
2751 Returns the view associated with this frame.
2753 return self
._childView
2756 def SetView(self
, view
):
2758 Sets the view for this frame.
2760 self
._childView
= view
2763 class DocPrintout(wx
.Printout
):
2765 DocPrintout is a default Printout that prints the first page of a document
2770 def __init__(self
, view
, title
= "Printout"):
2774 wx
.Printout
.__init
__(self
)
2775 self
._printoutView
= view
2780 Returns the DocPrintout's view.
2782 return self
._printoutView
2785 def OnPrintPage(self
, page
):
2787 Prints the first page of the view.
2790 ppiScreenX
, ppiScreenY
= self
.GetPPIScreen()
2791 ppiPrinterX
, ppiPrinterY
= self
.GetPPIPrinter()
2792 scale
= ppiPrinterX
/ppiScreenX
2794 pageWidth
, pageHeight
= self
.GetPageSizePixels()
2795 overallScale
= scale
* w
/ pageWidth
2796 dc
.SetUserScale(overallScale
, overallScale
)
2797 if self
._printoutView
:
2798 self
._printoutView
.OnDraw(dc
)
2802 def HasPage(self
, pageNum
):
2804 Indicates that the DocPrintout only has a single page.
2809 def OnBeginDocument(self
, startPage
, endPage
):
2811 Not quite sure why this was overridden, but it was in wxWindows! :)
2813 if not wx
.Printout
.base_OnBeginDocument(self
, startPage
, endPage
):
2818 def GetPageInfo(self
):
2820 Indicates that the DocPrintout only has a single page.
2826 return (minPage
, maxPage
, selPageFrom
, selPageTo
)
2829 #----------------------------------------------------------------------
2831 #----------------------------------------------------------------------
2833 class Command(wx
.Object
):
2835 wxCommand is a base class for modelling an application command, which is
2836 an action usually performed by selecting a menu item, pressing a toolbar
2837 button or any other means provided by the application to change the data
2842 def __init__(self
, canUndo
= False, name
= None):
2844 Constructor. wxCommand is an abstract class, so you will need to
2845 derive a new class and call this constructor from your own constructor.
2847 canUndo tells the command processor whether this command is undo-able.
2848 You can achieve the same functionality by overriding the CanUndo member
2849 function (if for example the criteria for undoability is context-
2852 name must be supplied for the command processor to display the command
2853 name in the application's edit menu.
2855 self
._canUndo
= canUndo
2861 Returns true if the command can be undone, false otherwise.
2863 return self
._canUndo
2868 Returns the command name.
2875 Override this member function to execute the appropriate action when
2876 called. Return true to indicate that the action has taken place, false
2877 otherwise. Returning false will indicate to the command processor that
2878 the action is not undoable and should not be added to the command
2886 Override this member function to un-execute a previous Do. Return true
2887 to indicate that the action has taken place, false otherwise. Returning
2888 false will indicate to the command processor that the action is not
2889 redoable and no change should be made to the command history.
2891 How you implement this command is totally application dependent, but
2892 typical strategies include:
2894 Perform an inverse operation on the last modified piece of data in the
2895 document. When redone, a copy of data stored in command is pasted back
2896 or some operation reapplied. This relies on the fact that you know the
2897 ordering of Undos; the user can never Undo at an arbitrary position in
2900 Restore the entire document state (perhaps using document
2901 transactioning). Potentially very inefficient, but possibly easier to
2902 code if the user interface and data are complex, and an 'inverse
2903 execute' operation is hard to write.
2908 class CommandProcessor(wx
.Object
):
2910 wxCommandProcessor is a class that maintains a history of wxCommands, with
2911 undo/redo functionality built-in. Derive a new class from this if you want
2912 different behaviour.
2916 def __init__(self
, maxCommands
= -1):
2918 Constructor. maxCommands may be set to a positive integer to limit
2919 the number of commands stored to it, otherwise (and by default) the
2920 list of commands can grow arbitrarily.
2922 self
._maxCommands
= maxCommands
2923 self
._editMenu
= None
2924 self
._undoAccelerator
= _("Ctrl+Z")
2925 self
._redoAccelerator
= _("Ctrl+Y")
2926 self
.ClearCommands()
2929 def _GetCurrentCommand(self
):
2930 if len(self
._commands
) == 0:
2933 return self
._commands
[-1]
2936 def _GetCurrentRedoCommand(self
):
2937 if len(self
._redoCommands
) == 0:
2940 return self
._redoCommands
[-1]
2943 def GetMaxCommands(self
):
2945 Returns the maximum number of commands that the command processor
2949 return self
._maxCommands
2952 def GetCommands(self
):
2954 Returns the list of commands.
2956 return self
._commands
2959 def ClearCommands(self
):
2961 Deletes all the commands in the list and sets the current command
2965 self
._redoCommands
= []
2968 def GetEditMenu(self
):
2970 Returns the edit menu associated with the command processor.
2972 return self
._editMenu
2975 def SetEditMenu(self
, menu
):
2977 Tells the command processor to update the Undo and Redo items on this
2978 menu as appropriate. Set this to NULL if the menu is about to be
2979 destroyed and command operations may still be performed, or the
2980 command processor may try to access an invalid pointer.
2982 self
._editMenu
= menu
2985 def GetUndoAccelerator(self
):
2987 Returns the string that will be appended to the Undo menu item.
2989 return self
._undoAccelerator
2992 def SetUndoAccelerator(self
, accel
):
2994 Sets the string that will be appended to the Redo menu item.
2996 self
._undoAccelerator
= accel
2999 def GetRedoAccelerator(self
):
3001 Returns the string that will be appended to the Redo menu item.
3003 return self
._redoAccelerator
3006 def SetRedoAccelerator(self
, accel
):
3008 Sets the string that will be appended to the Redo menu item.
3010 self
._redoAccelerator
= accel
3013 def SetEditMenu(self
, menu
):
3015 Tells the command processor to update the Undo and Redo items on this
3016 menu as appropriate. Set this to NULL if the menu is about to be
3017 destroyed and command operations may still be performed, or the
3018 command processor may try to access an invalid pointer.
3020 self
._editMenu
= menu
3023 def SetMenuStrings(self
):
3025 Sets the menu labels according to the currently set menu and the
3026 current command state.
3028 if self
.GetEditMenu() != None:
3029 undoCommand
= self
._GetCurrentCommand
()
3030 redoCommand
= self
._GetCurrentRedoCommand
()
3031 undoItem
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
)
3032 redoItem
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
)
3033 if self
.GetUndoAccelerator():
3034 undoAccel
= '\t' + self
.GetUndoAccelerator()
3037 if self
.GetRedoAccelerator():
3038 redoAccel
= '\t' + self
.GetRedoAccelerator()
3041 if undoCommand
and undoItem
and undoCommand
.CanUndo():
3042 undoItem
.SetText(_("Undo ") + undoCommand
.GetName() + undoAccel
)
3043 #elif undoCommand and not undoCommand.CanUndo():
3044 # undoItem.SetText(_("Can't Undo") + undoAccel)
3046 undoItem
.SetText(_("Undo" + undoAccel
))
3047 if redoCommand
and redoItem
:
3048 redoItem
.SetText(_("Redo ") + redoCommand
.GetName() + redoAccel
)
3050 redoItem
.SetText(_("Redo") + redoAccel
)
3055 Returns true if the currently-active command can be undone, false
3058 if self
._GetCurrentCommand
() == None:
3060 return self
._GetCurrentCommand
().CanUndo()
3065 Returns true if the currently-active command can be redone, false
3068 return self
._GetCurrentRedoCommand
() != None
3071 def Submit(self
, command
, storeIt
= True):
3073 Submits a new command to the command processor. The command processor
3074 calls wxCommand::Do to execute the command; if it succeeds, the
3075 command is stored in the history list, and the associated edit menu
3076 (if any) updated appropriately. If it fails, the command is deleted
3077 immediately. Once Submit has been called, the passed command should
3078 not be deleted directly by the application.
3080 storeIt indicates whether the successful command should be stored in
3084 if done
and storeIt
:
3085 self
._commands
.append(command
)
3086 if self
._maxCommands
> -1:
3087 if len(self
._commands
) > self
._maxCommands
:
3088 del self
._commands
[0]
3094 Redoes the command just undone.
3096 cmd
= self
._GetCurrentRedoCommand
()
3101 self
._commands
.append(self
._redoCommands
.pop())
3107 Undoes the command just executed.
3109 cmd
= self
._GetCurrentCommand
()
3114 self
._redoCommands
.append(self
._commands
.pop())