1 #---------------------------------------------------------------------------- 
   3 # Purpose:      Port of the wxWindows docview classes 
   9 # Copyright:    (c) 2003-2006 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al) 
  10 # License:      wxWindows license 
  11 #---------------------------------------------------------------------------- 
  22 #---------------------------------------------------------------------- 
  24 #---------------------------------------------------------------------- 
  32 DEFAULT_DOCMAN_FLAGS 
= DOC_SDI 
& DOC_OPEN_ONCE
 
  35 TEMPLATE_INVISIBLE 
= 2 
  36 TEMPLATE_NO_CREATE 
= (4 | TEMPLATE_VISIBLE
) 
  37 DEFAULT_TEMPLATE_FLAGS 
= TEMPLATE_VISIBLE
 
  42 #---------------------------------------------------------------------- 
  43 # Convenience functions from wxWindows used in docview 
  44 #---------------------------------------------------------------------- 
  47 def FileNameFromPath(path
): 
  49     Returns the filename for a full path. 
  51     return os
.path
.split(path
)[1] 
  53 def FindExtension(path
): 
  55     Returns the extension of a filename for a full path. 
  57     return os
.path
.splitext(path
)[1].lower() 
  61     Returns True if the path exists. 
  63     return os
.path
.isfile(path
) 
  67     Returns the path of a full path without the filename. 
  69     return os
.path
.split(path
)[0] 
  72 #---------------------------------------------------------------------- 
  73 # Document/View Classes 
  74 #---------------------------------------------------------------------- 
  77 class Document(wx
.EvtHandler
): 
  79     The document class can be used to model an application's file-based data. It 
  80     is part of the document/view framework supported by wxWindows, and cooperates 
  81     with the wxView, wxDocTemplate and wxDocManager classes. 
  83     Note this wxPython version also keeps track of the modification date of the 
  84     document and if it changes on disk outside of the application, we will warn the 
  85     user before saving to avoid clobbering the file. 
  89     def __init__(self
, parent
=None): 
  91         Constructor.  Define your own default constructor to initialize 
  92         application-specific data. 
  94         wx
.EvtHandler
.__init
__(self
) 
  96         self
._documentParent 
= parent
 
  97         self
._documentTemplate 
= None 
  98         self
._commandProcessor 
= None 
  99         self
._savedYet 
= False 
 100         self
._writeable 
= True 
 102         self
._documentTitle 
= None 
 103         self
._documentFile 
= None 
 104         self
._documentTypeName 
= None 
 105         self
._documentModified 
= False 
 106         self
._documentModificationDate 
= None 
 107         self
._documentViews 
= [] 
 110     def ProcessEvent(self
, event
): 
 112         Processes an event, searching event tables and calling zero or more 
 113         suitable event handler function(s).  Note that the ProcessEvent 
 114         method is called from the wxPython docview framework directly since 
 115         wxPython does not have a virtual ProcessEvent function. 
 120     def GetFilename(self
): 
 122         Gets the filename associated with this document, or "" if none is 
 125         return self
._documentFile
 
 130         Gets the title for this document. The document title is used for an 
 131         associated frame (if any), and is usually constructed by the framework 
 134         return self
._documentTitle
 
 137     def SetTitle(self
, title
): 
 139         Sets the title for this document. The document title is used for an 
 140         associated frame (if any), and is usually constructed by the framework 
 143         self
._documentTitle 
= title
 
 146     def GetDocumentName(self
): 
 148         The document type name given to the wxDocTemplate constructor, 
 149         copied to this document when the document is created. If several 
 150         document templates are created that use the same document type, this 
 151         variable is used in wxDocManager::CreateView to collate a list of 
 152         alternative view types that can be used on this kind of document. 
 154         return self
._documentTypeName
 
 157     def SetDocumentName(self
, name
): 
 159         Sets he document type name given to the wxDocTemplate constructor, 
 160         copied to this document when the document is created. If several 
 161         document templates are created that use the same document type, this 
 162         variable is used in wxDocManager::CreateView to collate a list of 
 163         alternative view types that can be used on this kind of document. Do 
 164         not change the value of this variable. 
 166         self
._documentTypeName 
= name
 
 169     def GetDocumentSaved(self
): 
 171         Returns True if the document has been saved.  This method has been 
 172         added to wxPython and is not in wxWindows. 
 174         return self
._savedYet
 
 177     def SetDocumentSaved(self
, saved
=True): 
 179         Sets whether the document has been saved.  This method has been 
 180         added to wxPython and is not in wxWindows. 
 182         self
._savedYet 
= saved
 
 185     def GetCommandProcessor(self
): 
 187         Returns the command processor associated with this document. 
 189         return self
._commandProcessor
 
 192     def SetCommandProcessor(self
, processor
): 
 194         Sets the command processor to be used for this document. The document 
 195         will then be responsible for its deletion. Normally you should not 
 196         call this; override OnCreateCommandProcessor instead. 
 198         self
._commandProcessor 
= processor
 
 201     def IsModified(self
): 
 203         Returns true if the document has been modified since the last save, 
 204         false otherwise. You may need to override this if your document view 
 205         maintains its own record of being modified (for example if using 
 206         wxTextWindow to view and edit the document). 
 208         return self
._documentModified
 
 211     def Modify(self
, modify
): 
 213         Call with true to mark the document as modified since the last save, 
 214         false otherwise. You may need to override this if your document view 
 215         maintains its own record of being modified (for example if using 
 216         xTextWindow to view and edit the document). 
 217         This method has been extended to notify its views that the dirty flag has changed. 
 219         self
._documentModified 
= modify
 
 220         self
.UpdateAllViews(hint
=("modify", self
, self
._documentModified
)) 
 223     def SetDocumentModificationDate(self
): 
 225         Saves the file's last modification date. 
 226         This is used to check if the file has been modified outside of the application. 
 227         This method has been added to wxPython and is not in wxWindows. 
 229         self
._documentModificationDate 
= os
.path
.getmtime(self
.GetFilename()) 
 232     def GetDocumentModificationDate(self
): 
 234         Returns the file's modification date when it was loaded from disk. 
 235         This is used to check if the file has been modified outside of the application.         
 236         This method has been added to wxPython and is not in wxWindows. 
 238         return self
._documentModificationDate
 
 241     def IsDocumentModificationDateCorrect(self
): 
 243         Returns False if the file has been modified outside of the application. 
 244         This method has been added to wxPython and is not in wxWindows. 
 246         if not os
.path
.exists(self
.GetFilename()):  # document must be in memory only and can't be out of date 
 248         return self
._documentModificationDate 
== os
.path
.getmtime(self
.GetFilename()) 
 253         Returns the list whose elements are the views on the document. 
 255         return self
._documentViews
 
 258     def GetDocumentTemplate(self
): 
 260         Returns the template that created the document. 
 262         return self
._documentTemplate
 
 265     def SetDocumentTemplate(self
, template
): 
 267         Sets the template that created the document. Should only be called by 
 270         self
._documentTemplate 
= template
 
 273     def DeleteContents(self
): 
 275         Deletes the contents of the document.  Override this method as 
 283         Destructor. Removes itself from the document manager. 
 285         self
.DeleteContents() 
 286         self
._documentModificationDate 
= None 
 287         if self
.GetDocumentManager(): 
 288             self
.GetDocumentManager().RemoveDocument(self
) 
 289         wx
.EvtHandler
.Destroy(self
) 
 294         Closes the document, by calling OnSaveModified and then (if this true) 
 295         OnCloseDocument. This does not normally delete the document object: 
 296         use DeleteAllViews to do this implicitly. 
 298         if self
.OnSaveModified(): 
 299             if self
.OnCloseDocument(): 
 307     def OnCloseDocument(self
): 
 309         The default implementation calls DeleteContents (an empty 
 310         implementation) sets the modified flag to false. Override this to 
 311         supply additional behaviour when the document is closed with Close. 
 314         self
.DeleteContents() 
 319     def DeleteAllViews(self
): 
 321         Calls wxView.Close and deletes each view. Deleting the final view will 
 322         implicitly delete the document itself, because the wxView destructor 
 323         calls RemoveView. This in turns calls wxDocument::OnChangedViewList, 
 324         whose default implemention is to save and delete the document if no 
 327         manager 
= self
.GetDocumentManager() 
 328         for view 
in self
._documentViews
: 
 331         if self 
in manager
.GetDocuments(): 
 336     def GetFirstView(self
): 
 338         A convenience function to get the first view for a document, because 
 339         in many cases a document will only have a single view. 
 341         if len(self
._documentViews
) == 0: 
 343         return self
._documentViews
[0] 
 346     def GetDocumentManager(self
): 
 348         Returns the associated document manager. 
 350         if self
._documentTemplate
: 
 351             return self
._documentTemplate
.GetDocumentManager() 
 355     def OnNewDocument(self
): 
 357         The default implementation calls OnSaveModified and DeleteContents, 
 358         makes a default title for the document, and notifies the views that 
 359         the filename (in fact, the title) has changed. 
 361         if not self
.OnSaveModified() or not self
.OnCloseDocument(): 
 363         self
.DeleteContents() 
 365         self
.SetDocumentSaved(False) 
 366         name 
= self
.GetDocumentManager().MakeDefaultName() 
 368         self
.SetFilename(name
, notifyViews 
= True) 
 373         Saves the document by calling OnSaveDocument if there is an associated 
 374         filename, or SaveAs if there is no filename. 
 376         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? 
 379         """ check for file modification outside of application """ 
 380         if not self
.IsDocumentModificationDateCorrect(): 
 381             msgTitle 
= wx
.GetApp().GetAppName() 
 383                 msgTitle 
= _("Application") 
 384             res 
= wx
.MessageBox(_("'%s' has been modified outside of %s.  Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()), 
 386                                 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
, 
 387                                 self
.GetDocumentWindow()) 
 393             else: # elif res == wx.CANCEL: 
 396         if not self
._documentFile 
or not self
._savedYet
: 
 398         return self
.OnSaveDocument(self
._documentFile
) 
 403         Prompts the user for a file to save to, and then calls OnSaveDocument. 
 405         docTemplate 
= self
.GetDocumentTemplate() 
 409         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 
 410         filename 
= wx
.FileSelector(_("Save As"), 
 411                                    docTemplate
.GetDirectory(), 
 412                                    FileNameFromPath(self
.GetFilename()), 
 413                                    docTemplate
.GetDefaultExtension(), 
 415                                    flags 
= wx
.SAVE | wx
.OVERWRITE_PROMPT
, 
 416                                    parent 
= self
.GetDocumentWindow()) 
 420         name
, ext 
= os
.path
.splitext(filename
) 
 422             filename 
+= '.' + docTemplate
.GetDefaultExtension() 
 424         self
.SetFilename(filename
) 
 425         self
.SetTitle(FileNameFromPath(filename
)) 
 427         for view 
in self
._documentViews
: 
 428             view
.OnChangeFilename() 
 430         if not self
.OnSaveDocument(filename
): 
 433         if docTemplate
.FileMatchesTemplate(filename
): 
 434             self
.GetDocumentManager().AddFileToHistory(filename
) 
 439     def OnSaveDocument(self
, filename
): 
 441         Constructs an output file for the given filename (which must 
 442         not be empty), and calls SaveObject. If SaveObject returns true, the 
 443         document is set to unmodified; otherwise, an error message box is 
 449         msgTitle 
= wx
.GetApp().GetAppName() 
 451             msgTitle 
= _("File Error") 
 453         backupFilename 
= None 
 457             # if current file exists, move it to a safe place temporarily 
 458             if os
.path
.exists(filename
): 
 460                 # Check if read-only. 
 461                 if not os
.access(filename
, os
.W_OK
): 
 462                     wx
.MessageBox("Could not save '%s'.  No write permission to overwrite existing file." % FileNameFromPath(filename
), 
 464                                   wx
.OK | wx
.ICON_EXCLAMATION
, 
 465                                   self
.GetDocumentWindow()) 
 469                 backupFilename 
= "%s.bak%s" % (filename
, i
) 
 470                 while os
.path
.exists(backupFilename
): 
 472                     backupFilename 
= "%s.bak%s" % (filename
, i
) 
 473                 shutil
.copy(filename
, backupFilename
) 
 476             fileObject 
= file(filename
, 'w') 
 477             self
.SaveObject(fileObject
) 
 482                 os
.remove(backupFilename
) 
 484             # for debugging purposes 
 486             traceback
.print_exc() 
 489                 fileObject
.close()  # file is still open, close it, need to do this before removal  
 491             # save failed, remove copied file 
 492             if backupFilename 
and copied
: 
 493                 os
.remove(backupFilename
) 
 495             wx
.MessageBox("Could not save '%s'.  %s" % (FileNameFromPath(filename
), sys
.exc_value
), 
 497                           wx
.OK | wx
.ICON_EXCLAMATION
, 
 498                           self
.GetDocumentWindow()) 
 501         self
.SetDocumentModificationDate() 
 502         self
.SetFilename(filename
, True) 
 504         self
.SetDocumentSaved(True) 
 505         #if wx.Platform == '__WXMAC__':  # Not yet implemented in wxPython 
 506         #    wx.FileName(file).MacSetDefaultTypeAndCreator() 
 510     def OnOpenDocument(self
, filename
): 
 512         Constructs an input file for the given filename (which must not 
 513         be empty), and calls LoadObject. If LoadObject returns true, the 
 514         document is set to unmodified; otherwise, an error message box is 
 515         displayed. The document's views are notified that the filename has 
 516         changed, to give windows an opportunity to update their titles. All of 
 517         the document's views are then updated. 
 519         if not self
.OnSaveModified(): 
 522         msgTitle 
= wx
.GetApp().GetAppName() 
 524             msgTitle 
= _("File Error") 
 526         fileObject 
= file(filename
, 'r') 
 528             self
.LoadObject(fileObject
) 
 532             # for debugging purposes 
 534             traceback
.print_exc() 
 537                 fileObject
.close()  # file is still open, close it  
 539             wx
.MessageBox("Could not open '%s'.  %s" % (FileNameFromPath(filename
), sys
.exc_value
), 
 541                           wx
.OK | wx
.ICON_EXCLAMATION
, 
 542                           self
.GetDocumentWindow()) 
 545         self
.SetDocumentModificationDate() 
 546         self
.SetFilename(filename
, True) 
 548         self
.SetDocumentSaved(True) 
 549         self
.UpdateAllViews() 
 553     def LoadObject(self
, file): 
 555         Override this function and call it from your own LoadObject before 
 556         loading your own data. LoadObject is called by the framework 
 557         automatically when the document contents need to be loaded. 
 559         Note that the wxPython version simply sends you a Python file object, 
 560         so you can use pickle. 
 565     def SaveObject(self
, file): 
 567         Override this function and call it from your own SaveObject before 
 568         saving your own data. SaveObject is called by the framework 
 569         automatically when the document contents need to be saved. 
 571         Note that the wxPython version simply sends you a Python file object, 
 572         so you can use pickle. 
 579         Override this function to revert the document to its last saved state. 
 584     def GetPrintableName(self
): 
 586         Copies a suitable document name into the supplied name buffer. 
 587         The default function uses the title, or if there is no title, uses the 
 588         filename; or if no filename, the string 'Untitled'. 
 590         if self
._documentTitle
: 
 591             return self
._documentTitle
 
 592         elif self
._documentFile
: 
 593             return FileNameFromPath(self
._documentFile
) 
 598     def GetDocumentWindow(self
): 
 600         Intended to return a suitable window for using as a parent for 
 601         document-related dialog boxes. By default, uses the frame associated 
 604         if len(self
._documentViews
) > 0: 
 605             return self
._documentViews
[0].GetFrame() 
 607             return wx
.GetApp().GetTopWindow() 
 610     def OnCreateCommandProcessor(self
): 
 612         Override this function if you want a different (or no) command 
 613         processor to be created when the document is created. By default, it 
 614         returns an instance of wxCommandProcessor. 
 616         return CommandProcessor() 
 619     def OnSaveModified(self
): 
 621         If the document has been modified, prompts the user to ask if the 
 622         changes should be changed. If the user replies Yes, the Save function 
 623         is called. If No, the document is marked as unmodified and the 
 624         function succeeds. If Cancel, the function fails. 
 626         if not self
.IsModified(): 
 629         """ check for file modification outside of application """ 
 630         if not self
.IsDocumentModificationDateCorrect(): 
 631             msgTitle 
= wx
.GetApp().GetAppName() 
 633                 msgTitle 
= _("Warning") 
 634             res 
= wx
.MessageBox(_("'%s' has been modified outside of %s.  Overwrite '%s' with current changes?") % (self
.GetPrintableName(), msgTitle
, self
.GetPrintableName()), 
 636                                 wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
, 
 637                                 self
.GetDocumentWindow()) 
 643                 return wx
.lib
.docview
.Document
.Save(self
) 
 644             else: # elif res == wx.CANCEL: 
 647         msgTitle 
= wx
.GetApp().GetAppName() 
 649             msgTitle 
= _("Warning") 
 651         res 
= wx
.MessageBox(_("Save changes to '%s'?") % self
.GetPrintableName(), 
 653                             wx
.YES_NO | wx
.CANCEL | wx
.ICON_QUESTION
, 
 654                             self
.GetDocumentWindow()) 
 661         else: # elif res == wx.CANCEL: 
 667         Called by printing framework to draw the view. 
 672     def AddView(self
, view
): 
 674         If the view is not already in the list of views, adds the view and 
 675         calls OnChangedViewList. 
 677         if not view 
in self
._documentViews
: 
 678             self
._documentViews
.append(view
) 
 679             self
.OnChangedViewList() 
 683     def RemoveView(self
, view
): 
 685         Removes the view from the document's list of views, and calls 
 688         if view 
in self
._documentViews
: 
 689             self
._documentViews
.remove(view
) 
 690             self
.OnChangedViewList() 
 694     def OnCreate(self
, path
, flags
): 
 696         The default implementation calls DeleteContents (an empty 
 697         implementation) sets the modified flag to false. Override this to 
 698         supply additional behaviour when the document is opened with Open. 
 700         if flags 
& DOC_NO_VIEW
: 
 702         return self
.GetDocumentTemplate().CreateView(self
, flags
) 
 705     def OnChangedViewList(self
): 
 707         Called when a view is added to or deleted from this document. The 
 708         default implementation saves and deletes the document if no views 
 709         exist (the last one has just been removed). 
 711         if len(self
._documentViews
) == 0: 
 712             if self
.OnSaveModified(): 
 713                 pass # C version does a delete but Python will garbage collect 
 716     def UpdateAllViews(self
, sender 
= None, hint 
= None): 
 718         Updates all views. If sender is non-NULL, does not update this view. 
 719         hint represents optional information to allow a view to optimize its 
 722         for view 
in self
._documentViews
: 
 724                 view
.OnUpdate(sender
, hint
) 
 727     def NotifyClosing(self
): 
 729         Notifies the views that the document is going to close. 
 731         for view 
in self
._documentViews
: 
 732             view
.OnClosingDocument() 
 735     def SetFilename(self
, filename
, notifyViews 
= False): 
 737         Sets the filename for this document. Usually called by the framework. 
 738         If notifyViews is true, wxView.OnChangeFilename is called for all 
 741         self
._documentFile 
= filename
 
 743             for view 
in self
._documentViews
: 
 744                 view
.OnChangeFilename() 
 747     def GetWriteable(self
): 
 749         Returns true if the document can be written to its accociated file path. 
 750         This method has been added to wxPython and is not in wxWindows. 
 752         if not self
._writeable
: 
 754         if not self
._documentFile
:  # Doesn't exist, do a save as 
 757             return os
.access(self
._documentFile
, os
.W_OK
) 
 760     def SetWriteable(self
, writeable
): 
 762         Set to False if the document can not be saved.  This will disable the ID_SAVE_AS 
 763         event and is useful for custom documents that should not be saveable.  The ID_SAVE 
 764         event can be disabled by never Modifying the document.  This method has been added 
 765         to wxPython and is not in wxWindows. 
 767         self
._writeable 
= writeable
 
 770 class View(wx
.EvtHandler
): 
 772     The view class can be used to model the viewing and editing component of 
 773     an application's file-based data. It is part of the document/view 
 774     framework supported by wxWindows, and cooperates with the wxDocument, 
 775     wxDocTemplate and wxDocManager classes. 
 780         Constructor. Define your own default constructor to initialize 
 781         application-specific data. 
 783         wx
.EvtHandler
.__init
__(self
) 
 784         self
._viewDocument 
= None 
 785         self
._viewFrame 
= None 
 790         Destructor. Removes itself from the document's list of views. 
 792         if self
._viewDocument
: 
 793             self
._viewDocument
.RemoveView(self
) 
 794         wx
.EvtHandler
.Destroy(self
) 
 797     def ProcessEvent(self
, event
): 
 799         Processes an event, searching event tables and calling zero or more 
 800         suitable event handler function(s).  Note that the ProcessEvent 
 801         method is called from the wxPython docview framework directly since 
 802         wxPython does not have a virtual ProcessEvent function. 
 804         if not self
.GetDocument() or not self
.GetDocument().ProcessEvent(event
): 
 810     def ProcessUpdateUIEvent(self
, event
): 
 812         Processes a UI event, searching event tables and calling zero or more 
 813         suitable event handler function(s).  Note that the ProcessEvent 
 814         method is called from the wxPython docview framework directly since 
 815         wxPython does not have a virtual ProcessEvent function. 
 820     def OnActivateView(self
, activate
, activeView
, deactiveView
): 
 822         Called when a view is activated by means of wxView::Activate. The 
 823         default implementation does nothing. 
 828     def OnClosingDocument(self
): 
 830         Override this to clean up the view when the document is being closed. 
 831         The default implementation does nothing. 
 836     def OnDraw(self
, dc
): 
 838         Override this to draw the view for the printing framework.  The 
 839         default implementation does nothing. 
 844     def OnPrint(self
, dc
, info
): 
 846         Override this to print the view for the printing framework.  The 
 847         default implementation calls View.OnDraw. 
 852     def OnUpdate(self
, sender
, hint
): 
 854         Called when the view should be updated. sender is a pointer to the 
 855         view that sent the update request, or NULL if no single view requested 
 856         the update (for instance, when the document is opened). hint is as yet 
 857         unused but may in future contain application-specific information for 
 858         making updating more efficient. 
 861             if hint
[0] == "modify":  # if dirty flag changed, update the view's displayed title 
 862                 frame 
= self
.GetFrame() 
 863                 if frame 
and hasattr(frame
, "OnTitleIsModified"): 
 864                     frame
.OnTitleIsModified() 
 869     def OnChangeFilename(self
): 
 871         Called when the filename has changed. The default implementation 
 872         constructs a suitable title and sets the title of the view frame (if 
 876             appName 
= wx
.GetApp().GetAppName() 
 877             if not self
.GetDocument(): 
 883                 if appName 
and isinstance(self
.GetFrame(), DocChildFrame
):  # Only need app name in title for SDI 
 884                     title 
= appName 
+ _(" - ") 
 887                 self
.GetFrame().SetTitle(title 
+ self
.GetDocument().GetPrintableName()) 
 890     def GetDocument(self
): 
 892         Returns the document associated with the view. 
 894         return self
._viewDocument
 
 897     def SetDocument(self
, doc
): 
 899         Associates the given document with the view. Normally called by the 
 902         self
._viewDocument 
= doc
 
 907     def GetViewName(self
): 
 909         Gets the name associated with the view (passed to the wxDocTemplate 
 910         constructor). Not currently used by the framework. 
 912         return self
._viewTypeName
 
 915     def SetViewName(self
, name
): 
 917         Sets the view type name. Should only be called by the framework. 
 919         self
._viewTypeName 
= name
 
 922     def Close(self
, deleteWindow
=True): 
 924         Closes the view by calling OnClose. If deleteWindow is true, this 
 925         function should delete the window associated with the view. 
 927         if self
.OnClose(deleteWindow 
= deleteWindow
): 
 933     def Activate(self
, activate
=True): 
 935         Call this from your view frame's OnActivate member to tell the 
 936         framework which view is currently active. If your windowing system 
 937         doesn't call OnActivate, you may need to call this function from 
 938         OnMenuCommand or any place where you know the view must be active, and 
 939         the framework will need to get the current view. 
 941         The prepackaged view frame wxDocChildFrame calls wxView.Activate from 
 942         its OnActivate member and from its OnMenuCommand member. 
 944         if self
.GetDocument() and self
.GetDocumentManager(): 
 945             self
.OnActivateView(activate
, self
, self
.GetDocumentManager().GetCurrentView()) 
 946             self
.GetDocumentManager().ActivateView(self
, activate
) 
 949     def OnClose(self
, deleteWindow
=True): 
 951         Implements closing behaviour. The default implementation calls 
 952         wxDocument.Close to close the associated document. Does not delete the 
 953         view. The application may wish to do some cleaning up operations in 
 954         this function, if a call to wxDocument::Close succeeded. For example, 
 955         if your application's all share the same window, you need to 
 956         disassociate the window from the view and perhaps clear the window. If 
 957         deleteWindow is true, delete the frame associated with the view. 
 959         if self
.GetDocument(): 
 960             return self
.GetDocument().Close() 
 965     def OnCreate(self
, doc
, flags
): 
 967         wxDocManager or wxDocument creates a wxView via a wxDocTemplate. Just 
 968         after the wxDocTemplate creates the wxView, it calls wxView::OnCreate. 
 969         In its OnCreate member function, the wxView can create a 
 970         wxDocChildFrame or a derived class. This wxDocChildFrame provides user 
 971         interface elements to view and/or edit the contents of the wxDocument. 
 973         By default, simply returns true. If the function returns false, the 
 974         view will be deleted. 
 979     def OnCreatePrintout(self
): 
 981         Returns a wxPrintout object for the purposes of printing. It should 
 982         create a new object every time it is called; the framework will delete 
 985         By default, this function returns an instance of wxDocPrintout, which 
 986         prints and previews one page by calling wxView.OnDraw. 
 988         Override to return an instance of a class other than wxDocPrintout. 
 990         return DocPrintout(self
, self
.GetDocument().GetPrintableName()) 
 995         Gets the frame associated with the view (if any). Note that this 
 996         "frame" is not a wxFrame at all in the generic MDI implementation 
 997         which uses the notebook pages instead of the frames and this is why 
 998         this method returns a wxWindow and not a wxFrame. 
1000         return self
._viewFrame
 
1003     def SetFrame(self
, frame
): 
1005         Sets the frame associated with this view. The application should call 
1006         this if possible, to tell the view about the frame.  See GetFrame for 
1007         the explanation about the mismatch between the "Frame" in the method 
1008         name and the type of its parameter. 
1010         self
._viewFrame 
= frame
 
1013     def GetDocumentManager(self
): 
1015         Returns the document manager instance associated with this view. 
1017         if self
._viewDocument
: 
1018             return self
.GetDocument().GetDocumentManager() 
1023 class DocTemplate(wx
.Object
): 
1025     The wxDocTemplate class is used to model the relationship between a 
1026     document class and a view class. 
1030     def __init__(self
, manager
, description
, filter, dir, ext
, docTypeName
, viewTypeName
, docType
, viewType
, flags
=DEFAULT_TEMPLATE_FLAGS
, icon
=None): 
1032         Constructor. Create instances dynamically near the start of your 
1033         application after creating a wxDocManager instance, and before doing 
1034         any document or view operations. 
1036         manager is the document manager object which manages this template. 
1038         description is a short description of what the template is for. This 
1039         string will be displayed in the file filter list of Windows file 
1042         filter is an appropriate file filter such as \*.txt. 
1044         dir is the default directory to use for file selectors. 
1046         ext is the default file extension (such as txt). 
1048         docTypeName is a name that should be unique for a given type of 
1049         document, used for gathering a list of views relevant to a 
1050         particular document. 
1052         viewTypeName is a name that should be unique for a given view. 
1054         docClass is a Python class. If this is not supplied, you will need to 
1055         derive a new wxDocTemplate class and override the CreateDocument 
1056         member to return a new document instance on demand. 
1058         viewClass is a Python class. If this is not supplied, you will need to 
1059         derive a new wxDocTemplate class and override the CreateView member to 
1060         return a new view instance on demand. 
1062         flags is a bit list of the following: 
1063         wx.TEMPLATE_VISIBLE The template may be displayed to the user in 
1066         wx.TEMPLATE_INVISIBLE The template may not be displayed to the user in 
1069         wx.DEFAULT_TEMPLATE_FLAGS Defined as wxTEMPLATE_VISIBLE. 
1071         self
._docManager 
= manager
 
1072         self
._description 
= description
 
1073         self
._fileFilter 
= filter 
1074         self
._directory 
= dir 
1075         self
._defaultExt 
= ext
 
1076         self
._docTypeName 
= docTypeName
 
1077         self
._viewTypeName 
= viewTypeName
 
1078         self
._docType 
= docType
 
1079         self
._viewType 
= viewType
 
1083         self
._docManager
.AssociateTemplate(self
) 
1086     def GetDefaultExtension(self
): 
1088         Returns the default file extension for the document data, as passed to 
1089         the document template constructor. 
1091         return self
._defaultExt
 
1094     def SetDefaultExtension(self
, defaultExt
): 
1096         Sets the default file extension. 
1098         self
._defaultExt 
= defaultExt
 
1101     def GetDescription(self
): 
1103         Returns the text description of this template, as passed to the 
1104         document template constructor. 
1106         return self
._description
 
1109     def SetDescription(self
, description
): 
1111         Sets the template description. 
1113         self
._description 
= description
 
1116     def GetDirectory(self
): 
1118         Returns the default directory, as passed to the document template 
1121         return self
._directory
 
1124     def SetDirectory(self
, dir): 
1126         Sets the default directory. 
1128         self
._directory 
= dir 
1131     def GetDocumentManager(self
): 
1133         Returns the document manager instance for which this template was 
1136         return self
._docManager
 
1139     def SetDocumentManager(self
, manager
): 
1141         Sets the document manager instance for which this template was 
1142         created. Should not be called by the application. 
1144         self
._docManager 
= manager
 
1147     def GetFileFilter(self
): 
1149         Returns the file filter, as passed to the document template 
1152         return self
._fileFilter
 
1155     def SetFileFilter(self
, filter): 
1157         Sets the file filter. 
1159         self
._fileFilter 
= filter 
1164         Returns the flags, as passed to the document template constructor. 
1165         (see the constructor description for more details). 
1170     def SetFlags(self
, flags
): 
1172         Sets the internal document template flags (see the constructor 
1173         description for more details). 
1180         Returns the icon, as passed to the document template 
1181         constructor.  This method has been added to wxPython and is 
1187     def SetIcon(self
, flags
): 
1189         Sets the icon.  This method has been added to wxPython and is not 
1195     def GetDocumentType(self
): 
1197         Returns the Python document class, as passed to the document template 
1200         return self
._docType
 
1203     def GetViewType(self
): 
1205         Returns the Python view class, as passed to the document template 
1208         return self
._viewType
 
1211     def IsVisible(self
): 
1213         Returns true if the document template can be shown in user dialogs, 
1216         return (self
._flags 
& TEMPLATE_VISIBLE
) == TEMPLATE_VISIBLE
 
1219     def IsNewable(self
): 
1221         Returns true if the document template can be shown in "New" dialogs, 
1224         This method has been added to wxPython and is not in wxWindows. 
1226         return (self
._flags 
& TEMPLATE_NO_CREATE
) != TEMPLATE_NO_CREATE
 
1229     def GetDocumentName(self
): 
1231         Returns the document type name, as passed to the document template 
1234         return self
._docTypeName
 
1237     def GetViewName(self
): 
1239         Returns the view type name, as passed to the document template 
1242         return self
._viewTypeName
 
1245     def CreateDocument(self
, path
, flags
): 
1247         Creates a new instance of the associated document class. If you have 
1248         not supplied a class to the template constructor, you will need to 
1249         override this function to return an appropriate document instance. 
1251         doc 
= self
._docType
() 
1252         doc
.SetFilename(path
) 
1253         doc
.SetDocumentTemplate(self
) 
1254         self
.GetDocumentManager().AddDocument(doc
) 
1255         doc
.SetCommandProcessor(doc
.OnCreateCommandProcessor()) 
1256         if doc
.OnCreate(path
, flags
): 
1259             if doc 
in self
.GetDocumentManager().GetDocuments(): 
1260                 doc
.DeleteAllViews() 
1264     def CreateView(self
, doc
, flags
): 
1266         Creates a new instance of the associated document view. If you have 
1267         not supplied a class to the template constructor, you will need to 
1268         override this function to return an appropriate view instance. 
1270         view 
= self
._viewType
() 
1271         view
.SetDocument(doc
) 
1272         if view
.OnCreate(doc
, flags
): 
1279     def FileMatchesTemplate(self
, path
): 
1281         Returns True if the path's extension matches one of this template's 
1282         file filter extensions. 
1284         ext 
= FindExtension(path
) 
1285         if not ext
: return False 
1287         extList 
= self
.GetFileFilter().replace('*','').split(';') 
1288         return ext 
in extList
 
1291 class DocManager(wx
.EvtHandler
): 
1293     The wxDocManager class is part of the document/view framework supported by 
1294     wxWindows, and cooperates with the wxView, wxDocument and wxDocTemplate 
1298     def __init__(self
, flags
=DEFAULT_DOCMAN_FLAGS
, initialize
=True): 
1300         Constructor. Create a document manager instance dynamically near the 
1301         start of your application before doing any document or view operations. 
1303         flags is used in the Python version to indicate whether the document 
1304         manager is in DOC_SDI or DOC_MDI mode. 
1306         If initialize is true, the Initialize function will be called to 
1307         create a default history list object. If you derive from wxDocManager, 
1308         you may wish to call the base constructor with false, and then call 
1309         Initialize in your own constructor, to allow your own Initialize or 
1310         OnCreateFileHistory functions to be called. 
1313         wx
.EvtHandler
.__init
__(self
) 
1315         self
._defaultDocumentNameCounter 
= 1 
1317         self
._currentView 
= None 
1318         self
._lastActiveView 
= None 
1319         self
._maxDocsOpen 
= 10000 
1320         self
._fileHistory 
= None 
1321         self
._templates 
= [] 
1323         self
._lastDirectory 
= "" 
1328         wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnFileOpen
) 
1329         wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.OnFileClose
) 
1330         wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.OnFileCloseAll
) 
1331         wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.OnFileRevert
) 
1332         wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnFileNew
) 
1333         wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnFileSave
) 
1334         wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnFileSaveAs
) 
1335         wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
) 
1336         wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
) 
1337         wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.OnPrint
) 
1338         wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.OnPrintSetup
) 
1339         wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.OnPreview
) 
1341         wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.OnUpdateFileOpen
) 
1342         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.OnUpdateFileClose
) 
1343         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.OnUpdateFileCloseAll
) 
1344         wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.OnUpdateFileRevert
) 
1345         wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.OnUpdateFileNew
) 
1346         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateFileSave
) 
1347         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.OnUpdateFileSaveAs
) 
1348         wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUndo
) 
1349         wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateRedo
) 
1350         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.OnUpdatePrint
) 
1351         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.OnUpdatePrintSetup
) 
1352         wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.OnUpdatePreview
) 
1360         wx
.EvtHandler
.Destroy(self
) 
1365         Returns the document manager's flags.  This method has been 
1366         added to wxPython and is not in wxWindows. 
1371     def CloseDocument(self
, doc
, force
=True): 
1373         Closes the specified document. 
1375         if doc
.Close() or force
: 
1376             doc
.DeleteAllViews() 
1377             if doc 
in self
._docs
: 
1383     def CloseDocuments(self
, force
=True): 
1385         Closes all currently opened documents. 
1387         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 
1388             if not self
.CloseDocument(document
, force
): 
1390             document
.DeleteAllViews() # Implicitly delete the document when the last view is removed 
1394     def Clear(self
, force
=True): 
1396         Closes all currently opened document by callling CloseDocuments and 
1397         clears the document manager's templates. 
1399         if not self
.CloseDocuments(force
): 
1401         self
._templates 
= [] 
1405     def Initialize(self
): 
1407         Initializes data; currently just calls OnCreateFileHistory. Some data 
1408         cannot always be initialized in the constructor because the programmer 
1409         must be given the opportunity to override functionality. In fact 
1410         Initialize is called from the wxDocManager constructor, but this can 
1411         be vetoed by passing false to the second argument, allowing the 
1412         derived class's constructor to call Initialize, possibly calling a 
1413         different OnCreateFileHistory from the default. 
1415         The bottom line: if you're not deriving from Initialize, forget it and 
1416         construct wxDocManager with no arguments. 
1418         self
.OnCreateFileHistory() 
1422     def OnCreateFileHistory(self
): 
1424         A hook to allow a derived class to create a different type of file 
1425         history. Called from Initialize. 
1427         self
._fileHistory 
= wx
.FileHistory() 
1430     def OnFileClose(self
, event
): 
1432         Closes and deletes the currently active document. 
1434         doc 
= self
.GetCurrentDocument() 
1436             doc
.DeleteAllViews() 
1437             if doc 
in self
._docs
: 
1438                 self
._docs
.remove(doc
) 
1441     def OnFileCloseAll(self
, event
): 
1443         Closes and deletes all the currently opened documents. 
1445         return self
.CloseDocuments(force 
= False) 
1448     def OnFileNew(self
, event
): 
1450         Creates a new document and reads in the selected file. 
1452         self
.CreateDocument('', DOC_NEW
) 
1455     def OnFileOpen(self
, event
): 
1457         Creates a new document and reads in the selected file. 
1459         if not self
.CreateDocument('', DEFAULT_DOCMAN_FLAGS
): 
1460             self
.OnOpenFileFailure() 
1463     def OnFileRevert(self
, event
): 
1465         Reverts the current document by calling wxDocument.Save for the current 
1468         doc 
= self
.GetCurrentDocument() 
1474     def OnFileSave(self
, event
): 
1476         Saves the current document by calling wxDocument.Save for the current 
1479         doc 
= self
.GetCurrentDocument() 
1485     def OnFileSaveAs(self
, event
): 
1487         Calls wxDocument.SaveAs for the current document. 
1489         doc 
= self
.GetCurrentDocument() 
1495     def OnPrint(self
, event
): 
1497         Prints the current document by calling its View's OnCreatePrintout 
1500         view 
= self
.GetCurrentView() 
1504         printout 
= view
.OnCreatePrintout() 
1506             if not hasattr(self
, "printData"): 
1507                 self
.printData 
= wx
.PrintData() 
1508                 self
.printData
.SetPaperId(wx
.PAPER_LETTER
) 
1509             self
.printData
.SetPrintMode(wx
.PRINT_MODE_PRINTER
) 
1511             pdd 
= wx
.PrintDialogData(self
.printData
) 
1512             printer 
= wx
.Printer(pdd
) 
1513             printer
.Print(view
.GetFrame(), printout
) 
1516     def OnPrintSetup(self
, event
): 
1518         Presents the print setup dialog. 
1520         view 
= self
.GetCurrentView() 
1522             parentWin 
= view
.GetFrame() 
1524             parentWin 
= wx
.GetApp().GetTopWindow() 
1526         if not hasattr(self
, "printData"): 
1527             self
.printData 
= wx
.PrintData() 
1528             self
.printData
.SetPaperId(wx
.PAPER_LETTER
) 
1530         data 
= wx
.PrintDialogData(self
.printData
) 
1531         printDialog 
= wx
.PrintDialog(parentWin
, data
) 
1532         printDialog
.GetPrintDialogData().SetSetupDialog(True) 
1533         printDialog
.ShowModal() 
1535         # this makes a copy of the wx.PrintData instead of just saving 
1536         # a reference to the one inside the PrintDialogData that will 
1537         # be destroyed when the dialog is destroyed 
1538         self
.printData 
= wx
.PrintData(printDialog
.GetPrintDialogData().GetPrintData()) 
1540         printDialog
.Destroy() 
1543     def OnPreview(self
, event
): 
1545         Previews the current document by calling its View's OnCreatePrintout 
1548         view 
= self
.GetCurrentView() 
1552         printout 
= view
.OnCreatePrintout() 
1554             if not hasattr(self
, "printData"): 
1555                 self
.printData 
= wx
.PrintData() 
1556                 self
.printData
.SetPaperId(wx
.PAPER_LETTER
) 
1557             self
.printData
.SetPrintMode(wx
.PRINT_MODE_PREVIEW
) 
1559             data 
= wx
.PrintDialogData(self
.printData
) 
1560             # Pass two printout objects: for preview, and possible printing. 
1561             preview 
= wx
.PrintPreview(printout
, view
.OnCreatePrintout(), data
) 
1562             if not preview
.Ok(): 
1563                 wx
.MessageBox(_("Unable to display print preview.")) 
1565             # 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. 
1566             mimicFrame 
=  wx
.GetApp().GetTopWindow() 
1567             frame 
= wx
.PreviewFrame(preview
, mimicFrame
, _("Print Preview"), mimicFrame
.GetPosition(), mimicFrame
.GetSize()) 
1568             frame
.SetIcon(mimicFrame
.GetIcon()) 
1569             frame
.SetTitle(_("%s - %s - Preview") % (mimicFrame
.GetTitle(), view
.GetDocument().GetPrintableName())) 
1574     def OnUndo(self
, event
): 
1576         Issues an Undo command to the current document's command processor. 
1578         doc 
= self
.GetCurrentDocument() 
1581         if doc
.GetCommandProcessor(): 
1582             doc
.GetCommandProcessor().Undo() 
1585     def OnRedo(self
, event
): 
1587         Issues a Redo command to the current document's command processor. 
1589         doc 
= self
.GetCurrentDocument() 
1592         if doc
.GetCommandProcessor(): 
1593             doc
.GetCommandProcessor().Redo() 
1596     def OnUpdateFileOpen(self
, event
): 
1598         Updates the user interface for the File Open command. 
1603     def OnUpdateFileClose(self
, event
): 
1605         Updates the user interface for the File Close command. 
1607         event
.Enable(self
.GetCurrentDocument() != None) 
1610     def OnUpdateFileCloseAll(self
, event
): 
1612         Updates the user interface for the File Close All command. 
1614         event
.Enable(self
.GetCurrentDocument() != None) 
1617     def OnUpdateFileRevert(self
, event
): 
1619         Updates the user interface for the File Revert command. 
1621         event
.Enable(self
.GetCurrentDocument() != None) 
1624     def OnUpdateFileNew(self
, event
): 
1626         Updates the user interface for the File New command. 
1631     def OnUpdateFileSave(self
, event
): 
1633         Updates the user interface for the File Save command. 
1635         doc 
= self
.GetCurrentDocument() 
1636         event
.Enable(doc 
!= None and doc
.IsModified()) 
1639     def OnUpdateFileSaveAs(self
, event
): 
1641         Updates the user interface for the File Save As command. 
1643         event
.Enable(self
.GetCurrentDocument() != None and self
.GetCurrentDocument().GetWriteable()) 
1646     def OnUpdateUndo(self
, event
): 
1648         Updates the user interface for the Undo command. 
1650         doc 
= self
.GetCurrentDocument() 
1651         event
.Enable(doc 
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanUndo()) 
1652         if doc 
and doc
.GetCommandProcessor(): 
1653             doc
.GetCommandProcessor().SetMenuStrings() 
1655             event
.SetText(_("&Undo\tCtrl+Z")) 
1658     def OnUpdateRedo(self
, event
): 
1660         Updates the user interface for the Redo command. 
1662         doc 
= self
.GetCurrentDocument() 
1663         event
.Enable(doc 
!= None and doc
.GetCommandProcessor() != None and doc
.GetCommandProcessor().CanRedo()) 
1664         if doc 
and doc
.GetCommandProcessor(): 
1665             doc
.GetCommandProcessor().SetMenuStrings() 
1667             event
.SetText(_("&Redo\tCtrl+Y")) 
1670     def OnUpdatePrint(self
, event
): 
1672         Updates the user interface for the Print command. 
1674         event
.Enable(self
.GetCurrentDocument() != None) 
1677     def OnUpdatePrintSetup(self
, event
): 
1679         Updates the user interface for the Print Setup command. 
1684     def OnUpdatePreview(self
, event
): 
1686         Updates the user interface for the Print Preview command. 
1688         event
.Enable(self
.GetCurrentDocument() != None) 
1691     def GetCurrentView(self
): 
1693         Returns the currently active view. 
1695         if self
._currentView
: 
1696             return self
._currentView
 
