+ return False
+
+
+ def ProcessUpdateUIEventBeforeWindows(self, event):
+ """
+ Processes a UI event before the main window has a chance to process the window.
+ Override this method for a particular service.
+ """
+ return False
+
+
+ def ProcessEvent(self, event):
+ """
+ Processes an event, searching event tables and calling zero or more
+ suitable event handler function(s). Note that the ProcessEvent
+ method is called from the wxPython docview framework directly since
+ wxPython does not have a virtual ProcessEvent function.
+ """
+ return False
+
+
+ def ProcessUpdateUIEvent(self, event):
+ """
+ Processes a UI event, searching event tables and calling zero or more
+ suitable event handler function(s). Note that the ProcessEvent
+ method is called from the wxPython docview framework directly since
+ wxPython does not have a virtual ProcessEvent function.
+ """
+ return False
+
+
+ def OnCloseFrame(self, event):
+ """
+ Called when the a docview frame is being closed. Override this method
+ so a service can either do cleanup or veto the frame being closed by
+ returning false.
+ """
+ return True
+
+
+ def OnExit(self):
+ """
+ Called when the the docview application is being closed. Override this method
+ so a service can either do cleanup or veto the frame being closed by
+ returning false.
+ """
+ pass
+
+
+ def GetMenuItemPos(self, menu, id):
+ """
+ Utility method used to find the position of a menu item so that services can
+ easily find where to insert a menu item in InstallControls.
+ """
+ menuItems = menu.GetMenuItems()
+ for i, menuItem in enumerate(menuItems):
+ if menuItem.GetId() == id:
+ return i
+ return i
+
+
+ def GetView(self):
+ """
+ Called by WindowMenuService to get views for services that don't
+ have dedicated documents such as the Outline Service.
+ """
+ return None
+
+
+class DocOptionsService(DocService):
+ """
+ A service that implements an options menu item and an options dialog with
+ notebook tabs. New tabs can be added by other services by calling the
+ "AddOptionsPanel" method.
+ """
+
+
+ def __init__(self, showGeneralOptions=True, supportedModes=wx.lib.docview.DOC_SDI & wx.lib.docview.DOC_MDI):
+ """
+ Initializes the options service with the option of suppressing the default
+ general options pane that is included with the options service by setting
+ showGeneralOptions to False. It allowModeChanges is set to False, the
+ default general options pane will allow users to change the document
+ interface mode between SDI and MDI modes.
+ """
+ DocService.__init__(self)
+ self.ClearOptionsPanels()
+ self._supportedModes = supportedModes
+ self._toolOptionsID = wx.ID_PREFERENCES
+ if showGeneralOptions:
+ self.AddOptionsPanel(GeneralOptionsPanel)
+
+
+ def InstallControls(self, frame, menuBar=None, toolBar=None, statusBar=None, document=None):
+ """
+ Installs a "Tools" menu with an "Options" menu item.
+ """
+ toolsMenuIndex = menuBar.FindMenu(_("&Tools"))
+ if toolsMenuIndex > -1:
+ toolsMenu = menuBar.GetMenu(toolsMenuIndex)
+ else:
+ toolsMenu = wx.Menu()
+ if toolsMenuIndex == -1:
+ formatMenuIndex = menuBar.FindMenu(_("&Format"))
+ menuBar.Insert(formatMenuIndex + 1, toolsMenu, _("&Tools"))
+ if toolsMenu:
+ if toolsMenu.GetMenuItemCount():
+ toolsMenu.AppendSeparator()
+ toolsMenu.Append(self._toolOptionsID, _("&Options..."), _("Sets options"))
+ wx.EVT_MENU(frame, self._toolOptionsID, frame.ProcessEvent)
+
+
+ def ProcessEvent(self, event):
+ """
+ Checks to see if the "Options" menu item has been selected.
+ """
+ id = event.GetId()
+ if id == self._toolOptionsID:
+ self.OnOptions(event)
+ return True
+ else:
+ return False
+
+
+ def GetSupportedModes(self):
+ """
+ Return the modes supported by the application. Use docview.DOC_SDI and
+ docview.DOC_MDI flags to check if SDI and/or MDI modes are supported.
+ """
+ return self._supportedModes
+
+
+ def SetSupportedModes(self, _supportedModessupportedModes):
+ """
+ Sets the modes supported by the application. Use docview.DOC_SDI and
+ docview.DOC_MDI flags to set if SDI and/or MDI modes are supported.
+ """
+ self._supportedModes = supportedModes
+
+
+ def ClearOptionsPanels(self):
+ """
+ Clears all of the options panels that have been added into the
+ options dialog.
+ """
+ self._optionsPanels = []
+
+
+ def AddOptionsPanel(self, optionsPanel):
+ """
+ Adds an options panel to the options dialog.
+ """
+ self._optionsPanels.append(optionsPanel)
+
+
+ def OnOptions(self, event):
+ """
+ Shows the options dialog, called when the "Options" menu item is selected.
+ """
+ if len(self._optionsPanels) == 0:
+ return
+ optionsDialog = OptionsDialog(wx.GetApp().GetTopWindow(), self._optionsPanels, self._docManager)
+ optionsDialog.CenterOnParent()
+ if optionsDialog.ShowModal() == wx.ID_OK:
+ optionsDialog.OnOK(optionsDialog) # wxBug: wxDialog should be calling this automatically but doesn't
+ optionsDialog.Destroy()
+
+
+class OptionsDialog(wx.Dialog):
+ """
+ A default options dialog used by the OptionsService that hosts a notebook
+ tab of options panels.
+ """
+
+
+ def __init__(self, parent, optionsPanelClasses, docManager):
+ """
+ Initializes the options dialog with a notebook page that contains new
+ instances of the passed optionsPanelClasses.
+ """
+ wx.Dialog.__init__(self, parent, -1, _("Options"))
+
+ self._optionsPanels = []
+ self._docManager = docManager
+
+ HALF_SPACE = 5
+ SPACE = 10
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ if wx.Platform == "__WXMAC__":
+ optionsNotebook = wx.Listbook(self, wx.NewId(), style=wx.LB_DEFAULT)
+ else:
+ optionsNotebook = wx.Notebook(self, wx.NewId(), style=wx.NB_MULTILINE) # NB_MULTILINE is windows platform only
+ sizer.Add(optionsNotebook, 0, wx.ALL | wx.EXPAND, SPACE)
+
+ if wx.Platform == "__WXMAC__":
+ iconList = wx.ImageList(16, 16, initialCount = len(optionsPanelClasses))
+ self._iconIndexLookup = []
+
+ for optionsPanelClass in optionsPanelClasses:
+ optionsPanel = optionsPanelClass(optionsNotebook, -1)
+ self._optionsPanels.append(optionsPanel)
+
+ # We need to populate the image list before setting notebook images
+ if hasattr(optionsPanel, "GetIcon"):
+ icon = optionsPanel.GetIcon()
+ else:
+ icon = None
+ if icon:
+ if icon.GetHeight() != 16 or icon.GetWidth() != 16:
+ icon.SetHeight(16)
+ icon.SetWidth(16)
+ if wx.GetApp().GetDebug():
+ print "Warning: icon for '%s' isn't 16x16, not crossplatform" % template._docTypeName
+ iconIndex = iconList.AddIcon(icon)
+ self._iconIndexLookup.append((optionsPanel, iconIndex))
+
+ else:
+ # use -1 to represent that this panel has no icon
+ self._iconIndexLookup.append((optionsPanel, -1))
+
+ optionsNotebook.AssignImageList(iconList)
+
+ # Add icons to notebook
+ for index in range(0, len(optionsPanelClasses)-1):
+ iconIndex = self._iconIndexLookup[index][1]
+ if iconIndex >= 0:
+ optionsNotebook.SetPageImage(index, iconIndex)
+ else:
+ for optionsPanelClass in optionsPanelClasses:
+ optionsPanel = optionsPanelClass(optionsNotebook, -1)
+ self._optionsPanels.append(optionsPanel)
+
+ sizer.Add(self.CreateButtonSizer(wx.OK | wx.CANCEL), 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, HALF_SPACE)
+ self.SetSizer(sizer)
+ self.Layout()
+ self.Fit()
+ wx.CallAfter(self.DoRefresh)
+
+
+ def DoRefresh(self):
+ """
+ wxBug: On Windows XP when using a multiline notebook the default page doesn't get
+ drawn, but it works when using a single line notebook.
+ """
+ self.Refresh()
+
+
+ def GetDocManager(self):
+ """
+ Returns the document manager passed to the OptionsDialog constructor.
+ """
+ return self._docManager
+
+
+ def OnOK(self, event):
+ """
+ Calls the OnOK method of all of the OptionDialog's embedded panels
+ """
+ for optionsPanel in self._optionsPanels:
+ optionsPanel.OnOK(event)
+
+
+class GeneralOptionsPanel(wx.Panel):
+ """
+ A general options panel that is used in the OptionDialog to configure the
+ generic properties of a pydocview application, such as "show tips at startup"
+ and whether to use SDI or MDI for the application.
+ """
+
+
+ def __init__(self, parent, id):
+ """
+ Initializes the panel by adding an "Options" folder tab to the parent notebook and
+ populating the panel with the generic properties of a pydocview application.
+ """
+ wx.Panel.__init__(self, parent, id)
+ SPACE = 10
+ HALF_SPACE = 5
+ config = wx.ConfigBase_Get()
+ self._showTipsCheckBox = wx.CheckBox(self, -1, _("Show tips at start up"))
+ self._showTipsCheckBox.SetValue(config.ReadInt("ShowTipAtStartup", True))
+ if self._AllowModeChanges():
+ supportedModes = wx.GetApp().GetService(DocOptionsService).GetSupportedModes()
+ choices = []
+ self._sdiChoice = _("Show each document in its own window")
+ self._mdiChoice = _("Show all documents in a single window with tabs")
+ self._winMdiChoice = _("Show all documents in a single window with child windows")
+ if supportedModes & wx.lib.docview.DOC_SDI:
+ choices.append(self._sdiChoice)
+ choices.append(self._mdiChoice)
+ if wx.Platform == "__WXMSW__":
+ choices.append(self._winMdiChoice)
+ self._documentRadioBox = wx.RadioBox(self, -1, _("Document Display Style"),
+ choices = choices,
+ majorDimension=1,
+ )
+ if config.ReadInt("UseWinMDI", False):
+ self._documentRadioBox.SetStringSelection(self._winMdiChoice)
+ elif config.ReadInt("UseMDI", True):
+ self._documentRadioBox.SetStringSelection(self._mdiChoice)
+ else:
+ self._documentRadioBox.SetStringSelection(self._sdiChoice)
+ def OnDocumentInterfaceSelect(event):
+ if not self._documentInterfaceMessageShown:
+ msgTitle = wx.GetApp().GetAppName()
+ if not msgTitle:
+ msgTitle = _("Document Options")
+ wx.MessageBox(_("Document interface changes will not appear until the application is restarted."),
+ msgTitle,
+ wx.OK | wx.ICON_INFORMATION,
+ self.GetParent())
+ self._documentInterfaceMessageShown = True
+ wx.EVT_RADIOBOX(self, self._documentRadioBox.GetId(), OnDocumentInterfaceSelect)
+ optionsBorderSizer = wx.BoxSizer(wx.VERTICAL)
+ optionsSizer = wx.BoxSizer(wx.VERTICAL)
+ if self._AllowModeChanges():
+ optionsSizer.Add(self._documentRadioBox, 0, wx.ALL, HALF_SPACE)
+ optionsSizer.Add(self._showTipsCheckBox, 0, wx.ALL, HALF_SPACE)
+ optionsBorderSizer.Add(optionsSizer, 0, wx.ALL, SPACE)
+ self.SetSizer(optionsBorderSizer)
+ self.Layout()
+ self._documentInterfaceMessageShown = False
+ parent.AddPage(self, _("General"))
+
+
+ def _AllowModeChanges(self):
+ supportedModes = wx.GetApp().GetService(DocOptionsService).GetSupportedModes()
+ return supportedModes & wx.lib.docview.DOC_SDI and supportedModes & wx.lib.docview.DOC_MDI or wx.Platform == "__WXMSW__" and supportedModes & wx.lib.docview.DOC_MDI # More than one mode is supported, allow selection
+
+
+ def OnOK(self, optionsDialog):
+ """
+ Updates the config based on the selections in the options panel.
+ """
+ config = wx.ConfigBase_Get()
+ config.WriteInt("ShowTipAtStartup", self._showTipsCheckBox.GetValue())
+ if self._AllowModeChanges():
+ config.WriteInt("UseMDI", (self._documentRadioBox.GetStringSelection() == self._mdiChoice))
+ config.WriteInt("UseWinMDI", (self._documentRadioBox.GetStringSelection() == self._winMdiChoice))
+
+
+ def GetIcon(self):
+ """ Return icon for options panel on the Mac. """
+ return wx.GetApp().GetDefaultIcon()
+
+
+class DocApp(wx.PySimpleApp):
+ """
+ The DocApp class serves as the base class for pydocview applications and offers
+ functionality such as services, creation of SDI and MDI frames, show tips,
+ and a splash screen.
+ """
+
+
+ def OnInit(self):
+ """
+ Initializes the DocApp.
+ """
+ self._services = []
+ self._defaultIcon = None
+ self._registeredCloseEvent = False
+ self._useTabbedMDI = True
+
+ 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() + self.GetAppName() + '-' + wx.GetUserId() + "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(), tempfile.gettempdir())
+ if self._singleInstanceChecker.IsAnotherRunning():
+ # have running single instance open file arguments
+ data = pickle.dumps(sys.argv[1:])
+ 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 OpenMainFrame(self):
+ docManager = self.GetDocumentManager()
+ if docManager.GetFlags() & wx.lib.docview.DOC_MDI:
+ if self.GetUseTabbedMDI():
+ frame = wx.lib.pydocview.DocTabbedParentFrame(docManager, None, -1, self.GetAppName())
+ else:
+ frame = wx.lib.pydocview.DocMDIParentFrame(docManager, None, -1, self.GetAppName())
+ frame.Show(True)
+
+ def MacOpenFile(self, filename):
+ self.GetDocumentManager().CreateDocument(os.path.normpath(filename), wx.lib.docview.DOC_SILENT)
+
+ # force display of running app
+ topWindow = wx.GetApp().GetTopWindow()
+ if topWindow.IsIconized():
+ topWindow.Iconize(False)
+ else:
+ topWindow.Raise()
+
+ def DoBackgroundListenAndLoad(self):
+ """
+ Open any files specified in the given command line argument passed in via shared memory
+ """
+ self._timer.Stop()
+
+ 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 (wx.Platform != "__WXMSW__" or arg[0] != "/") and arg[0] != '-' and os.path.exists(arg):
+ self.GetDocumentManager().CreateDocument(os.path.normpath(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):
+ """
+ Called to open files that have been passed to the application from the
+ command line.
+ """
+ args = sys.argv[1:]
+ for arg in args:
+ if (wx.Platform != "__WXMSW__" or arg[0] != "/") and arg[0] != '-' and os.path.exists(arg):
+ self.GetDocumentManager().CreateDocument(os.path.normpath(arg), wx.lib.docview.DOC_SILENT)
+
+
+ def GetDocumentManager(self):
+ """
+ Returns the document manager associated to the DocApp.
+ """
+ return self._docManager
+
+
+ def SetDocumentManager(self, docManager):
+ """
+ Sets the document manager associated with the DocApp and loads the
+ DocApp's file history into the document manager.
+ """
+ self._docManager = docManager
+ config = wx.ConfigBase_Get()
+ self.GetDocumentManager().FileHistoryLoad(config)
+
+
+ def ProcessEventBeforeWindows(self, event):
+ """
+ Enables services to process an event before the main window has a chance to
+ process the window.
+ """
+ for service in self._services:
+ if service.ProcessEventBeforeWindows(event):
+ return True
+ return False
+
+
+ def ProcessUpdateUIEventBeforeWindows(self, event):
+ """
+ Enables services to process a UI event before the main window has a chance
+ to process the window.
+ """
+ for service in self._services:
+ if service.ProcessUpdateUIEventBeforeWindows(event):
+ return True
+ return False
+
+
+ def ProcessEvent(self, event):
+ """
+ Processes an event, searching event tables and calling zero or more
+ suitable event handler function(s). Note that the ProcessEvent
+ method is called from the wxPython docview framework directly since
+ wxPython does not have a virtual ProcessEvent function.
+ """
+ for service in self._services:
+ if service.ProcessEvent(event):
+ return True
+ return False
+
+
+ def ProcessUpdateUIEvent(self, event):
+ """
+ Processes a UI event, searching event tables and calling zero or more
+ suitable event handler function(s). Note that the ProcessEvent
+ method is called from the wxPython docview framework directly since
+ wxPython does not have a virtual ProcessEvent function.
+ """
+ for service in self._services:
+ if service.ProcessUpdateUIEvent(event):
+ return True
+ return False
+
+
+ def InstallService(self, service):
+ """
+ Installs an instance of a DocService into the DocApp.
+ """
+ service.SetDocumentManager(self._docManager)
+ self._services.append(service)
+ return service
+
+
+ def GetServices(self):
+ """
+ Returns the DocService instances that have been installed into the DocApp.
+ """
+ return self._services
+
+
+ def GetService(self, type):
+ """
+ Returns the instance of a particular type of service that has been installed
+ into the DocApp. For example, "wx.GetApp().GetService(pydocview.OptionsService)"
+ returns the isntance of the OptionsService that is running within the DocApp.
+ """
+ for service in self._services:
+ if isinstance(service, type):
+ return service
+ return None
+
+
+ def OnExit(self):
+ """
+ Called when the DocApp is exited, enables the installed DocServices to exit
+ and saves the DocManager's file history.
+ """
+ for service in self._services:
+ service.OnExit()
+ config = wx.ConfigBase_Get()
+ self._docManager.FileHistorySave(config)
+
+ if hasattr(self, "_singleInstanceChecker"):
+ del self._singleInstanceChecker
+
+
+ def GetDefaultDocManagerFlags(self):
+ """
+ Returns the default flags to use when creating the DocManager.
+ """
+ config = wx.ConfigBase_Get()
+ if config.ReadInt("UseMDI", True) or config.ReadInt("UseWinMDI", False):
+ flags = wx.lib.docview.DOC_MDI | wx.lib.docview.DOC_OPEN_ONCE
+ if config.ReadInt("UseWinMDI", False):
+ self.SetUseTabbedMDI(False)
+ else:
+ flags = wx.lib.docview.DOC_SDI | wx.lib.docview.DOC_OPEN_ONCE
+ return flags
+
+
+ def ShowTip(self, frame, tipProvider):
+ """
+ Shows the tip window, generally this is called when an application starts.
+ A wx.TipProvider must be passed.
+ """
+ config = wx.ConfigBase_Get()
+ showTip = config.ReadInt("ShowTipAtStartup", 1)
+ if showTip:
+ index = config.ReadInt("TipIndex", 0)
+ showTipResult = wx.ShowTip(wx.GetApp().GetTopWindow(), tipProvider, showAtStartup = showTip)
+ if showTipResult != showTip:
+ config.WriteInt("ShowTipAtStartup", showTipResult)
+
+
+ def GetEditMenu(self, frame):
+ """
+ Utility method that finds the Edit menu within the menubar of a frame.
+ """
+ menuBar = frame.GetMenuBar()
+ if not menuBar:
+ return None
+ editMenuIndex = menuBar.FindMenu(_("&Edit"))
+ if editMenuIndex == -1:
+ return None
+ return menuBar.GetMenu(editMenuIndex)
+
+
+ def GetUseTabbedMDI(self):
+ """
+ Returns True if Windows MDI should use folder tabs instead of child windows.
+ """
+ return self._useTabbedMDI
+
+
+ def SetUseTabbedMDI(self, useTabbedMDI):
+ """
+ Set to True if Windows MDI should use folder tabs instead of child windows.
+ """
+ self._useTabbedMDI = useTabbedMDI
+
+
+ def CreateDocumentFrame(self, view, doc, flags, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
+ """
+ Called by the DocManager to create and return a new Frame for a Document.
+ Chooses whether to create an MDIChildFrame or SDI Frame based on the
+ DocManager's flags.
+ """
+ docflags = self.GetDocumentManager().GetFlags()
+ if docflags & wx.lib.docview.DOC_SDI:
+ frame = self.CreateSDIDocumentFrame(doc, view, id, title, pos, size, style)
+ frame.Show()
+
+ # wxBug: operating system bug, first window is set to the position of last window closed, ignoring passed in position on frame creation
+ # also, initial size is incorrect for the same reasons
+ if frame.GetPosition() != pos:
+ frame.Move(pos)
+ if frame.GetSize() != size:
+ frame.SetSize(size)
+
+ if doc and doc.GetCommandProcessor():
+ doc.GetCommandProcessor().SetEditMenu(self.GetEditMenu(frame))
+ elif docflags & wx.lib.docview.DOC_MDI:
+ if self.GetUseTabbedMDI():
+ frame = self.CreateTabbedDocumentFrame(doc, view, id, title, pos, size, style)
+ else:
+ frame = self.CreateMDIDocumentFrame(doc, view, id, title, pos, size, style)
+ if doc:
+ if doc.GetDocumentTemplate().GetIcon():
+ frame.SetIcon(doc.GetDocumentTemplate().GetIcon())
+ elif wx.GetApp().GetTopWindow().GetIcon():
+ frame.SetIcon(wx.GetApp().GetTopWindow().GetIcon())
+ if doc and doc.GetCommandProcessor():
+ doc.GetCommandProcessor().SetEditMenu(self.GetEditMenu(wx.GetApp().GetTopWindow()))
+ if not frame.GetIcon() and self._defaultIcon:
+ frame.SetIcon(self.GetDefaultIcon())
+ view.SetFrame(frame)
+ return frame
+
+
+ def CreateSDIDocumentFrame(self, doc, view, id=-1, title="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
+ """
+ Creates and returns an SDI Document Frame.
+ """
+ frame = DocSDIFrame(doc, view, None, id, title, pos, size, style)
+ return frame
+
+
+ def CreateTabbedDocumentFrame(self, doc, view, id=-1, title="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
+ """
+ Creates and returns an MDI Document Frame for a Tabbed MDI view
+ """
+ frame = DocTabbedChildFrame(doc, view, wx.GetApp().GetTopWindow(), id, title, pos, size, style)
+ return frame
+
+
+ def CreateMDIDocumentFrame(self, doc, view, id=-1, title="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
+ """
+ Creates and returns an MDI Document Frame.
+ """
+ # if any child windows are maximized, then user must want any new children maximized
+ # if no children exist, then use the default value from registry
+ # wxBug: Only current window is maximized, so need to check every child frame
+ parentFrame = wx.GetApp().GetTopWindow()
+ childrenMaximized = filter(lambda child: isinstance(child, wx.MDIChildFrame) and child.IsMaximized(), parentFrame.GetChildren())
+ if childrenMaximized:
+ maximize = True
+ else:
+ children = filter(lambda child: isinstance(child, wx.MDIChildFrame), parentFrame.GetChildren())
+ if children:
+ # other windows exist and none are maximized
+ maximize = False
+ else:
+ # get default setting from registry
+ maximize = wx.ConfigBase_Get().ReadInt("MDIChildFrameMaximized", False)
+
+ frame = wx.lib.docview.DocMDIChildFrame(doc, view, wx.GetApp().GetTopWindow(), id, title, pos, size, style)
+ if maximize: # wxBug: Should already be maximizing new child frames if one is maximized but it's not so we have to force it to
+ frame.Maximize(True)
+
+## wx.EVT_MAXIMIZE(frame, self.OnMaximize) # wxBug: This doesn't work, need to save MDIChildFrameMaximized state on close of windows instead
+ wx.EVT_CLOSE(frame, self.OnCloseChildWindow)
+ if not self._registeredCloseEvent:
+ wx.EVT_CLOSE(parentFrame, self.OnCloseMainWindow) # need to check on this, but only once
+ self._registeredCloseEvent = True
+
+ return frame
+
+
+ def SaveMDIDocumentFrameMaximizedState(self, maximized):
+ """
+ Remember in the config whether the MDI Frame is maximized so that it can be restored
+ on open.
+ """
+ config = wx.ConfigBase_Get()
+ maximizeFlag = config.ReadInt("MDIChildFrameMaximized", False)
+ if maximized != maximizeFlag:
+ config.WriteInt("MDIChildFrameMaximized", maximized)
+
+
+ def OnCloseChildWindow(self, event):
+ """
+ Called when an MDI Child Frame is closed. Calls SaveMDIDocumentFrameMaximizedState to
+ remember whether the MDI Frame is maximized so that it can be restored on open.
+ """
+ self.SaveMDIDocumentFrameMaximizedState(event.GetEventObject().IsMaximized())
+ event.Skip()
+
+
+ def OnCloseMainWindow(self, event):
+ """
+ Called when the MDI Parent Frame is closed. Remembers whether the MDI Parent Frame is
+ maximized.
+ """
+ children = event.GetEventObject().GetChildren()
+ childrenMaximized = filter(lambda child: isinstance(child, wx.MDIChildFrame)and child.IsMaximized(), children)
+ if childrenMaximized:
+ self.SaveMDIDocumentFrameMaximizedState(True)
+ else:
+ childrenNotMaximized = filter(lambda child: isinstance(child, wx.MDIChildFrame), children)
+
+ if childrenNotMaximized:
+ # other windows exist and none are maximized
+ self.SaveMDIDocumentFrameMaximizedState(False)
+
+ event.Skip()
+
+
+ def GetDefaultIcon(self):
+ """
+ Returns the application's default icon.
+ """
+ return self._defaultIcon
+
+
+ def SetDefaultIcon(self, icon):
+ """
+ Sets the application's default icon.
+ """
+ self._defaultIcon = icon
+
+
+ def GetDebug(self):
+ """
+ Returns True if the application is in debug mode.
+ """
+ return self._debug
+
+
+ def SetDebug(self, debug):
+ """
+ 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
+ is managed by the parent document frame, so it will be prompted to close if its
+ parent is closed, etc. Child Documents are useful when there are complicated
+ Views of a Document and users will need to tunnel into the View.
+ """
+ for document in self.GetDocumentManager().GetDocuments()[:]: # Cloning list to make sure we go through all docs even as they are deleted
+ if isinstance(document, ChildDocument) and document.GetParentDocument() == parentDocument:
+ if document.GetData() == objectToEdit:
+ if hasattr(document.GetFirstView().GetFrame(), "SetFocus"):
+ document.GetFirstView().GetFrame().SetFocus()
+ return document
+ for temp in wx.GetApp().GetDocumentManager().GetTemplates():
+ if temp.GetDocumentType() == documentType:
+ break
+ temp = None
+ newDoc = temp.CreateDocument(path, 0, data = objectToEdit, parentDocument = parentDocument)
+ newDoc.SetDocumentName(temp.GetDocumentName())
+ newDoc.SetDocumentTemplate(temp)
+ if path == '':
+ newDoc.OnNewDocument()
+ else:
+ if not newDoc.OnOpenDocument(path):
+ newDoc.DeleteAllViews() # Implicitly deleted by DeleteAllViews
+ return None
+ return newDoc
+
+
+ def CloseChildDocuments(self, parentDocument):
+ """
+ Closes the child windows of a Document.
+ """
+ for document in self.GetDocumentManager().GetDocuments()[:]: # Cloning list to make sure we go through all docs even as they are deleted
+ if isinstance(document, ChildDocument) and document.GetParentDocument() == parentDocument:
+ if document.GetFirstView().GetFrame():
+ document.GetFirstView().GetFrame().SetFocus()
+ if not document.GetFirstView().OnClose():
+ return False
+ return True
+
+
+ def IsMDI(self):
+ """
+ Returns True if the application is in MDI mode.
+ """
+ return self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_MDI
+
+
+ def IsSDI(self):
+ """
+ Returns True if the application is in SDI mode.
+ """
+ return self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI