Beispiel #1
0
    def edit(self, cursor):
        """Edit the block at the specified QTextCursor."""
        if self._document:
            self._document.closed.disconnect(self.reject)
        self._document = cursor.document()
        self._document.closed.connect(self.reject)

        # don't change the cursor
        c = self._range = QTextCursor(cursor)
        cursorpos = c.position() - c.block().position()
        cursortools.strip_indent(c)
        indentpos = c.position() - c.block().position()
        c.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
        self.view.setPlainText(c.selection().toPlainText())

        self.highlighter.setInitialState(
            tokeniter.state(cursortools.block(cursor)))
        self.highlighter.setHighlighting(
            metainfo.info(cursor.document()).highlighting)
        self.highlighter.rehighlight()

        # let autocomplete query the real document as if we're at the start
        # of the current block
        self.completer.document_cursor = QTextCursor(cursor.block())
        self.completer.autoComplete = QSettings().value("autocomplete",
                                                        True) not in ('false',
                                                                      False)

        cursor = self.view.textCursor()
        cursor.setPosition(max(0, cursorpos - indentpos))
        self.view.setTextCursor(cursor)

        self.updateMessage()
Beispiel #2
0
def insert_snippet(text, cursor, variables):
    """Inserts a normal text snippet.
    
    After the insert, the cursor points to the end of the inserted snippet.
    
    If this function returns a cursor it must be set as the cursor for the view
    after the snippet has been inserted.
    
    """
    exp_base = expand.Expander(cursor)
    
    evs = [] # make a list of events, either text or a constant
    for text, key in snippets.expand(text):
        if text:
            evs.append(text)
        if key == '$':
            evs.append('$')
        elif key:
            # basic variables
            func = getattr(exp_base, key, None)
            if func:
                evs.append(func())
    
    selectionUsed = expand.SELECTION in evs
    # do the padding if 'selection: strip;' is used
    if selectionUsed and 'strip' in variables.get('selection', ''):
        space = '\n' if '\n' in cursor.selection().toPlainText() else ' '
        # change whitespace in previous and next piece of text
        i = evs.index(expand.SELECTION)
        for j in range(i-1, -i, -1):
            if evs[j] not in expand.constants:
                evs[j] = evs[j].rstrip() + space
                break
        for j in range(i+1, len(evs)):
            if evs[j] not in expand.constants:
                evs[j] = space + evs[j].lstrip()
                break
    # now insert the text
    ins = QTextCursor(cursor)
    selectionUsed and ins.setPosition(cursor.selectionStart())
    a, c = -1, -1
    for e in evs:
        if e == expand.ANCHOR:
            a = ins.position()
        elif e == expand.CURSOR:
            c = ins.position()
        elif e == expand.SELECTION:
            ins.setPosition(cursor.selectionEnd())
        else:
            ins.insertText(e)
    cursor.setPosition(ins.position())
    # return a new cursor if requested
    if (a, c) != (-1, -1):
        new = QTextCursor(cursor)
        if a != -1:
            new.setPosition(a)
        if c != -1:
            new.setPosition(c, QTextCursor.KeepAnchor if a != -1 else QTextCursor.MoveAnchor)
        return new
 def put_some_text_in(self):
     c = QTextCursor(self.text.document())
     c.insertText("sat")
     c.insertBlock()
     c.insertImage(self.load_an_image(), 'image')
     c.insertBlock()
     c.insertText("unsat")
     # Move back to head of document
     self.text.setTextCursor(QTextCursor(self.text.document()))
