+ def CreateEmbeddedWindows(self, windows=0):
+ """
+ Create the specified embedded windows around the edges of the frame.
+ """
+ frameSize = self.GetSize() # TODO: GetClientWindow.GetSize is still returning 0,0 since the frame isn't fully constructed yet, so using full frame size
+ defaultHSize = int(frameSize[0] / 6)
+ defaultVSize = int(frameSize[1] / 7)
+ defaultSubVSize = int(frameSize[1] / 2)
+ config = wx.ConfigBase_Get()
+ if windows & (EMBEDDED_WINDOW_LEFT | EMBEDDED_WINDOW_TOPLEFT | EMBEDDED_WINDOW_BOTTOMLEFT):
+ self._leftEmbWindow = self._CreateEmbeddedWindow(self, (config.ReadInt("MDIEmbedLeftSize", defaultHSize), -1), wx.LAYOUT_VERTICAL, wx.LAYOUT_LEFT, visible = config.ReadInt("MDIEmbedLeftVisible", 1), sash = wx.SASH_RIGHT)
+ else:
+ self._leftEmbWindow = None
+ if windows & EMBEDDED_WINDOW_TOPLEFT:
+ self._topLeftEmbWindow = self._CreateEmbeddedWindow(self._leftEmbWindow, (-1, config.ReadInt("MDIEmbedTopLeftSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopLeftVisible", 1), sash = wx.SASH_BOTTOM)
+ else:
+ self._topLeftEmbWindow = None
+ if windows & EMBEDDED_WINDOW_BOTTOMLEFT:
+ self._bottomLeftEmbWindow = self._CreateEmbeddedWindow(self._leftEmbWindow, (-1, config.ReadInt("MDIEmbedBottomLeftSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomLeftVisible", 1))
+ else:
+ self._bottomLeftEmbWindow = None
+ if windows & (EMBEDDED_WINDOW_RIGHT | EMBEDDED_WINDOW_TOPRIGHT | EMBEDDED_WINDOW_BOTTOMRIGHT):
+ self._rightEmbWindow = self._CreateEmbeddedWindow(self, (config.ReadInt("MDIEmbedRightSize", defaultHSize), -1), wx.LAYOUT_VERTICAL, wx.LAYOUT_RIGHT, visible = config.ReadInt("MDIEmbedRightVisible", 1), sash = wx.SASH_LEFT)
+ else:
+ self._rightEmbWindow = None
+ if windows & EMBEDDED_WINDOW_TOPRIGHT:
+ self._topRightEmbWindow = self._CreateEmbeddedWindow(self._rightEmbWindow, (-1, config.ReadInt("MDIEmbedTopRightSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopRightVisible", 1), sash = wx.SASH_BOTTOM)
+ else:
+ self._topRightEmbWindow = None
+ if windows & EMBEDDED_WINDOW_BOTTOMRIGHT:
+ self._bottomRightEmbWindow = self._CreateEmbeddedWindow(self._rightEmbWindow, (-1, config.ReadInt("MDIEmbedBottomRightSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomRightVisible", 1))
+ else:
+ self._bottomRightEmbWindow = None
+ if windows & EMBEDDED_WINDOW_TOP:
+ self._topEmbWindow = self._CreateEmbeddedWindow(self, (-1, config.ReadInt("MDIEmbedTopSize", defaultVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopVisible", 1), sash = wx.SASH_BOTTOM)
+ else:
+ self._topEmbWindow = None
+ if windows & EMBEDDED_WINDOW_BOTTOM:
+ self._bottomEmbWindow = self._CreateEmbeddedWindow(self, (-1, config.ReadInt("MDIEmbedBottomSize", defaultVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomVisible", 1), sash = wx.SASH_TOP)
+ else:
+ self._bottomEmbWindow = None
+
+
+ def SaveEmbeddedWindowSizes(self):
+ """
+ Saves the sizes of the embedded windows.
+ """
+ config = wx.ConfigBase_Get()
+ if not self.IsMaximized():
+ config.WriteInt("MDIFrameXLoc", self.GetPositionTuple()[0])
+ config.WriteInt("MDIFrameYLoc", self.GetPositionTuple()[1])
+ config.WriteInt("MDIFrameXSize", self.GetSizeTuple()[0])
+ config.WriteInt("MDIFrameYSize", self.GetSizeTuple()[1])
+ config.WriteInt("MDIFrameMaximized", self.IsMaximized())
+ config.WriteInt("ViewToolBar", self._toolBar.IsShown())
+ config.WriteInt("ViewStatusBar", self.GetStatusBar().IsShown())
+
+ if self._leftEmbWindow:
+ config.WriteInt("MDIEmbedLeftSize", self._leftEmbWindow.GetSize()[0])
+ config.WriteInt("MDIEmbedLeftVisible", self._leftEmbWindow.IsShown())
+ if self._topLeftEmbWindow:
+ if self._topLeftEmbWindow._sizeBeforeHidden:
+ size = self._topLeftEmbWindow._sizeBeforeHidden[1]
+ else:
+ size = self._topLeftEmbWindow.GetSize()[1]
+ config.WriteInt("MDIEmbedTopLeftSize", size)
+ config.WriteInt("MDIEmbedTopLeftVisible", self._topLeftEmbWindow.IsShown())
+ if self._bottomLeftEmbWindow:
+ if self._bottomLeftEmbWindow._sizeBeforeHidden:
+ size = self._bottomLeftEmbWindow._sizeBeforeHidden[1]
+ else:
+ size = self._bottomLeftEmbWindow.GetSize()[1]
+ config.WriteInt("MDIEmbedBottomLeftSize", size)
+ config.WriteInt("MDIEmbedBottomLeftVisible", self._bottomLeftEmbWindow.IsShown())
+ if self._rightEmbWindow:
+ config.WriteInt("MDIEmbedRightSize", self._rightEmbWindow.GetSize()[0])
+ config.WriteInt("MDIEmbedRightVisible", self._rightEmbWindow.IsShown())
+ if self._topRightEmbWindow:
+ if self._topRightEmbWindow._sizeBeforeHidden:
+ size = self._topRightEmbWindow._sizeBeforeHidden[1]
+ else:
+ size = self._topRightEmbWindow.GetSize()[1]
+ config.WriteInt("MDIEmbedTopRightSize", size)
+ config.WriteInt("MDIEmbedTopRightVisible", self._topRightEmbWindow.IsShown())
+ if self._bottomRightEmbWindow:
+ if self._bottomRightEmbWindow._sizeBeforeHidden:
+ size = self._bottomRightEmbWindow._sizeBeforeHidden[1]
+ else:
+ size = self._bottomRightEmbWindow.GetSize()[1]
+ config.WriteInt("MDIEmbedBottomRightSize", size)
+ config.WriteInt("MDIEmbedBottomRightVisible", self._bottomRightEmbWindow.IsShown())
+ if self._topEmbWindow:
+ config.WriteInt("MDIEmbedTopSize", self._topEmbWindow.GetSize()[1])
+ config.WriteInt("MDIEmbedTopVisible", self._topEmbWindow.IsShown())
+ if self._bottomEmbWindow:
+ config.WriteInt("MDIEmbedBottomSize", self._bottomEmbWindow.GetSize()[1])
+ config.WriteInt("MDIEmbedBottomVisible", self._bottomEmbWindow.IsShown())
+
+
+ def GetEmbeddedWindow(self, loc):
+ """
+ Returns the instance of the embedded window specified by the embedded window location constant.
+ """
+ if loc == EMBEDDED_WINDOW_TOP:
+ return self._topEmbWindow
+ elif loc == EMBEDDED_WINDOW_BOTTOM:
+ return self._bottomEmbWindow
+ elif loc == EMBEDDED_WINDOW_LEFT:
+ return self._leftEmbWindow
+ elif loc == EMBEDDED_WINDOW_RIGHT:
+ return self._rightEmbWindow
+ elif loc == EMBEDDED_WINDOW_TOPLEFT:
+ return self._topLeftEmbWindow
+ elif loc == EMBEDDED_WINDOW_BOTTOMLEFT:
+ return self._bottomLeftEmbWindow
+ elif loc == EMBEDDED_WINDOW_TOPRIGHT:
+ return self._topRightEmbWindow
+ elif loc == EMBEDDED_WINDOW_BOTTOMRIGHT:
+ return self._bottomRightEmbWindow
+ return None
+
+
+ def _CreateEmbeddedWindow(self, parent, size, orientation, alignment, visible=True, sash=None):
+ """
+ Creates the embedded window with the specified size, orientation, and alignment. If the
+ window is not visible it will retain the size with which it was last viewed.
+ """
+ window = wx.SashLayoutWindow(parent, wx.NewId(), style = wx.NO_BORDER | wx.SW_3D)
+ window.SetDefaultSize(size)
+ window.SetOrientation(orientation)
+ window.SetAlignment(alignment)
+ if sash != None: # wx.SASH_TOP is 0 so check for None instead of just doing "if sash:"
+ window.SetSashVisible(sash, True)
+ ####
+ def OnEmbeddedWindowSashDrag(event):
+ if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE:
+ return
+ sashWindow = event.GetEventObject()
+ if sashWindow.GetAlignment() == wx.LAYOUT_TOP or sashWindow.GetAlignment() == wx.LAYOUT_BOTTOM:
+ size = wx.Size(-1, event.GetDragRect().height)
+ else:
+ size = wx.Size(event.GetDragRect().width, -1)
+ event.GetEventObject().SetDefaultSize(size)
+ self._LayoutFrame()
+ sashWindow.Refresh()
+ if isinstance(sashWindow.GetParent(), wx.SashLayoutWindow):
+ sashWindow.Show()
+ parentSashWindow = sashWindow.GetParent() # Force a refresh
+ parentSashWindow.Layout()
+ parentSashWindow.Refresh()
+ parentSashWindow.SetSize((parentSashWindow.GetSize().width + 1, parentSashWindow.GetSize().height + 1))
+ ####
+ wx.EVT_SASH_DRAGGED(window, window.GetId(), OnEmbeddedWindowSashDrag)
+ window._sizeBeforeHidden = None
+ if not visible:
+ window.Show(False)
+ if isinstance(parent, wx.SashLayoutWindow): # It's a window embedded in another sash window so remember its actual size to show it again
+ window._sizeBeforeHidden = size
+ return window
+
+
+ def ShowEmbeddedWindow(self, window, show=True):
+ """
+ Shows or hides the embedded window specified by the embedded window location constant.
+ """
+ window.Show(show)
+ if isinstance(window.GetParent(), wx.SashLayoutWindow): # It is a parent sashwindow with multiple embedded sashwindows
+ parentSashWindow = window.GetParent()
+ if show: # Make sure it is visible in case all of the subwindows were hidden
+ parentSashWindow.Show()
+ if show and window._sizeBeforeHidden:
+ if window._sizeBeforeHidden[1] == parentSashWindow.GetClientSize()[1]:
+ if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).IsShown():
+ window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).GetSize()[1]))
+ elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).IsShown():
+ window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).GetSize()[1]))
+ elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).IsShown():
+ window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).GetSize()[1]))
+ elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).IsShown():
+ window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).GetSize()[1]))
+ else:
+ window.SetDefaultSize(window._sizeBeforeHidden)
+ # If it is not the size of the full parent sashwindow set the other window's size so that if it gets shown it will have a cooresponding size
+ if window._sizeBeforeHidden[1] < parentSashWindow.GetClientSize()[1]:
+ otherWindowSize = (-1, parentSashWindow.GetClientSize()[1] - window._sizeBeforeHidden[1])
+ if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT):
+ self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).SetDefaultSize(otherWindowSize)
+ elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT):
+ self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).SetDefaultSize(otherWindowSize)
+ elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT):
+ self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).SetDefaultSize(otherWindowSize)
+ elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT):
+ self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).SetDefaultSize(otherWindowSize)
+
+ if not show:
+ if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).IsShown() \
+ or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).IsShown() \
+ or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).IsShown() \
+ or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).IsShown():
+ parentSashWindow.Hide() # Hide the parent sashwindow if all of the children are hidden
+ parentSashWindow.Layout() # Force a refresh
+ parentSashWindow.Refresh()
+ parentSashWindow.SetSize((parentSashWindow.GetSize().width + 1, parentSashWindow.GetSize().height + 1))
+ self._LayoutFrame()
+
+
+ def HideEmbeddedWindow(self):
+ """
+ Hides the embedded window specified by the embedded window location constant.
+ """
+ self.ShowEmbeddedWindow(show = False)
+
+
+class DocTabbedChildFrame(wx.Panel):
+ """
+ The wxDocMDIChildFrame class provides a default frame for displaying
+ documents on separate windows. This class can only be used for MDI child
+ frames.
+
+ The class is part of the document/view framework supported by wxWindows,
+ and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
+ classes.
+ """
+
+
+ def __init__(self, doc, view, frame, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name="frame"):
+ """
+ Constructor. Note that the event table must be rebuilt for the
+ frame since the EvtHandler is not virtual.
+ """
+ wx.Panel.__init__(self, frame.GetNotebook(), id)
+ self._childDocument = doc
+ self._childView = view
+ frame.AddNotebookPage(self, doc.GetPrintableName())
+ if view:
+ view.SetFrame(self)
+
+
+ def GetIcon(self):
+ """
+ Dummy method since the icon of tabbed frames are managed by the notebook.
+ """
+ return None
+
+
+ def SetIcon(self, icon):
+ """
+ Dummy method since the icon of tabbed frames are managed by the notebook.
+ """
+ pass
+
+
+ def Destroy(self):
+ """
+ Removes the current notebook page.
+ """
+ wx.GetApp().GetTopWindow().RemoveNotebookPage(self)
+
+
+ def SetFocus(self):
+ """
+ Activates the current notebook page.
+ """
+ wx.GetApp().GetTopWindow().ActivateNotebookPage(self)
+
+
+ def Activate(self): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
+ """
+ Activates the current view.
+ """
+ # Called by Project Editor
+ if self._childView:
+ self._childView.Activate(True)
+
+
+ def GetTitle(self):
+ """
+ Returns the frame's title.
+ """
+ wx.GetApp().GetTopWindow().GetNotebookPageTitle(self)
+
+
+ def SetTitle(self, title):
+ """
+ Sets the frame's title.
+ """
+ wx.GetApp().GetTopWindow().SetNotebookPageTitle(self, title)
+
+
+ def ProcessEvent(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.
+ """
+ if not self._childView or not self._childView.ProcessEvent(event):
+ if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
+ return False
+ else:
+ return True
+ else:
+ return True
+
+
+ def GetDocument(self):
+ """
+ Returns the document associated with this frame.
+ """
+ return self._childDocument
+
+
+ def SetDocument(self, document):
+ """
+ Sets the document for this frame.
+ """
+ self._childDocument = document
+
+
+ def GetView(self):
+ """
+ Returns the view associated with this frame.
+ """
+ return self._childView
+
+
+ def SetView(self, view):
+ """
+ Sets the view for this frame.
+ """
+ self._childView = view
+
+
+class DocTabbedParentFrame(wx.Frame, DocFrameMixIn, DocMDIParentFrameMixIn):
+ """
+ The DocTabbedParentFrame class provides a default top-level frame for
+ applications using the document/view framework. This class can only be
+ used for MDI parent frames that use a tabbed interface.
+
+ It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
+ classes.
+ """
+
+
+ def __init__(self, docManager, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "DocTabbedParentFrame", embeddedWindows = 0):
+ """
+ Constructor. Note that the event table must be rebuilt for the
+ frame since the EvtHandler is not virtual.
+ """
+ pos, size = self._GetPosSizeFromConfig(pos, size)
+ wx.Frame.__init__(self, frame, id, title, pos, size, style, name)
+
+ # From docview.MDIParentFrame
+ self._docManager = docManager
+
+ wx.EVT_CLOSE(self, self.OnCloseWindow)
+
+ wx.EVT_MENU(self, wx.ID_EXIT, self.OnExit)
+ wx.EVT_MENU_RANGE(self, wx.ID_FILE1, wx.ID_FILE9, self.OnMRUFile)
+
+ wx.EVT_MENU(self, wx.ID_NEW, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_OPEN, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_CLOSE_ALL, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_CLOSE, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_REVERT, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_SAVE, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_SAVEAS, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_UNDO, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_REDO, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_PRINT, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_PRINT_SETUP, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_PREVIEW, self.ProcessEvent)
+ wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
+
+ wx.EVT_UPDATE_UI(self, wx.ID_NEW, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_OPEN, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_CLOSE_ALL, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_CLOSE, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_REVERT, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_SAVE, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_SAVEAS, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_UNDO, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_REDO, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_PRINT, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_PRINT_SETUP, self.ProcessUpdateUIEvent)
+ wx.EVT_UPDATE_UI(self, wx.ID_PREVIEW, self.ProcessUpdateUIEvent)
+ # End From docview.MDIParentFrame
+
+ self.CreateNotebook()
+ self._InitFrame(embeddedWindows)
+
+
+ def _LayoutFrame(self):
+ """
+ Lays out the frame.
+ """
+ wx.LayoutAlgorithm().LayoutFrame(self, self._notebook)
+
+
+ def CreateNotebook(self):
+ """
+ Creates the notebook to use for the tabbed document interface.
+ """
+ self._notebook = wx.Notebook(self, wx.NewId())
+ # self._notebook.SetSizer(wx.NotebookSizer(self._notebook))
+ wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self._notebook.GetId(), self.OnNotebookPageChanged)
+ wx.EVT_RIGHT_DOWN(self._notebook, self.OnNotebookRightClick)
+ wx.EVT_MOTION(self._notebook, self.OnNotebookMouseOver)
+
+ templates = wx.GetApp().GetDocumentManager().GetTemplates()
+ iconList = wx.ImageList(16, 16, initialCount = len(templates))
+ self._iconIndexLookup = []
+ for template in templates:
+ icon = template.GetIcon()
+ 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((template, iconIndex))
+
+ icon = getBlankIcon()
+ if icon.GetHeight() != 16 or icon.GetWidth() != 16:
+ icon.SetHeight(16)
+ icon.SetWidth(16)
+ if wx.GetApp().GetDebug():
+ print "Warning: getBlankIcon isn't 16x16, not crossplatform"
+ self._blankIconIndex = iconList.AddIcon(icon)
+ self._notebook.AssignImageList(iconList)
+
+
+ def GetNotebook(self):
+ """
+ Returns the notebook used by the tabbed document interface.
+ """
+ return self._notebook
+
+
+ def GetActiveChild(self):
+ """
+ Returns the active notebook page, which to the framework is treated as
+ a document frame.
+ """
+ index = self._notebook.GetSelection()
+ if index == -1:
+ return None
+ return self._notebook.GetPage(index)
+
+
+ def OnNotebookPageChanged(self, event):
+ """
+ Activates a notebook page's view when it is selected.
+ """
+ index = self._notebook.GetSelection()
+ if index > -1:
+ self._notebook.GetPage(index).GetView().Activate()
+
+
+ def OnNotebookMouseOver(self, event):
+ # wxBug: On Windows XP the tooltips don't automatically disappear when you move the mouse and it is on a notebook tab, has nothing to do with this code!!!
+ index, type = self._notebook.HitTest(event.GetPosition())
+ if index > -1:
+ doc = self._notebook.GetPage(index).GetView().GetDocument()
+ self._notebook.SetToolTip(wx.ToolTip(doc.GetFilename()))
+ else:
+ self._notebook.SetToolTip(wx.ToolTip(""))
+ event.Skip()
+
+
+ def OnNotebookRightClick(self, event):
+ """
+ Handles right clicks for the notebook, enabling users to either close
+ a tab or select from the available documents if the user clicks on the
+ notebook's white space.
+ """
+ index, type = self._notebook.HitTest(event.GetPosition())
+ menu = wx.Menu()
+ x, y = event.GetX(), event.GetY()
+ if index > -1:
+ doc = self._notebook.GetPage(index).GetView().GetDocument()
+ id = wx.NewId()
+ menu.Append(id, _("Close"))
+ def OnRightMenuSelect(event):
+ doc.DeleteAllViews()
+ wx.EVT_MENU(self, id, OnRightMenuSelect)
+ if self._notebook.GetPageCount() > 1:
+ id = wx.NewId()
+ menu.Append(id, _("Close All but \"%s\"" % doc.GetPrintableName()))
+ def OnRightMenuSelect(event):
+ for i in range(self._notebook.GetPageCount()-1, -1, -1): # Go from len-1 to 0
+ if i != index:
+ doc = self._notebook.GetPage(i).GetView().GetDocument()
+ if not self.GetDocumentManager().CloseDocument(doc, False):
+ return
+ wx.EVT_MENU(self, id, OnRightMenuSelect)
+ menu.AppendSeparator()
+ tabsMenu = wx.Menu()
+ menu.AppendMenu(wx.NewId(), _("Select Tab"), tabsMenu)
+ else:
+ y = y - 25 # wxBug: It is offsetting click events in the blank notebook area
+ tabsMenu = menu
+
+ if self._notebook.GetPageCount() > 1:
+ selectIDs = {}
+ for i in range(0, self._notebook.GetPageCount()):
+ id = wx.NewId()
+ selectIDs[id] = i
+ tabsMenu.Append(id, self._notebook.GetPageText(i))
+ def OnRightMenuSelect(event):
+ self._notebook.SetSelection(selectIDs[event.GetId()])
+ wx.EVT_MENU(self, id, OnRightMenuSelect)
+
+ self._notebook.PopupMenu(menu, wx.Point(x, y))
+ menu.Destroy()
+
+
+ def AddNotebookPage(self, panel, title):
+ """
+ Adds a document page to the notebook.
+ """
+ self._notebook.AddPage(panel, title)
+ index = self._notebook.GetPageCount() - 1
+ self._notebook.SetSelection(index)
+
+ found = False # Now set the icon
+ template = panel.GetDocument().GetDocumentTemplate()
+ if template:
+ for t, iconIndex in self._iconIndexLookup:
+ if t is template:
+ self._notebook.SetPageImage(index, iconIndex)
+ found = True
+ break
+ if not found:
+ self._notebook.SetPageImage(index, self._blankIconIndex)
+ self._notebook.Layout()
+
+
+ def RemoveNotebookPage(self, panel):
+ """
+ Removes a document page from the notebook.
+ """
+ index = self.GetNotebookPageIndex(panel)
+ if index > -1:
+ self._notebook.DeletePage(index)
+
+
+ def ActivateNotebookPage(self, panel):
+ """
+ Sets the notebook to the specified panel.
+ """
+ index = self.GetNotebookPageIndex(panel)
+ if index > -1:
+ self._notebook.SetFocus()
+ self._notebook.SetSelection(index)
+
+
+ def GetNotebookPageTitle(self, panel):
+ self._notebook.GetPageText(self.GetNotebookPageIndex(panel))
+
+
+ def SetNotebookPageTitle(self, panel, title):
+ self._notebook.SetPageText(self.GetNotebookPageIndex(panel), title)
+
+
+ def GetNotebookPageIndex(self, panel):
+ """
+ Returns the index of particular notebook panel.
+ """
+ index = -1
+ for i in range(self._notebook.GetPageCount()):
+ if self._notebook.GetPage(i) == panel:
+ index = i
+ break
+ return index
+
+
+ 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.
+ """
+ if wx.GetApp().ProcessEventBeforeWindows(event):
+ return True
+ if self._docManager and self._docManager.ProcessEvent(event):
+ return True
+ return DocMDIParentFrameMixIn.ProcessEvent(self, event)
+
+
+ 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.
+ """
+ if wx.GetApp().ProcessUpdateUIEventBeforeWindows(event):
+ return True
+ if self._docManager and self._docManager.ProcessUpdateUIEvent(event):
+ return True
+ return DocMDIParentFrameMixIn.ProcessUpdateUIEvent(self, event)
+
+
+ def OnExit(self, event):
+ """
+ Called when File/Exit is chosen and closes the window.
+ """
+ self.Close()
+
+
+ def OnMRUFile(self, event):
+ """
+ Opens the appropriate file when it is selected from the file history
+ menu.
+ """
+ n = event.GetId() - wx.ID_FILE1
+ filename = self._docManager.GetHistoryFile(n)
+ if filename:
+ self._docManager.CreateDocument(filename, wx.lib.docview.DOC_SILENT)
+ else:
+ self._docManager.RemoveFileFromHistory(n)
+ msgTitle = wx.GetApp().GetAppName()
+ if not msgTitle:
+ msgTitle = _("File Error")
+ 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),
+ msgTitle,
+ wx.OK | wx.ICON_EXCLAMATION,
+ self)
+
+
+ def OnSize(self, event):
+ """
+ Called when the frame is resized and lays out the client window.
+ """
+ # Needed in case there are splitpanels around the mdi frame
+ self._LayoutFrame()
+
+
+ def OnCloseWindow(self, event):
+ """
+ Called when the frame is closed. Remembers the frame size.
+ """
+ self.SaveEmbeddedWindowSizes()
+
+ # save and close services last
+ for service in wx.GetApp().GetServices():
+ if not service.OnCloseFrame(event):
+ return
+
+ # From docview.MDIParentFrame
+ if self._docManager.Clear(not event.CanVeto()):
+ self.Destroy()
+ else:
+ event.Veto()
+
+
+class DocMDIChildFrame(wx.MDIChildFrame):
+ """
+ The wxDocMDIChildFrame class provides a default frame for displaying
+ documents on separate windows. This class can only be used for MDI child
+ frames.
+
+ The class is part of the document/view framework supported by wxWindows,
+ and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
+ classes.
+ """
+
+
+ def __init__(self, doc, view, frame, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name="frame"):
+ """
+ Constructor. Note that the event table must be rebuilt for the
+ frame since the EvtHandler is not virtual.
+ """
+ wx.MDIChildFrame.__init__(self, frame, id, title, pos, size, style, name)
+ self._childDocument = doc
+ self._childView = view
+ if view:
+ view.SetFrame(self)
+ # self.Create(doc, view, frame, id, title, pos, size, style, name)
+ self._activeEvent = None
+ self._activated = 0
+ wx.EVT_ACTIVATE(self, self.OnActivate)
+ wx.EVT_CLOSE(self, self.OnCloseWindow)
+
+ 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
+ mdiChildren = filter(lambda x: isinstance(x, wx.MDIChildFrame), frame.GetChildren())
+ if len(mdiChildren) == 1:
+ self.Activate()
+
+
+## # Couldn't get this to work, but seems to work fine with single stage construction
+## def Create(self, doc, view, frame, id, title, pos, size, style, name):
+## self._childDocument = doc
+## self._childView = view
+## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
+## if view:
+## view.SetFrame(self)
+## return True
+## return False
+
+
+
+ def Activate(self): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
+ """
+ Activates the current view.
+ """
+ if self._childView:
+ self._childView.Activate(True)
+
+
+ def ProcessEvent(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.
+ """
+ if self._activeEvent == event:
+ return False
+
+ self._activeEvent = event # Break recursion loops
+
+ if self._childView:
+ self._childView.Activate(True)
+
+ if not self._childView or not self._childView.ProcessEvent(event):
+ if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
+ ret = False
+ else:
+ ret = True
+ else:
+ ret = True
+
+ self._activeEvent = None
+ return ret
+
+
+ def OnActivate(self, event):
+ """
+ Sets the currently active view to be the frame's view. You may need to
+ override (but still call) this function in order to set the keyboard
+ focus for your subwindow.
+ """
+ if self._activated != 0:
+ return True
+ self._activated += 1
+ wx.MDIChildFrame.Activate(self)
+ if event.GetActive() and self._childView:
+ self._childView.Activate(event.GetActive())
+ self._activated = 0
+
+
+ def OnCloseWindow(self, event):