1697         if len(self
._docs
) == 1: 
1698             return self
._docs
[0].GetFirstView() 
1702     def GetLastActiveView(self
): 
1704         Returns the last active view.  This is used in the SDI framework where dialogs can be mistaken for a view 
1705         and causes the framework to deactivete the current view.  This happens when something like a custom dialog box used 
1706         to operate on the current view is shown. 
1708         if len(self
._docs
) >= 1: 
1709             return self
._lastActiveView
 
1714     def ProcessEvent(self
, event
): 
1716         Processes an event, searching event tables and calling zero or more 
1717         suitable event handler function(s).  Note that the ProcessEvent 
1718         method is called from the wxPython docview framework directly since 
1719         wxPython does not have a virtual ProcessEvent function. 
1721         view 
= self
.GetCurrentView() 
1723             if view
.ProcessEvent(event
): 
1726         if id == wx
.ID_OPEN
: 
1727             self
.OnFileOpen(event
) 
1729         elif id == wx
.ID_CLOSE
: 
1730             self
.OnFileClose(event
) 
1732         elif id == wx
.ID_CLOSE_ALL
: 
1733             self
.OnFileCloseAll(event
) 
1735         elif id == wx
.ID_REVERT
: 
1736             self
.OnFileRevert(event
) 
1738         elif id == wx
.ID_NEW
: 
1739             self
.OnFileNew(event
) 
1741         elif id == wx
.ID_SAVE
: 
1742             self
.OnFileSave(event
) 
1744         elif id == wx
.ID_SAVEAS
: 
1745             self
.OnFileSaveAs(event
) 
1747         elif id == wx
.ID_UNDO
: 
1750         elif id == wx
.ID_REDO
: 
1753         elif id == wx
.ID_PRINT
: 
1756         elif id == wx
.ID_PRINT_SETUP
: 
1757             self
.OnPrintSetup(event
) 
1759         elif id == wx
.ID_PREVIEW
: 
1760             self
.OnPreview(event
) 
1766     def ProcessUpdateUIEvent(self
, event
): 
1768         Processes a UI event, searching event tables and calling zero or more 
1769         suitable event handler function(s).  Note that the ProcessEvent 
1770         method is called from the wxPython docview framework directly since 
1771         wxPython does not have a virtual ProcessEvent function. 
1774         view 
= self
.GetCurrentView() 
1776             if view
.ProcessUpdateUIEvent(event
): 
1778         if id == wx
.ID_OPEN
: 
1779             self
.OnUpdateFileOpen(event
) 
1781         elif id == wx
.ID_CLOSE
: 
1782             self
.OnUpdateFileClose(event
) 
1784         elif id == wx
.ID_CLOSE_ALL
: 
1785             self
.OnUpdateFileCloseAll(event
) 
1787         elif id == wx
.ID_REVERT
: 
1788             self
.OnUpdateFileRevert(event
) 
1790         elif id == wx
.ID_NEW
: 
1791             self
.OnUpdateFileNew(event
) 
1793         elif id == wx
.ID_SAVE
: 
1794             self
.OnUpdateFileSave(event
) 
1796         elif id == wx
.ID_SAVEAS
: 
1797             self
.OnUpdateFileSaveAs(event
) 
1799         elif id == wx
.ID_UNDO
: 
1800             self
.OnUpdateUndo(event
) 
1802         elif id == wx
.ID_REDO
: 
1803             self
.OnUpdateRedo(event
) 
1805         elif id == wx
.ID_PRINT
: 
1806             self
.OnUpdatePrint(event
) 
1808         elif id == wx
.ID_PRINT_SETUP
: 
1809             self
.OnUpdatePrintSetup(event
) 
1811         elif id == wx
.ID_PREVIEW
: 
1812             self
.OnUpdatePreview(event
) 
1818     def CreateDocument(self
, path
, flags
=0): 
1820         Creates a new document in a manner determined by the flags parameter, 
1823         wx.lib.docview.DOC_NEW Creates a fresh document. 
1824         wx.lib.docview.DOC_SILENT Silently loads the given document file. 
1826         If wx.lib.docview.DOC_NEW is present, a new document will be created and returned, 
1827         possibly after asking the user for a template to use if there is more 
1828         than one document template. If wx.lib.docview.DOC_SILENT is present, a new document 
1829         will be created and the given file loaded into it. If neither of these 
1830         flags is present, the user will be presented with a file selector for 
1831         the file to load, and the template to use will be determined by the 
1832         extension (Windows) or by popping up a template choice list (other 
1835         If the maximum number of documents has been reached, this function 
1836         will delete the oldest currently loaded document before creating a new 
1839         wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE 
1840         and wx.lib.docview.DOC_NO_VIEW flag. 
1842         if wx.lib.docview.DOC_OPEN_ONCE is present, trying to open the same file multiple  
1843         times will just return the same document. 
1844         if wx.lib.docview.DOC_NO_VIEW is present, opening a file will generate the document, 
1845         but not generate a corresponding view. 
1848         for temp 
in self
._templates
: 
1849             if temp
.IsVisible(): 
1850                 templates
.append(temp
) 
1851         if len(templates
) == 0: 
1854         if len(self
.GetDocuments()) >= self
._maxDocsOpen
: 
1855            doc 
= self
.GetDocuments()[0] 
1856            if not self
.CloseDocument(doc
, False): 
1860             for temp 
in templates
[:]: 
1861                 if not temp
.IsNewable(): 
1862                     templates
.remove(temp
) 
1863             if len(templates
) == 1: 
1866                 temp 
= self
.SelectDocumentType(templates
) 
1868                 newDoc 
= temp
.CreateDocument(path
, flags
) 
1870                     newDoc
.SetDocumentName(temp
.GetDocumentName()) 
1871                     newDoc
.SetDocumentTemplate(temp
) 
1872                     newDoc
.OnNewDocument() 
1877         if path 
and flags 
& DOC_SILENT
: 
1878             temp 
= self
.FindTemplateForPath(path
) 
1880             temp
, path 
= self
.SelectDocumentPath(templates
, path
, flags
) 
1883         if path 
and self
.GetFlags() & DOC_OPEN_ONCE
: 
1884             for document 
in self
._docs
: 
1885                 if document
.GetFilename() and os
.path
.normcase(document
.GetFilename()) == os
.path
.normcase(path
): 
1886                     """ check for file modification outside of application """ 
1887                     if not document
.IsDocumentModificationDateCorrect(): 
1888                         msgTitle 
= wx
.GetApp().GetAppName() 
1890                             msgTitle 
= _("Warning") 
1891                         shortName 
= document
.GetPrintableName() 
1892                         res 
= wx
.MessageBox(_("'%s' has been modified outside of %s.  Reload '%s' from file system?") % (shortName
, msgTitle
, shortName
), 
1894                                             wx
.YES_NO | wx
.ICON_QUESTION
, 
1895                                             self
.FindSuitableParent()) 
1897                            if not self
.CloseDocument(document
, False): 
1898                                wx
.MessageBox(_("Couldn't reload '%s'.  Unable to close current '%s'.") % (shortName
, shortName
)) 
1900                            return self
.CreateDocument(path
, flags
) 
1901                         elif res 
== wx
.NO
:  # don't ask again 
1902                             document
.SetDocumentModificationDate() 
1904                     firstView 
= document
.GetFirstView() 
1905                     if not firstView 
and not (flags 
& DOC_NO_VIEW
): 
1906                         document
.GetDocumentTemplate().CreateView(document
, flags
) 
1907                         document
.UpdateAllViews() 
1908                         firstView 
= document
.GetFirstView() 
1910                     if firstView 
and firstView
.GetFrame() and not (flags 
& DOC_NO_VIEW
): 
1911                         firstView
.GetFrame().SetFocus()  # Not in wxWindows code but useful nonetheless 
1912                         if hasattr(firstView
.GetFrame(), "IsIconized") and firstView
.GetFrame().IsIconized():  # Not in wxWindows code but useful nonetheless 
1913                             firstView
.GetFrame().Iconize(False) 
1917             newDoc 
= temp
.CreateDocument(path
, flags
) 
1919                 newDoc
.SetDocumentName(temp
.GetDocumentName()) 
1920                 newDoc
.SetDocumentTemplate(temp
) 
1921                 if not newDoc
.OnOpenDocument(path
): 
1922                     newDoc
.DeleteAllViews()  # Implicitly deleted by DeleteAllViews 
1923                     frame 
= newDoc
.GetFirstView().GetFrame() 
1925                         frame
.Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it. 
1927                 self
.AddFileToHistory(path
) 
1933     def CreateView(self
, doc
, flags
=0): 
1935         Creates a new view for the given document. If more than one view is 
1936         allowed for the document (by virtue of multiple templates mentioning 
1937         the same document type), a choice of view is presented to the user. 
1940         for temp 
in self
._templates
: 
1941             if temp
.IsVisible(): 
1942                 if temp
.GetDocumentName() == doc
.GetDocumentName(): 
1943                     templates
.append(temp
) 
1944         if len(templates
) == 0: 
1947         if len(templates
) == 1: 
1949             view 
= temp
.CreateView(doc
, flags
) 
1951                 view
.SetViewName(temp
.GetViewName()) 
1954         temp 
= SelectViewType(templates
) 
1956             view 
= temp
.CreateView(doc
, flags
) 
1958                 view
.SetViewName(temp
.GetViewName()) 
1964     def DeleteTemplate(self
, template
, flags
): 
1966         Placeholder, not yet implemented in wxWindows. 
1971     def FlushDoc(self
, doc
): 
1973         Placeholder, not yet implemented in wxWindows. 
1978     def MatchTemplate(self
, path
): 
1980         Placeholder, not yet implemented in wxWindows. 
1985     def GetCurrentDocument(self
): 
1987         Returns the document associated with the currently active view (if any). 
1989         view 
= self
.GetCurrentView() 
1991             return view
.GetDocument() 
1996     def MakeDefaultName(self
): 
1998         Returns a suitable default name. This is implemented by appending an 
1999         integer counter to the string "Untitled" and incrementing the counter. 
2001         name 
= _("Untitled %d") % self
._defaultDocumentNameCounter
 
2002         self
._defaultDocumentNameCounter 
= self
._defaultDocumentNameCounter 
+ 1 
2006     def MakeFrameTitle(self
): 
2008         Returns a suitable title for a document frame. This is implemented by 
2009         appending the document name to the application name. 
2011         appName 
= wx
.GetApp().GetAppName() 
2015             docName 
= doc
.GetPrintableName() 
2016             title 
= docName 
+ _(" - ") + appName
 
2020     def AddFileToHistory(self
, fileName
): 
2022         Adds a file to the file history list, if we have a pointer to an 
2023         appropriate file menu. 
2025         if self
._fileHistory
: 
2026             self
._fileHistory
.AddFileToHistory(fileName
) 
2029     def RemoveFileFromHistory(self
, i
): 
2031         Removes a file from the file history list, if we have a pointer to an 
2032         appropriate file menu. 
2034         if self
._fileHistory
: 
2035             self
._fileHistory
.RemoveFileFromHistory(i
) 
2038     def GetFileHistory(self
): 
2040         Returns the file history. 
2042         return self
._fileHistory
 
2045     def GetHistoryFile(self
, i
): 
2047         Returns the file at index i from the file history. 
2049         if self
._fileHistory
: 
2050             return self
._fileHistory
.GetHistoryFile(i
) 
2055     def FileHistoryUseMenu(self
, menu
): 
2057         Use this menu for appending recently-visited document filenames, for 
2058         convenient access. Calling this function with a valid menu enables the 
2059         history list functionality. 
2061         Note that you can add multiple menus using this function, to be 
2062         managed by the file history object. 
2064         if self
._fileHistory
: 
2065             self
._fileHistory
.UseMenu(menu
) 
2068     def FileHistoryRemoveMenu(self
, menu
): 
2070         Removes the given menu from the list of menus managed by the file 
2073         if self
._fileHistory
: 
2074             self
._fileHistory
.RemoveMenu(menu
) 
2077     def FileHistoryLoad(self
, config
): 
2079         Loads the file history from a config object. 
2081         if self
._fileHistory
: 
2082             self
._fileHistory
.Load(config
) 
2085     def FileHistorySave(self
, config
): 
2087         Saves the file history into a config object. This must be called 
2088         explicitly by the application. 
2090         if self
._fileHistory
: 
2091             self
._fileHistory
.Save(config
) 
2094     def FileHistoryAddFilesToMenu(self
, menu
=None): 
2096         Appends the files in the history list, to all menus managed by the 
2097         file history object. 
2099         If menu is specified, appends the files in the history list to the 
2102         if self
._fileHistory
: 
2104                 self
._fileHistory
.AddFilesToThisMenu(menu
) 
2106                 self
._fileHistory
.AddFilesToMenu() 
2109     def GetHistoryFilesCount(self
): 
2111         Returns the number of files currently stored in the file history. 
2113         if self
._fileHistory
: 
2114             return self
._fileHistory
.GetNoHistoryFiles() 
2119     def FindTemplateForPath(self
, path
): 
2121         Given a path, try to find template that matches the extension. This is 
2122         only an approximate method of finding a template for creating a 
2125         Note this wxPython verson looks for and returns a default template if no specific template is found. 
2128         for temp 
in self
._templates
: 
2129             if temp
.FileMatchesTemplate(path
): 
2132             if "*.*" in temp
.GetFileFilter(): 
2137     def FindSuitableParent(self
): 
2139         Returns a parent frame or dialog, either the frame with the current 
2140         focus or if there is no current focus the application's top frame. 
2142         parent 
= wx
.GetApp().GetTopWindow() 
2143         focusWindow 
= wx
.Window_FindFocus() 
2145             while focusWindow 
and not isinstance(focusWindow
, wx
.Dialog
) and not isinstance(focusWindow
, wx
.Frame
): 
2146                 focusWindow 
= focusWindow
.GetParent() 
2148                 parent 
= focusWindow
 
2152     def SelectDocumentPath(self
, templates
, flags
, save
): 
2154         Under Windows, pops up a file selector with a list of filters 
2155         corresponding to document templates. The wxDocTemplate corresponding 
2156         to the selected file's extension is returned. 
2158         On other platforms, if there is more than one document template a 
2159         choice list is popped up, followed by a file selector. 
2161         This function is used in wxDocManager.CreateDocument. 
2163         if wx
.Platform 
== "__WXMSW__" or wx
.Platform 
== "__WXGTK__" or wx
.Platform 
== "__WXMAC__": 
2165             for temp 
in templates
: 
2166                 if temp
.IsVisible(): 
2168                         descr 
= descr 
+ _('|') 
2169                     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 
2170             descr 
= _("All|*.*|%s") % descr  
# spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk 
2174         dlg 
= wx
.FileDialog(self
.FindSuitableParent(), 
2177                                style
=wx
.OPEN|wx
.FILE_MUST_EXIST|wx
.CHANGE_DIR
) 
2178         # dlg.CenterOnParent()  # wxBug: caused crash with wx.FileDialog 
2179         if dlg
.ShowModal() == wx
.ID_OK
: 
2180             path 
= dlg
.GetPath() 
2186             theTemplate 
= self
.FindTemplateForPath(path
) 
2187             return (theTemplate
, path
) 
2192     def OnOpenFileFailure(self
): 
2194         Called when there is an error opening a file. 
2199     def SelectDocumentType(self
, temps
, sort
=False): 
2201         Returns a document template by asking the user (if there is more than 
2202         one template). This function is used in wxDocManager.CreateDocument. 
2206         templates - list of templates from which to choose a desired template. 
2208         sort - If more than one template is passed in in templates, then this 
2209         parameter indicates whether the list of templates that the user will 
2210         have to choose from is sorted or not when shown the choice box dialog. 
2215             if temp
.IsVisible(): 
2217                 for temp2 
in templates
: 
2218                     if temp
.GetDocumentName() == temp2
.GetDocumentName() and temp
.GetViewName() == temp2
.GetViewName(): 
2222                     templates
.append(temp
) 
2224         if len(templates
) == 0: 
2226         elif len(templates
) == 1: 
2231                 return cmp(a
.GetDescription(), b
.GetDescription()) 
2232             templates
.sort(tempcmp
) 
2235         for temp 
in templates
: 
2236             strings
.append(temp
.GetDescription()) 
2238         res 
= wx
.GetSingleChoiceIndex(_("Select a document type:"), 
2241                                       self
.FindSuitableParent()) 
2244         return templates
[res
] 
2247     def SelectViewType(self
, temps
, sort
=False): 
2249         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. 
2254             if temp
.IsVisible() and temp
.GetViewTypeName(): 
2255                 if temp
.GetViewName() not in strings
: 
2256                     templates
.append(temp
) 
2257                     strings
.append(temp
.GetViewTypeName()) 
2259         if len(templates
) == 0: 
2261         elif len(templates
) == 1: 
2266                 return cmp(a
.GetViewTypeName(), b
.GetViewTypeName()) 
2267             templates
.sort(tempcmp
) 
2269         res 
= wx
.GetSingleChoiceIndex(_("Select a document view:"), 
2272                                       self
.FindSuitableParent()) 
2275         return templates
[res
] 
2278     def GetTemplates(self
): 
2280         Returns the document manager's template list.  This method has been added to 
2281         wxPython and is not in wxWindows. 
2283         return self
._templates
 
2286     def AssociateTemplate(self
, docTemplate
): 
2288         Adds the template to the document manager's template list. 
2290         if docTemplate 
not in self
._templates
: 
2291             self
._templates
.append(docTemplate
) 
2294     def DisassociateTemplate(self
, docTemplate
): 
2296         Removes the template from the list of templates. 
2298         self
._templates
.remove(docTemplate
) 
2301     def AddDocument(self
, document
): 
2303         Adds the document to the list of documents. 
2305         if document 
not in self
._docs
: 
2306             self
._docs
.append(document
) 
2309     def RemoveDocument(self
, doc
): 
2311         Removes the document from the list of documents. 
2313         if doc 
in self
._docs
: 
2314             self
._docs
.remove(doc
) 
2317     def ActivateView(self
, view
, activate
=True, deleting
=False): 
2319         Sets the current view. 
2322             self
._currentView 
= view
 
2323             self
._lastActiveView 
= view
 
2325             self
._currentView 
= None 
2328     def GetMaxDocsOpen(self
): 
2330         Returns the number of documents that can be open simultaneously. 
2332         return self
._maxDocsOpen
 
2335     def SetMaxDocsOpen(self
, maxDocsOpen
): 
2337         Sets the maximum number of documents that can be open at a time. By 
2338         default, this is 10,000. If you set it to 1, existing documents will 
2339         be saved and deleted when the user tries to open or create a new one 
2340         (similar to the behaviour of Windows Write, for example). Allowing 
2341         multiple documents gives behaviour more akin to MS Word and other 
2342         Multiple Document Interface applications. 
2344         self
._maxDocsOpen 
= maxDocsOpen
 
2347     def GetDocuments(self
): 
2349         Returns the list of documents. 
2354 class DocParentFrame(wx
.Frame
): 
2356     The wxDocParentFrame class provides a default top-level frame for 
2357     applications using the document/view framework. This class can only be 
2358     used for SDI (not MDI) parent frames. 
2360     It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplates 
2364     def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"): 
2366         Constructor.  Note that the event table must be rebuilt for the 
2367         frame since the EvtHandler is not virtual. 
2369         wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
) 
2370         self
._docManager 
= manager
 