Beispiel #4
0
def insert_python(text, cursor, name, view):
    """Regards the text as Python code, and exec it.
    
    name and view are given in case an exception occurs.
    
    The following variables are available:
    
    - text: contains selection or '', set it to insert new text
    - state: contains simplestate for the cursor position
    - cursor: the QTextCursor

    After the insert, the cursor points to the end of the inserted snippet.
    
    """
    namespace = {
        'cursor': QTextCursor(cursor),
        'state': state(cursor),
        'text': cursor.selection().toPlainText(),
        'view': view,
        'ANCHOR': 1,
        'CURSOR': 2,
    }
    try:
        code = compile(text, "<snippet>", "exec")
        if sys.version_info < (3, 0):
            exec("exec code in namespace")
        else:
            exec(code, namespace)
        if 'main' in namespace:
            return namespace['main']()
    except Exception:
        handle_exception(name, view)
    else:
        text = namespace.get('text', '')
        if isinstance(text, (tuple, list)):
            ANCHOR = namespace.get('ANCHOR', 1)
            CURSOR = namespace.get('CURSOR', 2)
            a, c = -1, -1
            for t in text:
                if t == ANCHOR:
                    a = cursor.selectionStart()
                elif t == CURSOR:
                    c = cursor.selectionStart()
                else:
                    cursor.insertText(t)
            if (a, c) != (-1, -1):
                new = QTextCursor(cursor)
                if a != -1:
                    new.setPosition(a)
                if c != -1:
                    new.setPosition(
                        c, QTextCursor.KeepAnchor
                        if a != -1 else QTextCursor.MoveAnchor)
                return new
        else:
            cursor.insertText(namespace['text'])
Beispiel #5
0
    def selectedPosition(self, pos):
        anchorPos, cursorPos = pos
        anchorLine, anchorCol = anchorPos
        cursorLine, cursorCol = cursorPos

        anchorCursor = QTextCursor(
            self.document().findBlockByNumber(anchorLine))
        setPositionInBlock(anchorCursor, anchorCol)

        # just get absolute position
        cursor = QTextCursor(self.document().findBlockByNumber(cursorLine))
        setPositionInBlock(cursor, cursorCol)

        anchorCursor.setPosition(cursor.position(), QTextCursor.KeepAnchor)
        self.setTextCursor(anchorCursor)
Beispiel #6
0
 def append(self, text):
     """Append line to the end
     """
     cursor = QTextCursor(self._doc)
     cursor.movePosition(QTextCursor.End)
     cursor.insertBlock()
     cursor.insertText(text)
Beispiel #7
0
    def onMatchNumberChange(self, matchNumber):
        # Set default format on the whole text before highlighting the selected
        # match.
        document = self.matchText.document()
        cursor = QTextCursor(document)
        cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)
        cursor.setCharFormat(QTextCharFormat())

        search = self.getSearchText()
        for i, match in enumerate(self.regex.finditer(search)):
            if i + 1 == matchNumber:
                break
        else:
            assert False, ("We didn't find a match?! (RE=%r, text=%r" %
                           (self.regex.pattern, search))

        self.formatMatchedText(document, match)

        model = self.groupsView.model()
        model.clear()

        # Create a reversed self.regex.groupindex dictionnary
        groupsIndexes = dict(
            (v, k) for (k, v) in self.regex.groupindex.iteritems())

        for i in range(1, self.regex.groups + 1):
            groupName = groupsIndexes.get(i, "")
            groupValue = match.group(i)
            model.append((groupName, groupValue))
Beispiel #8
0
    def cursors(self):
        """Cursors for rectangular selection.
        1 cursor for every line
        """
        cursors = []
        if self._start is not None:
            startLine, startVisibleCol = self._start
            currentLine, currentCol = self._qpart.cursorPosition
            if abs(startLine - currentLine) > self._MAX_SIZE or \
               abs(startVisibleCol - currentCol) > self._MAX_SIZE:
                # Too big rectangular selection freezes the GUI
                self._qpart.userWarning.emit('Rectangular selection area is too big')
                self._start = None
                return []

            currentBlockText = self._qpart.textCursor().block().text()
            currentVisibleCol = self._realToVisibleColumn(currentBlockText, currentCol)

            for lineNumber in range(min(startLine, currentLine),
                                    max(startLine, currentLine) + 1):
                block = self._qpart.document().findBlockByNumber(lineNumber)
                cursor = QTextCursor(block)
                realStartCol = self._visibleToRealColumn(block.text(), startVisibleCol)
                realCurrentCol = self._visibleToRealColumn(block.text(), currentVisibleCol)
                if realStartCol is None:
                    realStartCol = block.length()  # out of range value
                if realCurrentCol is None:
                    realCurrentCol = block.length()  # out of range value

                cursor.setPosition(cursor.block().position() + min(realStartCol, block.length() - 1))
                cursor.setPosition(cursor.block().position() + min(realCurrentCol, block.length() - 1),
                                   QTextCursor.KeepAnchor)
                cursors.append(cursor)

        return cursors
