+
+    #----------------------------------------------------------------------------
+    # DynamicSashWindow methods
+    #----------------------------------------------------------------------------
+
+    def SetupDSScrollBars(self):
+        # hook the scrollbars provided by the wxDynamicSashWindow
+        # to this view
+        v_bar = self._dynSash.GetVScrollBar(self)
+        h_bar = self._dynSash.GetHScrollBar(self)
+        v_bar.Bind(wx.EVT_SCROLL, self.OnDSSBScroll)
+        h_bar.Bind(wx.EVT_SCROLL, self.OnDSSBScroll)
+        v_bar.Bind(wx.EVT_SET_FOCUS, self.OnDSSBFocus)
+        h_bar.Bind(wx.EVT_SET_FOCUS, self.OnDSSBFocus)
+
+        # And set the wxStyledText to use these scrollbars instead
+        # of its built-in ones.
+        self.SetVScrollBar(v_bar)
+        self.SetHScrollBar(h_bar)
+
+
+    def OnDSSplit(self, evt):
+        newCtrl = self._dynSash._view.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
+        newCtrl.SetDocPointer(self.GetDocPointer())     # use the same document
+        self.SetupDSScrollBars()
+        if self == self._dynSash._view.GetCtrl():  # originally had focus
+            wx.CallAfter(self.SetFocus)  # do this to set colors correctly.  wxBug:  for some reason, if we don't do a CallAfter, it immediately calls OnKillFocus right after our SetFocus.
+
+
+    def OnDSUnify(self, evt):
+        self.SetupDSScrollBars()
+        self.SetFocus()  # do this to set colors correctly
+
+
+    def OnDSSBScroll(self, evt):
+        # redirect the scroll events from the _dynSash's scrollbars to the STC
+        self.GetEventHandler().ProcessEvent(evt)
+
+
+    def OnDSSBFocus(self, evt):
+        # when the scrollbar gets the focus move it back to the STC
+        self.SetFocus()
+
+
+    def DSProcessEvent(self, event):
+        # wxHack: Needed for customized right mouse click menu items.        
+        if hasattr(self, "_dynSash"):
+            if event.GetId() == wx.ID_SELECTALL:
+                # force focus so that select all occurs in the window user right clicked on.
+                self.SetFocus()
+
+            return self._dynSash._view.ProcessEvent(event)
+        return False
+
+
+    def DSProcessUpdateUIEvent(self, event):
+        # wxHack: Needed for customized right mouse click menu items.        
+        if hasattr(self, "_dynSash"):
+            id = event.GetId()
+            if (id == wx.ID_SELECTALL  # allow select all even in non-active window, then force focus to it, see above ProcessEvent
+            or id == wx.ID_UNDO
+            or id == wx.ID_REDO):
+                pass  # allow these actions even in non-active window
+            else:  # disallow events in non-active windows.  Cut/Copy/Paste/Delete is too confusing user experience.
+                if self._dynSash._view.GetCtrl() != self:
+                     event.Enable(False)
+                     return True
+
+            return self._dynSash._view.ProcessUpdateUIEvent(event)
+        return False
+
+
+class TextPrintout(wx.lib.docview.DocPrintout):
+    """ for Print Preview and Print """
+    
+
+    def OnPreparePrinting(self):
+        """ initialization """
+        dc = self.GetDC()
+
+        ppiScreenX, ppiScreenY = self.GetPPIScreen()
+        ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
+        scaleX = float(ppiPrinterX)/ppiScreenX
+        scaleY = float(ppiPrinterY)/ppiScreenY
+
+        pageWidth, pageHeight = self.GetPageSizePixels()
+        self._scaleFactorX = scaleX/pageWidth
+        self._scaleFactorY = scaleY/pageHeight
+
+        w, h = dc.GetSize()
+        overallScaleX = self._scaleFactorX * w
+        overallScaleY = self._scaleFactorY * h
+        
+        txtCtrl = self._printoutView.GetCtrl()
+        font, color = txtCtrl.GetFontAndColorFromConfig()
+
+        self._margin = 40
+        self._fontHeight = font.GetPointSize() + 1
+        self._pageLines = int((h/overallScaleY - (2 * self._margin))/self._fontHeight)
+        self._maxLines = txtCtrl.GetLineCount()
+        self._numPages, remainder = divmod(self._maxLines, self._pageLines)
+        if remainder != 0:
+            self._numPages += 1
+
+        spaces = 1
+        lineNum = self._maxLines
+        while lineNum >= 10:
+            lineNum = lineNum/10
+            spaces += 1
+        self._printFormat = "%%0%sd: %%s" % spaces
+
+
+    def OnPrintPage(self, page):
+        """ Prints the given page of the view """
+        dc = self.GetDC()
+        
+        txtCtrl = self._printoutView.GetCtrl()
+        font, color = txtCtrl.GetFontAndColorFromConfig()
+        dc.SetFont(font)
+        
+        w, h = dc.GetSize()
+        dc.SetUserScale(self._scaleFactorX * w, self._scaleFactorY * h)
+        
+        dc.BeginDrawing()
+        
+        dc.DrawText("%s - page %s" % (self.GetTitle(), page), self._margin, self._margin/2)
+
+        startY = self._margin
+        startLine = (page - 1) * self._pageLines
+        endLine = min((startLine + self._pageLines), self._maxLines)
+        for i in range(startLine, endLine):
+            text = txtCtrl.GetLine(i).rstrip()
+            startY += self._fontHeight
+            if txtCtrl.GetViewLineNumbers():
+                dc.DrawText(self._printFormat % (i+1, text), self._margin, startY)
+            else:
+                dc.DrawText(text, self._margin, startY)
+                
+        dc.EndDrawing()
+
+        return True
+
+
+    def HasPage(self, pageNum):
+        return pageNum <= self._numPages
+
+
+    def GetPageInfo(self):
+        minPage = 1
+        maxPage = self._numPages
+        selPageFrom = 1
+        selPageTo = self._numPages
+        return (minPage, maxPage, selPageFrom, selPageTo)
+