2372         wx
.EVT_CLOSE(self
, self
.OnCloseWindow
) 
2374         wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
) 
2375         wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
) 
2377         wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
) 
2378         wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
) 
2379         wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
) 
2380         wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
) 
2381         wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
) 
2382         wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
) 
2383         wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
) 
2384         wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
) 
2385         wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
) 
2386         wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
) 
2387         wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
) 
2388         wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
) 
2390         wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
) 
2391         wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
) 
2392         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
) 
2393         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
) 
2394         wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
) 
2395         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
) 
2396         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
) 
2397         wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
) 
2398         wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
) 
2399         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
) 
2400         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
) 
2401         wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
) 
2404     def ProcessEvent(self
, event
): 
2406         Processes an event, searching event tables and calling zero or more 
2407         suitable event handler function(s).  Note that the ProcessEvent 
2408         method is called from the wxPython docview framework directly since 
2409         wxPython does not have a virtual ProcessEvent function. 
2411         return self
._docManager 
and self
._docManager
.ProcessEvent(event
) 
2414     def ProcessUpdateUIEvent(self
, event
): 
2416         Processes a UI event, searching event tables and calling zero or more 
2417         suitable event handler function(s).  Note that the ProcessEvent 
2418         method is called from the wxPython docview framework directly since 
2419         wxPython does not have a virtual ProcessEvent function. 
2421         return self
._docManager 
and self
._docManager
.ProcessUpdateUIEvent(event
) 
2424     def OnExit(self
, event
): 
2426         Called when File/Exit is chosen and closes the window. 
2431     def OnMRUFile(self
, event
): 
2433         Opens the appropriate file when it is selected from the file history 
2436         n 
= event
.GetId() - wx
.ID_FILE1
 