Beispiel #9
0
 def setLine(self, line):
     cursor = QTextCursor(self.document())
     cursor.movePosition(QTextCursor.End)
     cursor.setPosition(self.newPromptPos, QTextCursor.KeepAnchor)
     cursor.removeSelectedText()
     cursor.insertText(line)
     self.setTextCursor(cursor)
Beispiel #10
0
 def load(self, keepUndo=False):
     """Loads the current url.
     
     Returns True if loading succeeded, False if an error occurred,
     and None when the current url is empty or non-local.
     Currently only local files are supported.
     
     If keepUndo is True, the loading can be undone (with Ctrl-Z).
     
     """
     fileName = self.url().toLocalFile()
     if fileName:
         try:
             with open(fileName) as f:
                 data = f.read()
         except (IOError, OSError):
             return False # errors are caught in MainWindow.openUrl()
         text = util.decode(data)
         if keepUndo:
             c = QTextCursor(self)
             c.select(QTextCursor.Document)
             c.insertText(text)
         else:
             self.setPlainText(text)
         self.setModified(False)
         self.loaded()
         app.documentLoaded(self)
         return True
Beispiel #11
0
 def load(self, url=None, encoding=None, keepUndo=False):
     """Load the specified or current url (if None was specified).
     
     Currently only local files are supported. An IOError is raised
     when trying to load a nonlocal URL.
     
     If loading succeeds and an url was specified, the url is make the
     current url (by calling setUrl() internally).
     
     If keepUndo is True, the loading can be undone (with Ctrl-Z).
     
     """
     if url is None:
         url = QUrl()
     u = url if not url.isEmpty() else self.url()
     text = self.load_data(u, encoding or self._encoding)
     if keepUndo:
         c = QTextCursor(self)
         c.select(QTextCursor.Document)
         c.insertText(text)
     else:
         self.setPlainText(text)
     self.setModified(False)
     if not url.isEmpty():
         self.setUrl(url)
     self.loaded()
     app.documentLoaded(self)
Beispiel #12
0
def articulation_positions(cursor):
    """Returns a list of positions where an articulation can be added.
    
    Every position is given as a QTextCursor instance.
    If the cursor has a selection, all positions in the selection are returned.
    
    """
    c = lydocument.cursor(cursor)
    if not cursor.hasSelection():
        # just select until the end of the current line
        c.select_end_of_block()
        rests = True
        partial = ly.document.OUTSIDE
    else:
        rests = False
        partial = ly.document.INSIDE
    
    positions = []
    for item in ly.rhythm.music_items(c, partial):
        if not rests and item.tokens and isinstance(item.tokens[0], ly.lex.lilypond.Rest):
            continue
        csr = QTextCursor(cursor.document())
        csr.setPosition(item.end)
        positions.append(csr)
        if not cursor.hasSelection():
            break # leave if first found, that's enough
    return positions
Beispiel #13
0
 def cursor(self):
     """Return a QTextCursor with the same selection."""
     c = QTextCursor(self.document.document)
     c.movePosition(QTextCursor.End) if self.end is None else c.setPosition(
         self.end)
     c.setPosition(self.start, QTextCursor.KeepAnchor)
     return c
