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
)
462 os
.remove(backupFilename
)
464 # save failed, restore old file
467 os
.rename(backupFilename
, filename
)
468 self
.SetDocumentModificationDate()
470 wx
.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
472 wx
.OK | wx
.ICON_EXCLAMATION
,
473 self
.GetDocumentWindow())
476 self
.SetFilename(filename
, True)
478 self
.SetDocumentModificationDate()
479 self
.SetDocumentSaved(True)
480 #if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
481 # wx.FileName(file).MacSetDefaultTypeAndCreator()
485 def OnOpenDocument(self
, filename
):
487 Constructs an input file for the given filename (which must not
488 be empty), and calls LoadObject. If LoadObject returns true, the
489 document is set to unmodified; otherwise, an error message box is
490 displayed. The document's views are notified that the filename has
491 changed, to give windows an opportunity to update their titles. All of
492 the document's views are then updated.
494 if not self
.OnSaveModified():
497 msgTitle
= wx
.GetApp().GetAppName()
499 msgTitle
= _("File Error")
501 fileObject
= file(filename
, 'r')
503 self
.LoadObject(fileObject
)
505 wx
.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename
), sys
.exc_value
),
507 wx
.OK | wx
.ICON_EXCLAMATION
,
508 self
.GetDocumentWindow())
511 self
.SetFilename(filename
, True)
513 self
.SetDocumentModificationDate()
514 self
.SetDocumentSaved(True)
515 self
.UpdateAllViews()
519 def LoadObject(self
, file):
521 Override this function and call it from your own LoadObject before
522 loading your own data. LoadObject is called by the framework
523 automatically when the document contents need to be loaded.
525 Note that the wxPython version simply sends you a Python file object,
526 so you can use pickle.
531 def SaveObject(self
, file):
533 Override this function and call it from your own SaveObject before
534 saving your own data. SaveObject is called by the framework
535 automatically when the document contents need to be saved.
537 Note that the wxPython version simply sends you a Python file object,
538 so you can use pickle.
545 Override this function to revert the document to its last saved state.
550 def GetPrintableName(self
):
552 Copies a suitable document name into the supplied name buffer.
553 The default function uses the title, or if there is no title, uses the
554 filename; or if no filename, the string 'Untitled'.
556 if self
._documentTitle
:
557 return self
._documentTitle
558 elif self
._documentFile
:
559 return FileNameFromPath(self
._documentFile
)
564 def GetDocumentWindow(self
):
566 Intended to return a suitable window for using as a parent for
567 document-related dialog boxes. By default, uses the frame associated
570 if len(self
._documentViews
) > 0:
571 return self
._documentViews
[0].GetFrame()
573 return wx
.GetApp().GetTopWindow()
576 def OnCreateCommandProcessor(self
):
578 Override this function if you want a different (or no) command
579 processor to be created when the document is created. By default, it
580 returns an instance of wxCommandProcessor.
582 return CommandProcessor()
585 def OnSaveModified(self
):
587 If the document has been modified, prompts the user to ask if the
588 changes should be changed. If the user replies Yes, the Save function
589 is called. If No, the document is marked as unmodified and the
590 function succeeds. If Cancel, the function fails.
592 if not self
.IsModified():
595 """ check for file modification outside of application """
596 if os
.path
.exists(self
.GetFilename()) and os
.path
.getmtime(self
.GetFilename()) != self
.GetDocumentModificationDate():
597 msgTitle
= wx
.GetApp().GetAppName()
599 msgTitle
= _("Warning")
600 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()),
602 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
603 self
.GetDocumentWindow())
609 return wx
.lib
.docview
.Document
.Save(self
)
610 else: # elif res == wx.CANCEL:
613 msgTitle
= wx
.GetApp().GetAppName()
615 msgTitle
= _("Warning")
617 res
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(),
619 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
,
620 self
.GetDocumentWindow())
627 else: # elif res == wx.CANCEL:
633 Called by printing framework to draw the view.
638 def AddView(self
, view
):
640 If the view is not already in the list of views, adds the view and
641 calls OnChangedViewList.
643 if not view
in self
._documentViews
:
644 self
._documentViews
.append(view
)
645 self
.OnChangedViewList()
649 def RemoveView(self
, view
):
651 Removes the view from the document's list of views, and calls
654 if view
in self
._documentViews
:
655 self
._documentViews
.remove(view
)
656 self
.OnChangedViewList()
660 def OnCreate(self
, path
, flags
):
662 The default implementation calls DeleteContents (an empty
663 implementation) sets the modified flag to false. Override this to
664 supply additional behaviour when the document is closed with Close.
666 return self
.GetDocumentTemplate().CreateView(self
, flags
)
669 def OnChangedViewList(self
):
671 Called when a view is added to or deleted from this document. The
672 default implementation saves and deletes the document if no views
673 exist (the last one has just been removed).
675 if len(self
._documentViews
) == 0:
676 if self
.OnSaveModified():
677 pass # C version does a delete but Python will garbage collect
680 def UpdateAllViews(self
, sender
= None, hint
= None):
682 Updates all views. If sender is non-NULL, does not update this view.
683 hint represents optional information to allow a view to optimize its
686 for view
in self
._documentViews
:
688 view
.OnUpdate(sender
, hint
)
691 def NotifyClosing(self
):
693 Notifies the views that the document is going to close.
695 for view
in self
._documentViews
:
696 view
.OnClosingDocument()
699 def SetFilename(self
, filename
, notifyViews
= False):
701 Sets the filename for this document. Usually called by the framework.
702 If notifyViews is true, wxView.OnChangeFilename is called for all
705 self
._documentFile
= filename
707 for view
in self
._documentViews
:
708 view
.OnChangeFilename()
711 def GetWriteable(self
):
713 Returns true if the document can be written to its accociated file path.
714 This method has been added to wxPython and is not in wxWindows.
716 if not self
._writeable
:
718 if not self
._documentFile
: # Doesn't exist, do a save as
721 return os
.access(self
._documentFile
, os
.W_OK
)
724 def SetWriteable(self
, writeable
):
726 Set to False if the document can not be saved. This will disable the ID_SAVE_AS
727 event and is useful for custom documents that should not be saveable. The ID_SAVE
728 event can be disabled by never Modifying the document. This method has been added
729 to wxPython and is not in wxWindows.
731 self
._writeable
= writeable
734 class View(wx
.EvtHandler
):
736 The view class can be used to model the viewing and editing component of
737 an application's file-based data. It is part of the document/view
738 framework supported by wxWindows, and cooperates with the wxDocument,
739 wxDocTemplate and wxDocManager classes.
744 Constructor. Define your own default constructor to initialize
745 application-specific data.
747 wx
.EvtHandler
.__init
__(self
)
748 self
._viewDocument
= None
749 self
._viewFrame
= None
754 Destructor. Removes itself from the document's list of views.
756 if self
._viewDocument
:
757 self
._viewDocument
.RemoveView(self
)
758 wx
.EvtHandler
.Destroy(self
)
761 def ProcessEvent(self
, event
):
763 Processes an event, searching event tables and calling zero or more
764 suitable event handler function(s). Note that the ProcessEvent
765 method is called from the wxPython docview framework directly since
766 wxPython does not have a virtual ProcessEvent function.
768 if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
):
774 def ProcessUpdateUIEvent(self
, event
):
776 Processes a UI event, searching event tables and calling zero or more
777 suitable event handler function(s). Note that the ProcessEvent
778 method is called from the wxPython docview framework directly since
779 wxPython does not have a virtual ProcessEvent function.
784 def OnActivateView(self
, activate
, activeView
, deactiveView
):
786 Called when a view is activated by means of wxView::Activate. The
787 default implementation does nothing.
792 def OnClosingDocument(self
):
794 Override this to clean up the view when the document is being closed.
795 The default implementation does nothing.
800 def OnDraw(self
, dc
):
802 Override this to draw the view for the printing framework. The
803 default implementation does nothing.
808 def OnPrint(self
, dc
, info
):
810 Override this to print the view for the printing framework. The
811 default implementation calls View.OnDraw.
816 def OnUpdate(self
, sender
, hint
):
818 Called when the view should be updated. sender is a pointer to the
819 view that sent the update request, or NULL if no single view requested
820 the update (for instance, when the document is opened). hint is as yet
821 unused but may in future contain application-specific information for
822 making updating more efficient.
827 def OnChangeFilename(self
):
829 Called when the filename has changed. The default implementation
830 constructs a suitable title and sets the title of the view frame (if
834 appName
= wx
.GetApp().GetAppName()
835 if not self
.GetDocument():
841 if appName
and isinstance(self
.GetFrame(), DocChildFrame
): # Only need app name in title for SDI
842 title
= appName
+ _(" - ")
845 self
.GetFrame().SetTitle(title
+ self
.GetDocument().GetPrintableName())
848 def GetDocument(self
):
850 Returns the document associated with the view.
852 return self
._viewDocument
855 def SetDocument(self
, doc
):
857 Associates the given document with the view. Normally called by the
860 self
._viewDocument
= doc
865 def GetViewName(self
):
867 Gets the name associated with the view (passed to the wxDocTemplate
868 constructor). Not currently used by the framework.
870 return self
._viewTypeName
873 def SetViewName(self
, name
):
875 Sets the view type name. Should only be called by the framework.
877 self
._viewTypeName
= name
880 def Close(self
, deleteWindow
=True):
882 Closes the view by calling OnClose. If deleteWindow is true, this
883 function should delete the window associated with the view.
885 if self
.OnClose(deleteWindow
= deleteWindow
):
891 def Activate(self
, activate
=True):
893 Call this from your view frame's OnActivate member to tell the
894 framework which view is currently active. If your windowing system
895 doesn't call OnActivate, you may need to call this function from
896 OnMenuCommand or any place where you know the view must be active, and
897 the framework will need to get the current view.
899 The prepackaged view frame wxDocChildFrame calls wxView.Activate from
900 its OnActivate member and from its OnMenuCommand member.
902 if self
.GetDocument() and self
.GetDocumentManager():
903 self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView())
904 self
.GetDocumentManager().ActivateView(self
, activate
)
907 def OnClose(self
, deleteWindow
=True):
909 Implements closing behaviour. The default implementation calls
910 wxDocument.Close to close the associated document. Does not delete the
911 view. The application may wish to do some cleaning up operations in
912 this function, if a call to wxDocument::Close succeeded. For example,
913 if your application's all share the same window, you need to
914 disassociate the window from the view and perhaps clear the window. If
915 deleteWindow is true, delete the frame associated with the view.
917 if self
.GetDocument():
918 return self
.GetDocument().Close()
923 def OnCreate(self
, doc
, flags
):
925 wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just
926 after the wxDocTemplate creates the wxView, it calls wxView::OnCreate.
927 In its OnCreate member function, the wxView can create a
928 wxDocChildFrame or a derived class. This wxDocChildFrame provides user
929 interface elements to view and/or edit the contents of the wxDocument.
931 By default, simply returns true. If the function returns false, the
932 view will be deleted.
937 def OnCreatePrintout(self
):
939 Returns a wxPrintout object for the purposes of printing. It should
940 create a new object every time it is called; the framework will delete
943 By default, this function returns an instance of wxDocPrintout, which
944 prints and previews one page by calling wxView.OnDraw.
946 Override to return an instance of a class other than wxDocPrintout.
948 return DocPrintout(self
)
953 Gets the frame associated with the view (if any). Note that this
954 "frame" is not a wxFrame at all in the generic MDI implementation
955 which uses the notebook pages instead of the frames and this is why
956 this method returns a wxWindow and not a wxFrame.
958 return self
._viewFrame
961 def SetFrame(self
, frame
):
963 Sets the frame associated with this view. The application should call
964 this if possible, to tell the view about the frame. See GetFrame for
965 the explanation about the mismatch between the "Frame" in the method
966 name and the type of its parameter.
968 self
._viewFrame
= frame
971 def GetDocumentManager(self
):
973 Returns the document manager instance associated with this view.
975 if self
._viewDocument
:
976 return self
.GetDocument().GetDocumentManager()
981 class DocTemplate(wx
.Object
):
983 The wxDocTemplate class is used to model the relationship between a
984 document class and a view class.
988 def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
=DEFAULT_TEMPLATE_FLAGS
, icon
=None):
990 Constructor. Create instances dynamically near the start of your
991 application after creating a wxDocManager instance, and before doing
992 any document or view operations.
994 manager is the document manager object which manages this template.
996 description is a short description of what the template is for. This
997 string will be displayed in the file filter list of Windows file
1000 filter is an appropriate file filter such as *.txt.
1002 dir is the default directory to use for file selectors.
1004 ext is the default file extension (such as txt).
1006 docTypeName is a name that should be unique for a given type of
1007 document, used for gathering a list of views relevant to a
1008 particular document.
1010 viewTypeName is a name that should be unique for a given view.
1012 docClass is a Python class. If this is not supplied, you will need to
1013 derive a new wxDocTemplate class and override the CreateDocument
1014 member to return a new document instance on demand.
1016 viewClass is a Python class. If this is not supplied, you will need to
1017 derive a new wxDocTemplate class and override the CreateView member to
1018 return a new view instance on demand.
1020 flags is a bit list of the following:
1021 wx.TEMPLATE_VISIBLE The template may be displayed to the user in
1024 wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in
1027 wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE.
1029 self
._docManager
= manager
1030 self
._description
= description
1031 self
._fileFilter
= filter
1032 self
._directory
= dir
1033 self
._defaultExt
= ext
1034 self
._docTypeName
= docTypeName
1035 self
._viewTypeName
= viewTypeName
1036 self
._docType
= docType
1037 self
._viewType
= viewType
1041 self
._docManager
.AssociateTemplate(self
)
1044 def GetDefaultExtension(self
):
1046 Returns the default file extension for the document data, as passed to
1047 the document template constructor.
1049 return self
._defaultExt
1052 def SetDefaultExtension(self
, defaultExt
):
1054 Sets the default file extension.
1056 self
._defaultExt
= defaultExt
1059 def GetDescription(self
):
1061 Returns the text description of this template, as passed to the
1062 document template constructor.
1064 return self
._description
1067 def SetDescription(self
, description
):
1069 Sets the template description.
1071 self
._description
= description
1074 def GetDirectory(self
):
1076 Returns the default directory, as passed to the document template
1079 return self
._directory
1082 def SetDirectory(self
, dir):
1084 Sets the default directory.
1086 self
._directory
= dir
1089 def GetDocumentManager(self
):
1091 Returns the document manager instance for which this template was
1094 return self
._docManager
1097 def SetDocumentManager(self
, manager
):
1099 Sets the document manager instance for which this template was
1100 created. Should not be called by the application.
1102 self
._docManager
= manager
1105 def GetFileFilter(self
):
1107 Returns the file filter, as passed to the document template
1110 return self
._fileFilter
1113 def SetFileFilter(self
, filter):
1115 Sets the file filter.
1117 self
._fileFilter
= filter
1122 Returns the flags, as passed to the document template constructor.
1123 (see the constructor description for more details).
1128 def SetFlags(self
, flags
):
1130 Sets the internal document template flags (see the constructor
1131 description for more details).
1138 Returns the icon, as passed to the document template
1139 constructor. This method has been added to wxPython and is
1145 def SetIcon(self
, flags
):
1147 Sets the icon. This method has been added to wxPython and is not
1153 def GetDocumentType(self
):
1155 Returns the Python document class, as passed to the document template
1158 return self
._docType
1161 def GetViewType(self
):
1163 Returns the Python view class, as passed to the document template
1166 return self
._viewType
1169 def IsVisible(self
):
1171 Returns true if the document template can be shown in user dialogs,
1174 return (self
._flags
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
1177 def GetDocumentName(self
):
1179 Returns the document type name, as passed to the document template
1182 return self
._docTypeName
1185 def GetViewName(self
):
1187 Returns the view type name, as passed to the document template
1190 return self
._viewTypeName
1193 def CreateDocument(self
, path
, flags
):
1195 Creates a new instance of the associated document class. If you have
1196 not supplied a class to the template constructor, you will need to
1197 override this function to return an appropriate document instance.
1199 doc
= self
._docType
()
1200 doc
.SetFilename(path
)
1201 doc
.SetDocumentTemplate(self
)
1202 self
.GetDocumentManager().AddDocument(doc
)
1203 doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor())
1204 if doc
.OnCreate(path
, flags
):
1207 if doc
in self
.GetDocumentManager().GetDocuments():
1208 doc
.DeleteAllViews()
1212 def CreateView(self
, doc
, flags
):
1214 Creates a new instance of the associated document view. If you have
1215 not supplied a class to the template constructor, you will need to
1216 override this function to return an appropriate view instance.
1218 view
= self
._viewType
()
1219 view
.SetDocument(doc
)
1220 if view
.OnCreate(doc
, flags
):
1227 def FileMatchesTemplate(self
, path
):
1229 Returns True if the path's extension matches one of this template's
1230 file filter extensions.
1232 ext
= FindExtension(path
)
1233 if not ext
: return False
1234 return ext
in self
.GetFileFilter()
1235 # return self.GetDefaultExtension() == FindExtension(path)
1238 class DocManager(wx
.EvtHandler
):
1240 The wxDocManager class is part of the document/view framework supported by
1241 wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate
1245 def __init__(self
, flags
=DEFAULT_DOCMAN_FLAGS
, initialize
=True):
1247 Constructor. Create a document manager instance dynamically near the
1248 start of your application before doing any document or view operations.
1250 flags is used in the Python version to indicate whether the document
1251 manager is in DOC_SDI or DOC_MDI mode.
1253 If initialize is true, the Initialize function will be called to
1254 create a default history list object. If you derive from wxDocManager,
1255 you may wish to call the base constructor with false, and then call
1256 Initialize in your own constructor, to allow your own Initialize or
1257 OnCreateFileHistory functions to be called.
1260 wx
.EvtHandler
.__init
__(self
)
1262 self
._defaultDocumentNameCounter
= 1
1264 self
._currentView
= None
1265 self
._lastActiveView
= None
1266 self
._maxDocsOpen
= 10000
1267 self
._fileHistory
= None
1268 self
._templates
= []
1270 self
._lastDirectory
= ""
1275 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
)
1276 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
)
1277 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
)
1278 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
)
1279 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
)
1280 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
)
1281 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
)
1282 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
1283 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
1284 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
)
1285 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
)
1286 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
)
1288 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
)
1289 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
)
1290 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
)
1291 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
)
1292 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
)
1293 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
)
1294 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
)
1295 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
)
1296 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
)
1297 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
)
1298 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
)
1299 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
)
1307 wx
.EvtHandler
.Destroy(self
)
1312 Returns the document manager's flags. This method has been
1313 added to wxPython and is not in wxWindows.
1318 def CloseDocument(self
, doc
, force
=True):
1320 Closes the specified document.
1322 if doc
.Close() or force
:
1323 doc
.DeleteAllViews()
1324 if doc
in self
._docs
:
1330 def CloseDocuments(self
, force
=True):
1332 Closes all currently opened documents.
1334 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
1335 if not self
.CloseDocument(document
, force
):
1337 document
.DeleteAllViews() # Implicitly delete the document when the last view is removed
1341 def Clear(self
, force
=True):
1343 Closes all currently opened document by callling CloseDocuments and
1344 clears the document manager's templates.
1346 if not self
.CloseDocuments(force
):
1348 self
._templates
= []
1352 def Initialize(self
):
1354 Initializes data; currently just calls OnCreateFileHistory. Some data
1355 cannot always be initialized in the constructor because the programmer
1356 must be given the opportunity to override functionality. In fact
1357 Initialize is called from the wxDocManager constructor, but this can
1358 be vetoed by passing false to the second argument, allowing the
1359 derived class's constructor to call Initialize, possibly calling a
1360 different OnCreateFileHistory from the default.
1362 The bottom line: if you're not deriving from Initialize, forget it and
1363 construct wxDocManager with no arguments.
1365 self
.OnCreateFileHistory()
1369 def OnCreateFileHistory(self
):
1371 A hook to allow a derived class to create a different type of file
1372 history. Called from Initialize.
1374 self
._fileHistory
= wx
.FileHistory()
1377 def OnFileClose(self
, event
):
1379 Closes and deletes the currently active document.
1381 doc
= self
.GetCurrentDocument()
1383 doc
.DeleteAllViews()
1384 if doc
in self
._docs
:
1385 self
._docs
.remove(doc
)
1388 def OnFileCloseAll(self
, event
):
1390 Closes and deletes all the currently opened documents.
1392 return self
.CloseDocuments(force
= False)
1395 def OnFileNew(self
, event
):
1397 Creates a new document and reads in the selected file.
1399 self
.CreateDocument('', DOC_NEW
)
1402 def OnFileOpen(self
, event
):
1404 Creates a new document and reads in the selected file.
1406 if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
):
1407 self
.OnOpenFileFailure()
1410 def OnFileRevert(self
, event
):
1412 Reverts the current document by calling wxDocument.Save for the current
1415 doc
= self
.GetCurrentDocument()
1421 def OnFileSave(self
, event
):
1423 Saves the current document by calling wxDocument.Save for the current
1426 doc
= self
.GetCurrentDocument()
1432 def OnFileSaveAs(self
, event
):
1434 Calls wxDocument.SaveAs for the current document.
1436 doc
= self
.GetCurrentDocument()
1442 def OnPrint(self
, event
):
1444 Prints the current document by calling its View's OnCreatePrintout
1447 view
= self
.GetCurrentView()
1451 printout
= view
.OnCreatePrintout()
1453 pdd
= wx
.PrintDialogData()
1454 printer
= wx
.Printer(pdd
)
1455 printer
.Print(view
.GetFrame(), printout
) # , True)
1458 def OnPrintSetup(self
, event
):
1460 Presents the print setup dialog.
1462 view
= self
.GetCurrentView()
1464 parentWin
= view
.GetFrame()
1466 parentWin
= wx
.GetApp().GetTopWindow()
1468 data
= wx
.PrintDialogData()
1469 printDialog
= wx
.PrintDialog(parentWin
, data
)
1470 printDialog
.GetPrintDialogData().SetSetupDialog(True)
1471 printDialog
.ShowModal()
1472 # TODO: Confirm that we don't have to remember PrintDialogData
1475 def OnPreview(self
, event
):
1477 Previews the current document by calling its View's OnCreatePrintout
1480 view
= self
.GetCurrentView()
1484 printout
= view
.OnCreatePrintout()
1486 # Pass two printout objects: for preview, and possible printing.
1487 preview
= wx
.PrintPreview(printout
, view
.OnCreatePrintout())
1488 # 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.
1489 mimicFrame
= wx
.GetApp().GetTopWindow()
1490 frame
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize())
1491 frame
.SetIcon(mimicFrame
.GetIcon())
1492 frame
.SetTitle(mimicFrame
.GetTitle() + _(" - Preview"))
1497 def OnUndo(self
, event
):
1499 Issues an Undo command to the current document's command processor.
1501 doc
= self
.GetCurrentDocument()
1504 if doc
.GetCommandProcessor():
1505 doc
.GetCommandProcessor().Undo()
1508 def OnRedo(self
, event
):
1510 Issues a Redo command to the current document's command processor.
1512 doc
= self
.GetCurrentDocument()
1515 if doc
.GetCommandProcessor():
1516 doc
.GetCommandProcessor().Redo()
1519 def OnUpdateFileOpen(self
, event
):
1521 Updates the user interface for the File Open command.
1526 def OnUpdateFileClose(self
, event
):
1528 Updates the user interface for the File Close command.
1530 event
.Enable(self
.GetCurrentDocument() != None)
1533 def OnUpdateFileCloseAll(self
, event
):
1535 Updates the user interface for the File Close All command.
1537 event
.Enable(self
.GetCurrentDocument() != None)
1540 def OnUpdateFileRevert(self
, event
):
1542 Updates the user interface for the File Revert command.
1544 event
.Enable(self
.GetCurrentDocument() != None)
1547 def OnUpdateFileNew(self
, event
):
1549 Updates the user interface for the File New command.
1554 def OnUpdateFileSave(self
, event
):
1556 Updates the user interface for the File Save command.
1558 doc
= self
.GetCurrentDocument()
1559 event
.Enable(doc
!= None and doc
.IsModified())
1562 def OnUpdateFileSaveAs(self
, event
):
1564 Updates the user interface for the File Save As command.
1566 event
.Enable(self
.GetCurrentDocument() != None and self
.GetCurrentDocument().GetWriteable())
1569 def OnUpdateUndo(self
, event
):
1571 Updates the user interface for the Undo command.
1573 doc
= self
.GetCurrentDocument()
1574 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo())
1575 if doc
and doc
.GetCommandProcessor():
1576 doc
.GetCommandProcessor().SetMenuStrings()
1578 event
.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
1581 def OnUpdateRedo(self
, event
):
1583 Updates the user interface for the Redo command.
1585 doc
= self
.GetCurrentDocument()
1586 event
.Enable(doc
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo())
1587 if doc
and doc
.GetCommandProcessor():
1588 doc
.GetCommandProcessor().SetMenuStrings()
1590 event
.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
1593 def OnUpdatePrint(self
, event
):
1595 Updates the user interface for the Print command.
1597 event
.Enable(self
.GetCurrentDocument() != None)
1600 def OnUpdatePrintSetup(self
, event
):
1602 Updates the user interface for the Print Setup command.
1607 def OnUpdatePreview(self
, event
):
1609 Updates the user interface for the Print Preview command.
1611 event
.Enable(self
.GetCurrentDocument() != None)
1614 def GetCurrentView(self
):
1616 Returns the currently active view.
1618 if self
._currentView
:
1619 return self
._currentView
1620 if len(self
._docs
) == 1:
1621 return self
._docs
[0].GetFirstView()
1625 def GetLastActiveView(self
):
1627 Returns the last active view. This is used in the SDI framework where dialogs can be mistaken for a view
1628 and causes the framework to deactivete the current view. This happens when something like a custom dialog box used
1629 to operate on the current view is shown.
1631 if len(self
._docs
) >= 1:
1632 return self
._lastActiveView
1637 def ProcessEvent(self
, event
):
1639 Processes an event, searching event tables and calling zero or more
1640 suitable event handler function(s). Note that the ProcessEvent
1641 method is called from the wxPython docview framework directly since
1642 wxPython does not have a virtual ProcessEvent function.
1644 view
= self
.GetCurrentView()
1646 if view
.ProcessEvent(event
):
1649 if id == wx
.ID_OPEN
:
1650 self
.OnFileOpen(event
)
1652 elif id == wx
.ID_CLOSE
:
1653 self
.OnFileClose(event
)
1655 elif id == wx
.ID_CLOSE_ALL
:
1656 self
.OnFileCloseAll(event
)
1658 elif id == wx
.ID_REVERT
:
1659 self
.OnFileRevert(event
)
1661 elif id == wx
.ID_NEW
:
1662 self
.OnFileNew(event
)
1664 elif id == wx
.ID_SAVE
:
1665 self
.OnFileSave(event
)
1667 elif id == wx
.ID_SAVEAS
:
1668 self
.OnFileSaveAs(event
)
1670 elif id == wx
.ID_UNDO
:
1673 elif id == wx
.ID_REDO
:
1676 elif id == wx
.ID_PRINT
:
1679 elif id == wx
.ID_PRINT_SETUP
:
1680 self
.OnPrintSetup(event
)
1682 elif id == wx
.ID_PREVIEW
:
1683 self
.OnPreview(event
)
1689 def ProcessUpdateUIEvent(self
, event
):
1691 Processes a UI event, searching event tables and calling zero or more
1692 suitable event handler function(s). Note that the ProcessEvent
1693 method is called from the wxPython docview framework directly since
1694 wxPython does not have a virtual ProcessEvent function.
1697 view
= self
.GetCurrentView()
1699 if view
.ProcessUpdateUIEvent(event
):
1701 if id == wx
.ID_OPEN
:
1702 self
.OnUpdateFileOpen(event
)
1704 elif id == wx
.ID_CLOSE
:
1705 self
.OnUpdateFileClose(event
)
1707 elif id == wx
.ID_CLOSE_ALL
:
1708 self
.OnUpdateFileCloseAll(event
)
1710 elif id == wx
.ID_REVERT
:
1711 self
.OnUpdateFileRevert(event
)
1713 elif id == wx
.ID_NEW
:
1714 self
.OnUpdateFileNew(event
)
1716 elif id == wx
.ID_SAVE
:
1717 self
.OnUpdateFileSave(event
)
1719 elif id == wx
.ID_SAVEAS
:
1720 self
.OnUpdateFileSaveAs(event
)
1722 elif id == wx
.ID_UNDO
:
1723 self
.OnUpdateUndo(event
)
1725 elif id == wx
.ID_REDO
:
1726 self
.OnUpdateRedo(event
)
1728 elif id == wx
.ID_PRINT
:
1729 self
.OnUpdatePrint(event
)
1731 elif id == wx
.ID_PRINT_SETUP
:
1732 self
.OnUpdatePrintSetup(event
)
1734 elif id == wx
.ID_PREVIEW
:
1735 self
.OnUpdatePreview(event
)
1741 def CreateDocument(self
, path
, flags
=0):
1743 Creates a new document in a manner determined by the flags parameter,
1746 wx.lib.docview.DOC_NEW Creates a fresh document.
1747 wx.lib.docview.DOC_SILENT Silently loads the given document file.
1749 If wx.lib.docview.DOC_NEW is present, a new document will be created and returned,
1750 possibly after asking the user for a template to use if there is more
1751 than one document template. If wx.lib.docview.DOC_SILENT is present, a new document
1752 will be created and the given file loaded into it. If neither of these
1753 flags is present, the user will be presented with a file selector for
1754 the file to load, and the template to use will be determined by the
1755 extension (Windows) or by popping up a template choice list (other
1758 If the maximum number of documents has been reached, this function
1759 will delete the oldest currently loaded document before creating a new
1762 wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE flag.
1765 for temp
in self
._templates
:
1766 if temp
.IsVisible():
1767 templates
.append(temp
)
1768 if len(templates
) == 0:
1771 if len(self
.GetDocuments()) >= self
._maxDocsOpen
:
1772 doc
= self
.GetDocuments()[0]
1773 if not self
.CloseDocument(doc
, False):
1777 if len(templates
) == 1:
1779 newDoc
= temp
.CreateDocument(path
, flags
)
1781 newDoc
.SetDocumentName(temp
.GetDocumentName())
1782 newDoc
.SetDocumentTemplate(temp
)
1783 newDoc
.OnNewDocument()
1786 temp
= self
.SelectDocumentType(templates
)
1788 newDoc
= temp
.CreateDocument(path
, flags
)
1790 newDoc
.SetDocumentName(temp
.GetDocumentName())
1791 newDoc
.SetDocumentTemplate(temp
)
1792 newDoc
.OnNewDocument()
1797 if path
and flags
& DOC_SILENT
:
1798 temp
= self
.FindTemplateForPath(path
)
1800 temp
, path
= self
.SelectDocumentPath(templates
, path
, flags
)
1803 if self
.GetFlags() & DOC_OPEN_ONCE
:
1804 for document
in self
._docs
:
1805 if document
.GetFilename() == path
:
1806 """ check for file modification outside of application """
1807 if os
.path
.exists(path
) and os
.path
.getmtime(path
) != document
.GetDocumentModificationDate():
1808 msgTitle
= wx
.GetApp().GetAppName()
1810 msgTitle
= _("Warning")
1811 shortName
= document
.GetPrintableName()
1812 res
= wx
.MessageBox(_("'%s' has been modified outside of %s. Reload '%s' from file system?") % (shortName
, msgTitle
, shortName
),
1814 wx
.YES_NO | wx
.ICON_QUESTION
,
1815 self
.FindSuitableParent())
1817 if not self
.CloseDocument(document
, False):
1818 wx
.MessageBox(_("Couldn't reload '%s'. Unable to close current '%s'.") % (shortName
, shortName
))
1820 return self
.CreateDocument(path
, flags
)
1821 elif res
== wx
.NO
: # don't ask again
1822 document
.SetDocumentModificationDate()
1824 firstView
= document
.GetFirstView()
1825 if firstView
and firstView
.GetFrame():
1826 firstView
.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
1827 if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
1828 firstView
.GetFrame().Iconize(False)
1832 newDoc
= temp
.CreateDocument(path
, flags
)
1834 newDoc
.SetDocumentName(temp
.GetDocumentName())
1835 newDoc
.SetDocumentTemplate(temp
)
1836 if not newDoc
.OnOpenDocument(path
):
1837 newDoc
.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1838 newDoc
.GetFirstView().GetFrame().Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
1840 self
.AddFileToHistory(path
)
1846 def CreateView(self
, document
, flags
=0):
1848 Creates a new view for the given document. If more than one view is
1849 allowed for the document (by virtue of multiple templates mentioning
1850 the same document type), a choice of view is presented to the user.
1853 for temp
in self
._templates
:
1854 if temp
.IsVisible():
1855 if temp
.GetDocumentName() == doc
.GetDocumentName():
1856 templates
.append(temp
)
1857 if len(templates
) == 0:
1860 if len(templates
) == 1:
1862 view
= temp
.CreateView(doc
, flags
)
1864 view
.SetViewName(temp
.GetViewName())
1867 temp
= SelectViewType(templates
)
1869 view
= temp
.CreateView(doc
, flags
)
1871 view
.SetViewName(temp
.GetViewName())
1877 def DeleteTemplate(self
, template
, flags
):
1879 Placeholder, not yet implemented in wxWindows.
1884 def FlushDoc(self
, doc
):
1886 Placeholder, not yet implemented in wxWindows.
1891 def MatchTemplate(self
, path
):
1893 Placeholder, not yet implemented in wxWindows.
1898 def GetCurrentDocument(self
):
1900 Returns the document associated with the currently active view (if any).
1902 view
= self
.GetCurrentView()
1904 return view
.GetDocument()
1909 def MakeDefaultName(self
):
1911 Returns a suitable default name. This is implemented by appending an
1912 integer counter to the string "Untitled" and incrementing the counter.
1914 name
= _("Untitled %d") % self
._defaultDocumentNameCounter
1915 self
._defaultDocumentNameCounter
= self
._defaultDocumentNameCounter
+ 1
1919 def MakeFrameTitle(self
):
1921 Returns a suitable title for a document frame. This is implemented by
1922 appending the document name to the application name.
1924 appName
= wx
.GetApp().GetAppName()
1928 docName
= doc
.GetPrintableName()
1929 title
= docName
+ _(" - ") + appName
1933 def AddFileToHistory(self
, fileName
):
1935 Adds a file to the file history list, if we have a pointer to an
1936 appropriate file menu.
1938 if self
._fileHistory
:
1939 self
._fileHistory
.AddFileToHistory(fileName
)
1942 def RemoveFileFromHistory(self
, i
):
1944 Removes a file from the file history list, if we have a pointer to an
1945 appropriate file menu.
1947 if self
._fileHistory
:
1948 self
._fileHistory
.RemoveFileFromHistory(i
)
1951 def GetFileHistory(self
):
1953 Returns the file history.
1955 return self
._fileHistory
1958 def GetHistoryFile(self
, i
):
1960 Returns the file at index i from the file history.
1962 if self
._fileHistory
:
1963 return self
._fileHistory
.GetHistoryFile(i
)
1968 def FileHistoryUseMenu(self
, menu
):
1970 Use this menu for appending recently-visited document filenames, for
1971 convenient access. Calling this function with a valid menu enables the
1972 history list functionality.
1974 Note that you can add multiple menus using this function, to be
1975 managed by the file history object.
1977 if self
._fileHistory
:
1978 self
._fileHistory
.UseMenu(menu
)
1981 def FileHistoryRemoveMenu(self
, menu
):
1983 Removes the given menu from the list of menus managed by the file
1986 if self
._fileHistory
:
1987 self
._fileHistory
.RemoveMenu(menu
)
1990 def FileHistoryLoad(self
, config
):
1992 Loads the file history from a config object.
1994 if self
._fileHistory
:
1995 self
._fileHistory
.Load(config
)
1998 def FileHistorySave(self
, config
):
2000 Saves the file history into a config object. This must be called
2001 explicitly by the application.
2003 if self
._fileHistory
:
2004 self
._fileHistory
.Save(config
)
2007 def FileHistoryAddFilesToMenu(self
, menu
=None):
2009 Appends the files in the history list, to all menus managed by the
2010 file history object.
2012 If menu is specified, appends the files in the history list to the
2015 if self
._fileHistory
:
2017 self
._fileHistory
.AddFilesToThisMenu(menu
)
2019 self
._fileHistory
.AddFilesToMenu()
2022 def GetHistoryFilesCount(self
):
2024 Returns the number of files currently stored in the file history.
2026 if self
._fileHistory
:
2027 return self
._fileHistory
.GetNoHistoryFiles()
2032 def FindTemplateForPath(self
, path
):
2034 Given a path, try to find template that matches the extension. This is
2035 only an approximate method of finding a template for creating a
2038 for temp
in self
._templates
:
2039 if temp
.FileMatchesTemplate(path
):
2044 def FindSuitableParent(self
):
2046 Returns a parent frame or dialog, either the frame with the current
2047 focus or if there is no current focus the application's top frame.
2049 parent
= wx
.GetApp().GetTopWindow()
2050 focusWindow
= wx
.Window_FindFocus()
2052 while focusWindow
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
):
2053 focusWindow
= focusWindow
.GetParent()
2055 parent
= focusWindow
2059 def SelectDocumentPath(self
, templates
, flags
, save
):
2061 Under Windows, pops up a file selector with a list of filters
2062 corresponding to document templates. The wxDocTemplate corresponding
2063 to the selected file's extension is returned.
2065 On other platforms, if there is more than one document template a
2066 choice list is popped up, followed by a file selector.
2068 This function is used in wxDocManager.CreateDocument.
2070 if wx
.Platform
== "__WXMSW__" or wx
.Platform
== "__WXGTK__" or wx
.Platform
== "__WXMAC__":
2073 for temp
in templates
:
2074 if temp
.IsVisible():
2076 descr
= descr
+ _('|')
2077 allfilter
= allfilter
+ _(';')
2078 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
2079 allfilter
= allfilter
+ temp
.GetFileFilter()
2080 descr
= _("All") + _(" (") + allfilter
+ _(") |") + allfilter
+ _('|') + descr
# spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
2084 path
= wx
.FileSelector(_("Select a File"),
2085 self
._lastDirectory
,
2088 flags
= wx
.HIDE_READONLY
,
2089 parent
= self
.FindSuitableParent())
2091 if not FileExists(path
):
2092 msgTitle
= wx
.GetApp().GetAppName()
2094 msgTitle
= _("File Error")
2095 wx
.MessageBox("Could not open '%s'." % FileNameFromPath(path
),
2097 wx
.OK | wx
.ICON_EXCLAMATION
,
2100 self
._lastDirectory
= PathOnly(path
)
2102 theTemplate
= self
.FindTemplateForPath(path
)
2103 return (theTemplate
, path
)
2108 def OnOpenFileFailure(self
):
2110 Called when there is an error opening a file.
2115 def SelectDocumentType(self
, temps
, sort
=False):
2117 Returns a document template by asking the user (if there is more than
2118 one template). This function is used in wxDocManager.CreateDocument.
2122 templates - list of templates from which to choose a desired template.
2124 sort - If more than one template is passed in in templates, then this
2125 parameter indicates whether the list of templates that the user will
2126 have to choose from is sorted or not when shown the choice box dialog.
2131 if temp
.IsVisible():
2133 for temp2
in templates
:
2134 if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName():
2138 templates
.append(temp
)
2140 if len(templates
) == 0:
2142 elif len(templates
) == 1:
2147 return cmp(a
.GetDescription(), b
.GetDescription())
2148 templates
.sort(tempcmp
)
2151 for temp
in templates
:
2152 strings
.append(temp
.GetDescription())
2154 res
= wx
.GetSingleChoiceIndex(_("Select a document type:"),
2157 self
.FindSuitableParent())
2160 return templates
[res
]
2163 def SelectViewType(self
, temps
, sort
=False):
2165 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.
2170 if temp
.IsVisible() and temp
.GetViewTypeName():
2171 if temp
.GetViewName() not in strings
:
2172 templates
.append(temp
)
2173 strings
.append(temp
.GetViewTypeName())
2175 if len(templates
) == 0:
2177 elif len(templates
) == 1:
2182 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName())
2183 templates
.sort(tempcmp
)
2185 res
= wx
.GetSingleChoiceIndex(_("Select a document view:"),
2188 self
.FindSuitableParent())
2191 return templates
[res
]
2194 def GetTemplates(self
):
2196 Returns the document manager's template list. This method has been added to
2197 wxPython and is not in wxWindows.
2199 return self
._templates
2202 def AssociateTemplate(self
, docTemplate
):
2204 Adds the template to the document manager's template list.
2206 if docTemplate
not in self
._templates
:
2207 self
._templates
.append(docTemplate
)
2210 def DisassociateTemplate(self
, docTemplate
):
2212 Removes the template from the list of templates.
2214 self
._templates
.remove(docTemplate
)
2217 def AddDocument(self
, document
):
2219 Adds the document to the list of documents.
2221 if document
not in self
._docs
:
2222 self
._docs
.append(document
)
2225 def RemoveDocument(self
, doc
):
2227 Removes the document from the list of documents.
2229 if doc
in self
._docs
:
2230 self
._docs
.remove(doc
)
2233 def ActivateView(self
, view
, activate
=True, deleting
=False):
2235 Sets the current view.
2238 self
._currentView
= view
2239 self
._lastActiveView
= view
2241 self
._currentView
= None
2244 def GetMaxDocsOpen(self
):
2246 Returns the number of documents that can be open simultaneously.
2248 return self
._maxDocsOpen
2251 def SetMaxDocsOpen(self
, maxDocsOpen
):
2253 Sets the maximum number of documents that can be open at a time. By
2254 default, this is 10,000. If you set it to 1, existing documents will
2255 be saved and deleted when the user tries to open or create a new one
2256 (similar to the behaviour of Windows Write, for example). Allowing
2257 multiple documents gives behaviour more akin to MS Word and other
2258 Multiple Document Interface applications.
2260 self
._maxDocsOpen
= maxDocsOpen
2263 def GetDocuments(self
):
2265 Returns the list of documents.
2270 class DocParentFrame(wx
.Frame
):
2272 The wxDocParentFrame class provides a default top-level frame for
2273 applications using the document/view framework. This class can only be
2274 used for SDI (not MDI) parent frames.
2276 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates
2280 def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2282 Constructor. Note that the event table must be rebuilt for the
2283 frame since the EvtHandler is not virtual.
2285 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
)
2286 self
._docManager
= manager
2288 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2290 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2291 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2293 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2294 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2295 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2296 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2297 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2298 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2299 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2300 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2301 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2302 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2303 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2304 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2306 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2307 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2308 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2309 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2310 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2311 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2312 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2313 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2314 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2315 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2316 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2317 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2320 def ProcessEvent(self
, event
):
2322 Processes an event, searching event tables and calling zero or more
2323 suitable event handler function(s). Note that the ProcessEvent
2324 method is called from the wxPython docview framework directly since
2325 wxPython does not have a virtual ProcessEvent function.
2327 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2330 def ProcessUpdateUIEvent(self
, event
):
2332 Processes a UI event, searching event tables and calling zero or more
2333 suitable event handler function(s). Note that the ProcessEvent
2334 method is called from the wxPython docview framework directly since
2335 wxPython does not have a virtual ProcessEvent function.
2337 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2340 def OnExit(self
, event
):
2342 Called when File/Exit is chosen and closes the window.
2347 def OnMRUFile(self
, event
):
2349 Opens the appropriate file when it is selected from the file history
2352 n
= event
.GetId() - wx
.ID_FILE1
2353 filename
= self
._docManager
.GetHistoryFile(n
)
2355 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2357 self
._docManager
.RemoveFileFromHistory(n
)
2358 msgTitle
= wx
.GetApp().GetAppName()
2360 msgTitle
= _("File Error")
2361 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),
2363 wx
.OK | wx
.ICON_EXCLAMATION
,
2367 def OnCloseWindow(self
, event
):
2369 Deletes all views and documents. If no user input cancelled the
2370 operation, the frame will be destroyed and the application will exit.
2372 if self
._docManager
.Clear(not event
.CanVeto()):
2378 class DocChildFrame(wx
.Frame
):
2380 The wxDocChildFrame class provides a default frame for displaying
2381 documents on separate windows. This class can only be used for SDI (not
2384 The class is part of the document/view framework supported by wxWindows,
2385 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2390 def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2392 Constructor. Note that the event table must be rebuilt for the
2393 frame since the EvtHandler is not virtual.
2395 wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2396 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2397 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2398 self
._childDocument
= doc
2399 self
._childView
= view
2403 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2404 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2405 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2406 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2407 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2408 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2409 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2410 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2411 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2412 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2413 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2414 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2416 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2417 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2418 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2419 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2420 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2421 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2422 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2423 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2424 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2425 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2426 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2427 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2430 def ProcessEvent(self
, event
):
2432 Processes an event, searching event tables and calling zero or more
2433 suitable event handler function(s). Note that the ProcessEvent
2434 method is called from the wxPython docview framework directly since
2435 wxPython does not have a virtual ProcessEvent function.
2438 self
._childView
.Activate(True)
2439 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2440 # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows
2441 # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
2442 if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2450 def ProcessUpdateUIEvent(self
, event
):
2452 Processes a UI event, searching event tables and calling zero or more
2453 suitable event handler function(s). Note that the ProcessEvent
2454 method is called from the wxPython docview framework directly since
2455 wxPython does not have a virtual ProcessEvent function.
2457 if self
.GetParent():
2458 self
.GetParent().ProcessUpdateUIEvent(event
)
2463 def OnActivate(self
, event
):
2465 Activates the current view.
2467 # wx.Frame.OnActivate(event) This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead
2469 self
._childView
.Activate(event
.GetActive())
2472 def OnCloseWindow(self
, event
):
2474 Closes and deletes the current view and document.
2478 if not event
.CanVeto():
2481 ans
= self
._childView
.Close(deleteWindow
= False)
2484 self
._childView
.Activate(False)
2485 self
._childView
.Destroy()
2486 self
._childView
= None
2487 if self
._childDocument
:
2488 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2489 self
._childDocument
= None
2497 def GetDocument(self
):
2499 Returns the document associated with this frame.
2501 return self
._childDocument
2504 def SetDocument(self
, document
):
2506 Sets the document for this frame.
2508 self
._childDocument
= document
2513 Returns the view associated with this frame.
2515 return self
._childView
2518 def SetView(self
, view
):
2520 Sets the view for this frame.
2522 self
._childView
= view
2525 class DocMDIParentFrame(wx
.MDIParentFrame
):
2527 The wxDocMDIParentFrame class provides a default top-level frame for
2528 applications using the document/view framework. This class can only be
2529 used for MDI parent frames.
2531 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2536 def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2538 Constructor. Note that the event table must be rebuilt for the
2539 frame since the EvtHandler is not virtual.
2541 wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2542 self
._docManager
= manager
2544 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2546 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
2547 wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
)
2549 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
)
2550 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
)
2551 wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
)
2552 wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
)
2553 wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
)
2554 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
)
2555 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
)
2556 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
)
2557 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
)
2558 wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
)
2559 wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
)
2560 wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
)
2562 wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
)
2563 wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
)
2564 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
)
2565 wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
)
2566 wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
)
2567 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
)
2568 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
)
2569 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
)
2570 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
)
2571 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
)
2572 wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
)
2573 wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
)
2576 def ProcessEvent(self
, event
):
2578 Processes an event, searching event tables and calling zero or more
2579 suitable event handler function(s). Note that the ProcessEvent
2580 method is called from the wxPython docview framework directly since
2581 wxPython does not have a virtual ProcessEvent function.
2583 return self
._docManager
and self
._docManager
.ProcessEvent(event
)
2586 def ProcessUpdateUIEvent(self
, event
):
2588 Processes a UI event, searching event tables and calling zero or more
2589 suitable event handler function(s). Note that the ProcessEvent
2590 method is called from the wxPython docview framework directly since
2591 wxPython does not have a virtual ProcessEvent function.
2593 return self
._docManager
and self
._docManager
.ProcessUpdateUIEvent(event
)
2596 def OnExit(self
, event
):
2598 Called when File/Exit is chosen and closes the window.
2603 def OnMRUFile(self
, event
):
2605 Opens the appropriate file when it is selected from the file history
2608 n
= event
.GetId() - wx
.ID_FILE1
2609 filename
= self
._docManager
.GetHistoryFile(n
)
2611 self
._docManager
.CreateDocument(filename
, DOC_SILENT
)
2613 self
._docManager
.RemoveFileFromHistory(n
)
2614 msgTitle
= wx
.GetApp().GetAppName()
2616 msgTitle
= _("File Error")
2617 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),
2619 wx
.OK | wx
.ICON_EXCLAMATION
,
2623 def OnCloseWindow(self
, event
):
2625 Deletes all views and documents. If no user input cancelled the
2626 operation, the frame will be destroyed and the application will exit.
2628 if self
._docManager
.Clear(not event
.CanVeto()):
2634 class DocMDIChildFrame(wx
.MDIChildFrame
):
2636 The wxDocMDIChildFrame class provides a default frame for displaying
2637 documents on separate windows. This class can only be used for MDI child
2640 The class is part of the document/view framework supported by wxWindows,
2641 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
2646 def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"):
2648 Constructor. Note that the event table must be rebuilt for the
2649 frame since the EvtHandler is not virtual.
2651 wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
)
2652 self
._childDocument
= doc
2653 self
._childView
= view
2656 # self.Create(doc, view, frame, id, title, pos, size, style, name)
2657 self
._activeEvent
= None
2659 wx
.EVT_ACTIVATE(self
, self
.OnActivate
)
2660 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
2662 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
2663 mdiChildren
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren())
2664 if len(mdiChildren
) == 1:
2668 ## # Couldn't get this to work, but seems to work fine with single stage construction
2669 ## def Create(self, doc, view, frame, id, title, pos, size, style, name):
2670 ## self._childDocument = doc
2671 ## self._childView = view
2672 ## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
2674 ## view.SetFrame(self)
2680 def Activate(self
): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
2682 Activates the current view.
2685 self
._childView
.Activate(True)
2688 def ProcessEvent(event
):
2690 Processes an event, searching event tables and calling zero or more
2691 suitable event handler function(s). Note that the ProcessEvent
2692 method is called from the wxPython docview framework directly since
2693 wxPython does not have a virtual ProcessEvent function.
2695 if self
._activeEvent
== event
:
2698 self
._activeEvent
= event
# Break recursion loops
2701 self
._childView
.Activate(True)
2703 if not self
._childView
or not self
._childView
.ProcessEvent(event
):
2704 if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
):
2711 self
._activeEvent
= None
2715 def OnActivate(self
, event
):
2717 Sets the currently active view to be the frame's view. You may need to
2718 override (but still call) this function in order to set the keyboard
2719 focus for your subwindow.
2721 if self
._activated
!= 0:
2723 self
._activated
+= 1
2724 wx
.MDIChildFrame
.Activate(self
)
2725 if event
.GetActive() and self
._childView
:
2726 self
._childView
.Activate(event
.GetActive())
2729 def OnCloseWindow(self
, event
):
2731 Closes and deletes the current view and document.
2735 if not event
.CanVeto():
2738 ans
= self
._childView
.Close(deleteWindow
= False)
2741 self
._childView
.Activate(False)
2742 self
._childView
.Destroy()
2743 self
._childView
= None
2744 if self
._childDocument
:
2745 self
._childDocument
.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
2746 self
._childDocument
= None
2754 def GetDocument(self
):
2756 Returns the document associated with this frame.
2758 return self
._childDocument
2761 def SetDocument(self
, document
):
2763 Sets the document for this frame.
2765 self
._childDocument
= document
2770 Returns the view associated with this frame.
2772 return self
._childView
2775 def SetView(self
, view
):
2777 Sets the view for this frame.
2779 self
._childView
= view
2782 class DocPrintout(wx
.Printout
):
2784 DocPrintout is a default Printout that prints the first page of a document
2789 def __init__(self
, view
, title
="Printout"):
2793 wx
.Printout
.__init
__(self
)
2794 self
._printoutView
= view
2799 Returns the DocPrintout's view.
2801 return self
._printoutView
2804 def OnPrintPage(self
, page
):
2806 Prints the first page of the view.
2809 ppiScreenX
, ppiScreenY
= self
.GetPPIScreen()
2810 ppiPrinterX
, ppiPrinterY
= self
.GetPPIPrinter()
2811 scale
= ppiPrinterX
/ppiScreenX
2813 pageWidth
, pageHeight
= self
.GetPageSizePixels()
2814 overallScale
= scale
* w
/ pageWidth
2815 dc
.SetUserScale(overallScale
, overallScale
)
2816 if self
._printoutView
:
2817 self
._printoutView
.OnDraw(dc
)
2821 def HasPage(self
, pageNum
):
2823 Indicates that the DocPrintout only has a single page.
2828 def OnBeginDocument(self
, startPage
, endPage
):
2830 Not quite sure why this was overridden, but it was in wxWindows! :)
2832 if not wx
.Printout
.base_OnBeginDocument(self
, startPage
, endPage
):
2837 def GetPageInfo(self
):
2839 Indicates that the DocPrintout only has a single page.
2845 return (minPage
, maxPage
, selPageFrom
, selPageTo
)
2848 #----------------------------------------------------------------------
2850 #----------------------------------------------------------------------
2852 class Command(wx
.Object
):
2854 wxCommand is a base class for modelling an application command, which is
2855 an action usually performed by selecting a menu item, pressing a toolbar
2856 button or any other means provided by the application to change the data
2861 def __init__(self
, canUndo
= False, name
= None):
2863 Constructor. wxCommand is an abstract class, so you will need to
2864 derive a new class and call this constructor from your own constructor.
2866 canUndo tells the command processor whether this command is undo-able.
2867 You can achieve the same functionality by overriding the CanUndo member
2868 function (if for example the criteria for undoability is context-
2871 name must be supplied for the command processor to display the command
2872 name in the application's edit menu.
2874 self
._canUndo
= canUndo
2880 Returns true if the command can be undone, false otherwise.
2882 return self
._canUndo
2887 Returns the command name.
2894 Override this member function to execute the appropriate action when
2895 called. Return true to indicate that the action has taken place, false
2896 otherwise. Returning false will indicate to the command processor that
2897 the action is not undoable and should not be added to the command
2905 Override this member function to un-execute a previous Do. Return true
2906 to indicate that the action has taken place, false otherwise. Returning
2907 false will indicate to the command processor that the action is not
2908 redoable and no change should be made to the command history.
2910 How you implement this command is totally application dependent, but
2911 typical strategies include:
2913 Perform an inverse operation on the last modified piece of data in the
2914 document. When redone, a copy of data stored in command is pasted back
2915 or some operation reapplied. This relies on the fact that you know the
2916 ordering of Undos; the user can never Undo at an arbitrary position in
2919 Restore the entire document state (perhaps using document
2920 transactioning). Potentially very inefficient, but possibly easier to
2921 code if the user interface and data are complex, and an 'inverse
2922 execute' operation is hard to write.
2927 class CommandProcessor(wx
.Object
):
2929 wxCommandProcessor is a class that maintains a history of wxCommands, with
2930 undo/redo functionality built-in. Derive a new class from this if you want
2931 different behaviour.
2935 def __init__(self
, maxCommands
=-1):
2937 Constructor. maxCommands may be set to a positive integer to limit
2938 the number of commands stored to it, otherwise (and by default) the
2939 list of commands can grow arbitrarily.
2941 self
._maxCommands
= maxCommands
2942 self
._editMenu
= None
2943 self
._undoAccelerator
= _("Ctrl+Z")
2944 self
._redoAccelerator
= _("Ctrl+Y")
2945 self
.ClearCommands()
2948 def _GetCurrentCommand(self
):
2949 if len(self
._commands
) == 0:
2952 return self
._commands
[-1]
2955 def _GetCurrentRedoCommand(self
):
2956 if len(self
._redoCommands
) == 0:
2959 return self
._redoCommands
[-1]
2962 def GetMaxCommands(self
):
2964 Returns the maximum number of commands that the command processor
2968 return self
._maxCommands
2971 def GetCommands(self
):
2973 Returns the list of commands.
2975 return self
._commands
2978 def ClearCommands(self
):
2980 Deletes all the commands in the list and sets the current command
2984 self
._redoCommands
= []
2987 def GetEditMenu(self
):
2989 Returns the edit menu associated with the command processor.
2991 return self
._editMenu
2994 def SetEditMenu(self
, menu
):
2996 Tells the command processor to update the Undo and Redo items on this
2997 menu as appropriate. Set this to NULL if the menu is about to be
2998 destroyed and command operations may still be performed, or the
2999 command processor may try to access an invalid pointer.
3001 self
._editMenu
= menu
3004 def GetUndoAccelerator(self
):
3006 Returns the string that will be appended to the Undo menu item.
3008 return self
._undoAccelerator
3011 def SetUndoAccelerator(self
, accel
):
3013 Sets the string that will be appended to the Redo menu item.
3015 self
._undoAccelerator
= accel
3018 def GetRedoAccelerator(self
):
3020 Returns the string that will be appended to the Redo menu item.
3022 return self
._redoAccelerator
3025 def SetRedoAccelerator(self
, accel
):
3027 Sets the string that will be appended to the Redo menu item.
3029 self
._redoAccelerator
= accel
3032 def SetEditMenu(self
, menu
):
3034 Tells the command processor to update the Undo and Redo items on this
3035 menu as appropriate. Set this to NULL if the menu is about to be
3036 destroyed and command operations may still be performed, or the
3037 command processor may try to access an invalid pointer.
3039 self
._editMenu
= menu
3042 def SetMenuStrings(self
):
3044 Sets the menu labels according to the currently set menu and the
3045 current command state.
3047 if self
.GetEditMenu() != None:
3048 undoCommand
= self
._GetCurrentCommand
()
3049 redoCommand
= self
._GetCurrentRedoCommand
()
3050 undoItem
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
)
3051 redoItem
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
)
3052 if self
.GetUndoAccelerator():
3053 undoAccel
= '\t' + self
.GetUndoAccelerator()
3056 if self
.GetRedoAccelerator():
3057 redoAccel
= '\t' + self
.GetRedoAccelerator()
3060 if undoCommand
and undoItem
and undoCommand
.CanUndo():
3061 undoItem
.SetText(_("Undo ") + undoCommand
.GetName() + undoAccel
)
3062 #elif undoCommand and not undoCommand.CanUndo():
3063 # undoItem.SetText(_("Can't Undo") + undoAccel)
3065 undoItem
.SetText(_("Undo" + undoAccel
))
3066 if redoCommand
and redoItem
:
3067 redoItem
.SetText(_("Redo ") + redoCommand
.GetName() + redoAccel
)
3069 redoItem
.SetText(_("Redo") + redoAccel
)
3074 Returns true if the currently-active command can be undone, false
3077 if self
._GetCurrentCommand
() == None:
3079 return self
._GetCurrentCommand
().CanUndo()
3084 Returns true if the currently-active command can be redone, false
3087 return self
._GetCurrentRedoCommand
() != None
3090 def Submit(self
, command
, storeIt
=True):
3092 Submits a new command to the command processor. The command processor
3093 calls wxCommand::Do to execute the command; if it succeeds, the
3094 command is stored in the history list, and the associated edit menu
3095 (if any) updated appropriately. If it fails, the command is deleted
3096 immediately. Once Submit has been called, the passed command should
3097 not be deleted directly by the application.
3099 storeIt indicates whether the successful command should be stored in
3103 if done
and storeIt
:
3104 self
._commands
.append(command
)
3105 if self
._maxCommands
> -1:
3106 if len(self
._commands
) > self
._maxCommands
:
3107 del self
._commands
[0]
3113 Redoes the command just undone.
3115 cmd
= self
._GetCurrentRedoCommand
()
3120 self
._commands
.append(self
._redoCommands
.pop())
3126 Undoes the command just executed.
3128 cmd
= self
._GetCurrentCommand
()
3133 self
._redoCommands
.append(self
._commands
.pop())