2437         filename 
= self
._docManager
.GetHistoryFile(n
) 
2439             self
._docManager
.CreateDocument(filename
, DOC_SILENT
) 
2441             self
._docManager
.RemoveFileFromHistory(n
) 
2442             msgTitle 
= wx
.GetApp().GetAppName() 
2444                 msgTitle 
= _("File Error") 
2445             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), 
2447                           wx
.OK | wx
.ICON_EXCLAMATION
, 
2451     def OnCloseWindow(self
, event
): 
2453         Deletes all views and documents. If no user input cancelled the 
2454         operation, the frame will be destroyed and the application will exit. 
2456         if self
._docManager
.Clear(not event
.CanVeto()): 
2462 class DocChildFrame(wx
.Frame
): 
2464     The wxDocChildFrame class provides a default frame for displaying 
2465     documents on separate windows. This class can only be used for SDI (not 
2468     The class is part of the document/view framework supported by wxWindows, 
2469     and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate 
2474     def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"): 
2476         Constructor.  Note that the event table must be rebuilt for the 
2477         frame since the EvtHandler is not virtual. 
2479         wx
.Frame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
) 
2480         wx
.EVT_ACTIVATE(self
, self
.OnActivate
) 
2481         wx
.EVT_CLOSE(self
, self
.OnCloseWindow
) 
2482         self
._childDocument 
= doc
 