Beispiel #14
0
    def postImport(self, settings, doc):
        """Adaptations of the source after running musicxml2ly
		
		Present settings: 
		Reformat source
        Remove superfluous durations
        Remove duration scaling
        Engrave directly
		
        """
        cursor = QTextCursor(doc)
        if settings[0]:
            import reformat
            reformat.reformat(cursor)
        if settings[1]:
            cursor.select(QTextCursor.Document)
            from rhythm import rhythm
            rhythm.rhythm_implicit_per_line(cursor)
        if settings[2]:
            cursor.select(QTextCursor.Document)
            from rhythm import rhythm
            rhythm.rhythm_remove_fraction_scaling(cursor)
        if settings[3]:
            import engrave
            engrave.engraver(self.mainwindow()).engrave('preview', doc, False)
    def _find(self, textEdit=None, backward=False):
        if textEdit is None:
            textEdit = self.textEdit

        found = False

        if textEdit is not None:
            cursor = textEdit.textCursor()
            text, flags = self._textAndFindFlags(backward=backward)
            position = cursor.position()
            cursor = textEdit.document().find(text, cursor, flags)

            if not cursor.isNull():
                textEdit.setTextCursor(cursor)
                found = True
            elif self.wrapAroundCheckBox.isChecked():
                cursor = QTextCursor(textEdit.textCursor())
                cursor.movePosition(backward and QTextCursor.End
                                    or QTextCursor.Start)
                cursor = textEdit.document().find(text, cursor, flags)
                if not cursor.isNull():
                    if position == cursor.position():
                        pass  #todo
                    textEdit.setTextCursor(cursor)
                    found = True
            self.writeSettings()

        if not found:
            QApplication.beep()
            self.feedbackLabel.setText(self.tr("Not found"))
        else:
            self.clearFeedback()
Beispiel #16
0
    def drawContents(self, painter):
        """
        Reimplementation of drawContents to limit the drawing
        inside `textRext`.

        """
        painter.setPen(self.__color)
        painter.setFont(self.font())

        if self.__textRect:
            rect = self.__textRect
        else:
            rect = self.rect().adjusted(5, 5, -5, -5)
        if Qt.mightBeRichText(self.__message):
            doc = QTextDocument()
            doc.setHtml(self.__message)
            doc.setTextWidth(rect.width())
            cursor = QTextCursor(doc)
            cursor.select(QTextCursor.Document)
            fmt = QTextBlockFormat()
            fmt.setAlignment(self.__alignment)
            cursor.mergeBlockFormat(fmt)
            painter.save()
            painter.translate(rect.topLeft())
            doc.drawContents(painter)
            painter.restore()
        else:
            painter.drawText(rect, self.__alignment, self.__message)
Beispiel #17
0
 def actionTriggered(self, name):
     # convert arpeggio_normal to arpeggioNormal, etc.
     name = _arpeggioTypes[name]
     cursor = self.mainwindow().textCursor()
     # which arpeggio type is last used?
     lastused = '\\arpeggioNormal'
     types = set(_arpeggioTypes.values())
     block = cursor.block()
     while block.isValid():
         s = types.intersection(tokeniter.tokens(block))
         if s:
             lastused = s.pop()
             break
         block = block.previous()
     # where to insert
     c = lydocument.cursor(cursor)
     c.select_end_of_block()
     with cursortools.compress_undo(cursor):
         for item in ly.rhythm.music_items(c, partial=ly.document.OUTSIDE):
             c = QTextCursor(cursor.document())
             c.setPosition(item.end)
             c.insertText('\\arpeggio')
             if name != lastused:
                 cursortools.strip_indent(c)
                 indent = c.block().text()[:c.position() -
                                           c.block().position()]
                 c.insertText(name + '\n' + indent)
             # just pick the first place
             return
