From: Robin Dunn Date: Mon, 28 Feb 2005 20:16:34 +0000 (+0000) Subject: Updates for doc/view from Morgan Hua X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/74b8945829b602ebeae29f0237fbb8ff3f041f87 Updates for doc/view from Morgan Hua git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32496 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/wxPython/samples/docview/DocViewDemo.py b/wxPython/samples/docview/DocViewDemo.py index 55eb2a1a28..c22b3539cc 100644 --- a/wxPython/samples/docview/DocViewDemo.py +++ b/wxPython/samples/docview/DocViewDemo.py @@ -91,6 +91,7 @@ class TextEditView(wx.lib.docview.View): sizer.Add(self._textsw, 1, wx.EXPAND, 0) self._frame.SetSizer(sizer) self._frame.Layout() + self._frame.Show(True) self.Activate(True) return True else: # flags & wx.lib.docview.DOC_SDI diff --git a/wxPython/samples/docview/PyDocViewDemo.py b/wxPython/samples/docview/PyDocViewDemo.py index 92bb8d4d4f..9243aea8fd 100644 --- a/wxPython/samples/docview/PyDocViewDemo.py +++ b/wxPython/samples/docview/PyDocViewDemo.py @@ -17,7 +17,8 @@ import wx.lib.docview import wx.lib.pydocview import activegrid.tool.TextEditor as TextEditor import activegrid.tool.FindService as FindService -import wx.lib.pydocview as WindowMenuService +_ = wx.GetTranslation + #---------------------------------------------------------------------------- # Classes @@ -31,19 +32,19 @@ class TextEditorApplication(wx.lib.pydocview.DocApp): wx.lib.pydocview.DocApp.ShowSplash(self, "activegrid/tool/images/splash.jpg") - self.SetAppName(wx.GetTranslation("wxPython DocView Demo")) + self.SetAppName(_("wxPython PyDocView Demo")) config = wx.Config(self.GetAppName(), style = wx.CONFIG_USE_LOCAL_FILE) docManager = wx.lib.docview.DocManager(flags = self.GetDefaultDocManagerFlags()) self.SetDocumentManager(docManager) textTemplate = wx.lib.docview.DocTemplate(docManager, - wx.GetTranslation("Text"), + _("Text"), "*.text;*.txt", - wx.GetTranslation("Text"), - wx.GetTranslation(".txt"), - wx.GetTranslation("Text Document"), - wx.GetTranslation("Text View"), + _("Text"), + _(".txt"), + _("Text Document"), + _("Text View"), TextEditor.TextDocument, TextEditor.TextView) docManager.AssociateTemplate(textTemplate) @@ -51,11 +52,12 @@ class TextEditorApplication(wx.lib.pydocview.DocApp): textService = self.InstallService(TextEditor.TextService()) findService = self.InstallService(FindService.FindService()) optionsService = self.InstallService(wx.lib.pydocview.DocOptionsService()) - windowMenuService = self.InstallService(WindowMenuService.WindowMenuService()) + windowMenuService = self.InstallService(wx.lib.pydocview.WindowMenuService()) optionsService.AddOptionsPanel(TextEditor.TextOptionsPanel) filePropertiesService = self.InstallService(wx.lib.pydocview.FilePropertiesService()) + aboutService = self.InstallService(wx.lib.pydocview.AboutService()) - self.SetDefaultIcon(getDocIcon()) +## self.SetDefaultIcon(getAppIcon()) # set this for your custom icon if docManager.GetFlags() & wx.lib.docview.DOC_MDI: frame = wx.lib.pydocview.DocMDIParentFrame(docManager, None, -1, wx.GetApp().GetAppName()) @@ -68,96 +70,11 @@ class TextEditorApplication(wx.lib.pydocview.DocApp): if not docManager.GetDocuments() and docManager.GetFlags() & wx.lib.docview.DOC_SDI: textTemplate.CreateDocument('', wx.lib.docview.DOC_NEW).OnNewDocument() - wx.CallAfter(self.ShowTip, docManager.FindSuitableParent(), wx.CreateFileTipProvider("activegrid/tool/data/tips.txt", 0)) + wx.CallAfter(self.ShowTip, wx.GetApp().GetTopWindow(), wx.CreateFileTipProvider("activegrid/tool/data/tips.txt", 0)) return True -#---------------------------------------------------------------------------- -# Menu Bitmaps - generated by encode_bitmaps.py -#---------------------------------------------------------------------------- -from wx import ImageFromStream, BitmapFromImage -from wx import EmptyIcon -import cStringIO - - -def getDocData(): - return \ -'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\ -\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x05cID\ -ATX\x85\xed\x97\xcbo\x1b\xd7\x15\xc6\x7fw^\x1c\x92C\x8a\xa4DQ\xa2)\xd9\xb2%?\ -\xe0\xa7\x82\xc0\x85\x83"\xa8\x1b\x17AwYtQtU\xb4\x8b\xa2\x7fH\xfe\x8c\xee\ -\x8b\xac\x124\xab\x02E\n\x17h\x01\x17\x86Q7\xaac7~I\xb2hZ\xe2sH\xce\x83s\xef\ -\xedB\xa6dI~))\x90E\xf2\x01\x17\x98\xb9s\xe7\x9c\xef\x9c\xf9\xce\xb9w\x840L\ -\xbeK\x18\xdf\xa9\xf7\x1f\x08\x00\xa2\xd5ji!\x04\xe3\xf1ma\x9a\x02!\x0c\xe0\ -\xa0-\xa55O\xb6\x06t\xfb\x11\xa0\x98\xca\x99\x880\x0c5\xf0R\xe7B\x08\xb4\xde\ -\xbd6\xc4\xd8\xee\x0bk\xb5\xde3\'\x84f\x10J\x06aB4R\xd8\x96\xc1\x97\x8f{\xfc\ -\xfbq\x97-?\xa2\xe49\x9c\x9d\xf38u\xc4\xa3\x945\xb0\xc6\x8e\r!`\x1f\t!\xd8C\ -\x004\x89\xd4\x04\xb1$\x88%#\xa9(f,\xd6\xdb!\xab\x9b\x01\x9b\xbd\x98 \x96\ -\xb4z\x11\xa6\x80\xea\x94K\x9ch\xfe\xf5\xa0\xcb\xfa\xd6\x90\xea\xa4\xcb\x99Z\ -\x8e\xead\x96\xa2\x97\xc2\x14\t\xd6s\xf3h\x04JC"\xf5\xf3\xa1\x00M.c\xd1\xe9\ -\'\xf4\x82\x11\xc3H\xd2\x0f\x13\xda~L\xcb\x8fI\x12\xc9\x953\x93\\\xff\xaa\ -\xc9\x17\xb7\xb7\xf8j\xdd\xa7\x13J\x82aB\xad\x94\xe2\x83\xe5)\xba\xc3\x84\ -\xde a\xa6\x98\xe2\xc3wf\xb8\xbcX\xa2\xe89(\xa5\x08\x82\xd1\x98\x00\x04qB/\ -\x1c\xd1\xf6Gl\xf6"\x9euc\x84\xd0\xfc\xf4\\\x99Oo\xd4\xf9\xe2\xf6\x16w\x9f\ -\x0chG\t\xbe\x1f\x13\xf9#\xa63\x16\x1f\xff\xee\x027\xefw\xb9\xf5\xb0K\xc7\ -\x8f\x11\xa6`a\xc6\xe5\xdc\xbc\xc7\xfcT\x06/msa~\x82\xa5\xd9\x1c\x8em`\x08\ -\xd0Z\xa1\x94\x02\xc0\xb2,\x8b\x8d\xe6\x90\xcfnl\xf0\xf9\xcd\x06\xf1H\x13E\ -\x92h0\xa2\x906\xe9\x0eF\xf4#I<\x88\xb9w\xa7I\x9cs\xc8\xa5-\xcae\x97\xa3\x93\ -i\xdc\x94\xa0\xe4\xd9\x143\x16\xfd~\xc4\xf4D\x8ak\x17\xa6\xb9z\xae\xcc\xd1r\ -\x06\xc76)dm\xb2)\x03\xa5\xf7jLk\xb0\xc6\x9f~\xbd\x19r}\xa5\xc9\xb0\x9fl?\ -\x1d)&2\x16n\xe9\x19?_.sf>\xcf\xbd\xc7>x6\xaeka\n0S&~\x980\x88\x12l[\xb08\ -\x9b\xe1\xda\xa5\nW\xcfW8;\x9f\'\xefZ;\x02\xd5Z\xa3\xb5~\xae\xa5\xdd\xaa\xb3\ -\x94R\x94<\x87\xc5\xaa\xc7\xe9#9V\xee\xb61\x1d\x13\xc7\xb3I\xa7L\xfe[\x1f\ -\xf0\xd1\xe5\x19\x96O\x97\x08\x84\xa6\xd1\x0c\xe9\r\x136\xfd\x98F7f\xbd\x19Q\ -\xefD\xa4]\x93\xf7O\x95\xf9\xed\xb5\x05\xa6\x0bi\xd0\xa0\xb5\x06\xa5w\x8a\ -\xe6\xc5J\x13B`Y\x16\x96\x94\n\xc76\xf9\xd9\xc5il\x03>\x1e\xc6\x94\x8b.\xc7g\ -2\xcc\x16]\xc2(a\xbd\x19\xa2\xd0,U\xb2\xfc\xf1\xcf\xab\xb4\xba#\xd2\x9eM\xed\ -H\x96 N\xa8\xe4m~\xb4X\xe47W\x8f\x92\xcf\xd8\xe8\xfd\xb9~\x05l\xdb\xde\x16\ -\xa1R\x8a\xa9\xbc\xc3\xd5\xf3\x15\x8a\x9e\xc3\xadG\x1dV\xd6|\xfe\xfa\xe5\x16\ -\x83@"\xa4f\xf9D\x9eKKE\xe6k9\xaa\x15I\xca1\xc9y\x16\xbd0ay\xa1\xc0\xf2B\x91\ -B\xd6\xd9\x8ez\x7f-\xbf\x04\xe3lX\xdb\xcdF\xe3\x98\x06\xd5\x92Kmj\x96l\xc6\ -\xa4\xd1\x89\xf8\xc7\x9d6O\x9e\x05\xa8 \xc1\x16P\x9b\xcd\xf2\xd1{U\xfe\xb3\ -\xda\xe5\xd1\xd3!A?\xa1\x92Oq\xf1X\x81\x93\xd5\xdc[E\xbd\x1f;e8f\xae\xb5\xe0\ -lm\x82\xa7\xa7c\xd67CB\x7fD\xa4!\x1a):\xc3\x84_\xfd\xf8\x08\x1b\xad!\x8f\x1a\ -CD\xa4x\xf7x\x81\xc5\x19\x8fl\xcaDJu\xe8v.\xe28\xd6cu\x8e\xb3\xa1\x81`\xa4y\ -\xd8\x18\xf0\xc9\xdf\xd6ht\x02\x0c\xd3`\xc2\xb3\t\xa5\xa2\xde\x8eX\xdb\n0\ -\x81?\xfc\xfe"\x8b3y,\xcb\xf8F\x04,8\xb8\x0f\x18B\xe0\xa5\x04K\xb3Y~\xf9\xfe\ -\x1c\xc3(\xe1\xc6\xd7m>\xffg\x9d\x87\xf7{,\x1d\xcfsr6K\xde5\x01\x81T\x1a\xeb\ -%v\xde\x9a\xc0\x9e\x94<7\xa2\xb5&e\x19\x9c\x9d\xcbo\xef\th\xee\xac\xf6xp\xb7\ -\x8b\x1f\x8c\xa8\x98i\xe6\xa6\\6\xfd\x98\xf2\xc4\xb6(w\xeb\xfc[\x10x\x81\xca\ -\x9e\xe6qy\xb1Dm2\x83e\x18\xdcZ\xed\xd2\xe8\x84,L\xbb\xdc\xaf\x0f\xa8\x163L\ -\xe6R\x87\x0b}\xec%\x8e\xe3\x9d\xba\xd9\xcf~,\xcc\xf1\xbc\xd2\xb0\xd9\r\xb8\ -\xf9\xa0\xc3\xdf\xef5Yy\xd2\xe7|-\xc7/\xae\xd4\xb8t\xac\x88\x94\xf2\xff\x99\ -\x81\x83\x84L\x01\xd5R\x1a\xcb2\t\x13\xcd\xd7\x8d!\xd7\xef\xb4x\xf7D\x89ss\ -\x13\x98\xc6\xee\xf9\xe1M\xd0Z\x93$\xc9\xe1\x8edZk\x94\x86r>\xc5\x85\xa3\x05\ -\xde;9\x89\xd2\xb0\xb2\xd6\xe3\xee\x86\x8fa\x18\xe3\x85oM\xe0\xb5\x198\x00!P\ -J\x03\x9a\xc5J\x86_\xff\xe4\x18\x00\xb7\x1ev\xf8\xd3\xcd\xa7,\xcd\xe6\xb0\ -\x0e\x11\x92R\xea\xf5\x1ax\x15\xf3\x9dk\xa0\xd9O\xf8\xcb\xed\x06\x1b\xed\x80\ -\x13\x95,\x1f\x9c\x9f\xc6s\xdf\x1c\xd7\xf6\x81$\xc08\xd0\xbb\xdf\x80=;\x1a0\ -\x9dw\xb8rj\x92w\x16\nH\xa9h\xf9\x11\xe1H\x1e \xfb*[\x96\x94r\xe7\xe6\xb0\n\ -\xd6Z\xa3\x94b\xae\x94"\x97\x12<\xde2\x08\xa2\x98 2\xb0\r\xe7\xb5}AJ\xb9]5\ -\xf5z]\x03\xbb\x02\xfa\x06\x10\x80m\x1b\x18\xa6\xc9\xda3\x1f\xd71\xc9\xb9\ -\xf6k\xdf\x91R\x12E\x11\xe2\x87\x7f\xc3\xef=\x81\xff\x01\x1d\xae\x83\xc3q\ -\xb9\xc6\x9f\x00\x00\x00\x00IEND\xaeB`\x82' - - - -def getDocBitmap(): - return BitmapFromImage(getDocImage()) - - -def getDocImage(): - stream = cStringIO.StringIO(getDocData()) - return ImageFromStream(stream) - - -def getDocIcon(): - icon = EmptyIcon() - icon.CopyFromBitmap(getDocBitmap()) - return icon - - #---------------------------------------------------------------------------- # Main #---------------------------------------------------------------------------- diff --git a/wxPython/wx/lib/docview.py b/wxPython/wx/lib/docview.py index 8f5f038ba7..aad8359e14 100644 --- a/wxPython/wx/lib/docview.py +++ b/wxPython/wx/lib/docview.py @@ -1318,7 +1318,7 @@ class DocManager(wx.EvtHandler): """ Creates a new document and reads in the selected file. """ - if not self.CreateDocument('', 0): + if not self.CreateDocument('', DEFAULT_DOCMAN_FLAGS): self.OnOpenFileFailure() @@ -1709,6 +1709,11 @@ class DocManager(wx.EvtHandler): else: return None + if path and flags & DOC_SILENT: + temp = self.FindTemplateForPath(path) + else: + temp, path = self.SelectDocumentPath(templates, path, flags) + # Existing document if self.GetFlags() & DOC_OPEN_ONCE: for document in self._docs: @@ -1720,11 +1725,6 @@ class DocManager(wx.EvtHandler): firstView.GetFrame().Iconize(False) return None - if flags & DOC_SILENT: - temp = self.FindTemplateForPath(path) - else: - temp, path = self.SelectDocumentPath(templates, path, flags) - if temp: newDoc = temp.CreateDocument(path, flags) if newDoc: diff --git a/wxPython/wx/lib/pydocview.py b/wxPython/wx/lib/pydocview.py index 97ad542f87..94e41b48ba 100644 --- a/wxPython/wx/lib/pydocview.py +++ b/wxPython/wx/lib/pydocview.py @@ -20,8 +20,13 @@ import os import os.path import time import string +import pickle +import getpass +import tempfile +import mmap _ = wx.GetTranslation + #---------------------------------------------------------------------------- # Constants #---------------------------------------------------------------------------- @@ -236,7 +241,7 @@ class OptionsDialog(wx.Dialog): Initializes the options dialog with a notebook page that contains new instances of the passed optionsPanelClasses. """ - wx.Dialog.__init__(self, parent, -1, _("Options"), size = (310, 375)) + wx.Dialog.__init__(self, parent, -1, _("Options"), size = (310, 400)) self._optionsPanels = [] self._docManager = docManager @@ -307,14 +312,11 @@ class GeneralOptionsPanel(wx.Panel): choices = [_("Show each document in its own window (SDI)"), _("Show All documents in a single window (MDI)")], majorDimension=1, - #style = wx.RA_SPECIFY_ROWS ) - #self._documentRadioBox.SetBackgroundColour(backgroundColor) # wxBug: uses wrong background color if config.ReadInt("UseMDI", True): self._documentRadioBox.SetSelection(1) else: self._documentRadioBox.SetSelection(0) - def OnDocumentInterfaceSelect(event): if not self._documentInterfaceMessageShown: msgTitle = wx.GetApp().GetAppName() @@ -324,8 +326,7 @@ class GeneralOptionsPanel(wx.Panel): msgTitle, wx.OK | wx.ICON_INFORMATION, self.GetParent()) - self._documentInterfaceMessageShown = True - + self._documentInterfaceMessageShown = True wx.EVT_RADIOBOX(self, self._documentRadioBox.GetId(), OnDocumentInterfaceSelect) optionsBorderSizer = wx.BoxSizer(wx.VERTICAL) optionsSizer = wx.BoxSizer(wx.VERTICAL) @@ -361,8 +362,88 @@ class DocApp(wx.PySimpleApp): self._services = [] self._defaultIcon = None self._registeredCloseEvent = False - self._debug = False + if not hasattr(self, "_debug"): # only set if not already initialized + self._debug = False + if not hasattr(self, "_singleInstance"): # only set if not already initialized + self._singleInstance = True + + # if _singleInstance is TRUE only allow one single instance of app to run. + # When user tries to run a second instance of the app, abort startup, + # But if user also specifies files to open in command line, send message to running app to open those files + if self._singleInstance: + # create shared memory temporary file + if wx.Platform == '__WXMSW__': + tfile = tempfile.TemporaryFile(prefix="ag", suffix="tmp") + fno = tfile.fileno() + self._sharedMemory = mmap.mmap(fno, 1024, "shared_memory") + else: + tfile = file(os.path.join(tempfile.gettempdir(), tempfile.gettempprefix() + getpass.getuser() + "AGSharedMemory"), 'w+b') + tfile.write("*") + tfile.seek(1024) + tfile.write(" ") + tfile.flush() + fno = tfile.fileno() + self._sharedMemory = mmap.mmap(fno, 1024) + + self._singleInstanceChecker = wx.SingleInstanceChecker(self.GetAppName() + '-' + wx.GetUserId()) + if self._singleInstanceChecker.IsAnotherRunning(): + # have running single instance open file arguments + foundArgs = False + args = sys.argv[1:] + for arg in args: + if arg[0] != '/' and arg[0] != '-': + foundArgs = True + break + + if foundArgs: + data = pickle.dumps(args) + while 1: + self._sharedMemory.seek(0) + marker = self._sharedMemory.read_byte() + if marker == '\0' or marker == '*': # available buffer + self._sharedMemory.seek(0) + self._sharedMemory.write_byte('-') # set writing marker + self._sharedMemory.write(data) # write files we tried to open to shared memory + self._sharedMemory.seek(0) + self._sharedMemory.write_byte('+') # set finished writing marker + self._sharedMemory.flush() + break + else: + time.sleep(1) # give enough time for buffer to be available + + return False + else: + self._timer = wx.PyTimer(self.DoBackgroundListenAndLoad) + self._timer.Start(250) + return True + + + def DoBackgroundListenAndLoad(self): + """ + Open any files specified in the given command line argument passed in via shared memory + """ + + self._sharedMemory.seek(0) + if self._sharedMemory.read_byte() == '+': # available data + data = self._sharedMemory.read(1024-1) + self._sharedMemory.seek(0) + self._sharedMemory.write_byte("*") # finished reading, set buffer free marker + self._sharedMemory.flush() + args = pickle.loads(data) + for arg in args: + if arg[0] != '/' and arg[0] != '-': + self.GetDocumentManager().CreateDocument(arg, wx.lib.docview.DOC_SILENT) + + # force display of running app + topWindow = wx.GetApp().GetTopWindow() + if topWindow.IsIconized(): + topWindow.Iconize(False) + else: + topWindow.Raise() + + + self._timer.Start(1000) # 1 second interval def OpenCommandLineArgs(self): @@ -654,11 +735,26 @@ class DocApp(wx.PySimpleApp): def SetDebug(self, debug): """ - Returns False if the application is in debug mode. + Sets the application's debug mode. """ self._debug = debug + def GetSingleInstance(self): + """ + Returns True if the application is in single instance mode. Used to determine if multiple instances of the application is allowed to launch. + """ + return self._singleInstance + + + def SetSingleInstance(self, singleInstance): + """ + Sets application's single instance mode. + """ + self._singleInstance = singleInstance + + + def CreateChildDocument(self, parentDocument, documentType, objectToEdit, path = ''): """ Creates a child window of a document that edits an object. The child window @@ -720,9 +816,12 @@ class DocApp(wx.PySimpleApp): def ShowSplash(self, image): """ - Shows a splash window with the given image. + Shows a splash window with the given image. Input parameter 'image' can either be a wx.Bitmap or a filename. """ - splash_bmp = wx.Image(image).ConvertToBitmap() + if isinstance(image, wx.Bitmap): + splash_bmp = image + else: + splash_bmp = wx.Image(image).ConvertToBitmap() self._splash = wx.SplashScreen(splash_bmp,wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_NO_TIMEOUT,0, None, -1) self._splash.Show() @@ -767,33 +866,6 @@ class _DocFrameFileDropTarget(wx.FileDropTarget): self._docManager.FindSuitableParent()) -def _AboutDialog(frame): - """ - Opens an AboutDialog. Shared by DocMDIParentFrame and DocSDIFrame. - """ - dlg = wx.Dialog(frame, -1, _("About ") + wx.GetApp().GetAppName(), style = wx.DEFAULT_DIALOG_STYLE) - dlg.SetBackgroundColour(wx.WHITE) - sizer = wx.BoxSizer(wx.VERTICAL) - splash_bmp = wx.Image("activegrid/tool/images/splash.jpg").ConvertToBitmap() - image = wx.StaticBitmap(dlg, -1, splash_bmp, (0,0), (splash_bmp.GetWidth(), splash_bmp.GetHeight())) - sizer.Add(image, 0, wx.ALIGN_CENTER|wx.ALL, 0) - sizer.Add(wx.StaticText(dlg, -1, _("ActiveGrid Application Builder\nVersion 1.0\n\nCopyright (c) 2003-2005 ActiveGrid Incorporated and Contributors. All rights reserved.")), 0, wx.ALIGN_LEFT|wx.ALL, 5) - sizer.Add(wx.StaticText(dlg, -1, _("ActiveGrid Development Team:\nLawrence Bruhmuller\nMatt Fryer\nJoel Hare\nMorgan Hua\nJeff Norton\nPeter Yared")), 0, wx.ALIGN_LEFT|wx.ALL, 5) - sizer.Add(wx.StaticText(dlg, -1, _("http://www.activegrid.com")), 0, wx.ALIGN_LEFT|wx.ALL, 5) - - - btn = wx.Button(dlg, wx.ID_OK) - sizer.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5) - - dlg.SetSizer(sizer) - dlg.SetAutoLayout(True) - sizer.Fit(dlg) - - dlg.CenterOnScreen() - dlg.ShowModal() - dlg.Destroy() - - class DocMDIParentFrame(wx.lib.docview.DocMDIParentFrame): """ The DocMDIParentFrame is the primary frame which the DocApp uses to host MDI child windows. It offers @@ -1273,7 +1345,7 @@ class DocMDIParentFrame(wx.lib.docview.DocMDIParentFrame): def UpdateWindowMenu(self): """ - Updates the WindowMenu Windows platforms. + Updates the WindowMenu on Windows platforms. """ if wx.Platform == '__WXMSW__': children = filter(lambda child: isinstance(child, wx.MDIChildFrame), self.GetChildren()) @@ -1332,7 +1404,9 @@ class DocMDIParentFrame(wx.lib.docview.DocMDIParentFrame): """ Invokes the about dialog. """ - _AboutDialog(self) + aboutService = wx.GetApp().GetService(AboutService) + if aboutService: + aboutService.ShowAbout() def OnViewToolBar(self, event): @@ -1671,7 +1745,9 @@ class DocSDIFrame(wx.lib.docview.DocChildFrame): """ Invokes the about dialog. """ - _AboutDialog(self) + aboutService = wx.GetApp().GetService(AboutService) + if aboutService: + aboutService.ShowAbout() def OnViewToolBar(self, event): @@ -1724,9 +1800,68 @@ class DocSDIFrame(wx.lib.docview.DocChildFrame): self._docManager.FileHistoryRemoveMenu(self._fileMenu) +class AboutService(DocService): + """ + About Dialog Service that installs under the Help menu to show the properties of the current application. + """ + + def __init__(self, aboutDialog = None): + """ + Initializes the AboutService. + """ + if aboutDialog: + self._dlg = aboutDialog + else: + self._dlg = AboutDialog # use default AboutDialog + + + def ShowAbout(self): + """ + Show the AboutDialog + """ + dlg = self._dlg(wx.GetApp().GetTopWindow()) + dlg.CenterOnScreen() + dlg.ShowModal() + dlg.Destroy() + + + def SetAboutDialog(self, dlg): + """ + Customize the AboutDialog + """ + self._dlg = dlg + + +class AboutDialog(wx.Dialog): + """ + Opens an AboutDialog. Shared by DocMDIParentFrame and DocSDIFrame. + """ + + def __init__(self, parent): + """ + Initializes the about dialog. + """ + wx.Dialog.__init__(self, parent, -1, _("About ") + wx.GetApp().GetAppName(), style = wx.DEFAULT_DIALOG_STYLE) + + self.SetBackgroundColour(wx.WHITE) + sizer = wx.BoxSizer(wx.VERTICAL) + splash_bmp = wx.Image("activegrid/tool/images/splash.jpg").ConvertToBitmap() + image = wx.StaticBitmap(self, -1, splash_bmp, (0,0), (splash_bmp.GetWidth(), splash_bmp.GetHeight())) + sizer.Add(image, 0, wx.ALIGN_CENTER|wx.ALL, 0) + sizer.Add(wx.StaticText(self, -1, wx.GetApp().GetAppName()), 0, wx.ALIGN_LEFT|wx.ALL, 5) + + btn = wx.Button(self, wx.ID_OK) + sizer.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5) + + self.SetSizer(sizer) + self.SetAutoLayout(True) + sizer.Fit(self) + + + class FilePropertiesService(DocService): """ - Service that installas under the File menu to show the properties of the file associated + Service that installs under the File menu to show the properties of the file associated with the current document. """ @@ -1825,7 +1960,7 @@ class FilePropertiesService(DocService): and creates odd word boundaries. Instead, we will chop the path without regard to spaces, but pay attention to path delimiters. """ - chopped = None + chopped = "" textLen = len(text) start = 0 @@ -1840,7 +1975,7 @@ class FilePropertiesService(DocService): if lastSep != -1 and lastSep != start: end = lastSep - if chopped: + if len(chopped): chopped = chopped + '\n' + text[start:end] else: chopped = text[start:end] @@ -1867,6 +2002,8 @@ class FilePropertiesDialog(wx.Dialog): filePropertiesService = wx.GetApp().GetService(FilePropertiesService) + fileExists = os.path.exists(filename) + notebook = wx.Notebook(self, -1) tab = wx.Panel(notebook, -1) @@ -1879,20 +2016,24 @@ class FilePropertiesDialog(wx.Dialog): gridSizer.Add(wx.StaticText(tab, -1, filePropertiesService.chopPath(os.path.dirname(filename))), flag=wx.BOTTOM, border=SPACE, row=1, col=1) gridSizer.Add(wx.StaticText(tab, -1, _("Size:")), flag=wx.RIGHT, border=HALF_SPACE, row=2, col=0) - gridSizer.Add(wx.StaticText(tab, -1, str(os.path.getsize(filename)) + ' ' + _("bytes")), row=2, col=1) + if fileExists: + gridSizer.Add(wx.StaticText(tab, -1, str(os.path.getsize(filename)) + ' ' + _("bytes")), row=2, col=1) lineSizer = wx.BoxSizer(wx.VERTICAL) # let the line expand horizontally without vertical expansion lineSizer.Add(wx.StaticLine(tab, -1, size = (10,-1)), 0, wx.EXPAND) gridSizer.Add(lineSizer, flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=HALF_SPACE, row=3, col=0, colspan=2) gridSizer.Add(wx.StaticText(tab, -1, _("Created:")), flag=wx.RIGHT, border=HALF_SPACE, row=4, col=0) - gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getctime(filename))), row=4, col=1) + if fileExists: + gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getctime(filename))), row=4, col=1) gridSizer.Add(wx.StaticText(tab, -1, _("Modified:")), flag=wx.RIGHT, border=HALF_SPACE, row=5, col=0) - gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getmtime(filename))), row=5, col=1) + if fileExists: + gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getmtime(filename))), row=5, col=1) gridSizer.Add(wx.StaticText(tab, -1, _("Accessed:")), flag=wx.RIGHT, border=HALF_SPACE, row=6, col=0) - gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getatime(filename))), row=6, col=1) + if fileExists: + gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getatime(filename))), row=6, col=1) # add a border around the inside of the tab spacerGrid = wx.BoxSizer(wx.VERTICAL)