2483         self
._childView 
= view
 
2487         wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
) 
2488         wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
) 
2489         wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
) 
2490         wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
) 
2491         wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
) 
2492         wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
) 
2493         wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
) 
2494         wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
) 
2495         wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
) 
2496         wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
) 
2497         wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
) 
2498         wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
) 
2500         wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
) 
2501         wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
) 
2502         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
) 
2503         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
) 
2504         wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
) 
2505         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
) 
2506         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
) 
2507         wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
) 
2508         wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
) 
2509         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
) 
2510         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
) 
2511         wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
) 
2514     def ProcessEvent(self
, event
): 
2516         Processes an event, searching event tables and calling zero or more 
2517         suitable event handler function(s).  Note that the ProcessEvent 
2518         method is called from the wxPython docview framework directly since 
2519         wxPython does not have a virtual ProcessEvent function. 
2522             self
._childView
.Activate(True) 
2523         if not self
._childView 
or not self
._childView
.ProcessEvent(event
): 
2524             # IsInstance not working, but who cares just send all the commands up since this isn't a real ProcessEvent like wxWindows 
2525             # if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event): 
2526             if not self
.GetParent() or not self
.GetParent().ProcessEvent(event
): 
2534     def ProcessUpdateUIEvent(self
, event
): 
2536         Processes a UI event, searching event tables and calling zero or more 
2537         suitable event handler function(s).  Note that the ProcessEvent 
2538         method is called from the wxPython docview framework directly since 
2539         wxPython does not have a virtual ProcessEvent function. 
2541         if self
.GetParent(): 
2542             self
.GetParent().ProcessUpdateUIEvent(event
) 
2547     def OnActivate(self
, event
): 
2549         Activates the current view. 
2551         # wx.Frame.OnActivate(event)  This is in the wxWindows docview demo but there is no such method in wxPython, so do a Raise() instead 
2553             self
._childView
.Activate(event
.GetActive()) 
2556     def OnCloseWindow(self
, event
): 
2558         Closes and deletes the current view and document. 
2562             if not event
.CanVeto(): 
2565                 ans 
= self
._childView
.Close(deleteWindow 
= False) 
2568                 self
._childView
.Activate(False) 
2569                 self
._childView
.Destroy() 
2570                 self
._childView 
= None 
2571                 if self
._childDocument
: 
2572                     self
._childDocument
.Destroy()  # This isn't in the wxWindows codebase but the document needs to be disposed of somehow 
2573                     self
._childDocument 
= None 
2581     def GetDocument(self
): 
2583         Returns the document associated with this frame. 
2585         return self
._childDocument
 