Beispiel #18
0
    def selected_comment_changed(self, curr, prev):
        #called whenever another comment is selected
        self.ui.plainTextEditComment.blockSignals(True) #otherwise it would cause a textChanged() event which would overwrite the data
        if not curr is None:
            self.current_comment = self.comments[curr]
            comment_text = self.current_comment.get_text()
            self.ui.plainTextEditComment.setPlainText(comment_text)
            self.ui.plainTextEditComment.setReadOnly(False)
            self.ui.spinBoxStartLine.setEnabled(True)
            self.ui.spinBoxEndLine.setEnabled(True)

            self.ui.spinBoxStartLine.blockSignals(True)
            self.ui.spinBoxStartLine.setValue(self.current_comment.start_line)
            self.ui.spinBoxStartLine.blockSignals(False)

            self.ui.spinBoxEndLine.blockSignals(True)
            self.ui.spinBoxEndLine.setValue(self.current_comment.end_line)
            self.ui.spinBoxEndLine.blockSignals(False)

            #jump to first marker
            if len(self.current_comment.markers) > 0:
                first_marker = self.current_comment.markers[0]
                line = first_marker.line_index
                cursor = QTextCursor(self.ui.plainTextEditCode.document().findBlockByNumber(line)) #only works without word wrap
                self.ui.plainTextEditCode.setTextCursor(cursor)

        else:
            self.ui.plainTextEditComment.clear()
            self.ui.plainTextEditComment.setReadOnly(True)
            self.ui.actionRemove_Comment.setEnabled(False)
            self.ui.spinBoxStartLine.setEnabled(False)
            self.ui.spinBoxEndLine.setEnabled(False)
            self.current_comment = None
        self.ui.plainTextEditComment.blockSignals(False)
Beispiel #19
0
def spanner_positions(cursor):
    """Return a list with 0 to 2 QTextCursor instances.
    
    At the first cursor a starting spanner item can be inserted, at the
    second an ending item.
    
    """
    c = lydocument.cursor(cursor)
    if cursor.hasSelection():
        partial = ly.document.INSIDE
    else:
        # just select until the end of the current line
        c.select_end_of_block()
        partial = ly.document.OUTSIDE

    items = list(ly.rhythm.music_items(c, partial=partial))
    if cursor.hasSelection():
        del items[1:-1]
    else:
        del items[2:]

    positions = []
    for i in items:
        c = QTextCursor(cursor.document())
        c.setPosition(i.end)
        positions.append(c)
    return positions
Beispiel #20
0
def html_copy(cursor, scheme='editor', number_lines=False):
    """Return a new QTextDocument with highlighting set as HTML textcharformats.
    
    The cursor is a cursor of a document.Document instance. If the cursor 
    has a selection, only the selection is put in the new document.
    
    If number_lines is True, line numbers are added.
    
    """
    data = textformats.formatData(scheme)
    doc = QTextDocument()
    doc.setDefaultFont(data.font)
    doc.setPlainText(cursor.document().toPlainText())
    if metainfo.info(cursor.document()).highlighting:
        highlight(doc, mapping(data),
                  ly.lex.state(documentinfo.mode(cursor.document())))
    if cursor.hasSelection():
        # cut out not selected text
        start, end = cursor.selectionStart(), cursor.selectionEnd()
        cur1 = QTextCursor(doc)
        cur1.setPosition(start, QTextCursor.KeepAnchor)
        cur2 = QTextCursor(doc)
        cur2.setPosition(end)
        cur2.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)
        cur2.removeSelectedText()
        cur1.removeSelectedText()
    if number_lines:
        c = QTextCursor(doc)
        f = QTextCharFormat()
        f.setBackground(QColor('#eeeeee'))
        if cursor.hasSelection():
            num = cursor.document().findBlock(
                cursor.selectionStart()).blockNumber() + 1
            last = cursor.document().findBlock(cursor.selectionEnd())
        else:
            num = 1
            last = cursor.document().lastBlock()
        lastnum = last.blockNumber() + 1
        padding = len(format(lastnum))
        block = doc.firstBlock()
        while block.isValid():
            c.setPosition(block.position())
            c.setCharFormat(f)
            c.insertText('{0:>{1}d} '.format(num, padding))
            block = block.next()
            num += 1
    return doc
Beispiel #21
0
def goto_target(mainwindow, target):
    """Switch to the document and location where the node target is."""
    filename = target.document.filename
    doc = app.openUrl(QUrl.fromLocalFile(filename))
    cursor = QTextCursor(doc)
    cursor.setPosition(target.position)
    browseriface.get(mainwindow).setTextCursor(cursor)
    mainwindow.currentView().centerCursor()
