"Fossies" - the Fresh Open Source Software Archive

Member "eric6-20.9/eric/eric6/QScintilla/QsciScintillaCompat.py" (4 Jul 2020, 67469 Bytes) of package /linux/misc/eric6-20.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "QsciScintillaCompat.py" see the Fossies "Dox" file reference documentation.

    1 # -*- coding: utf-8 -*-
    2 
    3 # Copyright (c) 2004 - 2020 Detlev Offenbach <detlev@die-offenbachs.de>
    4 #
    5 
    6 """
    7 Module implementing a compatability interface class to QsciScintilla.
    8 """
    9 
   10 
   11 from PyQt5.QtCore import pyqtSignal, Qt, QPoint
   12 from PyQt5.QtGui import QPalette, QColor, QFontMetrics
   13 from PyQt5.QtWidgets import QApplication, QListWidget
   14 from PyQt5.Qsci import (
   15     QsciScintillaBase, QsciScintilla,
   16     QSCINTILLA_VERSION as QSCIQSCINTILLA_VERSION
   17 )
   18 
   19 ###############################################################################
   20 
   21 
   22 def QSCINTILLA_VERSION():
   23     """
   24     Module function to return the QScintilla version.
   25     
   26     @return QScintilla version (integer)
   27     """
   28     return QSCIQSCINTILLA_VERSION
   29     
   30 ###############################################################################
   31 
   32 
   33 class QsciScintillaCompat(QsciScintilla):
   34     """
   35     Class implementing a compatability interface to QsciScintilla.
   36     
   37     This class implements all the functions, that were added to
   38     QsciScintilla incrementally. This class ensures compatibility
   39     to older versions of QsciScintilla.
   40     
   41     @signal zoomValueChanged(int) emitted to signal a change of the zoom value
   42     """
   43     zoomValueChanged = pyqtSignal(int)
   44     
   45     ArrowFoldStyle = QsciScintilla.BoxedTreeFoldStyle + 1
   46     ArrowTreeFoldStyle = ArrowFoldStyle + 1
   47     
   48     UserSeparator = '\x04'
   49     
   50     if QSCINTILLA_VERSION() < 0x020A00:
   51         IndicatorStyleMax = QsciScintilla.INDIC_TEXTFORE
   52     elif QSCINTILLA_VERSION() < 0x020B00:
   53         IndicatorStyleMax = QsciScintilla.INDIC_POINTCHARACTER
   54     else:
   55         IndicatorStyleMax = QsciScintilla.INDIC_GRADIENTCENTRE
   56     
   57     def __init__(self, parent=None):
   58         """
   59         Constructor
   60         
   61         @param parent parent widget (QWidget)
   62         """
   63         super(QsciScintillaCompat, self).__init__(parent)
   64         
   65         self.zoom = 0
   66         
   67         self.__targetSearchFlags = 0
   68         self.__targetSearchExpr = ""
   69         self.__targetSearchStart = 0
   70         self.__targetSearchEnd = -1
   71         self.__targetSearchActive = False
   72         
   73         self.__modified = False
   74         
   75         self.userListActivated.connect(self.__completionListSelected)
   76         self.modificationChanged.connect(self.__modificationChanged)
   77         
   78         self.maxLines = 5
   79         self.maxChars = 40
   80         # Adjust the min. size of the autocomplete list box for short strings.
   81         # Otherwise the width of the list box is at least the standard width.
   82         self.SendScintilla(QsciScintilla.SCI_AUTOCSETMAXWIDTH, 5)
   83     
   84     def __modificationChanged(self, m):
   85         """
   86         Private slot to handle the modificationChanged signal.
   87         
   88         @param m modification status (boolean)
   89         """
   90         self.__modified = m
   91     
   92     def isModified(self):
   93         """
   94         Public method to return the modification status.
   95         
   96         @return flag indicating the modification status (boolean)
   97         """
   98         return self.__modified
   99     
  100     def setModified(self, m):
  101         """
  102         Public slot to set the modification status.
  103         
  104         @param m new modification status (boolean)
  105         """
  106         self.__modified = m
  107         super(QsciScintillaCompat, self).setModified(m)
  108         self.modificationChanged.emit(m)
  109     
  110     def setLexer(self, lex=None):
  111         """
  112         Public method to set the lexer.
  113         
  114         @param lex the lexer to be set or None to reset it.
  115         """
  116         super(QsciScintillaCompat, self).setLexer(lex)
  117         if lex is None:
  118             self.clearStyles()
  119     
  120     def clearStyles(self):
  121         """
  122         Public method to set the styles according the selected Qt style.
  123         """
  124         palette = QApplication.palette()
  125         self.SendScintilla(QsciScintilla.SCI_STYLESETFORE,
  126                            QsciScintilla.STYLE_DEFAULT,
  127                            palette.color(QPalette.Text))
  128         self.SendScintilla(QsciScintilla.SCI_STYLESETBACK,
  129                            QsciScintilla.STYLE_DEFAULT,
  130                            palette.color(QPalette.Base))
  131         self.SendScintilla(QsciScintilla.SCI_STYLECLEARALL)
  132         self.SendScintilla(QsciScintilla.SCI_CLEARDOCUMENTSTYLE)
  133     
  134     def monospacedStyles(self, font):
  135         """
  136         Public method to set the current style to be monospaced.
  137         
  138         @param font font to be used (QFont)
  139         """
  140         try:
  141             rangeLow = list(range(self.STYLE_DEFAULT))
  142         except AttributeError:
  143             rangeLow = list(range(32))
  144         try:
  145             rangeHigh = list(range(self.STYLE_LASTPREDEFINED + 1,
  146                                    self.STYLE_MAX + 1))
  147         except AttributeError:
  148             rangeHigh = list(range(40, 128))
  149         
  150         f = font.family().encode("utf-8")
  151         ps = font.pointSize()
  152         weight = -font.weight()
  153         italic = font.italic()
  154         underline = font.underline()
  155         bold = font.bold()
  156         for style in rangeLow + rangeHigh:
  157             self.SendScintilla(QsciScintilla.SCI_STYLESETFONT, style, f)
  158             self.SendScintilla(QsciScintilla.SCI_STYLESETSIZE, style, ps)
  159             try:
  160                 self.SendScintilla(
  161                     QsciScintilla.SCI_STYLESETWEIGHT, style, weight)
  162             except AttributeError:
  163                 self.SendScintilla(QsciScintilla.SCI_STYLESETBOLD, style, bold)
  164             self.SendScintilla(QsciScintilla.SCI_STYLESETITALIC, style, italic)
  165             self.SendScintilla(
  166                 QsciScintilla.SCI_STYLESETUNDERLINE, style, underline)
  167     
  168     def linesOnScreen(self):
  169         """
  170         Public method to get the amount of visible lines.
  171         
  172         @return amount of visible lines (integer)
  173         """
  174         return self.SendScintilla(QsciScintilla.SCI_LINESONSCREEN)
  175     
  176     def lineAt(self, pos):
  177         """
  178         Public method to calculate the line at a position.
  179         
  180         This variant is able to calculate the line for positions in the
  181         margins and for empty lines.
  182         
  183         @param pos position to calculate the line for (integer or QPoint)
  184         @return linenumber at position or -1, if there is no line at pos
  185             (integer, zero based)
  186         """
  187         if isinstance(pos, int):
  188             scipos = pos
  189         else:
  190             scipos = self.SendScintilla(
  191                 QsciScintilla.SCI_POSITIONFROMPOINT,
  192                 pos.x(), pos.y()
  193             )
  194         line = self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, scipos)
  195         if line >= self.lines():
  196             line = -1
  197         return line
  198     
  199     def currentPosition(self):
  200         """
  201         Public method to get the current position.
  202         
  203         @return absolute position of the cursor (integer)
  204         """
  205         return self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
  206     
  207     def styleAt(self, pos):
  208         """
  209         Public method to get the style at a position in the text.
  210         
  211         @param pos position in the text (integer)
  212         @return style at the requested position or 0, if the position
  213             is negative or past the end of the document (integer)
  214         """
  215         return self.SendScintilla(QsciScintilla.SCI_GETSTYLEAT, pos)
  216     
  217     def currentStyle(self):
  218         """
  219         Public method to get the style at the current position.
  220         
  221         @return style at the current position (integer)
  222         """
  223         return self.styleAt(self.currentPosition())
  224     
  225     def getEndStyled(self):
  226         """
  227         Public method to get the last styled position.
  228         
  229         @return end position of the last styling run (integer)
  230         """
  231         return self.SendScintilla(QsciScintilla.SCI_GETENDSTYLED)
  232     
  233     def startStyling(self, pos, mask):
  234         """
  235         Public method to prepare styling.
  236         
  237         @param pos styling positition to start at (integer)
  238         @param mask mask of bits to use for styling (integer)
  239         """
  240         self.SendScintilla(QsciScintilla.SCI_STARTSTYLING, pos, mask)
  241     
  242     def setStyling(self, length, style):
  243         """
  244         Public method to style some text.
  245         
  246         @param length length of text to style (integer)
  247         @param style style to set for text (integer)
  248         """
  249         self.SendScintilla(QsciScintilla.SCI_SETSTYLING, length, style)
  250     
  251     def charAt(self, pos):
  252         """
  253         Public method to get the character at a position in the text observing
  254         multibyte characters.
  255         
  256         @param pos position in the text (integer)
  257         @return character at the requested position or empty string, if the
  258             position is negative or past the end of the document (string)
  259         """
  260         ch = self.byteAt(pos)
  261         if ch and ord(ch) > 127 and self.isUtf8():
  262             if (ch[0] & 0xF0) == 0xF0:
  263                 utf8Len = 4
  264             elif (ch[0] & 0xE0) == 0xE0:
  265                 utf8Len = 3
  266             elif (ch[0] & 0xC0) == 0xC0:
  267                 utf8Len = 2
  268             else:
  269                 utf8Len = 1
  270             while len(ch) < utf8Len:
  271                 pos += 1
  272                 ch += self.byteAt(pos)
  273             try:
  274                 return ch.decode('utf8')
  275             except UnicodeDecodeError:
  276                 if pos > 0:
  277                     # try it one position before; maybe we are in the
  278                     # middle of a unicode character
  279                     return self.charAt(pos - 1)
  280                 else:
  281                     return ""
  282         else:
  283             return ch.decode()
  284     
  285     def byteAt(self, pos):
  286         """
  287         Public method to get the raw character (bytes) at a position in the
  288         text.
  289         
  290         @param pos position in the text (integer)
  291         @return raw character at the requested position or empty bytes, if the
  292             position is negative or past the end of the document (bytes)
  293         """
  294         char = self.SendScintilla(QsciScintilla.SCI_GETCHARAT, pos)
  295         if char == 0:
  296             return bytearray()
  297         if char < 0:
  298             char += 256
  299         return bytearray((char,))
  300     
  301     def foldLevelAt(self, line):
  302         """
  303         Public method to get the fold level of a line of the document.
  304         
  305         @param line line number (integer)
  306         @return fold level of the given line (integer)
  307         """
  308         lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line)
  309         return (
  310             (lvl & QsciScintilla.SC_FOLDLEVELNUMBERMASK) -
  311             QsciScintilla.SC_FOLDLEVELBASE
  312         )
  313     
  314     def foldFlagsAt(self, line):
  315         """
  316         Public method to get the fold flags of a line of the document.
  317         
  318         @param line line number (integer)
  319         @return fold flags of the given line (integer)
  320         """
  321         lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line)
  322         return lvl & ~QsciScintilla.SC_FOLDLEVELNUMBERMASK
  323     
  324     def foldHeaderAt(self, line):
  325         """
  326         Public method to determine, if a line of the document is a fold header
  327         line.
  328         
  329         @param line line number (integer)
  330         @return flag indicating a fold header line (boolean)
  331         """
  332         lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line)
  333         return lvl & QsciScintilla.SC_FOLDLEVELHEADERFLAG
  334     
  335     def foldExpandedAt(self, line):
  336         """
  337         Public method to determine, if a fold is expanded.
  338         
  339         @param line line number (integer)
  340         @return flag indicating the fold expansion state of the line (boolean)
  341         """
  342         return self.SendScintilla(QsciScintilla.SCI_GETFOLDEXPANDED, line)
  343     
  344     def setIndentationGuideView(self, view):
  345         """
  346         Public method to set the view of the indentation guides.
  347         
  348         @param view view of the indentation guides (SC_IV_NONE, SC_IV_REAL,
  349             SC_IV_LOOKFORWARD or SC_IV_LOOKBOTH)
  350         """
  351         self.SendScintilla(QsciScintilla.SCI_SETINDENTATIONGUIDES, view)
  352     
  353     def indentationGuideView(self):
  354         """
  355         Public method to get the indentation guide view.
  356         
  357         @return indentation guide view (SC_IV_NONE, SC_IV_REAL,
  358             SC_IV_LOOKFORWARD or SC_IV_LOOKBOTH)
  359         """
  360         return self.SendScintilla(QsciScintilla.SCI_GETINDENTATIONGUIDES)
  361     
  362     ###########################################################################
  363     ## methods below are missing from QScintilla
  364     ###########################################################################
  365 
  366     def zoomIn(self, zoom=1):
  367         """
  368         Public method used to increase the zoom factor.
  369         
  370         @param zoom zoom factor increment (integer)
  371         """
  372         super(QsciScintillaCompat, self).zoomIn(zoom)
  373     
  374     def zoomOut(self, zoom=1):
  375         """
  376         Public method used to decrease the zoom factor.
  377         
  378         @param zoom zoom factor decrement (integer)
  379         """
  380         super(QsciScintillaCompat, self).zoomOut(zoom)
  381     
  382     def zoomTo(self, zoom):
  383         """
  384         Public method used to zoom to a specific zoom factor.
  385         
  386         @param zoom zoom factor (integer)
  387         """
  388         self.zoom = zoom
  389         super(QsciScintillaCompat, self).zoomTo(zoom)
  390         self.zoomValueChanged.emit(self.zoom)
  391     
  392     def getZoom(self):
  393         """
  394         Public method used to retrieve the current zoom factor.
  395         
  396         @return zoom factor (integer)
  397         """
  398         return self.zoom
  399     
  400     def editorCommand(self, cmd):
  401         """
  402         Public method to perform a simple editor command.
  403         
  404         @param cmd the scintilla command to be performed (integer)
  405         """
  406         self.SendScintilla(cmd)
  407     
  408     def scrollVertical(self, lines):
  409         """
  410         Public method to scroll the text area.
  411         
  412         @param lines number of lines to scroll (negative scrolls up,
  413             positive scrolls down) (integer)
  414         """
  415         self.SendScintilla(QsciScintilla.SCI_LINESCROLL, 0, lines)
  416     
  417     def moveCursorToEOL(self):
  418         """
  419         Public method to move the cursor to the end of line.
  420         """
  421         self.SendScintilla(QsciScintilla.SCI_LINEEND)
  422     
  423     def moveCursorLeft(self):
  424         """
  425         Public method to move the cursor left.
  426         """
  427         self.SendScintilla(QsciScintilla.SCI_CHARLEFT)
  428     
  429     def moveCursorRight(self):
  430         """
  431         Public method to move the cursor right.
  432         """
  433         self.SendScintilla(QsciScintilla.SCI_CHARRIGHT)
  434     
  435     def moveCursorWordLeft(self):
  436         """
  437         Public method to move the cursor left one word.
  438         """
  439         self.SendScintilla(QsciScintilla.SCI_WORDLEFT)
  440     
  441     def moveCursorWordRight(self):
  442         """
  443         Public method to move the cursor right one word.
  444         """
  445         self.SendScintilla(QsciScintilla.SCI_WORDRIGHT)
  446     
  447     def newLineBelow(self):
  448         """
  449         Public method to insert a new line below the current one.
  450         """
  451         self.SendScintilla(QsciScintilla.SCI_LINEEND)
  452         self.SendScintilla(QsciScintilla.SCI_NEWLINE)
  453     
  454     def deleteBack(self):
  455         """
  456         Public method to delete the character to the left of the cursor.
  457         """
  458         self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
  459     
  460     def delete(self):
  461         """
  462         Public method to delete the character to the right of the cursor.
  463         """
  464         self.SendScintilla(QsciScintilla.SCI_CLEAR)
  465     
  466     def deleteWordLeft(self):
  467         """
  468         Public method to delete the word to the left of the cursor.
  469         """
  470         self.SendScintilla(QsciScintilla.SCI_DELWORDLEFT)
  471     
  472     def deleteWordRight(self):
  473         """
  474         Public method to delete the word to the right of the cursor.
  475         """
  476         self.SendScintilla(QsciScintilla.SCI_DELWORDRIGHT)
  477     
  478     def deleteLineLeft(self):
  479         """
  480         Public method to delete the line to the left of the cursor.
  481         """
  482         self.SendScintilla(QsciScintilla.SCI_DELLINELEFT)
  483     
  484     def deleteLineRight(self):
  485         """
  486         Public method to delete the line to the right of the cursor.
  487         """
  488         self.SendScintilla(QsciScintilla.SCI_DELLINERIGHT)
  489     
  490     def extendSelectionLeft(self):
  491         """
  492         Public method to extend the selection one character to the left.
  493         """
  494         self.SendScintilla(QsciScintilla.SCI_CHARLEFTEXTEND)
  495     
  496     def extendSelectionRight(self):
  497         """
  498         Public method to extend the selection one character to the right.
  499         """
  500         self.SendScintilla(QsciScintilla.SCI_CHARRIGHTEXTEND)
  501     
  502     def extendSelectionWordLeft(self):
  503         """
  504         Public method to extend the selection one word to the left.
  505         """
  506         self.SendScintilla(QsciScintilla.SCI_WORDLEFTEXTEND)
  507     
  508     def extendSelectionWordRight(self):
  509         """
  510         Public method to extend the selection one word to the right.
  511         """
  512         self.SendScintilla(QsciScintilla.SCI_WORDRIGHTEXTEND)
  513     
  514     def extendSelectionToBOL(self):
  515         """
  516         Public method to extend the selection to the beginning of the line.
  517         """
  518         self.SendScintilla(QsciScintilla.SCI_VCHOMEEXTEND)
  519     
  520     def extendSelectionToEOL(self):
  521         """
  522         Public method to extend the selection to the end of the line.
  523         """
  524         self.SendScintilla(QsciScintilla.SCI_LINEENDEXTEND)
  525     
  526     def hasSelection(self):
  527         """
  528         Public method to check for a selection.
  529         
  530         @return flag indicating the presence of a selection (boolean)
  531         """
  532         return self.getSelection()[0] != -1
  533     
  534     def hasSelectedText(self):
  535         """
  536         Public method to indicate the presence of selected text.
  537         
  538         This is an overriding method to cope with a bug in QsciScintilla.
  539         
  540         @return flag indicating the presence of selected text (boolean)
  541         """
  542         return bool(self.selectedText())
  543     
  544     def selectionIsRectangle(self):
  545         """
  546         Public method to check, if the current selection is rectangular.
  547         
  548         @return flag indicating a rectangular selection (boolean)
  549         """
  550         startLine, startIndex, endLine, endIndex = self.getSelection()
  551         return (
  552             startLine != -1 and
  553             startLine != endLine and
  554             self.SendScintilla(QsciScintilla.SCI_SELECTIONISRECTANGLE)
  555         )
  556     
  557     def getRectangularSelection(self):
  558         """
  559         Public method to retrieve the start and end of a rectangular selection.
  560         
  561         @return tuple with start line and index and end line and index
  562             (tuple of four int)
  563         """
  564         if not self.selectionIsRectangle():
  565             return (-1, -1, -1, -1)
  566         
  567         startPos = self.SendScintilla(
  568             QsciScintilla.SCI_GETRECTANGULARSELECTIONANCHOR)
  569         endPos = self.SendScintilla(
  570             QsciScintilla.SCI_GETRECTANGULARSELECTIONCARET)
  571         startLine, startIndex = self.lineIndexFromPosition(startPos)
  572         endLine, endIndex = self.lineIndexFromPosition(endPos)
  573         
  574         return (startLine, startIndex, endLine, endIndex)
  575     
  576     def setRectangularSelection(self, startLine, startIndex, endLine,
  577                                 endIndex):
  578         """
  579         Public method to set a rectangular selection.
  580         
  581         @param startLine line number of the start of the selection (int)
  582         @param startIndex index number of the start of the selection (int)
  583         @param endLine line number of the end of the selection (int)
  584         @param endIndex index number of the end of the selection (int)
  585         """
  586         startPos = self.positionFromLineIndex(startLine, startIndex)
  587         endPos = self.positionFromLineIndex(endLine, endIndex)
  588         
  589         self.SendScintilla(
  590             QsciScintilla.SCI_SETRECTANGULARSELECTIONANCHOR, startPos)
  591         self.SendScintilla(
  592             QsciScintilla.SCI_SETRECTANGULARSELECTIONCARET, endPos)
  593     
  594     def getSelectionCount(self):
  595         """
  596         Public method to get the number of active selections.
  597         
  598         @return number of active selection (integer)
  599         """
  600         return self.SendScintilla(QsciScintilla.SCI_GETSELECTIONS)
  601     
  602     def getSelectionN(self, index):
  603         """
  604         Public method to get the start and end of a selection given by its
  605         index.
  606         
  607         @param index index of the selection (integer)
  608         @return tuple with start line and index and end line and index
  609             (tuple of four int) for the given selection
  610         """
  611         startPos = self.SendScintilla(
  612             QsciScintilla.SCI_GETSELECTIONNSTART, index)
  613         endPos = self.SendScintilla(QsciScintilla.SCI_GETSELECTIONNEND, index)
  614         startLine, startIndex = self.lineIndexFromPosition(startPos)
  615         endLine, endIndex = self.lineIndexFromPosition(endPos)
  616         
  617         return (startLine, startIndex, endLine, endIndex)
  618     
  619     def getSelections(self):
  620         """
  621         Public method to get the start and end coordinates of all active
  622         selections.
  623         
  624         @return list of tuples with start line and index and end line and index
  625             of each active selection (list of tuples of four int)
  626         """
  627         selections = []
  628         for index in range(self.getSelectionCount()):
  629             selections.append(self.getSelectionN(index))
  630         return selections
  631     
  632     def setVirtualSpaceOptions(self, options):
  633         """
  634         Public method to set the virtual space usage options.
  635         
  636         @param options usage options to set (integer, 0 to 3)
  637         """
  638         self.SendScintilla(QsciScintilla.SCI_SETVIRTUALSPACEOPTIONS, options)
  639     
  640     def getLineSeparator(self):
  641         """
  642         Public method to get the line separator for the current eol mode.
  643         
  644         @return eol string (string)
  645         """
  646         m = self.eolMode()
  647         if m == QsciScintilla.EolWindows:
  648             eol = '\r\n'
  649         elif m == QsciScintilla.EolUnix:
  650             eol = '\n'
  651         elif m == QsciScintilla.EolMac:
  652             eol = '\r'
  653         else:
  654             eol = ''
  655         return eol
  656     
  657     def getEolIndicator(self):
  658         """
  659         Public method to get the eol indicator for the current eol mode.
  660         
  661         @return eol indicator (string)
  662         """
  663         m = self.eolMode()
  664         if m == QsciScintilla.EolWindows:
  665             eol = 'CRLF'
  666         elif m == QsciScintilla.EolUnix:
  667             eol = 'LF'
  668         elif m == QsciScintilla.EolMac:
  669             eol = 'CR'
  670         else:
  671             eol = ''
  672         return eol
  673     
  674     def setEolModeByEolString(self, eolStr):
  675         """
  676         Public method to set the eol mode given the eol string.
  677         
  678         @param eolStr eol string (string)
  679         """
  680         if eolStr == '\r\n':
  681             self.setEolMode(QsciScintilla.EolMode(QsciScintilla.EolWindows))
  682         elif eolStr == '\n':
  683             self.setEolMode(QsciScintilla.EolMode(QsciScintilla.EolUnix))
  684         elif eolStr == '\r':
  685             self.setEolMode(QsciScintilla.EolMode(QsciScintilla.EolMac))
  686     
  687     def detectEolString(self, txt):
  688         """
  689         Public method to determine the eol string used.
  690         
  691         @param txt text from which to determine the eol string (string)
  692         @return eol string (string)
  693         """
  694         if len(txt.split("\r\n", 1)) == 2:
  695             return '\r\n'
  696         elif len(txt.split("\n", 1)) == 2:
  697             return '\n'
  698         elif len(txt.split("\r", 1)) == 2:
  699             return '\r'
  700         else:
  701             return None
  702     
  703     def getCursorFlashTime(self):
  704         """
  705         Public method to get the flash (blink) time of the cursor in
  706         milliseconds.
  707         
  708         The flash time is the time required to display, invert and restore the
  709         caret display. Usually the text cursor is displayed for half the cursor
  710         flash time, then hidden for the same amount of time.
  711         
  712         @return flash time of the cursor in milliseconds (integer)
  713         """
  714         return 2 * self.SendScintilla(QsciScintilla.SCI_GETCARETPERIOD)
  715     
  716     def setCursorFlashTime(self, time):
  717         """
  718         Public method to set the flash (blink) time of the cursor in
  719         milliseconds.
  720         
  721         The flash time is the time required to display, invert and restore the
  722         caret display. Usually the text cursor is displayed for half the cursor
  723         flash time, then hidden for the same amount of time.
  724         
  725         @param time flash time of the cursor in milliseconds (integer)
  726         """
  727         self.SendScintilla(QsciScintilla.SCI_SETCARETPERIOD, time // 2)
  728     
  729     def getCaretLineAlwaysVisible(self):
  730         """
  731         Public method to determine, if the caret line is visible even if
  732         the editor doesn't have the focus.
  733         
  734         @return flag indicating an always visible caret line (boolean)
  735         """
  736         try:
  737             return self.SendScintilla(
  738                 QsciScintilla.SCI_GETCARETLINEVISIBLEALWAYS)
  739         except AttributeError:
  740             return False
  741     
  742     def setCaretLineAlwaysVisible(self, alwaysVisible):
  743         """
  744         Public method to set the caret line visible even if the editor doesn't
  745         have the focus.
  746         
  747         @param alwaysVisible flag indicating that the caret line shall be
  748             visible even if the editor doesn't have the focus (boolean)
  749         """
  750         try:
  751             self.SendScintilla(
  752                 QsciScintilla.SCI_SETCARETLINEVISIBLEALWAYS, alwaysVisible)
  753         except AttributeError:
  754             pass
  755     
  756     def canPaste(self):
  757         """
  758         Public method to test, if the paste action is available (i.e. if the
  759         clipboard contains some text).
  760         
  761         @return flag indicating the availability of 'paste'
  762         @rtype bool
  763         """
  764         return self.SendScintilla(QsciScintilla.SCI_CANPASTE)
  765     
  766     ###########################################################################
  767     ## methods to perform searches in target range
  768     ###########################################################################
  769     
  770     def positionFromPoint(self, point):
  771         """
  772         Public method to calculate the scintilla position from a point in the
  773         window.
  774         
  775         @param point point in the window (QPoint)
  776         @return scintilla position (integer) or -1 to indicate, that the point
  777             is not near any character
  778         """
  779         return self.SendScintilla(QsciScintilla.SCI_POSITIONFROMPOINTCLOSE,
  780                                   point.x(), point.y())
  781     
  782     def positionBefore(self, pos):
  783         """
  784         Public method to get the position before the given position taking into
  785         account multibyte characters.
  786         
  787         @param pos position (integer)
  788         @return position before the given one (integer)
  789         """
  790         return self.SendScintilla(QsciScintilla.SCI_POSITIONBEFORE, pos)
  791     
  792     def positionAfter(self, pos):
  793         """
  794         Public method to get the position after the given position taking into
  795         account multibyte characters.
  796         
  797         @param pos position (integer)
  798         @return position after the given one (integer)
  799         """
  800         return self.SendScintilla(QsciScintilla.SCI_POSITIONAFTER, pos)
  801     
  802     def lineEndPosition(self, line):
  803         """
  804         Public method to determine the line end position of the given line.
  805         
  806         @param line line number (integer)
  807         @return position of the line end disregarding line end characters
  808             (integer)
  809         """
  810         return self.SendScintilla(QsciScintilla.SCI_GETLINEENDPOSITION, line)
  811     
  812     def __doSearchTarget(self):
  813         """
  814         Private method to perform the search in target.
  815         
  816         @return flag indicating a successful search (boolean)
  817         """
  818         if self.__targetSearchStart == self.__targetSearchEnd:
  819             self.__targetSearchActive = False
  820             return False
  821         
  822         self.SendScintilla(QsciScintilla.SCI_SETTARGETSTART,
  823                            self.__targetSearchStart)
  824         self.SendScintilla(QsciScintilla.SCI_SETTARGETEND,
  825                            self.__targetSearchEnd)
  826         self.SendScintilla(QsciScintilla.SCI_SETSEARCHFLAGS,
  827                            self.__targetSearchFlags)
  828         targetSearchExpr = self._encodeString(self.__targetSearchExpr)
  829         pos = self.SendScintilla(QsciScintilla.SCI_SEARCHINTARGET,
  830                                  len(targetSearchExpr),
  831                                  targetSearchExpr)
  832         
  833         if pos == -1:
  834             self.__targetSearchActive = False
  835             return False
  836         
  837         targend = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND)
  838         self.__targetSearchStart = targend
  839         
  840         return True
  841     
  842     def getFoundTarget(self):
  843         """
  844         Public method to get the recently found target.
  845         
  846         @return found target as a tuple of starting position and target length
  847             (integer, integer)
  848         """
  849         if self.__targetSearchActive:
  850             spos = self.SendScintilla(QsciScintilla.SCI_GETTARGETSTART)
  851             epos = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND)
  852             return (spos, epos - spos)
  853         else:
  854             return (0, 0)
  855     
  856     def findFirstTarget(self, expr_, re_, cs_, wo_,
  857                         begline=-1, begindex=-1, endline=-1, endindex=-1,
  858                         ws_=False, posix=False, cxx11=False):
  859         """
  860         Public method to search in a specified range of text without
  861         setting the selection.
  862         
  863         @param expr_ search expression
  864         @type str
  865         @param re_ flag indicating a regular expression
  866         @type bool
  867         @param cs_ flag indicating a case sensitive search
  868         @type bool
  869         @param wo_ flag indicating a word only search
  870         @type bool
  871         @param begline line number to start from (-1 to indicate current
  872             position)
  873         @type int
  874         @param begindex index to start from (-1 to indicate current position)
  875         @type int
  876         @param endline line number to stop at (-1 to indicate end of document)
  877         @type int
  878         @param endindex index number to stop at (-1 to indicate end of
  879             document)
  880         @type int
  881         @param ws_ flag indicating a word start search (boolean)
  882         @type bool
  883         @param posix
  884         @type bool
  885         @param cxx11
  886         @type bool
  887         @return flag indicating a successful search
  888         @rtype bool
  889         """
  890         self.__targetSearchFlags = 0
  891         if re_:
  892             self.__targetSearchFlags |= QsciScintilla.SCFIND_REGEXP
  893         if cs_:
  894             self.__targetSearchFlags |= QsciScintilla.SCFIND_MATCHCASE
  895         if wo_:
  896             self.__targetSearchFlags |= QsciScintilla.SCFIND_WHOLEWORD
  897         if ws_:
  898             self.__targetSearchFlags |= QsciScintilla.SCFIND_WORDSTART
  899         if posix:
  900             self.__targetSearchFlags |= QsciScintilla.SCFIND_POSIX
  901         try:
  902             if cxx11:
  903                 self.__targetSearchFlags |= QsciScintilla.SCFIND_CXX11REGEX
  904         except AttributeError:
  905             # defined for QScintilla >= 2.11.0
  906             pass
  907         
  908         if begline < 0 or begindex < 0:
  909             self.__targetSearchStart = self.SendScintilla(
  910                 QsciScintilla.SCI_GETCURRENTPOS)
  911         else:
  912             self.__targetSearchStart = self.positionFromLineIndex(
  913                 begline, begindex)
  914         
  915         if endline < 0 or endindex < 0:
  916             self.__targetSearchEnd = self.SendScintilla(
  917                 QsciScintilla.SCI_GETTEXTLENGTH)
  918         else:
  919             self.__targetSearchEnd = self.positionFromLineIndex(
  920                 endline, endindex)
  921         
  922         self.__targetSearchExpr = expr_
  923         
  924         if self.__targetSearchExpr:
  925             self.__targetSearchActive = True
  926             
  927             return self.__doSearchTarget()
  928         
  929         return False
  930     
  931     def findNextTarget(self):
  932         """
  933         Public method to find the next occurrence in the target range.
  934         
  935         @return flag indicating a successful search (boolean)
  936         """
  937         if not self.__targetSearchActive:
  938             return False
  939         
  940         return self.__doSearchTarget()
  941     
  942     def replaceTarget(self, replaceStr):
  943         """
  944         Public method to replace the string found by the last search in target.
  945         
  946         @param replaceStr replacement string or regexp (string)
  947         """
  948         if not self.__targetSearchActive:
  949             return
  950         
  951         if self.__targetSearchFlags & QsciScintilla.SCFIND_REGEXP:
  952             cmd = QsciScintilla.SCI_REPLACETARGETRE
  953         else:
  954             cmd = QsciScintilla.SCI_REPLACETARGET
  955         r = self._encodeString(replaceStr)
  956         
  957         start = self.SendScintilla(QsciScintilla.SCI_GETTARGETSTART)
  958         self.SendScintilla(cmd, len(r), r)
  959         
  960         self.__targetSearchStart = start + len(r)
  961     
  962     ###########################################################################
  963     ## indicator handling methods
  964     ###########################################################################
  965     
  966     def indicatorDefine(self, indicator, style, color):
  967         """
  968         Public method to define the appearance of an indicator.
  969         
  970         @param indicator number of the indicator (integer,
  971             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
  972         @param style style to be used for the indicator
  973             (QsciScintilla.INDIC_PLAIN, QsciScintilla.INDIC_SQUIGGLE,
  974             QsciScintilla.INDIC_TT, QsciScintilla.INDIC_DIAGONAL,
  975             QsciScintilla.INDIC_STRIKE, QsciScintilla.INDIC_HIDDEN,
  976             QsciScintilla.INDIC_BOX, QsciScintilla.INDIC_ROUNDBOX,
  977             QsciScintilla.INDIC_STRAIGHTBOX, QsciScintilla.INDIC_FULLBOX,
  978             QsciScintilla.INDIC_DASH, QsciScintilla.INDIC_DOTS,
  979             QsciScintilla.INDIC_SQUIGGLELOW, QsciScintilla.INDIC_DOTBOX,
  980             QsciScintilla.INDIC_GRADIENT, QsciScintilla.INDIC_GRADIENTCENTRE,
  981             QsciScintilla.INDIC_SQUIGGLEPIXMAP,
  982             QsciScintilla.INDIC_COMPOSITIONTHICK,
  983             QsciScintilla.INDIC_COMPOSITIONTHIN, QsciScintilla.INDIC_TEXTFORE,
  984             QsciScintilla.INDIC_POINT, QsciScintilla.INDIC_POINTCHARACTER
  985             depending upon QScintilla version)
  986         @param color color to be used by the indicator (QColor)
  987         @exception ValueError the indicator or style are not valid
  988         """
  989         if (
  990             indicator < QsciScintilla.INDIC_CONTAINER or
  991             indicator > QsciScintilla.INDIC_MAX
  992         ):
  993             raise ValueError("indicator number out of range")
  994         
  995         if (
  996             style < QsciScintilla.INDIC_PLAIN or
  997             style > self.IndicatorStyleMax
  998         ):
  999             raise ValueError("style out of range")
 1000         
 1001         self.SendScintilla(QsciScintilla.SCI_INDICSETSTYLE, indicator, style)
 1002         self.SendScintilla(QsciScintilla.SCI_INDICSETFORE, indicator, color)
 1003         try:
 1004             self.SendScintilla(QsciScintilla.SCI_INDICSETALPHA, indicator,
 1005                                color.alpha())
 1006             if style in (
 1007                 QsciScintilla.INDIC_ROUNDBOX, QsciScintilla.INDIC_STRAIGHTBOX,
 1008                 QsciScintilla.INDIC_DOTBOX, QsciScintilla.INDIC_FULLBOX,
 1009             ):
 1010                 # set outline alpha less transparent
 1011                 self.SendScintilla(QsciScintilla.SCI_INDICSETOUTLINEALPHA,
 1012                                    indicator, color.alpha() + 20)
 1013         except AttributeError:
 1014             pass
 1015     
 1016     def setCurrentIndicator(self, indicator):
 1017         """
 1018         Public method to set the current indicator.
 1019         
 1020         @param indicator number of the indicator (integer,
 1021             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1022         @exception ValueError the indicator or style are not valid
 1023         """
 1024         if (
 1025             indicator < QsciScintilla.INDIC_CONTAINER or
 1026             indicator > QsciScintilla.INDIC_MAX
 1027         ):
 1028             raise ValueError("indicator number out of range")
 1029         
 1030         self.SendScintilla(QsciScintilla.SCI_SETINDICATORCURRENT, indicator)
 1031     
 1032     def setIndicatorRange(self, indicator, spos, length):
 1033         """
 1034         Public method to set an indicator for the given range.
 1035         
 1036         @param indicator number of the indicator (integer,
 1037             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1038         @param spos position of the indicator start (integer)
 1039         @param length length of the indicator (integer)
 1040         """
 1041         self.setCurrentIndicator(indicator)
 1042         self.SendScintilla(QsciScintilla.SCI_INDICATORFILLRANGE, spos, length)
 1043     
 1044     def setIndicator(self, indicator, sline, sindex, eline, eindex):
 1045         """
 1046         Public method to set an indicator for the given range.
 1047         
 1048         @param indicator number of the indicator (integer,
 1049             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1050         @param sline line number of the indicator start (integer)
 1051         @param sindex index of the indicator start (integer)
 1052         @param eline line number of the indicator end (integer)
 1053         @param eindex index of the indicator end (integer)
 1054         """
 1055         spos = self.positionFromLineIndex(sline, sindex)
 1056         epos = self.positionFromLineIndex(eline, eindex)
 1057         self.setIndicatorRange(indicator, spos, epos - spos)
 1058     
 1059     def clearIndicatorRange(self, indicator, spos, length):
 1060         """
 1061         Public method to clear an indicator for the given range.
 1062         
 1063         @param indicator number of the indicator (integer,
 1064             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1065         @param spos position of the indicator start (integer)
 1066         @param length length of the indicator (integer)
 1067         """
 1068         self.setCurrentIndicator(indicator)
 1069         self.SendScintilla(QsciScintilla.SCI_INDICATORCLEARRANGE, spos, length)
 1070     
 1071     def clearIndicator(self, indicator, sline, sindex, eline, eindex):
 1072         """
 1073         Public method to clear an indicator for the given range.
 1074         
 1075         @param indicator number of the indicator (integer,
 1076             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1077         @param sline line number of the indicator start (integer)
 1078         @param sindex index of the indicator start (integer)
 1079         @param eline line number of the indicator end (integer)
 1080         @param eindex index of the indicator end (integer)
 1081         """
 1082         spos = self.positionFromLineIndex(sline, sindex)
 1083         epos = self.positionFromLineIndex(eline, eindex)
 1084         self.clearIndicatorRange(indicator, spos, epos - spos)
 1085     
 1086     def clearAllIndicators(self, indicator):
 1087         """
 1088         Public method to clear all occurrences of an indicator.
 1089         
 1090         @param indicator number of the indicator (integer,
 1091             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1092         """
 1093         self.clearIndicatorRange(indicator, 0, self.length())
 1094     
 1095     def hasIndicator(self, indicator, pos):
 1096         """
 1097         Public method to test for the existence of an indicator.
 1098         
 1099         @param indicator number of the indicator (integer,
 1100             QsciScintilla.INDIC_CONTAINER .. QsciScintilla.INDIC_MAX)
 1101         @param pos position to test (integer)
 1102         @return flag indicating the existence of the indicator (boolean)
 1103         """
 1104         res = self.SendScintilla(QsciScintilla.SCI_INDICATORVALUEAT,
 1105                                  indicator, pos)
 1106         return res
 1107     
 1108     def showFindIndicator(self, sline, sindex, eline, eindex):
 1109         """
 1110         Public method to show the find indicator for the given range.
 1111         
 1112         @param sline line number of the indicator start (integer)
 1113         @param sindex index of the indicator start (integer)
 1114         @param eline line number of the indicator end (integer)
 1115         @param eindex index of the indicator end (integer)
 1116         """
 1117         if hasattr(QsciScintilla, "SCI_FINDINDICATORSHOW"):
 1118             spos = self.positionFromLineIndex(sline, sindex)
 1119             epos = self.positionFromLineIndex(eline, eindex)
 1120             self.SendScintilla(QsciScintilla.SCI_FINDINDICATORSHOW, spos, epos)
 1121     
 1122     def flashFindIndicator(self, sline, sindex, eline, eindex):
 1123         """
 1124         Public method to flash the find indicator for the given range.
 1125         
 1126         @param sline line number of the indicator start (integer)
 1127         @param sindex index of the indicator start (integer)
 1128         @param eline line number of the indicator end (integer)
 1129         @param eindex index of the indicator end (integer)
 1130         """
 1131         if hasattr(QsciScintilla, "SCI_FINDINDICATORFLASH"):
 1132             spos = self.positionFromLineIndex(sline, sindex)
 1133             epos = self.positionFromLineIndex(eline, eindex)
 1134             self.SendScintilla(QsciScintilla.SCI_FINDINDICATORFLASH,
 1135                                spos, epos)
 1136     
 1137     def hideFindIndicator(self):
 1138         """
 1139         Public method to hide the find indicator.
 1140         """
 1141         if hasattr(QsciScintilla, "SCI_FINDINDICATORHIDE"):
 1142             self.SendScintilla(QsciScintilla.SCI_FINDINDICATORHIDE)
 1143     
 1144     def getIndicatorStartPos(self, indicator, pos):
 1145         """
 1146         Public method to get the start position of an indicator at a position.
 1147         
 1148         @param indicator ID of the indicator (integer)
 1149         @param pos position within the indicator (integer)
 1150         @return start position of the indicator (integer)
 1151         """
 1152         return self.SendScintilla(QsciScintilla.SCI_INDICATORSTART,
 1153                                   indicator, pos)
 1154     
 1155     def getIndicatorEndPos(self, indicator, pos):
 1156         """
 1157         Public method to get the end position of an indicator at a position.
 1158         
 1159         @param indicator ID of the indicator (integer)
 1160         @param pos position within the indicator (integer)
 1161         @return end position of the indicator (integer)
 1162         """
 1163         return self.SendScintilla(QsciScintilla.SCI_INDICATOREND,
 1164                                   indicator, pos)
 1165     
 1166     def gotoPreviousIndicator(self, indicator, wrap):
 1167         """
 1168         Public method to move the cursor to the previous position of an
 1169         indicator.
 1170         
 1171         This method ensures, that the position found is visible (i.e. unfolded
 1172         and inside the visible range). The text containing the indicator is
 1173         selected.
 1174         
 1175         @param indicator ID of the indicator to search (integer)
 1176         @param wrap flag indicating to wrap around at the beginning of the
 1177             text (boolean)
 1178         @return flag indicating if the indicator was found (boolean)
 1179         """
 1180         pos = self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
 1181         docLen = self.SendScintilla(QsciScintilla.SCI_GETTEXTLENGTH)
 1182         isInIndicator = self.hasIndicator(indicator, pos)
 1183         posStart = self.getIndicatorStartPos(indicator, pos)
 1184         posEnd = self.getIndicatorEndPos(indicator, pos)
 1185         
 1186         if posStart == 0 and posEnd == docLen - 1:
 1187             # indicator does not exist
 1188             return False
 1189         
 1190         if posStart <= 0:
 1191             if not wrap:
 1192                 return False
 1193             
 1194             isInIndicator = self.hasIndicator(indicator, docLen - 1)
 1195             posStart = self.getIndicatorStartPos(indicator, docLen - 1)
 1196         
 1197         if isInIndicator:
 1198             # get out of it
 1199             posStart = self.getIndicatorStartPos(indicator, posStart - 1)
 1200             if posStart <= 0:
 1201                 if not wrap:
 1202                     return False
 1203                 
 1204                 posStart = self.getIndicatorStartPos(indicator, docLen - 1)
 1205         
 1206         newPos = posStart - 1
 1207         posStart = self.getIndicatorStartPos(indicator, newPos)
 1208         posEnd = self.getIndicatorEndPos(indicator, newPos)
 1209         
 1210         if self.hasIndicator(indicator, posStart):
 1211             # found it
 1212             line, index = self.lineIndexFromPosition(posEnd)
 1213             self.ensureLineVisible(line)
 1214             self.SendScintilla(QsciScintilla.SCI_SETSEL, posEnd, posStart)
 1215             self.SendScintilla(QsciScintilla.SCI_SCROLLCARET)
 1216             return True
 1217         
 1218         return False
 1219     
 1220     def gotoNextIndicator(self, indicator, wrap):
 1221         """
 1222         Public method to move the cursor to the next position of an indicator.
 1223         
 1224         This method ensures, that the position found is visible (i.e. unfolded
 1225         and inside the visible range). The text containing the indicator is
 1226         selected.
 1227         
 1228         @param indicator ID of the indicator to search (integer)
 1229         @param wrap flag indicating to wrap around at the beginning of the
 1230             text (boolean)
 1231         @return flag indicating if the indicator was found (boolean)
 1232         """
 1233         pos = self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
 1234         docLen = self.SendScintilla(QsciScintilla.SCI_GETTEXTLENGTH)
 1235         isInIndicator = self.hasIndicator(indicator, pos)
 1236         posStart = self.getIndicatorStartPos(indicator, pos)
 1237         posEnd = self.getIndicatorEndPos(indicator, pos)
 1238         
 1239         if posStart == 0 and posEnd == docLen - 1:
 1240             # indicator does not exist
 1241             return False
 1242         
 1243         if posEnd >= docLen:
 1244             if not wrap:
 1245                 return False
 1246             
 1247             isInIndicator = self.hasIndicator(indicator, 0)
 1248             posEnd = self.getIndicatorEndPos(indicator, 0)
 1249         
 1250         if isInIndicator:
 1251             # get out of it
 1252             posEnd = self.getIndicatorEndPos(indicator, posEnd)
 1253             if posEnd >= docLen:
 1254                 if not wrap:
 1255                     return False
 1256                 
 1257                 posEnd = self.getIndicatorEndPos(indicator, 0)
 1258         
 1259         newPos = posEnd + 1
 1260         posStart = self.getIndicatorStartPos(indicator, newPos)
 1261         posEnd = self.getIndicatorEndPos(indicator, newPos)
 1262         
 1263         if self.hasIndicator(indicator, posStart):
 1264             # found it
 1265             line, index = self.lineIndexFromPosition(posEnd)
 1266             self.ensureLineVisible(line)
 1267             self.SendScintilla(QsciScintilla.SCI_SETSEL, posStart, posEnd)
 1268             self.SendScintilla(QsciScintilla.SCI_SCROLLCARET)
 1269             return True
 1270         
 1271         return False
 1272     
 1273     ###########################################################################
 1274     ## methods to perform folding related stuff
 1275     ###########################################################################
 1276     
 1277     def __setFoldMarker(self, marknr, mark=QsciScintilla.SC_MARK_EMPTY):
 1278         """
 1279         Private method to define a fold marker.
 1280         
 1281         @param marknr marker number to define (integer)
 1282         @param mark fold mark symbol to be used (integer)
 1283         """
 1284         self.SendScintilla(QsciScintilla.SCI_MARKERDEFINE, marknr, mark)
 1285         
 1286         if mark != QsciScintilla.SC_MARK_EMPTY:
 1287             self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1288                                marknr, QColor(Qt.white))
 1289             self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1290                                marknr, QColor(Qt.black))
 1291     
 1292     def setFolding(self, style, margin=2):
 1293         """
 1294         Public method to set the folding style and margin.
 1295         
 1296         @param style folding style to set (integer)
 1297         @param margin margin number (integer)
 1298         """
 1299         if style < self.ArrowFoldStyle:
 1300             super(QsciScintillaCompat, self).setFolding(style, margin)
 1301         else:
 1302             super(QsciScintillaCompat, self).setFolding(
 1303                 QsciScintilla.PlainFoldStyle, margin)
 1304             
 1305             if style == self.ArrowFoldStyle:
 1306                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDER,
 1307                                      QsciScintilla.SC_MARK_ARROW)
 1308                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPEN,
 1309                                      QsciScintilla.SC_MARK_ARROWDOWN)
 1310                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERSUB)
 1311                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERTAIL)
 1312                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEREND)
 1313                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPENMID)
 1314                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL)
 1315             elif style == self.ArrowTreeFoldStyle:
 1316                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDER,
 1317                                      QsciScintilla.SC_MARK_ARROW)
 1318                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPEN,
 1319                                      QsciScintilla.SC_MARK_ARROWDOWN)
 1320                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERSUB,
 1321                                      QsciScintilla.SC_MARK_VLINE)
 1322                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERTAIL,
 1323                                      QsciScintilla.SC_MARK_LCORNER)
 1324                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEREND,
 1325                                      QsciScintilla.SC_MARK_ARROW)
 1326                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDEROPENMID,
 1327                                      QsciScintilla.SC_MARK_ARROWDOWN)
 1328                 self.__setFoldMarker(QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL,
 1329                                      QsciScintilla.SC_MARK_TCORNER)
 1330     
 1331     def setFoldMarkersColors(self, foreColor, backColor):
 1332         """
 1333         Public method to set the foreground and background colors of the
 1334         fold markers.
 1335         
 1336         @param foreColor foreground color (QColor)
 1337         @param backColor background color (QColor)
 1338         """
 1339         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1340                            QsciScintilla.SC_MARKNUM_FOLDER, foreColor)
 1341         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1342                            QsciScintilla.SC_MARKNUM_FOLDER, backColor)
 1343         
 1344         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1345                            QsciScintilla.SC_MARKNUM_FOLDEROPEN, foreColor)
 1346         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1347                            QsciScintilla.SC_MARKNUM_FOLDEROPEN, backColor)
 1348         
 1349         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1350                            QsciScintilla.SC_MARKNUM_FOLDEROPENMID, foreColor)
 1351         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1352                            QsciScintilla.SC_MARKNUM_FOLDEROPENMID, backColor)
 1353         
 1354         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1355                            QsciScintilla.SC_MARKNUM_FOLDERSUB, foreColor)
 1356         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1357                            QsciScintilla.SC_MARKNUM_FOLDERSUB, backColor)
 1358         
 1359         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1360                            QsciScintilla.SC_MARKNUM_FOLDERTAIL, foreColor)
 1361         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1362                            QsciScintilla.SC_MARKNUM_FOLDERTAIL, backColor)
 1363         
 1364         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1365                            QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL, foreColor)
 1366         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1367                            QsciScintilla.SC_MARKNUM_FOLDERMIDTAIL, backColor)
 1368         
 1369         self.SendScintilla(QsciScintilla.SCI_MARKERSETFORE,
 1370                            QsciScintilla.SC_MARKNUM_FOLDEREND, foreColor)
 1371         self.SendScintilla(QsciScintilla.SCI_MARKERSETBACK,
 1372                            QsciScintilla.SC_MARKNUM_FOLDEREND, backColor)
 1373     
 1374     def getVisibleLineFromDocLine(self, docLine):
 1375         """
 1376         Public method to convert a document line number to a visible line
 1377         number (i.e. respect folded lines and annotations).
 1378         
 1379         @param docLine document line number to be converted
 1380         @type int
 1381         @return visible line number
 1382         @rtype int
 1383         """
 1384         return self.SendScintilla(QsciScintilla.SCI_VISIBLEFROMDOCLINE,
 1385                                   docLine)
 1386     
 1387     def getDocLineFromVisibleLine(self, displayLine):
 1388         """
 1389         Public method to convert a visible line number to a document line
 1390         number (i.e. respect folded lines and annotations).
 1391         
 1392         @param displayLine display line number to be converted
 1393         @type int
 1394         @return document line number
 1395         @rtype int
 1396         """
 1397         return self.SendScintilla(QsciScintilla.SCI_DOCLINEFROMVISIBLE,
 1398                                   displayLine)
 1399     
 1400     ###########################################################################
 1401     ## interface methods to the standard keyboard command set
 1402     ###########################################################################
 1403     
 1404     def clearKeys(self):
 1405         """
 1406         Public method to clear the key commands.
 1407         """
 1408         # call into the QsciCommandSet
 1409         self.standardCommands().clearKeys()
 1410         
 1411     def clearAlternateKeys(self):
 1412         """
 1413         Public method to clear the alternate key commands.
 1414         """
 1415         # call into the QsciCommandSet
 1416         self.standardCommands().clearAlternateKeys()
 1417 
 1418     ###########################################################################
 1419     ## specialized event handlers
 1420     ###########################################################################
 1421     
 1422     def focusOutEvent(self, event):
 1423         """
 1424         Protected method called when the editor loses focus.
 1425         
 1426         @param event event object (QFocusEvent)
 1427         """
 1428         if self.isListActive():
 1429             if event.reason() in [
 1430                 Qt.ActiveWindowFocusReason,
 1431                 Qt.OtherFocusReason
 1432             ]:
 1433                 aw = QApplication.activeWindow()
 1434                 if aw is None or aw.parent() is not self:
 1435                     self.cancelList()
 1436             else:
 1437                 self.cancelList()
 1438         
 1439         if self.isCallTipActive():
 1440             if event.reason() in [
 1441                 Qt.ActiveWindowFocusReason,
 1442                 Qt.OtherFocusReason
 1443             ]:
 1444                 aw = QApplication.activeWindow()
 1445                 if aw is None or aw.parent() is not self:
 1446                     self.SendScintilla(QsciScintilla.SCI_CALLTIPCANCEL)
 1447             else:
 1448                 self.SendScintilla(QsciScintilla.SCI_CALLTIPCANCEL)
 1449         
 1450         super(QsciScintillaCompat, self).focusOutEvent(event)
 1451     
 1452     def event(self, evt):
 1453         """
 1454         Public method to handle events.
 1455         
 1456         Note: We are not interested in the standard QsciScintilla event
 1457         handling because we do it ourselves.
 1458         
 1459         @param evt event object to handle (QEvent)
 1460         @return result of the event handling (boolean)
 1461         """
 1462         return QsciScintillaBase.event(self, evt)
 1463 
 1464     ###########################################################################
 1465     ## interface methods to the mini editor
 1466     ###########################################################################
 1467 
 1468     def getFileName(self):
 1469         """
 1470         Public method to return the name of the file being displayed.
 1471         
 1472         @return filename of the displayed file (string)
 1473         """
 1474         p = self.parent()
 1475         if p is None:
 1476             return ""
 1477         else:
 1478             try:
 1479                 return p.getFileName()
 1480             except AttributeError:
 1481                 return ""
 1482     
 1483     ###########################################################################
 1484     ## replacements for buggy methods
 1485     ###########################################################################
 1486     
 1487     def showUserList(self, listId, lst):
 1488         """
 1489         Public method to show a user supplied list.
 1490         
 1491         @param listId id of the list (integer)
 1492         @param lst list to be show (list of strings)
 1493         """
 1494         if listId <= 0:
 1495             return
 1496         
 1497         # Setup seperator for user lists
 1498         self.SendScintilla(
 1499             QsciScintilla.SCI_AUTOCSETSEPARATOR, ord(self.UserSeparator))
 1500         self.SendScintilla(
 1501             QsciScintilla.SCI_USERLISTSHOW, listId,
 1502             self._encodeString(self.UserSeparator.join(lst)))
 1503         
 1504         self.updateUserListSize()
 1505     
 1506     def autoCompleteFromDocument(self):
 1507         """
 1508         Public method to resize list box after creation.
 1509         """
 1510         super(QsciScintillaCompat, self).autoCompleteFromDocument()
 1511         self.updateUserListSize()
 1512     
 1513     def autoCompleteFromAPIs(self):
 1514         """
 1515         Public method to resize list box after creation.
 1516         """
 1517         super(QsciScintillaCompat, self).autoCompleteFromAPIs()
 1518         self.updateUserListSize()
 1519     
 1520     def autoCompleteFromAll(self):
 1521         """
 1522         Public method to resize list box after creation.
 1523         """
 1524         super(QsciScintillaCompat, self).autoCompleteFromAll()
 1525         self.updateUserListSize()
 1526     
 1527     ###########################################################################
 1528     ## work-arounds for buggy behavior
 1529     ###########################################################################
 1530     
 1531     def updateUserListSize(self):
 1532         """
 1533         Public method to resize the completion list to fit with contents.
 1534         """
 1535         children = self.findChildren(QListWidget)
 1536         if children:
 1537             userListWidget = children[-1]
 1538             geom = userListWidget.geometry()
 1539             
 1540             baseHeight = geom.height()
 1541             
 1542             # Workaround for getting all items instead of
 1543             # userListWidget.items() call with unknown mime types.
 1544             all_items = userListWidget.findItems('', Qt.MatchStartsWith)
 1545             if not all_items:
 1546                 return
 1547             
 1548             width = 0
 1549             maxItemHeight = 0
 1550             for item in all_items:
 1551                 visualRect = userListWidget.visualItemRect(item)
 1552                 itemWidth = visualRect.width()
 1553                 if itemWidth > width:
 1554                     width = itemWidth
 1555                 itemHeight = visualRect.height()
 1556                 if itemHeight > maxItemHeight:
 1557                     maxItemHeight = itemHeight
 1558             
 1559             height = min(self.maxLines, len(all_items)) * maxItemHeight
 1560             # Just a fiddling factor: 2 for better readability,
 1561             # e.g. underscores at the end of the list.
 1562             height += 2
 1563             
 1564             # Borders
 1565             borders = geom.size() - userListWidget.contentsRect().size()
 1566             width += borders.width()
 1567             height += borders.height()
 1568             
 1569             font = userListWidget.font()
 1570             fm = QFontMetrics(font)
 1571             averageCharWidth = fm.averageCharWidth()
 1572             maxWidth = averageCharWidth * self.maxChars
 1573             if width > maxWidth:
 1574                 width = maxWidth
 1575                 height += (
 1576                     userListWidget.horizontalScrollBar().sizeHint().height()
 1577                 )
 1578                 # List box doesn't honor limited size to show scroll bars.
 1579                 # So just force it.
 1580                 userListWidget.setHorizontalScrollBarPolicy(
 1581                     Qt.ScrollBarAlwaysOn)
 1582             
 1583             if len(all_items) > self.maxLines:
 1584                 width += userListWidget.verticalScrollBar().sizeHint().width()
 1585             
 1586             # Special case, where the space below current line where to less
 1587             yPos = geom.y()
 1588             charPos = self.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
 1589             currentYPos = self.SendScintilla(
 1590                 QsciScintilla.SCI_POINTYFROMPOSITION, 0, charPos)
 1591             
 1592             # X position doesn't matter: set to 0
 1593             globalPos = self.mapToGlobal(QPoint(0, currentYPos))
 1594             if yPos < globalPos.y():
 1595                 deltaHeight = baseHeight - height
 1596                 geom.setY(yPos + deltaHeight - 4)
 1597             
 1598             geom.setWidth(width)
 1599             geom.setHeight(height)
 1600             userListWidget.setGeometry(geom)
 1601     
 1602     def __completionListSelected(self, listId, txt):
 1603         """
 1604         Private slot to handle the selection from the completion list.
 1605         
 1606         Note: This works around an issue of some window managers taking
 1607         focus away from the application when clicked inside a completion
 1608         list but not giving it back when an item is selected via a
 1609         double-click.
 1610         
 1611         @param listId the ID of the user list (integer)
 1612         @param txt the selected text (string)
 1613         """
 1614         self.activateWindow()
 1615     
 1616     def updateVerticalScrollBar(self):
 1617         """
 1618         Public method to update the vertical scroll bar to reflect the
 1619         additional lines added by annotations.
 1620         """
 1621         # Workaround because Scintilla.Redraw isn't implemented
 1622         self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 0)
 1623         self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 1)
 1624     
 1625     ###########################################################################
 1626     ## utility methods
 1627     ###########################################################################
 1628     
 1629     def _encodeString(self, string):
 1630         """
 1631         Protected method to encode a string depending on the current mode.
 1632         
 1633         @param string string to be encoded (str)
 1634         @return encoded string (bytes)
 1635         """
 1636         if isinstance(string, bytes):
 1637             return string
 1638         else:
 1639             if self.isUtf8():
 1640                 return string.encode("utf-8")
 1641             else:
 1642                 return string.encode("latin-1")
 1643     
 1644     ###########################################################################
 1645     ## methods to implement workarounds for broken things
 1646     ###########################################################################
 1647     
 1648     if QSCINTILLA_VERSION() == 0x020B00:
 1649         def insert(self, txt):
 1650             """
 1651             Public method to insert text at the cursor position.
 1652             
 1653             @param txt text to be inserted
 1654             @type str
 1655             """
 1656             line, col = self.getCursorPosition()
 1657             self.insertAt(txt, line, col)
 1658     
 1659     def positionFromLineIndex(self, line, index):
 1660         """
 1661         Public method to convert line and index to an absolute position.
 1662         
 1663         @param line line number (integer)
 1664         @param index index number (integer)
 1665         @return absolute position in the editor (integer)
 1666         """
 1667         pos = self.SendScintilla(QsciScintilla.SCI_POSITIONFROMLINE, line)
 1668         return pos + index
 1669     
 1670     def lineIndexFromPosition(self, pos):
 1671         """
 1672         Public method to convert an absolute position to line and index.
 1673         
 1674         @param pos absolute position in the editor (integer)
 1675         @return tuple of line number (integer) and index number (integer)
 1676         """
 1677         lin = self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, pos)
 1678         linpos = self.SendScintilla(
 1679             QsciScintilla.SCI_POSITIONFROMLINE, lin)
 1680         return lin, pos - linpos
 1681     
 1682     ###########################################################################
 1683     ## methods below have been added to QScintilla starting with version 2.5
 1684     ###########################################################################
 1685     
 1686     if "contractedFolds" not in QsciScintilla.__dict__:
 1687         def contractedFolds(self):
 1688             """
 1689             Public method to get a list of line numbers of collapsed folds.
 1690             
 1691             @return list of line numbers of folded lines (list of integer)
 1692             """
 1693             line = 0
 1694             folds = []
 1695             maxline = self.lines()
 1696             while line < maxline:
 1697                 if self.foldHeaderAt(line) and not self.foldExpandedAt(line):
 1698                     folds.append(line)
 1699                 line += 1
 1700             return folds
 1701     
 1702     if "setContractedFolds" not in QsciScintilla.__dict__:
 1703         def setContractedFolds(self, folds):
 1704             """
 1705             Public method to set a list of line numbers of collapsed folds.
 1706             
 1707             @param folds list of line numbers of folded lines (list of integer)
 1708             """
 1709             for line in folds:
 1710                 self.foldLine(line)
 1711     
 1712     #########################################################################
 1713     ## Method below implements a compatibility variant for the findFirst()
 1714     ## extended with version 2.11.
 1715     #########################################################################
 1716 
 1717     def findFirst(self, expression, regexp, caseSensitive, word, wrap,
 1718                   forward=True, line=-1, index=-1, show=True, posix=False,
 1719                   cxx11=False):
 1720         """
 1721         Public method to search in the current editor text.
 1722         
 1723         @param expression search expression
 1724         @type str
 1725         @param regexp flag indicating a regular expression
 1726         @type bool
 1727         @param caseSensitive flag indicating a case sensitive search
 1728         @type bool
 1729         @param word flag indicating a word only search
 1730         @type bool
 1731         @param wrap flag indicating to warp around
 1732         @type bool
 1733         @param forward flag indicating the search direction
 1734         @type bool
 1735         @param line line to start the search on
 1736         @type int
 1737         @param index index to start the search on
 1738         @type int
 1739         @param show flag indicating to set the selection to the found
 1740             expression
 1741         @type bool
 1742         @param posix flag indicating the POSIX regular expression search mode
 1743         @type bool
 1744         @param cxx11 flag indicating the CXX11 regular expression search mode
 1745         @type bool
 1746         @return flag indicating a successful search
 1747         @rtype bool
 1748         """
 1749         if QSCINTILLA_VERSION() >= 0x020B00:
 1750             return super(QsciScintillaCompat, self).findFirst(
 1751                 expression, regexp, caseSensitive, word, wrap,
 1752                 forward=forward, line=line, index=index, show=show,
 1753                 posix=posix, cxx11=cxx11)
 1754         else:
 1755             return super(QsciScintillaCompat, self).findFirst(
 1756                 expression, regexp, caseSensitive, word, wrap,
 1757                 forward=forward, line=line, index=index, show=show,
 1758                 posix=posix)
 1759     
 1760     #########################################################################
 1761     ## Methods below are missing from QScintilla.
 1762     #########################################################################
 1763 
 1764     if "setWrapStartIndent" not in QsciScintilla.__dict__:
 1765         def setWrapStartIndent(self, indent):
 1766             """
 1767             Public method to set a the amount of characters wrapped sublines
 1768             shall be indented.
 1769             
 1770             @param indent amount of characters to indent
 1771             @type int
 1772             """
 1773             self.SendScintilla(QsciScintilla.SCI_SETWRAPSTARTINDENT, indent)
 1774     
 1775 ##    #########################################################################
 1776 ##    ## Methods below have been added to QScintilla starting with version 2.x.
 1777 ##    #########################################################################
 1778 ##
 1779 ##    if "newMethod" not in QsciScintilla.__dict__:
 1780 ##        def newMethod(self, param):
 1781 ##            """
 1782 ##            Public method to do something.
 1783 ##
 1784 ##            @param param parameter for method
 1785 ##            """
 1786 ##            pass
 1787 ##