2588     def SetDocument(self
, document
): 
2590         Sets the document for this frame. 
2592         self
._childDocument 
= document
 
2597         Returns the view associated with this frame. 
2599         return self
._childView
 
2602     def SetView(self
, view
): 
2604         Sets the view for this frame. 
2606         self
._childView 
= view
 
2609 class DocMDIParentFrame(wx
.MDIParentFrame
): 
2611     The wxDocMDIParentFrame class provides a default top-level frame for 
2612     applications using the document/view framework. This class can only be 
2613     used for MDI parent frames. 
2615     It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate 
2620     def __init__(self
, manager
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"): 
2622         Constructor.  Note that the event table must be rebuilt for the 
2623         frame since the EvtHandler is not virtual. 
2625         wx
.MDIParentFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
) 
2626         self
._docManager 
= manager
 
2628         wx
.EVT_CLOSE(self
, self
.OnCloseWindow
) 
2630         wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
) 
2631         wx
.EVT_MENU_RANGE(self
, wx
.ID_FILE1
, wx
.ID_FILE9
, self
.OnMRUFile
) 
2633         wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.ProcessEvent
) 
2634         wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.ProcessEvent
) 
2635         wx
.EVT_MENU(self
, wx
.ID_CLOSE_ALL
, self
.ProcessEvent
) 
2636         wx
.EVT_MENU(self
, wx
.ID_CLOSE
, self
.ProcessEvent
) 
2637         wx
.EVT_MENU(self
, wx
.ID_REVERT
, self
.ProcessEvent
) 
2638         wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.ProcessEvent
) 
2639         wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.ProcessEvent
) 
2640         wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.ProcessEvent
) 
2641         wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.ProcessEvent
) 
2642         wx
.EVT_MENU(self
, wx
.ID_PRINT
, self
.ProcessEvent
) 
2643         wx
.EVT_MENU(self
, wx
.ID_PRINT_SETUP
, self
.ProcessEvent
) 
2644         wx
.EVT_MENU(self
, wx
.ID_PREVIEW
, self
.ProcessEvent
) 
2646         wx
.EVT_UPDATE_UI(self
, wx
.ID_NEW
, self
.ProcessUpdateUIEvent
) 
2647         wx
.EVT_UPDATE_UI(self
, wx
.ID_OPEN
, self
.ProcessUpdateUIEvent
) 
2648         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE_ALL
, self
.ProcessUpdateUIEvent
) 
2649         wx
.EVT_UPDATE_UI(self
, wx
.ID_CLOSE
, self
.ProcessUpdateUIEvent
) 
2650         wx
.EVT_UPDATE_UI(self
, wx
.ID_REVERT
, self
.ProcessUpdateUIEvent
) 
2651         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.ProcessUpdateUIEvent
) 
2652         wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVEAS
, self
.ProcessUpdateUIEvent
) 
2653         wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.ProcessUpdateUIEvent
) 
2654         wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.ProcessUpdateUIEvent
) 
2655         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT
, self
.ProcessUpdateUIEvent
) 
2656         wx
.EVT_UPDATE_UI(self
, wx
.ID_PRINT_SETUP
, self
.ProcessUpdateUIEvent
) 
2657         wx
.EVT_UPDATE_UI(self
, wx
.ID_PREVIEW
, self
.ProcessUpdateUIEvent
) 
2660     def ProcessEvent(self
, event
): 
2662         Processes an event, searching event tables and calling zero or more 
2663         suitable event handler function(s).  Note that the ProcessEvent 
2664         method is called from the wxPython docview framework directly since 
2665         wxPython does not have a virtual ProcessEvent function. 
2667         return self
._docManager 
and self
._docManager
.ProcessEvent(event
) 
2670     def ProcessUpdateUIEvent(self
, event
): 
2672         Processes a UI event, searching event tables and calling zero or more 
2673         suitable event handler function(s).  Note that the ProcessEvent 
2674         method is called from the wxPython docview framework directly since 
2675         wxPython does not have a virtual ProcessEvent function. 
2677         return self
._docManager 
and self
._docManager
.ProcessUpdateUIEvent(event
) 
2680     def OnExit(self
, event
): 
2682         Called when File/Exit is chosen and closes the window. 
2687     def OnMRUFile(self
, event
): 
2689         Opens the appropriate file when it is selected from the file history 
2692         n 
= event
.GetId() - wx
.ID_FILE1
 
2693         filename 
= self
._docManager
.GetHistoryFile(n
) 
2695             self
._docManager
.CreateDocument(filename
, DOC_SILENT
) 
2697             self
._docManager
.RemoveFileFromHistory(n
) 
2698             msgTitle 
= wx
.GetApp().GetAppName() 
2700                 msgTitle 
= _("File Error") 
2701             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), 
2703                           wx
.OK | wx
.ICON_EXCLAMATION
, 
2707     def OnCloseWindow(self
, event
): 
2709         Deletes all views and documents. If no user input cancelled the 
2710         operation, the frame will be destroyed and the application will exit. 
2712         if self
._docManager
.Clear(not event
.CanVeto()): 
2718 class DocMDIChildFrame(wx
.MDIChildFrame
): 
2720     The wxDocMDIChildFrame class provides a default frame for displaying 
2721     documents on separate windows. This class can only be used for MDI child 
2724     The class is part of the document/view framework supported by wxWindows, 
2725     and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate 
2730     def __init__(self
, doc
, view
, frame
, id, title
, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, style
=wx
.DEFAULT_FRAME_STYLE
, name
="frame"): 
2732         Constructor.  Note that the event table must be rebuilt for the 
2733         frame since the EvtHandler is not virtual. 
2735         wx
.MDIChildFrame
.__init
__(self
, frame
, id, title
, pos
, size
, style
, name
) 
2736         self
._childDocument 
= doc
 
2737         self
._childView 
= view
 
2740         # self.Create(doc, view, frame, id, title, pos, size, style, name) 
2741         self
._activeEvent 
= None 
2743         wx
.EVT_ACTIVATE(self
, self
.OnActivate
) 
2744         wx
.EVT_CLOSE(self
, self
.OnCloseWindow
) 
2746         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 
2747             mdiChildren 
= filter(lambda x
: isinstance(x
, wx
.MDIChildFrame
), frame
.GetChildren()) 
2748             if len(mdiChildren
) == 1: 
2752 ##    # Couldn't get this to work, but seems to work fine with single stage construction 
2753 ##    def Create(self, doc, view, frame, id, title, pos, size, style, name): 
2754 ##        self._childDocument = doc 
2755 ##        self._childView = view 
2756 ##        if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name): 
2758 ##                view.SetFrame(self) 
2764     def Activate(self
):  # Need this in case there are embedded sash windows and such, OnActivate is not getting called 
2766         Activates the current view. 
2769             self
._childView
.Activate(True) 
2772     def ProcessEvent(event
): 
2774         Processes an event, searching event tables and calling zero or more 
2775         suitable event handler function(s).  Note that the ProcessEvent 
2776         method is called from the wxPython docview framework directly since 
2777         wxPython does not have a virtual ProcessEvent function. 
2779         if self
._activeEvent 
== event
: 
2782         self
._activeEvent 
= event  
# Break recursion loops 
2785             self
._childView
.Activate(True) 
2787         if not self
._childView 
or not self
._childView
.ProcessEvent(event
): 
2788             if not isinstance(event
, wx
.CommandEvent
) or not self
.GetParent() or not self
.GetParent().ProcessEvent(event
): 
2795         self
._activeEvent 
= None 
2799     def OnActivate(self
, event
): 
2801         Sets the currently active view to be the frame's view. You may need to 
2802         override (but still call) this function in order to set the keyboard 
2803         focus for your subwindow. 
2805         if self
._activated 
!= 0: 
2807         self
._activated 
+= 1 
2808         wx
.MDIChildFrame
.Activate(self
) 
2809         if event
.GetActive() and self
._childView
: 
2810             self
._childView
.Activate(event
.GetActive()) 
2814     def OnCloseWindow(self
, event
): 
2816         Closes and deletes the current view and document. 
2820             if not event
.CanVeto(): 
2823                 ans 
= self
._childView
.Close(deleteWindow 
= False) 
2826                 self
._childView
.Activate(False) 
2827                 self
._childView
.Destroy() 
2828                 self
._childView 
= None 
2829                 if self
._childDocument
:  # This isn't in the wxWindows codebase but the document needs to be disposed of somehow 
2830                     self
._childDocument
.DeleteContents() 
2831                     if self
._childDocument
.GetDocumentManager(): 
2832                         self
._childDocument
.GetDocumentManager().RemoveDocument(self
._childDocument
) 
2833                 self
._childDocument 
= None 
2841     def GetDocument(self
): 
2843         Returns the document associated with this frame. 
2845         return self
._childDocument
 