Beispiel #22
0
    def insert(self, index, text):
        """Insert line to the document
        """
        if index < 0 or index > self._doc.blockCount():
            raise IndexError('Invalid block index', index)

        if index == 0:  # first
            cursor = QTextCursor(self._doc.firstBlock())
            cursor.insertText(text)
            cursor.insertBlock()
        elif index != self._doc.blockCount():  # not the last
            cursor = QTextCursor(self._doc.findBlockByNumber(index).previous())
            cursor.movePosition(QTextCursor.EndOfBlock)
            cursor.insertBlock()
            cursor.insertText(text)
        else:  # last append to the end
            self.append(text)
Beispiel #23
0
    def formatMatchedText(self, document, match):
        """Format the matched text in a document"""

        cursor = QTextCursor(document)
        cursor.setPosition(match.start())
        cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor,
                            match.end() - match.start())
        cursor.setCharFormat(self.matchFormat)
Beispiel #24
0
 def _makeQtExtraSelection(startAbsolutePosition, length):
     selection = QTextEdit.ExtraSelection()
     cursor = QTextCursor(self.document())
     cursor.setPosition(startAbsolutePosition)
     cursor.setPosition(startAbsolutePosition + length,
                        QTextCursor.KeepAnchor)
     selection.cursor = cursor
     selection.format = self._userExtraSelectionFormat
     return selection
 def show_msg(self, message):
     """Show message in textBrowser
     """
     self.textEdit.append(message)
     # Scroll to end of the last message
     cursor = QTextCursor(self.textEdit.textCursor())
     cursor.movePosition(QTextCursor.End)
     self.textEdit.setTextCursor(cursor)
     QApplication.processEvents()
Beispiel #26
0
 def _removeBlock(blockIndex):
     block = self._doc.findBlockByNumber(blockIndex)
     if block.next().isValid():  # not the last
         cursor = QTextCursor(block)
         cursor.movePosition(QTextCursor.NextBlock,
                             QTextCursor.KeepAnchor)
     elif block.previous().isValid():  # the last, not the first
         cursor = QTextCursor(block.previous())
         cursor.movePosition(QTextCursor.EndOfBlock)
         cursor.movePosition(QTextCursor.NextBlock,
                             QTextCursor.KeepAnchor)
         cursor.movePosition(QTextCursor.EndOfBlock,
                             QTextCursor.KeepAnchor)
     else:  # only one block
         cursor = QTextCursor(block)
         cursor.movePosition(QTextCursor.EndOfBlock,
                             QTextCursor.KeepAnchor)
     cursor.removeSelectedText()
Beispiel #27
0
 def _onNextBookmark(self):
     """Previous Bookmark action triggered. Move cursor
     """
     for block in qutepart.iterateBlocksFrom(
             self._qpart.textCursor().block().next()):
         if self.isBlockMarked(block) or \
            block.blockNumber() in self._qpart.lintMarks:
             self._qpart.setTextCursor(QTextCursor(block))
             return
Beispiel #28
0
 def _selectLines(self, startBlockNumber, endBlockNumber):
     """Select whole lines
     """
     startBlock = self.document().findBlockByNumber(startBlockNumber)
     endBlock = self.document().findBlockByNumber(endBlockNumber)
     cursor = QTextCursor(startBlock)
     cursor.setPosition(endBlock.position(), QTextCursor.KeepAnchor)
     cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
     self.setTextCursor(cursor)
Beispiel #29
0
 def save(self):
     """Called to perform the edits in the document."""
     cursor = QTextCursor(self._range)
     start = cursor.selectionStart()
     # use cursordiff; don't destroy point and click positions
     cursordiff.insert_text(cursor, self.view.toPlainText())
     cursor.setPosition(start, QTextCursor.KeepAnchor)
     with cursortools.compress_undo(cursor, True):
         # re-indent the inserted line(s)
         indent.re_indent(cursor)
Beispiel #30
0
 def is_cell_separator(self, cursor=None, block=None):
     """Return True if cursor (or text block) is on a block separator"""
     assert cursor is not None or block is not None
     if cursor is not None:
         cursor0 = QTextCursor(cursor)
         cursor0.select(QTextCursor.BlockUnderCursor)
         text = to_text_string(cursor0.selectedText())
     else:
         text = to_text_string(block.text())
     return text.lstrip().startswith(self.CELL_SEPARATORS)