eric6/QScintilla/QsciScintillaCompat.py

changeset 6942
2602857055c5
parent 6932
8a3df4c6ac9a
child 6948
c6e580fd9bb1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric6/QScintilla/QsciScintillaCompat.py	Sun Apr 14 15:09:21 2019 +0200
@@ -0,0 +1,1849 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2004 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a compatability interface class to QsciScintilla.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import pyqtSignal, Qt, QPoint
+from PyQt5.QtGui import QPalette, QColor, QFontMetrics
+from PyQt5.QtWidgets import QApplication, QListWidget
+from PyQt5.Qsci import QsciScintillaBase, QsciScintilla, \
+    QSCINTILLA_VERSION as QSCIQSCINTILLA_VERSION
+
+###############################################################################
+
+
+def QSCINTILLA_VERSION():
+    """
+    Module function to return the QScintilla version.
+    
+    @return QScintilla version (integer)
+    """
+    return QSCIQSCINTILLA_VERSION
+    
+###############################################################################
+
+
+class QsciScintillaCompat(QsciScintilla):
+    """
+    Class implementing a compatability interface to QsciScintilla.
+    
+    This class implements all the functions, that were added to
+    QsciScintilla incrementally. This class ensures compatibility
+    to older versions of QsciScintilla.
+    
+    @signal zoomValueChanged(int) emitted to signal a change of the zoom value
+    """
+    zoomValueChanged = pyqtSignal(int)
+    
+    ArrowFoldStyle = QsciScintilla.BoxedTreeFoldStyle + 1
+    ArrowTreeFoldStyle = ArrowFoldStyle + 1
+    
+    UserSeparator = '\x04'
+    
+    if QSCINTILLA_VERSION() < 0x020600:
+        IndicatorStyleMax = QsciScintilla.INDIC_ROUNDBOX
+    elif QSCINTILLA_VERSION() < 0x020700:
+        IndicatorStyleMax = QsciScintilla.INDIC_DOTBOX
+    elif QSCINTILLA_VERSION() < 0x020800:
+        IndicatorStyleMax = QsciScintilla.INDIC_SQUIGGLEPIXMAP
+    elif QSCINTILLA_VERSION() < 0x020900:
+        IndicatorStyleMax = QsciScintilla.INDIC_TEXTFORE
+    elif QSCINTILLA_VERSION() < 0x020A00:
+        IndicatorStyleMax = QsciScintilla.INDIC_POINTCHARACTER
+    else:
+        IndicatorStyleMax = QsciScintilla.INDIC_GRADIENTCENTRE
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent parent widget (QWidget)
+        """
+        super(QsciScintillaCompat, self).__init__(parent)
+        
+        self.zoom = 0
+        
+        self.__targetSearchFlags = 0
+        self.__targetSearchExpr = ""
+        self.__targetSearchStart = 0
+        self.__targetSearchEnd = -1
+        self.__targetSearchActive = False
+        
+        self.__modified = False
+        
+        self.userListActivated.connect(self.__completionListSelected)
+        self.modificationChanged.connect(self.__modificationChanged)
+        
+        self.maxLines = 5
+        self.maxChars = 40
+        # Adjust the min. size of the autocomplete list box for short strings.
+        # Otherwise the width of the list box is at least the standard width.
+        self.SendScintilla(QsciScintilla.SCI_AUTOCSETMAXWIDTH, 5)
+    
+    def __modificationChanged(self, m):
+        """
+        Private slot to handle the modificationChanged signal.
+        
+        @param m modification status (boolean)
+        """
+        self.__modified = m
+    
+    def isModified(self):
+        """
+        Public method to return the modification status.
+        
+        @return flag indicating the modification status (boolean)
+        """
+        return self.__modified
+    
+    def setModified(self, m):
+        """
+        Public slot to set the modification status.
+        
+        @param m new modification status (boolean)
+        """
+        self.__modified = m
+        super(QsciScintillaCompat, self).setModified(m)
+        self.modificationChanged.emit(m)
+    
+    def setLexer(self, lex=None):
+        """
+        Public method to set the lexer.
+        
+        @param lex the lexer to be set or None to reset it.
+        """
+        super(QsciScintillaCompat, self).setLexer(lex)
+        if lex is None:
+            self.clearStyles()
+    
+    def clearStyles(self):
+        """
+        Public method to set the styles according the selected Qt style.
+        """
+        palette = QApplication.palette()
+        self.SendScintilla(QsciScintilla.SCI_STYLESETFORE,
+                           QsciScintilla.STYLE_DEFAULT,
+                           palette.color(QPalette.Text))
+        self.SendScintilla(QsciScintilla.SCI_STYLESETBACK,
+                           QsciScintilla.STYLE_DEFAULT,
+                           palette.color(QPalette.Base))
+        self.SendScintilla(QsciScintilla.SCI_STYLECLEARALL)
+        self.SendScintilla(QsciScintilla.SCI_CLEARDOCUMENTSTYLE)
+    
+    def monospacedStyles(self, font):
+        """
+        Public method to set the current style to be monospaced.
+        
+        @param font font to be used (QFont)
+        """
+        try:
+            rangeLow = list(range(self.STYLE_DEFAULT))
+        except AttributeError:
+            rangeLow = list(range(32))
+        try:
+            rangeHigh = list(range(self.STYLE_LASTPREDEFINED + 1,
+                                   self.STYLE_MAX + 1))
+        except AttributeError:
+            rangeHigh = list(range(40, 128))
+        
+        f = font.family().encode("utf-8")
+        ps = font.pointSize()
+        weight = -font.weight()
+        italic = font.italic()
+        underline = font.underline()
+        bold = font.bold()
+        for style in rangeLow + rangeHigh:
+            self.SendScintilla(QsciScintilla.SCI_STYLESETFONT, style, f)
+            self.SendScintilla(QsciScintilla.SCI_STYLESETSIZE, style, ps)
+            try:
+                self.SendScintilla(
+                    QsciScintilla.SCI_STYLESETWEIGHT, style, weight)
+            except AttributeError:
+                self.SendScintilla(QsciScintilla.SCI_STYLESETBOLD, style, bold)
+            self.SendScintilla(QsciScintilla.SCI_STYLESETITALIC, style, italic)
+            self.SendScintilla(
+                QsciScintilla.SCI_STYLESETUNDERLINE, style, underline)
+    
+    def linesOnScreen(self):
+        """
+        Public method to get the amount of visible lines.
+        
+        @return amount of visible lines (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_LINESONSCREEN)
+    
+    def lineAt(self, pos):
+        """
+        Public method to calculate the line at a position.
+        
+        This variant is able to calculate the line for positions in the
+        margins and for empty lines.
+        
+        @param pos position to calculate the line for (integer or QPoint)
+        @return linenumber at position or -1, if there is no line at pos
+            (integer, zero based)
+        """
+        if isinstance(pos, int):
+            scipos = pos
+        else:
+            scipos = \
+                self.SendScintilla(QsciScintilla.SCI_POSITIONFROMPOINT,
+                                   pos.x(), pos.y())
+        line = self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, scipos)
+        if line >= self.lines():
+            line = -1
+        return line
+    
+    def currentPosition(self):
+        """
+        Public method to get the current position.
+        
+        @return absolute position of the cursor (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
+    
+    def styleAt(self, pos):
+        """
+        Public method to get the style at a position in the text.
+        
+        @param pos position in the text (integer)
+        @return style at the requested position or 0, if the position
+            is negative or past the end of the document (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETSTYLEAT, pos)
+    
+    def currentStyle(self):
+        """
+        Public method to get the style at the current position.
+        
+        @return style at the current position (integer)
+        """
+        return self.styleAt(self.currentPosition())
+    
+    def getEndStyled(self):
+        """
+        Public method to get the last styled position.
+        
+        @return end position of the last styling run (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETENDSTYLED)
+    
+    def startStyling(self, pos, mask):
+        """
+        Public method to prepare styling.
+        
+        @param pos styling positition to start at (integer)
+        @param mask mask of bits to use for styling (integer)
+        """
+        self.SendScintilla(QsciScintilla.SCI_STARTSTYLING, pos, mask)
+    
+    def setStyling(self, length, style):
+        """
+        Public method to style some text.
+        
+        @param length length of text to style (integer)
+        @param style style to set for text (integer)
+        """
+        self.SendScintilla(QsciScintilla.SCI_SETSTYLING, length, style)
+    
+    def charAt(self, pos):
+        """
+        Public method to get the character at a position in the text observing
+        multibyte characters.
+        
+        @param pos position in the text (integer)
+        @return character at the requested position or empty string, if the
+            position is negative or past the end of the document (string)
+        """
+        ch = self.byteAt(pos)
+        if ch and ord(ch) > 127 and self.isUtf8():
+            if (ch[0] & 0xF0) == 0xF0:
+                utf8Len = 4
+            elif (ch[0] & 0xE0) == 0xE0:
+                utf8Len = 3
+            elif (ch[0] & 0xC0) == 0xC0:
+                utf8Len = 2
+            else:
+                utf8Len = 1
+            while len(ch) < utf8Len:
+                pos += 1
+                ch += self.byteAt(pos)
+            try:
+                return ch.decode('utf8')
+            except UnicodeDecodeError:
+                if pos > 0:
+                    # try it one position before; maybe we are in the
+                    # middle of a unicode character
+                    return self.charAt(pos - 1)
+                else:
+                    return ""
+        else:
+            return ch.decode()
+    
+    def byteAt(self, pos):
+        """
+        Public method to get the raw character (bytes) at a position in the
+        text.
+        
+        @param pos position in the text (integer)
+        @return raw character at the requested position or empty bytes, if the
+            position is negative or past the end of the document (bytes)
+        """
+        char = self.SendScintilla(QsciScintilla.SCI_GETCHARAT, pos)
+        if char == 0:
+            return bytearray()
+        if char < 0:
+            char += 256
+        return bytearray((char,))
+    
+    def foldLevelAt(self, line):
+        """
+        Public method to get the fold level of a line of the document.
+        
+        @param line line number (integer)
+        @return fold level of the given line (integer)
+        """
+        lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line)
+        return \
+            (lvl & QsciScintilla.SC_FOLDLEVELNUMBERMASK) - \
+            QsciScintilla.SC_FOLDLEVELBASE
+    
+    def foldFlagsAt(self, line):
+        """
+        Public method to get the fold flags of a line of the document.
+        
+        @param line line number (integer)
+        @return fold flags of the given line (integer)
+        """
+        lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line)
+        return lvl & ~QsciScintilla.SC_FOLDLEVELNUMBERMASK
+    
+    def foldHeaderAt(self, line):
+        """
+        Public method to determine, if a line of the document is a fold header
+        line.
+        
+        @param line line number (integer)
+        @return flag indicating a fold header line (boolean)
+        """
+        lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line)
+        return lvl & QsciScintilla.SC_FOLDLEVELHEADERFLAG
+    
+    def foldExpandedAt(self, line):
+        """
+        Public method to determine, if a fold is expanded.
+        
+        @param line line number (integer)
+        @return flag indicating the fold expansion state of the line (boolean)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETFOLDEXPANDED, line)
+    
+    def setIndentationGuideView(self, view):
+        """
+        Public method to set the view of the indentation guides.
+        
+        @param view view of the indentation guides (SC_IV_NONE, SC_IV_REAL,
+            SC_IV_LOOKFORWARD or SC_IV_LOOKBOTH)
+        """
+        self.SendScintilla(QsciScintilla.SCI_SETINDENTATIONGUIDES, view)
+    
+    def indentationGuideView(self):
+        """
+        Public method to get the indentation guide view.
+        
+        @return indentation guide view (SC_IV_NONE, SC_IV_REAL,
+            SC_IV_LOOKFORWARD or SC_IV_LOOKBOTH)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETINDENTATIONGUIDES)
+    
+    ###########################################################################
+    ## methods below are missing from QScintilla
+    ###########################################################################
+
+    def zoomIn(self, zoom=1):
+        """
+        Public method used to increase the zoom factor.
+        
+        @param zoom zoom factor increment (integer)
+        """
+        super(QsciScintillaCompat, self).zoomIn(zoom)
+    
+    def zoomOut(self, zoom=1):
+        """
+        Public method used to decrease the zoom factor.
+        
+        @param zoom zoom factor decrement (integer)
+        """
+        super(QsciScintillaCompat, self).zoomOut(zoom)
+    
+    def zoomTo(self, zoom):
+        """
+        Public method used to zoom to a specific zoom factor.
+        
+        @param zoom zoom factor (integer)
+        """
+        self.zoom = zoom
+        super(QsciScintillaCompat, self).zoomTo(zoom)
+        self.zoomValueChanged.emit(self.zoom)
+    
+    def getZoom(self):
+        """
+        Public method used to retrieve the current zoom factor.
+        
+        @return zoom factor (integer)
+        """
+        return self.zoom
+    
+    def editorCommand(self, cmd):
+        """
+        Public method to perform a simple editor command.
+        
+        @param cmd the scintilla command to be performed (integer)
+        """
+        self.SendScintilla(cmd)
+    
+    def scrollVertical(self, lines):
+        """
+        Public method to scroll the text area.
+        
+        @param lines number of lines to scroll (negative scrolls up,
+            positive scrolls down) (integer)
+        """
+        self.SendScintilla(QsciScintilla.SCI_LINESCROLL, 0, lines)
+    
+    def moveCursorToEOL(self):
+        """
+        Public method to move the cursor to the end of line.
+        """
+        self.SendScintilla(QsciScintilla.SCI_LINEEND)
+    
+    def moveCursorLeft(self):
+        """
+        Public method to move the cursor left.
+        """
+        self.SendScintilla(QsciScintilla.SCI_CHARLEFT)
+    
+    def moveCursorRight(self):
+        """
+        Public method to move the cursor right.
+        """
+        self.SendScintilla(QsciScintilla.SCI_CHARRIGHT)
+    
+    def moveCursorWordLeft(self):
+        """
+        Public method to move the cursor left one word.
+        """
+        self.SendScintilla(QsciScintilla.SCI_WORDLEFT)
+    
+    def moveCursorWordRight(self):
+        """
+        Public method to move the cursor right one word.
+        """
+        self.SendScintilla(QsciScintilla.SCI_WORDRIGHT)
+    
+    def newLineBelow(self):
+        """
+        Public method to insert a new line below the current one.
+        """
+        self.SendScintilla(QsciScintilla.SCI_LINEEND)
+        self.SendScintilla(QsciScintilla.SCI_NEWLINE)
+    
+    def deleteBack(self):
+        """
+        Public method to delete the character to the left of the cursor.
+        """
+        self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
+    
+    def delete(self):
+        """
+        Public method to delete the character to the right of the cursor.
+        """
+        self.SendScintilla(QsciScintilla.SCI_CLEAR)
+    
+    def deleteWordLeft(self):
+        """
+        Public method to delete the word to the left of the cursor.
+        """
+        self.SendScintilla(QsciScintilla.SCI_DELWORDLEFT)
+    
+    def deleteWordRight(self):
+        """
+        Public method to delete the word to the right of the cursor.
+        """
+        self.SendScintilla(QsciScintilla.SCI_DELWORDRIGHT)
+    
+    def deleteLineLeft(self):
+        """
+        Public method to delete the line to the left of the cursor.
+        """
+        self.SendScintilla(QsciScintilla.SCI_DELLINELEFT)
+    
+    def deleteLineRight(self):
+        """
+        Public method to delete the line to the right of the cursor.
+        """
+        self.SendScintilla(QsciScintilla.SCI_DELLINERIGHT)
+    
+    def extendSelectionLeft(self):
+        """
+        Public method to extend the selection one character to the left.
+        """
+        self.SendScintilla(QsciScintilla.SCI_CHARLEFTEXTEND)
+    
+    def extendSelectionRight(self):
+        """
+        Public method to extend the selection one character to the right.
+        """
+        self.SendScintilla(QsciScintilla.SCI_CHARRIGHTEXTEND)
+    
+    def extendSelectionWordLeft(self):
+        """
+        Public method to extend the selection one word to the left.
+        """
+        self.SendScintilla(QsciScintilla.SCI_WORDLEFTEXTEND)
+    
+    def extendSelectionWordRight(self):
+        """
+        Public method to extend the selection one word to the right.
+        """
+        self.SendScintilla(QsciScintilla.SCI_WORDRIGHTEXTEND)
+    
+    def extendSelectionToBOL(self):
+        """
+        Public method to extend the selection to the beginning of the line.
+        """
+        self.SendScintilla(QsciScintilla.SCI_VCHOMEEXTEND)
+    
+    def extendSelectionToEOL(self):
+        """
+        Public method to extend the selection to the end of the line.
+        """
+        self.SendScintilla(QsciScintilla.SCI_LINEENDEXTEND)
+    
+    def hasSelection(self):
+        """
+        Public method to check for a selection.
+        
+        @return flag indicating the presence of a selection (boolean)
+        """
+        return self.getSelection()[0] != -1
+    
+    def hasSelectedText(self):
+        """
+        Public method to indicate the presence of selected text.
+        
+        This is an overriding method to cope with a bug in QsciScintilla.
+        
+        @return flag indicating the presence of selected text (boolean)
+        """
+        return bool(self.selectedText())
+    
+    def selectionIsRectangle(self):
+        """
+        Public method to check, if the current selection is rectangular.
+        
+        @return flag indicating a rectangular selection (boolean)
+        """
+        startLine, startIndex, endLine, endIndex = self.getSelection()
+        return startLine != -1 and \
+            startLine != endLine and \
+            self.SendScintilla(QsciScintilla.SCI_SELECTIONISRECTANGLE)
+    
+    def getRectangularSelection(self):
+        """
+        Public method to retrieve the start and end of a rectangular selection.
+        
+        @return tuple with start line and index and end line and index
+            (tuple of four int)
+        """
+        if not self.selectionIsRectangle():
+            return (-1, -1, -1, -1)
+        
+        startPos = self.SendScintilla(
+            QsciScintilla.SCI_GETRECTANGULARSELECTIONANCHOR)
+        endPos = self.SendScintilla(
+            QsciScintilla.SCI_GETRECTANGULARSELECTIONCARET)
+        startLine, startIndex = self.lineIndexFromPosition(startPos)
+        endLine, endIndex = self.lineIndexFromPosition(endPos)
+        
+        return (startLine, startIndex, endLine, endIndex)
+    
+    def setRectangularSelection(self, startLine, startIndex, endLine,
+                                endIndex):
+        """
+        Public method to set a rectangular selection.
+        
+        @param startLine line number of the start of the selection (int)
+        @param startIndex index number of the start of the selection (int)
+        @param endLine line number of the end of the selection (int)
+        @param endIndex index number of the end of the selection (int)
+        """
+        startPos = self.positionFromLineIndex(startLine, startIndex)
+        endPos = self.positionFromLineIndex(endLine, endIndex)
+        
+        self.SendScintilla(
+            QsciScintilla.SCI_SETRECTANGULARSELECTIONANCHOR, startPos)
+        self.SendScintilla(
+            QsciScintilla.SCI_SETRECTANGULARSELECTIONCARET, endPos)
+    
+    def getSelectionCount(self):
+        """
+        Public method to get the number of active selections.
+        
+        @return number of active selection (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETSELECTIONS)
+    
+    def getSelectionN(self, index):
+        """
+        Public method to get the start and end of a selection given by its
+        index.
+        
+        @param index index of the selection (integer)
+        @return tuple with start line and index and end line and index
+            (tuple of four int) for the given selection
+        """
+        startPos = self.SendScintilla(
+            QsciScintilla.SCI_GETSELECTIONNSTART, index)
+        endPos = self.SendScintilla(QsciScintilla.SCI_GETSELECTIONNEND, index)
+        startLine, startIndex = self.lineIndexFromPosition(startPos)
+        endLine, endIndex = self.lineIndexFromPosition(endPos)
+        
+        return (startLine, startIndex, endLine, endIndex)
+    
+    def getSelections(self):
+        """
+        Public method to get the start and end coordinates of all active
+        selections.
+        
+        @return list of tuples with start line and index and end line and index
+            of each active selection (list of tuples of four int)
+        """
+        selections = []
+        for index in range(self.getSelectionCount()):
+            selections.append(self.getSelectionN(index))
+        return selections
+    
+    def setVirtualSpaceOptions(self, options):
+        """
+        Public method to set the virtual space usage options.
+        
+        @param options usage options to set (integer, 0 to 3)
+        """
+        self.SendScintilla(QsciScintilla.SCI_SETVIRTUALSPACEOPTIONS, options)
+    
+    def getLineSeparator(self):
+        """
+        Public method to get the line separator for the current eol mode.
+        
+        @return eol string (string)
+        """
+        m = self.eolMode()
+        if m == QsciScintilla.EolWindows:
+            eol = '\r\n'
+        elif m == QsciScintilla.EolUnix:
+            eol = '\n'
+        elif m == QsciScintilla.EolMac:
+            eol = '\r'
+        else:
+            eol = ''
+        return eol
+    
+    def getEolIndicator(self):
+        """
+        Public method to get the eol indicator for the current eol mode.
+        
+        @return eol indicator (string)
+        """
+        m = self.eolMode()
+        if m == QsciScintilla.EolWindows:
+            eol = 'CRLF'
+        elif m == QsciScintilla.EolUnix:
+            eol = 'LF'
+        elif m == QsciScintilla.EolMac:
+            eol = 'CR'
+        else:
+            eol = ''
+        return eol
+    
+    def setEolModeByEolString(self, eolStr):
+        """
+        Public method to set the eol mode given the eol string.
+        
+        @param eolStr eol string (string)
+        """
+        if eolStr == '\r\n':
+            self.setEolMode(QsciScintilla.EolMode(QsciScintilla.EolWindows))
+        elif eolStr == '\n':
+            self.setEolMode(QsciScintilla.EolMode(QsciScintilla.EolUnix))
+        elif eolStr == '\r':
+            self.setEolMode(QsciScintilla.EolMode(QsciScintilla.EolMac))
+    
+    def detectEolString(self, txt):
+        """
+        Public method to determine the eol string used.
+        
+        @param txt text from which to determine the eol string (string)
+        @return eol string (string)
+        """
+        if len(txt.split("\r\n", 1)) == 2:
+            return '\r\n'
+        elif len(txt.split("\n", 1)) == 2:
+            return '\n'
+        elif len(txt.split("\r", 1)) == 2:
+            return '\r'
+        else:
+            return None
+    
+    def getCursorFlashTime(self):
+        """
+        Public method to get the flash (blink) time of the cursor in
+        milliseconds.
+        
+        The flash time is the time required to display, invert and restore the
+        caret display. Usually the text cursor is displayed for half the cursor
+        flash time, then hidden for the same amount of time.
+        
+        @return flash time of the cursor in milliseconds (integer)
+        """
+        return 2 * self.SendScintilla(QsciScintilla.SCI_GETCARETPERIOD)
+    
+    def setCursorFlashTime(self, time):
+        """
+        Public method to set the flash (blink) time of the cursor in
+        milliseconds.
+        
+        The flash time is the time required to display, invert and restore the
+        caret display. Usually the text cursor is displayed for half the cursor
+        flash time, then hidden for the same amount of time.
+        
+        @param time flash time of the cursor in milliseconds (integer)
+        """
+        self.SendScintilla(QsciScintilla.SCI_SETCARETPERIOD, time // 2)
+    
+    def getCaretLineAlwaysVisible(self):
+        """
+        Public method to determine, if the caret line is visible even if
+        the editor doesn't have the focus.
+        
+        @return flag indicating an always visible caret line (boolean)
+        """
+        try:
+            return self.SendScintilla(
+                QsciScintilla.SCI_GETCARETLINEVISIBLEALWAYS)
+        except AttributeError:
+            return False
+    
+    def setCaretLineAlwaysVisible(self, alwaysVisible):
+        """
+        Public method to set the caret line visible even if the editor doesn't
+        have the focus.
+        
+        @param alwaysVisible flag indicating that the caret line shall be
+            visible even if the editor doesn't have the focus (boolean)
+        """
+        try:
+            self.SendScintilla(
+                QsciScintilla.SCI_SETCARETLINEVISIBLEALWAYS, alwaysVisible)
+        except AttributeError:
+            pass
+    
+    def canPaste(self):
+        """
+        Public method to test, if the paste action is available (i.e. if the
+        clipboard contains some text).
+        
+        @return flag indicating the availability of 'paste'
+        @rtype bool
+        """
+        return self.SendScintilla(QsciScintilla.SCI_CANPASTE)
+    
+    ###########################################################################
+    ## methods to perform searches in target range
+    ###########################################################################
+    
+    def positionFromPoint(self, point):
+        """
+        Public method to calculate the scintilla position from a point in the
+        window.
+        
+        @param point point in the window (QPoint)
+        @return scintilla position (integer) or -1 to indicate, that the point
+            is not near any character
+        """
+        return self.SendScintilla(QsciScintilla.SCI_POSITIONFROMPOINTCLOSE,
+                                  point.x(), point.y())
+    
+    def positionBefore(self, pos):
+        """
+        Public method to get the position before the given position taking into
+        account multibyte characters.
+        
+        @param pos position (integer)
+        @return position before the given one (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_POSITIONBEFORE, pos)
+    
+    def positionAfter(self, pos):
+        """
+        Public method to get the position after the given position taking into
+        account multibyte characters.
+        
+        @param pos position (integer)
+        @return position after the given one (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_POSITIONAFTER, pos)
+    
+    def lineEndPosition(self, line):
+        """
+        Public method to determine the line end position of the given line.
+        
+        @param line line number (integer)
+        @return position of the line end disregarding line end characters
+            (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_GETLINEENDPOSITION, line)
+    
+    def __doSearchTarget(self):
+        """
+        Private method to perform the search in target.
+        
+        @return flag indicating a successful search (boolean)
+        """
+        if self.__targetSearchStart == self.__targetSearchEnd:
+            self.__targetSearchActive = False
+            return False
+        
+        self.SendScintilla(QsciScintilla.SCI_SETTARGETSTART,
+                           self.__targetSearchStart)
+        self.SendScintilla(QsciScintilla.SCI_SETTARGETEND,
+                           self.__targetSearchEnd)
+        self.SendScintilla(QsciScintilla.SCI_SETSEARCHFLAGS,
+                           self.__targetSearchFlags)
+        targetSearchExpr = self._encodeString(self.__targetSearchExpr)
+        pos = self.SendScintilla(QsciScintilla.SCI_SEARCHINTARGET,
+                                 len(targetSearchExpr),
+                                 targetSearchExpr)
+        
+        if pos == -1:
+            self.__targetSearchActive = False
+            return False
+        
+        targend = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND)
+        self.__targetSearchStart = targend
+        
+        return True
+    
+    def getFoundTarget(self):
+        """
+        Public method to get the recently found target.
+        
+        @return found target as a tuple of starting position and target length
+            (integer, integer)
+        """
+        if self.__targetSearchActive:
+            spos = self.SendScintilla(QsciScintilla.SCI_GETTARGETSTART)
+            epos = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND)
+            return (spos, epos - spos)
+        else:
+            return (0, 0)
+    
+    def findFirstTarget(self, expr_, re_, cs_, wo_,
+                        begline=-1, begindex=-1, endline=-1, endindex=-1,
+                        ws_=False, posix=False, cxx11=False):
+        """
+        Public method to search in a specified range of text without
+        setting the selection.
+        
+        @param expr_ search expression
+        @type str
+        @param re_ flag indicating a regular expression
+        @type bool
+        @param cs_ flag indicating a case sensitive search
+        @type bool
+        @param wo_ flag indicating a word only search
+        @type bool
+        @param begline line number to start from (-1 to indicate current
+            position)
+        @type int
+        @param begindex index to start from (-1 to indicate current position)
+        @type int
+        @param endline line number to stop at (-1 to indicate end of document)
+        @type int
+        @param endindex index number to stop at (-1 to indicate end of
+            document)
+        @type int
+        @param ws_ flag indicating a word start search (boolean)
+        @type bool
+        @param posix
+        @type bool
+        @param cxx11
+        @type bool
+        @return flag indicating a successful search
+        @rtype bool
+        """
+        self.__targetSearchFlags = 0
+        if re_:
+            self.__targetSearchFlags |= QsciScintilla.SCFIND_REGEXP
+        if cs_:
+            self.__targetSearchFlags |= QsciScintilla.SCFIND_MATCHCASE
+        if wo_:
+            self.__targetSearchFlags |= QsciScintilla.SCFIND_WHOLEWORD
+        if ws_:
+            self.__targetSearchFlags |= QsciScintilla.SCFIND_WORDSTART
+        if posix:
+            self.__targetSearchFlags |= QsciScintilla.SCFIND_POSIX
+        try:
+            if cxx11:
+                self.__targetSearchFlags |= QsciScintilla.SCFIND_CXX11REGEX
+        except AttributeError:
+            # defined for PyQt >= 2.11.0
+            pass
+        
+        if begline < 0 or begindex < 0:
+            self.__targetSearchStart = self.SendScintilla(
+                QsciScintilla.SCI_GETCURRENTPOS)
+        else:
+            self.__targetSearchStart = self.positionFromLineIndex(
+                begline, begindex)
+        
+        if endline < 0 or endindex < 0:
+            self.__targetSearchEnd = self.SendScintilla(
+                QsciScintilla.SCI_GETTEXTLENGTH)
+        else:
+            self.__targetSearchEnd = self.positionFromLineIndex(
+                endline, endindex)
+        
+        self.__targetSearchExpr = expr_
+        
+        if self.__targetSearchExpr:
+            self.__targetSearchActive = True
+            
+            return self.__doSearchTarget()
+        
+        return False
+    
+    def findNextTarget(self):
+        """
+        Public method to find the next occurrence in the target range.
+        
+        @return flag indicating a successful search (boolean)
+        """
+        if not self.__targetSearchActive:
+            return False
+        
+        return self.__doSearchTarget()
+    
+    def replaceTarget(self, replaceStr):
+        """
+        Public method to replace the string found by the last search in target.
+        
+        @param replaceStr replacement string or regexp (string)
+        """
+        if not self.__targetSearchActive:
+            return
+        
+        if self.__targetSearchFlags & QsciScintilla.SCFIND_REGEXP:
+            cmd = QsciScintilla.SCI_REPLACETARGETRE
+        else:
+            cmd = QsciScintilla.SCI_REPLACETARGET
+        r = self._encodeString(replaceStr)
+        
+        start = self.SendScintilla(QsciScintilla.SCI_GETTARGETSTART)
+        self.SendScintilla(cmd, len(r), r)
+        
+        self.__targetSearchStart = start + len(r)
+    
+    ###########################################################################
+    ## indicator handling methods
+    ###########################################################################
+    
+    def indicatorDefine(self, indicator, style, color):
+        """
+        Public method to define the appearance of an indicator.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @param style style to be used for the indicator
+            (QsciScintilla.INDIC_PLAIN, QsciScintilla.INDIC_SQUIGGLE,
+            QsciScintilla.INDIC_TT, QsciScintilla.INDIC_DIAGONAL,
+            QsciScintilla.INDIC_STRIKE, QsciScintilla.INDIC_HIDDEN,
+            QsciScintilla.INDIC_BOX, QsciScintilla.INDIC_ROUNDBOX,
+            QsciScintilla.INDIC_STRAIGHTBOX, QsciScintilla.INDIC_FULLBOX,
+            QsciScintilla.INDIC_DASH, QsciScintilla.INDIC_DOTS,
+            QsciScintilla.INDIC_SQUIGGLELOW, QsciScintilla.INDIC_DOTBOX,
+            QsciScintilla.INDIC_GRADIENT, QsciScintilla.INDIC_GRADIENTCENTRE,
+            QsciScintilla.INDIC_SQUIGGLEPIXMAP,
+            QsciScintilla.INDIC_COMPOSITIONTHICK,
+            QsciScintilla.INDIC_COMPOSITIONTHIN, QsciScintilla.INDIC_TEXTFORE,
+            QsciScintilla.INDIC_POINT, QsciScintilla.INDIC_POINTCHARACTER
+            depending upon QScintilla version)
+        @param color color to be used by the indicator (QColor)
+        @exception ValueError the indicator or style are not valid
+        """
+        if indicator < QsciScintilla.INDIC_CONTAINER or \
+           indicator > QsciScintilla.INDIC_MAX:
+            raise ValueError("indicator number out of range")
+        
+        if style < QsciScintilla.INDIC_PLAIN or \
+           style > self.IndicatorStyleMax:
+            raise ValueError("style out of range")
+        
+        self.SendScintilla(QsciScintilla.SCI_INDICSETSTYLE, indicator, style)
+        self.SendScintilla(QsciScintilla.SCI_INDICSETFORE, indicator, color)
+        try:
+            self.SendScintilla(QsciScintilla.SCI_INDICSETALPHA, indicator,
+                               color.alpha())
+            if style in (
+                QsciScintilla.INDIC_ROUNDBOX, QsciScintilla.INDIC_STRAIGHTBOX,
+                QsciScintilla.INDIC_DOTBOX, QsciScintilla.INDIC_FULLBOX,
+            ):
+                # set outline alpha less transparent
+                self.SendScintilla(QsciScintilla.SCI_INDICSETOUTLINEALPHA,
+                                   indicator, color.alpha() + 20)
+        except AttributeError:
+            pass
+    
+    def setCurrentIndicator(self, indicator):
+        """
+        Public method to set the current indicator.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @exception ValueError the indicator or style are not valid
+        """
+        if indicator < QsciScintilla.INDIC_CONTAINER or \
+           indicator > QsciScintilla.INDIC_MAX:
+            raise ValueError("indicator number out of range")
+        
+        self.SendScintilla(QsciScintilla.SCI_SETINDICATORCURRENT, indicator)
+    
+    def setIndicatorRange(self, indicator, spos, length):
+        """
+        Public method to set an indicator for the given range.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @param spos position of the indicator start (integer)
+        @param length length of the indicator (integer)
+        """
+        self.setCurrentIndicator(indicator)
+        self.SendScintilla(QsciScintilla.SCI_INDICATORFILLRANGE, spos, length)
+    
+    def setIndicator(self, indicator, sline, sindex, eline, eindex):
+        """
+        Public method to set an indicator for the given range.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @param sline line number of the indicator start (integer)
+        @param sindex index of the indicator start (integer)
+        @param eline line number of the indicator end (integer)
+        @param eindex index of the indicator end (integer)
+        """
+        spos = self.positionFromLineIndex(sline, sindex)
+        epos = self.positionFromLineIndex(eline, eindex)
+        self.setIndicatorRange(indicator, spos, epos - spos)
+    
+    def clearIndicatorRange(self, indicator, spos, length):
+        """
+        Public method to clear an indicator for the given range.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @param spos position of the indicator start (integer)
+        @param length length of the indicator (integer)
+        """
+        self.setCurrentIndicator(indicator)
+        self.SendScintilla(QsciScintilla.SCI_INDICATORCLEARRANGE, spos, length)
+    
+    def clearIndicator(self, indicator, sline, sindex, eline, eindex):
+        """
+        Public method to clear an indicator for the given range.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @param sline line number of the indicator start (integer)
+        @param sindex index of the indicator start (integer)
+        @param eline line number of the indicator end (integer)
+        @param eindex index of the indicator end (integer)
+        """
+        spos = self.positionFromLineIndex(sline, sindex)
+        epos = self.positionFromLineIndex(eline, eindex)
+        self.clearIndicatorRange(indicator, spos, epos - spos)
+    
+    def clearAllIndicators(self, indicator):
+        """
+        Public method to clear all occurrences of an indicator.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        """
+        self.clearIndicatorRange(indicator, 0, self.length())
+    
+    def hasIndicator(self, indicator, pos):
+        """
+        Public method to test for the existence of an indicator.
+        
+        @param indicator number of the indicator (integer,
+            QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
+        @param pos position to test (integer)
+        @return flag indicating the existence of the indicator (boolean)
+        """
+        res = self.SendScintilla(QsciScintilla.SCI_INDICATORVALUEAT,
+                                 indicator, pos)
+        return res
+    
+    def showFindIndicator(self, sline, sindex, eline, eindex):
+        """
+        Public method to show the find indicator for the given range.
+        
+        @param sline line number of the indicator start (integer)
+        @param sindex index of the indicator start (integer)
+        @param eline line number of the indicator end (integer)
+        @param eindex index of the indicator end (integer)
+        """
+        if hasattr(QsciScintilla, "SCI_FINDINDICATORSHOW"):
+            spos = self.positionFromLineIndex(sline, sindex)
+            epos = self.positionFromLineIndex(eline, eindex)
+            self.SendScintilla(QsciScintilla.SCI_FINDINDICATORSHOW, spos, epos)
+    
+    def flashFindIndicator(self, sline, sindex, eline, eindex):
+        """
+        Public method to flash the find indicator for the given range.
+        
+        @param sline line number of the indicator start (integer)
+        @param sindex index of the indicator start (integer)
+        @param eline line number of the indicator end (integer)
+        @param eindex index of the indicator end (integer)
+        """
+        if hasattr(QsciScintilla, "SCI_FINDINDICATORFLASH"):
+            spos = self.positionFromLineIndex(sline, sindex)
+            epos = self.positionFromLineIndex(eline, eindex)
+            self.SendScintilla(QsciScintilla.SCI_FINDINDICATORFLASH,
+                               spos, epos)
+    
+    def hideFindIndicator(self):
+        """
+        Public method to hide the find indicator.
+        """
+        if hasattr(QsciScintilla, "SCI_FINDINDICATORHIDE"):
+            self.SendScintilla(QsciScintilla.SCI_FINDINDICATORHIDE)
+    
+    def getIndicatorStartPos(self, indicator, pos):
+        """
+        Public method to get the start position of an indicator at a position.
+        
+        @param indicator ID of the indicator (integer)
+        @param pos position within the indicator (integer)
+        @return start position of the indicator (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_INDICATORSTART,
+                                  indicator, pos)
+    
+    def getIndicatorEndPos(self, indicator, pos):
+        """
+        Public method to get the end position of an indicator at a position.
+        
+        @param indicator ID of the indicator (integer)
+        @param pos position within the indicator (integer)
+        @return end position of the indicator (integer)
+        """
+        return self.SendScintilla(QsciScintilla.SCI_INDICATOREND,
+                                  indicator, pos)
+    
+    def gotoPreviousIndicator(self, indicator, wrap):
+        """
+        Public method to move the cursor to the previous position of an
+        indicator.
+        
+        This method ensures, that the position found is visible (i.e. unfolded
+        and inside the visible range). The text containing the indicator is
+        selected.
+        
+        @param indicator ID of the indicator to search (integer)
+        @param wrap flag indicating to wrap around at the beginning of the
+            text (boolean)
+        @return flag indicating if the indicator was found (boolean)
+        """
+        pos = self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
+        docLen = self.SendScintilla(QsciScintilla.SCI_GETTEXTLENGTH)
+        isInIndicator = self.hasIndicator(indicator, pos)
+        posStart = self.getIndicatorStartPos(indicator, pos)
+        posEnd = self.getIndicatorEndPos(indicator, pos)
+        
+        if posStart == 0 and posEnd == docLen - 1:
+            # indicator does not exist
+            return False
+        
+        if posStart <= 0:
+            if not wrap:
+                return False
+            
+            isInIndicator = self.hasIndicator(indicator, docLen - 1)
+            posStart = self.getIndicatorStartPos(indicator, docLen - 1)
+        
+        if isInIndicator:
+            # get out of it
+            posStart = self.getIndicatorStartPos(indicator, posStart - 1)
+            if posStart <= 0:
+                if not wrap:
+                    return False
+                
+                posStart = self.getIndicatorStartPos(indicator, docLen - 1)
+        
+        newPos = posStart - 1
+        posStart = self.getIndicatorStartPos(indicator, newPos)
+        posEnd = self.getIndicatorEndPos(indicator, newPos)
+        
+        if self.hasIndicator(indicator, posStart):
+            # found it
+            line, index = self.lineIndexFromPosition(posEnd)
+            self.ensureLineVisible(line)
+            self.SendScintilla(QsciScintilla.SCI_SETSEL, posEnd, posStart)
+            self.SendScintilla(QsciScintilla.SCI_SCROLLCARET)
+            return True
+        
+        return False
+    
+    def gotoNextIndicator(self, indicator, wrap):
+        """
+        Public method to move the cursor to the next position of an indicator.
+        
+        This method ensures, that the position found is visible (i.e. unfolded
+        and inside the visible range). The text containing the indicator is
+        selected.
+        
+        @param indicator ID of the indicator to search (integer)
+        @param wrap flag indicating to wrap around at the beginning of the
+            text (boolean)
+        @return flag indicating if the indicator was found (boolean)
+        """
+        pos = self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
+        docLen = self.SendScintilla(QsciScintilla.SCI_GETTEXTLENGTH)
+        isInIndicator = self.hasIndicator(indicator, pos)
+        posStart = self.getIndicatorStartPos(indicator, pos)
+        posEnd = self.getIndicatorEndPos(indicator, pos)
+        
+        if posStart == 0 and posEnd == docLen - 1:
+            # indicator does not exist
+            return False
+        
+        if posEnd >= docLen:
+            if not wrap:
+                return False
+            
+            isInIndicator = self.hasIndicator(indicator, 0)
+            posEnd = self.getIndicatorEndPos(indicator, 0)
+        
+        if isInIndicator:
+            # get out of it
+            posEnd = self.getIndicatorEndPos(indicator, posEnd)
+            if posEnd >= docLen:
+                if not wrap:
+                    return False
+                
+                posEnd = self.getIndicatorEndPos(indicator, 0)
+        
+        newPos = posEnd + 1
+        posStart = self.getIndicatorStartPos(indicator, newPos)
+        posEnd = self.getIndicatorEndPos(indicator, newPos)
+        
+        if self.hasIndicator(indicator, posStart):
+            # found it
+            line, index = self.lineIndexFromPosition(posEnd)
+            self.ensureLineVisible(line)
+            self.SendScintilla(QsciScintilla.SCI_SETSEL, posStart, posEnd)
+            self.SendScintilla(QsciScintilla.SCI_SCROLLCARET)
+            return True
+        
+        return False
+    
+    ###########################################################################
+    ## methods to perform folding related stuff
+    ###########################################################################
+    
+    def __setFoldMarker(self, marknr, mark=QsciScintilla.SC_MARK_EMPTY):
+        """
+        Private method to define a fold marker.
+        
+        @param marknr marker number to define (integer)
+        @param mark fold mark symbol to be used (integer)
+        """
+        self.SendScintilla(QsciScintilla.SCI_MARKERDEFINE, marknr, mark)
+        
+        if mark != QsciScintilla.SC_MARK_EMPTY:
+            self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                               marknr, QColor(Qt.white))
+            self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                               marknr, QColor(Qt.black))
+    
+    def setFolding(self, style, margin=2):
+        """
+        Public method to set the folding style and margin.
+        
+        @param style folding style to set (integer)
+        @param margin margin number (integer)
+        """
+        if style < self.ArrowFoldStyle:
+            super(QsciScintillaCompat, self).setFolding(style, margin)
+        else:
+            super(QsciScintillaCompat, self).setFolding(
+                QsciScintilla.PlainFoldStyle, margin)
+            
+            if style == self.ArrowFoldStyle:
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDER,
+                                     QsciScintilla.SC_MARK_ARROW)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPEN,
+                                     QsciScintilla.SC_MARK_ARROWDOWN)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERSUB)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERTAIL)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEREND)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPENMID)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL)
+            elif style == self.ArrowTreeFoldStyle:
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDER,
+                                     QsciScintilla.SC_MARK_ARROW)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPEN,
+                                     QsciScintilla.SC_MARK_ARROWDOWN)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERSUB,
+                                     QsciScintilla.SC_MARK_VLINE)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERTAIL,
+                                     QsciScintilla.SC_MARK_LCORNER)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEREND,
+                                     QsciScintilla.SC_MARK_ARROW)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPENMID,
+                                     QsciScintilla.SC_MARK_ARROWDOWN)
+                self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL,
+                                     QsciScintilla.SC_MARK_TCORNER)
+    
+    def setFoldMarkersColors(self, foreColor, backColor):
+        """
+        Public method to set the foreground and background colors of the
+        fold markers.
+        
+        @param foreColor foreground color (QColor)
+        @param backColor background color (QColor)
+        """
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDER, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDER, backColor)
+        
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDEROPEN, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDEROPEN, backColor)
+        
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDEROPENMID, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDEROPENMID, backColor)
+        
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDERSUB, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDERSUB, backColor)
+        
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDERTAIL, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDERTAIL, backColor)
+        
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL, backColor)
+        
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
+                           QsciScintilla.SC_MARKNUM_FOLDEREND, foreColor)
+        self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
+                           QsciScintilla.SC_MARKNUM_FOLDEREND, backColor)
+    
+    def getVisibleLineFromDocLine(self, docLine):
+        """
+        Public method to convert a document line number to a visible line
+        number (i.e. respect folded lines and annotations).
+        
+        @param docLine document line number to be converted
+        @type int
+        @return visible line number
+        @rtype int
+        """
+        return self.SendScintilla(QsciScintilla.SCI_VISIBLEFROMDOCLINE,
+                                  docLine)
+    
+    def getDocLineFromVisibleLine(self, displayLine):
+        """
+        Public method to convert a visible line number to a document line
+        number (i.e. respect folded lines and annotations).
+        
+        @param displayLine display line number to be converted
+        @type int
+        @return document line number
+        @rtype int
+        """
+        return self.SendScintilla(QsciScintilla.SCI_DOCLINEFROMVISIBLE,
+                                  displayLine)
+    
+    ###########################################################################
+    ## interface methods to the standard keyboard command set
+    ###########################################################################
+    
+    def clearKeys(self):
+        """
+        Public method to clear the key commands.
+        """
+        # call into the QsciCommandSet
+        self.standardCommands().clearKeys()
+        
+    def clearAlternateKeys(self):
+        """
+        Public method to clear the alternate key commands.
+        """
+        # call into the QsciCommandSet
+        self.standardCommands().clearAlternateKeys()
+
+    ###########################################################################
+    ## specialized event handlers
+    ###########################################################################
+    
+    def focusOutEvent(self, event):
+        """
+        Protected method called when the editor loses focus.
+        
+        @param event event object (QFocusEvent)
+        """
+        if self.isListActive():
+            if event.reason() == Qt.ActiveWindowFocusReason:
+                aw = QApplication.activeWindow()
+                if aw is None or aw.parent() is not self:
+                    self.cancelList()
+            else:
+                self.cancelList()
+        
+        if self.isCallTipActive():
+            if event.reason() == Qt.ActiveWindowFocusReason:
+                aw = QApplication.activeWindow()
+                if aw is None or aw.parent() is not self:
+                    self.SendScintilla(QsciScintilla.SCI_CALLTIPCANCEL)
+            else:
+                self.SendScintilla(QsciScintilla.SCI_CALLTIPCANCEL)
+        
+        super(QsciScintillaCompat, self).focusOutEvent(event)
+    
+    def event(self, evt):
+        """
+        Public method to handle events.
+        
+        Note: We are not interested in the standard QsciScintilla event
+        handling because we do it ourselves.
+        
+        @param evt event object to handle (QEvent)
+        @return result of the event handling (boolean)
+        """
+        return QsciScintillaBase.event(self, evt)
+    
+    if "inputMethodEvent" in QsciScintillaBase.__dict__ and \
+            QSCINTILLA_VERSION() < 0x020801:
+        def inputMethodEvent(self, evt):
+            """
+            Protected method to cope with a glitch in some Qscintilla versions
+            handling input events.
+            
+            Note: This simply disables the Qscintilla behavior.
+            
+            @param evt reference to the input method event object
+                (QInputMethodEvent)
+            """
+            pass
+        
+        def inputMethodQuery(self, query):
+            """
+            Public method to cope with a glitch in some Qscintilla versions
+            handling input events.
+            
+            Note: This simply disables the Qscintilla behavior.
+            
+            @param query reference to the input method query object
+                (Qt.InputMethodQuery)
+            @return object containing the requested information
+            """
+            return None     # __IGNORE_WARNING_M831__
+
+    ###########################################################################
+    ## interface methods to the mini editor
+    ###########################################################################
+
+    def getFileName(self):
+        """
+        Public method to return the name of the file being displayed.
+        
+        @return filename of the displayed file (string)
+        """
+        p = self.parent()
+        if p is None:
+            return ""
+        else:
+            try:
+                return p.getFileName()
+            except AttributeError:
+                return ""
+    
+    ###########################################################################
+    ## replacements for buggy methods
+    ###########################################################################
+    
+    def showUserList(self, listId, lst):
+        """
+        Public method to show a user supplied list.
+        
+        @param listId id of the list (integer)
+        @param lst list to be show (list of strings)
+        """
+        if listId <= 0:
+            return
+        
+        # Setup seperator for user lists
+        self.SendScintilla(
+            QsciScintilla.SCI_AUTOCSETSEPARATOR, ord(self.UserSeparator))
+        self.SendScintilla(
+            QsciScintilla.SCI_USERLISTSHOW, listId,
+            self._encodeString(self.UserSeparator.join(lst)))
+        
+        self.updateUserListSize()
+    
+    def autoCompleteFromDocument(self):
+        """
+        Public method to resize list box after creation.
+        """
+        super(QsciScintillaCompat, self).autoCompleteFromDocument()
+        self.updateUserListSize()
+    
+    def autoCompleteFromAPIs(self):
+        """
+        Public method to resize list box after creation.
+        """
+        super(QsciScintillaCompat, self).autoCompleteFromAPIs()
+        self.updateUserListSize()
+    
+    def autoCompleteFromAll(self):
+        """
+        Public method to resize list box after creation.
+        """
+        super(QsciScintillaCompat, self).autoCompleteFromAll()
+        self.updateUserListSize()
+    
+    ###########################################################################
+    ## work-arounds for buggy behavior
+    ###########################################################################
+    
+    def updateUserListSize(self):
+        """
+        Public method to resize the completion list to fit with contents.
+        """
+        children = self.findChildren(QListWidget)
+        if children:
+            userListWidget = children[-1]
+            geom = userListWidget.geometry()
+            
+            baseHeight = geom.height()
+            
+            # Workaround for getting all items instead of
+            # userListWidget.items() call with unknown mime types.
+            all_items = userListWidget.findItems('', Qt.MatchStartsWith)
+            if not all_items:
+                return
+            
+            width = 0
+            maxItemHeight = 0
+            for item in all_items:
+                visualRect = userListWidget.visualItemRect(item)
+                itemWidth = visualRect.width()
+                if itemWidth > width:
+                    width = itemWidth
+                itemHeight = visualRect.height()
+                if itemHeight > maxItemHeight:
+                    maxItemHeight = itemHeight
+            
+            height = min(self.maxLines, len(all_items)) * maxItemHeight
+            # Just a fiddling factor: 2 for better readability,
+            # e.g. underscores at the end of the list.
+            height += 2
+            
+            # Borders
+            borders = geom.size() - userListWidget.contentsRect().size()
+            width += borders.width()
+            height += borders.height()
+            
+            font = userListWidget.font()
+            fm = QFontMetrics(font)
+            averageCharWidth = fm.averageCharWidth()
+            maxWidth = averageCharWidth * self.maxChars
+            if width > maxWidth:
+                width = maxWidth
+                height += userListWidget.horizontalScrollBar().sizeHint()\
+                    .height()
+                # List box doesn't honor limited size to show scroll bars, e.g.
+                # Python 2 on Win 10. So just force it.
+                userListWidget.setHorizontalScrollBarPolicy(
+                    Qt.ScrollBarAlwaysOn)
+            
+            if len(all_items) > self.maxLines:
+                width += userListWidget.verticalScrollBar().sizeHint().width()
+            
+            # Special case, where the space below current line where to less
+            yPos = geom.y()
+            charPos = self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
+            currentYPos = self.SendScintilla(
+                QsciScintilla.SCI_POINTYFROMPOSITION, 0, charPos)
+            
+            # X position doesn't matter: set to 0
+            globalPos = self.mapToGlobal(QPoint(0, currentYPos))
+            if yPos < globalPos.y():
+                deltaHeight = baseHeight - height
+                geom.setY(yPos + deltaHeight - 4)
+            
+            geom.setWidth(width)
+            geom.setHeight(height)
+            userListWidget.setGeometry(geom)
+    
+    def __completionListSelected(self, listId, txt):
+        """
+        Private slot to handle the selection from the completion list.
+        
+        Note: This works around an issue of some window managers taking
+        focus away from the application when clicked inside a completion
+        list but not giving it back when an item is selected via a
+        double-click.
+        
+        @param listId the ID of the user list (integer)
+        @param txt the selected text (string)
+        """
+        self.activateWindow()
+    
+    def updateVerticalScrollBar(self):
+        """
+        Public method to update the vertical scroll bar to reflect the
+        additional lines added by annotations.
+        """
+        # Workaround because Scintilla.Redraw isn't implemented
+        self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 0)
+        self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 1)
+    
+    ###########################################################################
+    ## utility methods
+    ###########################################################################
+    
+    def _encodeString(self, string):
+        """
+        Protected method to encode a string depending on the current mode.
+        
+        @param string string to be encoded (str)
+        @return encoded string (bytes)
+        """
+        if isinstance(string, bytes):
+            return string
+        else:
+            if self.isUtf8():
+                return string.encode("utf-8")
+            else:
+                return string.encode("latin-1")
+    
+    ###########################################################################
+    ## methods to implement workarounds for broken things
+    ###########################################################################
+    
+    if QSCINTILLA_VERSION() == 0x020B00:
+        def insert(self, txt):
+            """
+            Public method to insert text at the cursor position.
+            
+            @param txt text to be inserted
+            @type str
+            """
+            line, col = self.getCursorPosition()
+            self.insertAt(txt, line, col)
+    
+    ###########################################################################
+    ## methods below have been added to QScintilla starting with version 2.5
+    ###########################################################################
+    
+    if "positionFromLineIndex" not in QsciScintilla.__dict__:
+        def positionFromLineIndex(self, line, index):
+            """
+            Public method to convert line and index to an absolute position.
+            
+            @param line line number (integer)
+            @param index index number (integer)
+            @return absolute position in the editor (integer)
+            """
+            pos = self.SendScintilla(QsciScintilla.SCI_POSITIONFROMLINE, line)
+            
+            # Allow for multi-byte characters
+            for _ in range(index):
+                pos = self.positionAfter(pos)
+            
+            return pos
+    
+    elif QSCINTILLA_VERSION() >= 0x020700:
+        def positionFromLineIndex(self, line, index):
+            """
+            Public method to convert line and index to an absolute position.
+            
+            @param line line number (integer)
+            @param index index number (integer)
+            @return absolute position in the editor (integer)
+            """
+            pos = self.SendScintilla(QsciScintilla.SCI_POSITIONFROMLINE, line)
+            return pos + index
+    
+    if "lineIndexFromPosition" not in QsciScintilla.__dict__:
+        def lineIndexFromPosition(self, pos):
+            """
+            Public method to convert an absolute position to line and index.
+            
+            @param pos absolute position in the editor (integer)
+            @return tuple of line number (integer) and index number (integer)
+            """
+            lin = self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, pos)
+            linpos = self.SendScintilla(
+                QsciScintilla.SCI_POSITIONFROMLINE, lin)
+            indx = 0
+            
+            # Allow for multi-byte characters.
+            while linpos < pos:
+                new_linpos = self.positionAfter(linpos)
+                
+                # If the position hasn't moved then we must be at the end of
+                # the text (which implies that the position passed was beyond
+                # the end of the text).
+                if new_linpos == linpos:
+                    break
+                
+                linpos = new_linpos
+                indx += 1
+            
+            return lin, indx
+    
+    elif QSCINTILLA_VERSION() >= 0x020700:
+        def lineIndexFromPosition(self, pos):
+            """
+            Public method to convert an absolute position to line and index.
+            
+            @param pos absolute position in the editor (integer)
+            @return tuple of line number (integer) and index number (integer)
+            """
+            lin = self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, pos)
+            linpos = self.SendScintilla(
+                QsciScintilla.SCI_POSITIONFROMLINE, lin)
+            return lin, pos - linpos
+    
+    if "contractedFolds" not in QsciScintilla.__dict__:
+        def contractedFolds(self):
+            """
+            Public method to get a list of line numbers of collapsed folds.
+            
+            @return list of line numbers of folded lines (list of integer)
+            """
+            line = 0
+            folds = []
+            maxline = self.lines()
+            while line < maxline:
+                if self.foldHeaderAt(line) and not self.foldExpandedAt(line):
+                    folds.append(line)
+                line += 1
+            return folds
+    
+    if "setContractedFolds" not in QsciScintilla.__dict__:
+        def setContractedFolds(self, folds):
+            """
+            Public method to set a list of line numbers of collapsed folds.
+            
+            @param folds list of line numbers of folded lines (list of integer)
+            """
+            for line in folds:
+                self.foldLine(line)
+    
+    #########################################################################
+    ## Method below implements a compatibility variant for the findFirst()
+    ## extended with version 2.11.
+    #########################################################################
+
+    def findFirst(self, expression, regexp, caseSensitive, word, wrap,
+                  forward=True, line=-1, index=-1, show=True, posix=False,
+                  cxx11=False):
+        """
+        Public method to search in the current editor text.
+        
+        @param expression search expression
+        @type str
+        @param regexp flag indicating a regular expression
+        @type bool
+        @param caseSensitive flag indicating a case sensitive search
+        @type bool
+        @param word flag indicating a word only search
+        @type bool
+        @param wrap flag indicating to warp around
+        @type bool
+        @param forward flag indicating the search direction
+        @type bool
+        @param line line to start the search on
+        @type int
+        @param index index to start the search on
+        @type int
+        @param show flag indicating to set the selection to the found
+            expression
+        @type bool
+        @param posix flag indicating the POSIX regular expression search mode
+        @type bool
+        @param cxx11 flag indicating the CXX11 regular expression search mode
+        @type bool
+        @return flag indicating a successful search
+        @rtype bool
+        """
+        if QSCINTILLA_VERSION() >= 0x020B00:
+            return super(QsciScintillaCompat, self).findFirst(
+                expression, regexp, caseSensitive, word, wrap,
+                forward=forward, line=line, index=index, show=show,
+                posix=posix, cxx11=cxx11)
+        else:
+            return super(QsciScintillaCompat, self).findFirst(
+                expression, regexp, caseSensitive, word, wrap,
+                forward=forward, line=line, index=index, show=show,
+                posix=posix)
+    
+    #########################################################################
+    ## Methods below are missing from QScintilla.
+    #########################################################################
+
+    if "setWrapStartIndent" not in QsciScintilla.__dict__:
+        def setWrapStartIndent(self, indent):
+            """
+            Public method to set a the amount of characters wrapped sublines
+            shall be indented.
+            
+            @param indent amount of characters to indent
+            @type int
+            """
+            self.SendScintilla(QsciScintilla.SCI_SETWRAPSTARTINDENT, indent)
+    
+##    #########################################################################
+##    ## Methods below have been added to QScintilla starting with version 2.x.
+##    #########################################################################
+##
+##    if "newMethod" not in QsciScintilla.__dict__:
+##        def newMethod(self, param):
+##            """
+##            Public method to do something.
+##
+##            @param param parameter for method
+##            """
+##            pass
+##

eric ide

mercurial