#
# Created: 5/15/03
# CVS-ID: $Id$
-# Copyright: (c) 2003-2005 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
+# Copyright: (c) 2003-2006 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
# License: wxWindows license
#----------------------------------------------------------------------------
import os
import os.path
+import shutil
import wx
import sys
_ = wx.GetTranslation
DOC_NEW = 4
DOC_SILENT = 8
DOC_OPEN_ONCE = 16
+DOC_NO_VIEW = 32
DEFAULT_DOCMAN_FLAGS = DOC_SDI & DOC_OPEN_ONCE
TEMPLATE_VISIBLE = 1
TEMPLATE_INVISIBLE = 2
+TEMPLATE_NO_CREATE = (4 | TEMPLATE_VISIBLE)
DEFAULT_TEMPLATE_FLAGS = TEMPLATE_VISIBLE
MAX_FILE_HISTORY = 9
false otherwise. You may need to override this if your document view
maintains its own record of being modified (for example if using
xTextWindow to view and edit the document).
+ This method has been extended to notify its views that the dirty flag has changed.
"""
self._documentModified = modify
+ self.UpdateAllViews(hint=("modify", self, self._documentModified))
def SetDocumentModificationDate(self):
return self._documentModificationDate
+ def IsDocumentModificationDateCorrect(self):
+ """
+ Returns False if the file has been modified outside of the application.
+ This method has been added to wxPython and is not in wxWindows.
+ """
+ if not os.path.exists(self.GetFilename()): # document must be in memory only and can't be out of date
+ return True
+ return self._documentModificationDate == os.path.getmtime(self.GetFilename())
+
+
def GetViews(self):
"""
Returns the list whose elements are the views on the document.
Destructor. Removes itself from the document manager.
"""
self.DeleteContents()
+ self._documentModificationDate = None
if self.GetDocumentManager():
self.GetDocumentManager().RemoveDocument(self)
wx.EvtHandler.Destroy(self)
return True
""" check for file modification outside of application """
- if os.path.exists(self.GetFilename()) and os.path.getmtime(self.GetFilename()) != self.GetDocumentModificationDate():
+ if not self.IsDocumentModificationDateCorrect():
msgTitle = wx.GetApp().GetAppName()
if not msgTitle:
msgTitle = _("Application")
backupFilename = None
fileObject = None
+ copied = False
try:
# if current file exists, move it to a safe place temporarily
if os.path.exists(filename):
while os.path.exists(backupFilename):
i += 1
backupFilename = "%s.bak%s" % (filename, i)
- os.rename(filename, backupFilename)
+ shutil.copy(filename, backupFilename)
+ copied = True
fileObject = file(filename, 'w')
self.SaveObject(fileObject)
if fileObject:
fileObject.close() # file is still open, close it, need to do this before removal
- # save failed, restore old file
- if backupFilename:
- os.remove(filename)
- os.rename(backupFilename, filename)
- self.SetDocumentModificationDate()
+ # save failed, remove copied file
+ if backupFilename and copied:
+ os.remove(backupFilename)
wx.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename), sys.exc_value),
msgTitle,
self.GetDocumentWindow())
return False
+ self.SetDocumentModificationDate()
self.SetFilename(filename, True)
self.Modify(False)
- self.SetDocumentModificationDate()
self.SetDocumentSaved(True)
#if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
# wx.FileName(file).MacSetDefaultTypeAndCreator()
self.GetDocumentWindow())
return False
+ self.SetDocumentModificationDate()
self.SetFilename(filename, True)
self.Modify(False)
- self.SetDocumentModificationDate()
self.SetDocumentSaved(True)
self.UpdateAllViews()
return True
return True
""" check for file modification outside of application """
- if os.path.exists(self.GetFilename()) and os.path.getmtime(self.GetFilename()) != self.GetDocumentModificationDate():
+ if not self.IsDocumentModificationDateCorrect():
msgTitle = wx.GetApp().GetAppName()
if not msgTitle:
msgTitle = _("Warning")
"""
The default implementation calls DeleteContents (an empty
implementation) sets the modified flag to false. Override this to
- supply additional behaviour when the document is closed with Close.
+ supply additional behaviour when the document is opened with Open.
"""
+ if flags & DOC_NO_VIEW:
+ return True
return self.GetDocumentTemplate().CreateView(self, flags)
unused but may in future contain application-specific information for
making updating more efficient.
"""
- pass
-
+ if hint:
+ if hint[0] == "modify": # if dirty flag changed, update the view's displayed title
+ frame = self.GetFrame()
+ if frame and hasattr(frame, "OnTitleIsModified"):
+ frame.OnTitleIsModified()
+ return True
+ return False
+
def OnChangeFilename(self):
"""
string will be displayed in the file filter list of Windows file
selectors.
- filter is an appropriate file filter such as *.txt.
+ filter is an appropriate file filter such as \*.txt.
dir is the default directory to use for file selectors.
return (self._flags & TEMPLATE_VISIBLE) == TEMPLATE_VISIBLE
+ def IsNewable(self):
+ """
+ Returns true if the document template can be shown in "New" dialogs,
+ false otherwise.
+
+ This method has been added to wxPython and is not in wxWindows.
+ """
+ return (self._flags & TEMPLATE_NO_CREATE) != TEMPLATE_NO_CREATE
+
+
def GetDocumentName(self):
"""
Returns the document type name, as passed to the document template
Returns True if the path's extension matches one of this template's
file filter extensions.
"""
-## print "*** path", path
-## if "*.*" in self.GetFileFilter():
-## return True
-##
ext = FindExtension(path)
if not ext: return False
- return ext in self.GetFileFilter()
- # return self.GetDefaultExtension() == FindExtension(path)
+
+ extList = self.GetFileFilter().replace('*','').split(';')
+ return ext in extList
class DocManager(wx.EvtHandler):
will delete the oldest currently loaded document before creating a new
one.
- wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE flag.
+ wxPython version supports the document manager's wx.lib.docview.DOC_OPEN_ONCE
+ and wx.lib.docview.DOC_NO_VIEW flag.
+
+ if wx.lib.docview.DOC_OPEN_ONCE is present, trying to open the same file multiple
+ times will just return the same document.
+ if wx.lib.docview.DOC_NO_VIEW is present, opening a file will generate the document,
+ but not generate a corresponding view.
"""
templates = []
for temp in self._templates:
return None
if flags & DOC_NEW:
+ for temp in templates[:]:
+ if not temp.IsNewable():
+ templates.remove(temp)
if len(templates) == 1:
temp = templates[0]
- newDoc = temp.CreateDocument(path, flags)
- if newDoc:
- newDoc.SetDocumentName(temp.GetDocumentName())
- newDoc.SetDocumentTemplate(temp)
- newDoc.OnNewDocument()
- return newDoc
-
- temp = self.SelectDocumentType(templates)
+ else:
+ temp = self.SelectDocumentType(templates)
if temp:
newDoc = temp.CreateDocument(path, flags)
if newDoc:
for document in self._docs:
if document.GetFilename() and os.path.normcase(document.GetFilename()) == os.path.normcase(path):
""" check for file modification outside of application """
- if os.path.exists(path) and os.path.getmtime(path) != document.GetDocumentModificationDate():
+ if not document.IsDocumentModificationDateCorrect():
msgTitle = wx.GetApp().GetAppName()
if not msgTitle:
msgTitle = _("Warning")
document.SetDocumentModificationDate()
firstView = document.GetFirstView()
- if firstView and firstView.GetFrame():
+ if not firstView and not (flags & DOC_NO_VIEW):
+ document.GetDocumentTemplate().CreateView(document, flags)
+ document.UpdateAllViews()
+ firstView = document.GetFirstView()
+
+ if firstView and firstView.GetFrame() and not (flags & DOC_NO_VIEW):
firstView.GetFrame().SetFocus() # Not in wxWindows code but useful nonetheless
if hasattr(firstView.GetFrame(), "IsIconized") and firstView.GetFrame().IsIconized(): # Not in wxWindows code but useful nonetheless
firstView.GetFrame().Iconize(False)
newDoc.SetDocumentTemplate(temp)
if not newDoc.OnOpenDocument(path):
newDoc.DeleteAllViews() # Implicitly deleted by DeleteAllViews
- newDoc.GetFirstView().GetFrame().Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
+ frame = newDoc.GetFirstView().GetFrame()
+ if frame:
+ frame.Destroy() # DeleteAllViews doesn't get rid of the frame, so we'll explicitly destroy it.
return None
self.AddFileToHistory(path)
return newDoc
This function is used in wxDocManager.CreateDocument.
"""
if wx.Platform == "__WXMSW__" or wx.Platform == "__WXGTK__" or wx.Platform == "__WXMAC__":
- allfilter = ''
descr = ''
for temp in templates:
if temp.IsVisible():
if len(descr) > 0:
descr = descr + _('|')
- allfilter = allfilter + _(';')
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
- allfilter = allfilter + temp.GetFileFilter()
- descr = _("All (%s)|%s|%s|Any (*.*) | *.*") % (allfilter, allfilter, descr) # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
+ descr = _("All|*.*|%s") % descr # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
else:
descr = _("*.*")
- path = wx.FileSelector(_("Select a File"),
- self._lastDirectory,
- _(""),
- wildcard = descr,
- flags = wx.HIDE_READONLY,
- parent = self.FindSuitableParent())
- if path:
- if not FileExists(path):
- msgTitle = wx.GetApp().GetAppName()
- if not msgTitle:
- msgTitle = _("File Error")
- wx.MessageBox("Could not open '%s'." % FileNameFromPath(path),
- msgTitle,
- wx.OK | wx.ICON_EXCLAMATION,
- parent)
- return (None, None)
- self._lastDirectory = PathOnly(path)
-
+ dlg = wx.FileDialog(self.FindSuitableParent(),
+ _("Select a File"),
+ wildcard=descr,
+ style=wx.OPEN|wx.FILE_MUST_EXIST|wx.CHANGE_DIR)
+ # dlg.CenterOnParent() # wxBug: caused crash with wx.FileDialog
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ else:
+ path = None
+ dlg.Destroy()
+
+ if path:
theTemplate = self.FindTemplateForPath(path)
return (theTemplate, path)
-
- return (None, None)
+
+ return (None, None)
def OnOpenFileFailure(self):
self._childView.Activate(event.GetActive())
self._activated = 0
+
def OnCloseWindow(self, event):
"""
Closes and deletes the current view and document.
self._childView.Activate(False)
self._childView.Destroy()
self._childView = None
- if self._childDocument:
- self._childDocument.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
+ if self._childDocument: # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
+ self._childDocument.DeleteContents()
+ if self._childDocument.GetDocumentManager():
+ self._childDocument.GetDocumentManager().RemoveDocument(self._childDocument)
self._childDocument = None
self.Destroy()
else:
self._childView = view
+ def OnTitleIsModified(self):
+ """
+ Add/remove to the frame's title an indication that the document is dirty.
+ If the document is dirty, an '*' is appended to the title
+ This method has been added to wxPython and is not in wxWindows.
+ """
+ title = self.GetTitle()
+ if title:
+ if self.GetDocument().IsModified():
+ if title.endswith("*"):
+ return
+ else:
+ title = title + "*"
+ self.SetTitle(title)
+ else:
+ if title.endswith("*"):
+ title = title[:-1]
+ self.SetTitle(title)
+ else:
+ return
+
+
class DocPrintout(wx.Printout):
"""
DocPrintout is a default Printout that prints the first page of a document
return pageNum == 1
- def OnBeginDocument(self, startPage, endPage):
- """
- Not quite sure why this was overridden, but it was in wxWindows! :)
- """
- if not wx.Printout.base_OnBeginDocument(self, startPage, endPage):
- return False
- return True
-
-
def GetPageInfo(self):
"""
Indicates that the DocPrintout only has a single page.
the history list.
"""
done = command.Do()
- if done and storeIt:
- self._commands.append(command)
+ if done:
+ del self._redoCommands[:]
+ if storeIt:
+ self._commands.append(command)
if self._maxCommands > -1:
if len(self._commands) > self._maxCommands:
del self._commands[0]