2848     def SetDocument(self
, document
): 
2850         Sets the document for this frame. 
2852         self
._childDocument 
= document
 
2857         Returns the view associated with this frame. 
2859         return self
._childView
 
2862     def SetView(self
, view
): 
2864         Sets the view for this frame. 
2866         self
._childView 
= view
 
2869     def OnTitleIsModified(self
): 
2871         Add/remove to the frame's title an indication that the document is dirty. 
2872         If the document is dirty, an '*' is appended to the title 
2873         This method has been added to wxPython and is not in wxWindows. 
2875         title 
= self
.GetTitle() 
2877             if self
.GetDocument().IsModified(): 
2878                 if title
.endswith("*"): 
2882                     self
.SetTitle(title
) 
2884                 if title
.endswith("*"): 
2886                     self
.SetTitle(title
)                 
2891 class DocPrintout(wx
.Printout
): 
2893     DocPrintout is a default Printout that prints the first page of a document 
2898     def __init__(self
, view
, title
="Printout"): 
2902         wx
.Printout
.__init
__(self
, title
) 
2903         self
._printoutView 
= view
 
2908         Returns the DocPrintout's view. 
2910         return self
._printoutView
 
2913     def OnPrintPage(self
, page
): 
2915         Prints the first page of the view. 
2918         ppiScreenX
, ppiScreenY 
= self
.GetPPIScreen() 
2919         ppiPrinterX
, ppiPrinterY 
= self
.GetPPIPrinter() 
2920         scale 
= ppiPrinterX
/ppiScreenX
 
2922         pageWidth
, pageHeight 
= self
.GetPageSizePixels() 
2923         overallScale 
= scale 
* w 
/ pageWidth
 
2924         dc
.SetUserScale(overallScale
, overallScale
) 
2925         if self
._printoutView
: 
2926             self
._printoutView
.OnDraw(dc
) 
2930     def HasPage(self
, pageNum
): 
2932         Indicates that the DocPrintout only has a single page. 
2937     def GetPageInfo(self
): 
2939         Indicates that the DocPrintout only has a single page. 
2945         return (minPage
, maxPage
, selPageFrom
, selPageTo
) 
2948 #---------------------------------------------------------------------- 
2950 #---------------------------------------------------------------------- 
2952 class Command(wx
.Object
): 
2954     wxCommand is a base class for modelling an application command, which is 
2955     an action usually performed by selecting a menu item, pressing a toolbar 
2956     button or any other means provided by the application to change the data 
2961     def __init__(self
, canUndo 
= False, name 
= None): 
2963         Constructor. wxCommand is an abstract class, so you will need to 
2964         derive a new class and call this constructor from your own constructor. 
2966         canUndo tells the command processor whether this command is undo-able. 
2967         You can achieve the same functionality by overriding the CanUndo member 
2968         function (if for example the criteria for undoability is context- 
2971         name must be supplied for the command processor to display the command 
2972         name in the application's edit menu. 
2974         self
._canUndo 
= canUndo
 
2980         Returns true if the command can be undone, false otherwise. 
2982         return self
._canUndo
 
2987         Returns the command name. 
2994         Override this member function to execute the appropriate action when 
2995         called. Return true to indicate that the action has taken place, false 
2996         otherwise. Returning false will indicate to the command processor that 
2997         the action is not undoable and should not be added to the command 
3005         Override this member function to un-execute a previous Do. Return true 
3006         to indicate that the action has taken place, false otherwise. Returning 
3007         false will indicate to the command processor that the action is not 
3008         redoable and no change should be made to the command history. 
3010         How you implement this command is totally application dependent, but 
3011         typical strategies include: 
3013         Perform an inverse operation on the last modified piece of data in the 
3014         document. When redone, a copy of data stored in command is pasted back 
3015         or some operation reapplied. This relies on the fact that you know the 
3016         ordering of Undos; the user can never Undo at an arbitrary position in 
3019         Restore the entire document state (perhaps using document 
3020         transactioning). Potentially very inefficient, but possibly easier to 
3021         code if the user interface and data are complex, and an 'inverse 
3022         execute' operation is hard to write. 
3027 class CommandProcessor(wx
.Object
): 
3029     wxCommandProcessor is a class that maintains a history of wxCommands, with 
3030     undo/redo functionality built-in. Derive a new class from this if you want 
3031     different behaviour. 
3035     def __init__(self
, maxCommands
=-1): 
3037         Constructor.  maxCommands may be set to a positive integer to limit 
3038         the number of commands stored to it, otherwise (and by default) the 
3039         list of commands can grow arbitrarily. 
3041         self
._maxCommands 
= maxCommands
 
3042         self
._editMenu 
= None 
3043         self
._undoAccelerator 
= _("Ctrl+Z") 
3044         self
._redoAccelerator 
= _("Ctrl+Y") 
3045         self
.ClearCommands() 
3048     def _GetCurrentCommand(self
): 
3049         if len(self
._commands
) == 0: 
3052             return self
._commands
[-1] 
3055     def _GetCurrentRedoCommand(self
): 
3056         if len(self
._redoCommands
) == 0: 
3059             return self
._redoCommands
[-1] 
3062     def GetMaxCommands(self
): 
3064         Returns the maximum number of commands that the command processor 
3068         return self
._maxCommands
 
3071     def GetCommands(self
): 
3073         Returns the list of commands. 
3075         return self
._commands
 
3078     def ClearCommands(self
): 
3080         Deletes all the commands in the list and sets the current command 
3084         self
._redoCommands 
= [] 
3087     def GetEditMenu(self
): 
3089         Returns the edit menu associated with the command processor. 
3091         return self
._editMenu
 
3094     def SetEditMenu(self
, menu
): 
3096         Tells the command processor to update the Undo and Redo items on this 
3097         menu as appropriate. Set this to NULL if the menu is about to be 
3098         destroyed and command operations may still be performed, or the 
3099         command processor may try to access an invalid pointer. 
3101         self
._editMenu 
= menu
 
3104     def GetUndoAccelerator(self
): 
3106         Returns the string that will be appended to the Undo menu item. 
3108         return self
._undoAccelerator
 
3111     def SetUndoAccelerator(self
, accel
): 
3113         Sets the string that will be appended to the Redo menu item. 
3115         self
._undoAccelerator 
= accel
 
3118     def GetRedoAccelerator(self
): 
3120         Returns the string that will be appended to the Redo menu item. 
3122         return self
._redoAccelerator
 
3125     def SetRedoAccelerator(self
, accel
): 
3127         Sets the string that will be appended to the Redo menu item. 
3129         self
._redoAccelerator 
= accel
 
3132     def SetEditMenu(self
, menu
): 
3134         Tells the command processor to update the Undo and Redo items on this 
3135         menu as appropriate. Set this to NULL if the menu is about to be 
3136         destroyed and command operations may still be performed, or the 
3137         command processor may try to access an invalid pointer. 
3139         self
._editMenu 
= menu
 
3142     def SetMenuStrings(self
): 
3144         Sets the menu labels according to the currently set menu and the 
3145         current command state. 
3147         if self
.GetEditMenu() != None: 
3148             undoCommand 
= self
._GetCurrentCommand
() 
3149             redoCommand 
= self
._GetCurrentRedoCommand
() 
3150             undoItem 
= self
.GetEditMenu().FindItemById(wx
.ID_UNDO
) 
3151             redoItem 
= self
.GetEditMenu().FindItemById(wx
.ID_REDO
) 
3152             if self
.GetUndoAccelerator(): 
3153                 undoAccel 
= '\t' + self
.GetUndoAccelerator() 
3156             if self
.GetRedoAccelerator(): 
3157                 redoAccel 
= '\t' + self
.GetRedoAccelerator() 
3160             if undoCommand 
and undoItem 
and undoCommand
.CanUndo(): 
3161                 undoItem
.SetText(_("&Undo ") + undoCommand
.GetName() + undoAccel
) 
3162             #elif undoCommand and not undoCommand.CanUndo(): 
3163             #    undoItem.SetText(_("Can't Undo") + undoAccel) 
3165                 undoItem
.SetText(_("&Undo" + undoAccel
)) 
3166             if redoCommand 
and redoItem
: 
3167                 redoItem
.SetText(_("&Redo ") + redoCommand
.GetName() + redoAccel
) 
3169                 redoItem
.SetText(_("&Redo") + redoAccel
) 
3174         Returns true if the currently-active command can be undone, false 
3177         if self
._GetCurrentCommand
() == None: 
3179         return self
._GetCurrentCommand
().CanUndo() 
3184         Returns true if the currently-active command can be redone, false 
3187         return self
._GetCurrentRedoCommand
() != None 
3190     def Submit(self
, command
, storeIt
=True): 
3192         Submits a new command to the command processor. The command processor 
3193         calls wxCommand::Do to execute the command; if it succeeds, the 
3194         command is stored in the history list, and the associated edit menu 
3195         (if any) updated appropriately. If it fails, the command is deleted 
3196         immediately. Once Submit has been called, the passed command should 
3197         not be deleted directly by the application. 
3199         storeIt indicates whether the successful command should be stored in 
3204             del self
._redoCommands
[:] 
3206                 self
._commands
.append(command
) 
3207         if self
._maxCommands 
> -1: 
3208             if len(self
._commands
) > self
._maxCommands
: 
3209                 del self
._commands
[0] 
3215         Redoes the command just undone. 
3217         cmd 
= self
._GetCurrentRedoCommand
() 
3222             self
._commands
.append(self
._redoCommands
.pop()) 
3228         Undoes the command just executed. 
3230         cmd 
= self
._GetCurrentCommand
() 
3235             self
._redoCommands
.append(self
._commands
.pop())