Example #1
0
    def doTextEdit(self, url, setCursor=False):
        """Process a textedit link and either highlight
           the corresponding source code or set the 
           cursor to it.
        """
        t = textedit.link(url)
        # Only process textedit links
        if not t:
            return False
        filename = util.normpath(t.filename)
        doc = self.document(filename, setCursor)
        if doc:
            cursor = QTextCursor(doc)
            b = doc.findBlockByNumber(t.line - 1)
            p = b.position() + t.column
            cursor.setPosition(p)
            cursors = pointandclick.positions(cursor)
            # Do highlighting if the document is active
            if cursors and doc == self.mainwindow().currentDocument():
                import viewhighlighter

                view = self.mainwindow().currentView()
                viewhighlighter.highlighter(view).highlight(self._highlightFormat, cursors, 2, 0)
            # set the cursor and bring the document to front
            if setCursor:
                mainwindow = self.mainwindow()
                mainwindow.setTextCursor(cursor)
                import widgets.blink

                widgets.blink.Blinker.blink_cursor(mainwindow.currentView())
                self.mainwindow().setCurrentDocument(doc)
                mainwindow.activateWindow()
                mainwindow.currentView().setFocus()
        return True
Example #2
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
Example #3
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
Example #4
0
	def lineNumberAreaWidth(self):
		if not globalSettings.lineNumbersEnabled:
			return 0
		cursor = QTextCursor(self.document())
		cursor.movePosition(QTextCursor.End)
		digits = len(str(cursor.blockNumber() + 1))
		return 5 + self.fontMetrics().width('9') * digits
Example #5
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
Example #6
0
    def indent_selection(self):
        def indent_block(block):
            cursor = QTextCursor(block)
            indentation = self.__block_indentation(block)
            cursor.setPosition(block.position() + len(indentation))
            cursor.insertText(self.text())

        cursor = self._neditor.textCursor()
        start_block = self._neditor.document().findBlock(
            cursor.selectionStart())
        end_block = self._neditor.document().findBlock(
            cursor.selectionEnd())

        with self._neditor:
            if start_block != end_block:
                stop_block = end_block.next()
                # Indent multiple lines
                block = start_block
                while block != stop_block:
                    indent_block(block)
                    block = block.next()
                new_cursor = QTextCursor(start_block)
                new_cursor.setPosition(
                    end_block.position() + len(end_block.text()),
                    QTextCursor.KeepAnchor)
                self._neditor.setTextCursor(new_cursor)
            else:
                # Indent one line
                indent_block(start_block)
Example #7
0
 def keyPressEvent(self, event):
     #utilities.printKeyEvent(event)
     kkey = int( int(event.modifiers()) & C.KEYPAD_MOD_CLEAR) | int(event.key())
     if kkey in C.KEYS_EDITOR :
         event.accept() # yes, this is one we handle
         if kkey in C.KEYS_FIND :
             # ^f, ^g, etc. -- just pass them straight to the Find panel
             self.editFindKey.emit(kkey)
         elif kkey in C.KEYS_ZOOM :
             self.setFont( fonts.scale(kkey, self.font()) )
             self.my_book.save_font_size(self.font().pointSize())
         elif kkey in C.KEYS_BOOKMARKS :
             # Something to do with a bookmark. They are kept in the Book
             # because they are read and written in the metadata.
             mark_number = int(event.key()) - 0x31  # number in 0..8
             mark_list = self.my_book.bookmarks # quick reference to the list
             if kkey in C.KEYS_MARK_SET : # alt-1..9, set bookmark
                 # Set a bookmark to the current edit selection
                 mark_list[mark_number] = QTextCursor(self.textCursor())
                 self.my_book.metadata_modified(True, C.MD_MOD_FLAG)
             elif kkey in C.KEYS_MARK : # ctl-1..9, go to mark
                 # Move to the save position including a saved selection
                 if mark_list[mark_number] is not None :
                     self.parent().center_this(mark_list[mark_number])
             else : # shft-ctl-1..9, go to mark, extending selection
                 if mark_list[mark_number] is not None:
                     pos = mark_list[mark_number].position()
                     tc = QTextCursor(self.textCursor())
                     tc.setPosition(pos, QTextCursor.KeepAnchor)
                     self.setTextCursor(tc)
                     self.ensureCursorVisible()
     else: # not a key for the editor, pass it on.
         event.ignore()
         super().keyPressEvent(event)
Example #8
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 made 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)
Example #9
0
    def scrollToLine(self, lineNumber, columnNumber=None):
        """
        Scrolls this widget’s viewport to the line *lineNumber* and sets the
        text cursor to that line, at *columnNumber*. If *columnNumber* is None,
        bookkeeping will be performed.

        Strictly positive numbers are expected.
        """
        lineNumber -= 1
        if columnNumber is None:
            columnNumber = self.textCursor().positionInBlock()
        else:
            columnNumber -= 1
        scrollingUp = lineNumber < self.textCursor().blockNumber()
        # scroll to block
        textBlock = self.document().findBlockByLineNumber(lineNumber)
        newCursor = QTextCursor(textBlock)
        self.setTextCursor(newCursor)
        # make some headroom
        one, two = QTextCursor.Down, QTextCursor.Up
        if scrollingUp:
            one, two = two, one
        for move in (one, one, two, two):
            self.moveCursor(move)
        # address column
        newCursor.movePosition(QTextCursor.NextCharacter, n=columnNumber)
        self.setTextCursor(newCursor)
Example #10
0
	def test_indentLessWithSelection(self):
		self.document.setPlainText('    foo\n    bar\nbaz')
		cursor = QTextCursor(self.document)
		cursor.setPosition(5)
		cursor.setPosition(11, QTextCursor.KeepAnchor)
		documentIndentLess(self.document, cursor, self.settings)
		self.assertEqual('foo\nbar\nbaz', self.document.toPlainText())
Example #11
0
 def scan_pages(self):
     global re_line_sep
     # first page is Arabic starting at 1
     rule = C.FolioRuleSet
     fmt = C.FolioFormatArabic
     nbr = 1
     self.explicit_formats = {0}
     for qtb in self.document.all_blocks() :
         m = re_line_sep.match(qtb.text())
         if m :
             # capture the image filename
             fname = m.group(1)
             if m.group(3) is not None :
                 # record proofers as a list, omitting the
                 # null element caused by the leading '\'
                 plist = m.group(3).split('\\')[1:]
             else :
                 # sep. line with no proofers, minimal list
                 plist = ['']
             qtc = QTextCursor(self.document)
             qtc.setPosition(qtb.position())
             self.cursor_list.append(qtc)
             self.filename_list.append(fname)
             self.folio_list.append( [rule,fmt,nbr] )
             self.proofers_list.append(plist)
             # remaining pages are ditto, add 1, next number
             rule = C.FolioRuleAdd1
             fmt = C.FolioFormatSame
             nbr += 1
     if 0 < len(self.cursor_list) : # we found at least 1
         self.my_book.metadata_modified(True, C.MD_MOD_FLAG)
         self._active = True
         self._add_stopper()
Example #12
0
	def test_indentLess(self):
		self.document.setPlainText('        foo')
		cursor = QTextCursor(self.document)
		cursor.setPosition(10)
		documentIndentLess(self.document, cursor, self.settings)
		self.assertEqual('    foo', self.document.toPlainText())
		documentIndentLess(self.document, cursor, self.settings)
		self.assertEqual('foo', self.document.toPlainText())
Example #13
0
 def cursor_position(self, position):
     line, column = position
     line = min(line, self.line_count() - 1)
     column = min(column, len(self.line_text(line)))
     cursor = QTextCursor(self.document().findBlockByNumber(line))
     cursor.setPosition(cursor.block().position() + column,
                        QTextCursor.MoveAnchor)
     self.setTextCursor(cursor)
Example #14
0
 def make_cursor(self, position, anchor):
     mx = self.document.characterCount()
     tc = QTextCursor(self.Editor.textCursor())
     anchor = min( max(0,anchor), mx )
     position = min ( max(0,position), mx )
     tc.setPosition(anchor)
     tc.setPosition(position,QTextCursor.KeepAnchor)
     return tc
Example #15
0
 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()
Example #16
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)
Example #17
0
 def _make_selection(self, block, index, matched):
     cur = QTextCursor(block)
     cur.setPosition(block.position() + index)
     cur.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor)
     selection = ExtraSelection(cur)
     background = self.matched_background
     if not matched:
         background = self.unmatched_background
     selection.set_background(background)
     return selection
Example #18
0
	def test_indentMore(self):
		cursor = QTextCursor(self.document)
		cursor.setPosition(4)
		documentIndentMore(self.document, cursor, self.settings)
		self.assertEqual('foo\n    bar\nbaz',
		                 self.document.toPlainText())
		cursor.setPosition(3)
		documentIndentMore(self.document, cursor, self.settings)
		self.assertEqual('foo \n    bar\nbaz',
		                 self.document.toPlainText())
Example #19
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)
Example #20
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'])
Example #21
0
	def updateSelection(self, tc):
		# block selection rectagle
		rect = self.__editor.cursorRect(tc)
		w = rect.width()
		tc2 = QTextCursor(tc)
		tc2.setPosition(tc.anchor())
		rect = rect.united( self.__editor.cursorRect(tc2) )
		x = self.__lineWidth / 2
		rect.adjust(-x, -x, x - w, x)

		QWidget.setGeometry(self, rect)
Example #22
0
 def read_meta(self,qts,sentinel,version,parm):
     self.document().clear()
     for line in metadata.read_to(qts,sentinel):
         if line.startswith(C.UNICODE_REPL+'{{'):
             line = line[1:]
         self.appendPlainText(line)
     tc = QTextCursor(self.document())
     tc.setPosition(0)
     self.setTextCursor(tc)
     self.document().setModified(False)
     self.font_change(True) # update font selection
Example #23
0
 def actionTriggered(self, name):
     name = name[8:]
     direction = ['_', '', '^'][self.direction() + 1]
     isSpanner = name not in dynamic_marks
     if isSpanner:
         dynamic = dynamic_spanners[name]
     else:
         dynamic = '\\' + name
     cursor = self.mainwindow().textCursor()
     if not cursor.hasSelection():
         # dynamic right before the cursor?
         left = tokeniter.partition(cursor).left
         if not left or not isinstance(left[-1], ly.lex.lilypond.Dynamic):
             # no, find the first pitch
             c = lydocument.cursor(cursor)
             c.end = None
             for item in ly.rhythm.music_items(c, partial=ly.document.OUTSIDE):
                 cursor.setPosition(item.end)
                 break
         cursor.insertText(direction + dynamic)
         self.mainwindow().currentView().setTextCursor(cursor)
     else:
         c = lydocument.cursor(cursor)
         cursors = []
         for item in ly.rhythm.music_items(c):
             csr = QTextCursor(cursor.document())
             csr.setPosition(item.end)
             cursors.append(csr)
         if not cursors:
             return
         c1, c2 = cursors[0], cursors[-1]
         # are there dynamics at the cursor? then skip them
         d1 = dynamics(c1)
         if d1:
             c1 = tokeniter.cursor(c1.block(), d1[-1], start=len(d1[-1]))
         with cursortools.compress_undo(cursor):
             if len(cursors) > 1:
                 # dynamics after the end cursor?
                 d2 = dynamics(c2)
                 if isSpanner and not d2:
                     # don't terminate the spanner if there's a dynamic there
                     c2.insertText('\\!')
                 elif set(d1).intersection(dynamic_spanners.values()):
                     # write the dynamic at the end if there's a spanner at start
                     # remove ending \! if there
                     terminator = tokeniter.find("\\!", d2)
                     if terminator:
                         c2 = tokeniter.cursor(c2.block(), terminator)
                     if direction in d1:
                         c2.insertText(dynamic)
                     else:
                         c2.insertText(direction + dynamic)
                     return
             c1.insertText(direction + dynamic)
Example #24
0
 def cursorForItem(self, item):
     """Returns a cursor for the specified item.
     
     This method (as all others) assume that the item refers to the current
     Document.
     
     """
     doc = self.parent().mainwindow().currentDocument()
     cursor = QTextCursor(doc)
     cursor.setPosition(item.position)
     return cursor
Example #25
0
 def show_position(self, pos):
     try:
         pos = int(pos)
         if (pos < 0) or (pos >= self.document.characterCount() ) :
             raise ValueError
     except:
         utilities.beep()
         editview_logger.error('Request to show invalid position {0}'.format(pos))
         pos = self.document.characterCount()
     tc = QTextCursor(self.Editor.textCursor())
     tc.setPosition(pos)
     self.show_this(tc)
Example #26
0
 def dragElement(self, url):
     t = textedit.link(url)
     # Only process textedit links
     if not t:
         return False
     filename = util.normpath(t.filename)
     doc = self.document(filename, True)
     if doc:
         cursor = QTextCursor(doc)
         b = doc.findBlockByNumber(t.line - 1)
         p = b.position() + t.column
         cursor.setPosition(p)
     self.emitCursor(cursor)
Example #27
0
 def setMark(self, linenum, type):
     """Marks the given line number with a mark of the given type."""
     nums = [mark.blockNumber() for mark in self._marks[type]]
     if linenum in nums:
         return
     index = bisect.bisect_left(nums, linenum)
     mark = QTextCursor(self.document().findBlockByNumber(linenum))
     try:
         # only available in very recent PyQt5 versions
         mark.setKeepPositionOnInsert(True)
     except AttributeError:
         pass
     self._marks[type].insert(index, mark)
     self.marksChanged()
Example #28
0
def goto_target(mainwindow, target):
    """Switch to the document and location where the node target is."""
    lydoc = target.document
    try:
        # this succeeds if this is a document that is currently open
        doc = lydoc.document
    except AttributeError:
        # it is an included file, just load it
        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()
Example #29
0
def pixmap(cursor, num_lines=6, scale=0.8):
    """Return a QPixmap displaying the selected lines of the document.

    If the cursor has no selection, num_lines are drawn.

    By default the text is drawn 0.8 * the normal font size. You can change
    that by supplying the scale parameter.

    """
    block = cursor.document().findBlock(cursor.selectionStart())
    c2 = QTextCursor(block)
    if cursor.hasSelection():
        c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor)
        c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
    else:
        c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines)

    data = textformats.formatData('editor')
    doc = QTextDocument()
    font = QFont(data.font)
    font.setPointSizeF(font.pointSizeF() * scale)
    doc.setDefaultFont(font)
    doc.setPlainText(c2.selection().toPlainText())
    if metainfo.info(cursor.document()).highlighting:
        highlighter.highlight(doc, state=tokeniter.state(block))
    size = doc.size().toSize() + QSize(8, -4)
    pix = QPixmap(size)
    pix.fill(data.baseColors['background'])
    doc.drawContents(QPainter(pix))
    return pix
Example #30
0
 def _cursor_moved(self):
     tc = QTextCursor(self.Editor.textCursor()) # copy of cursor
     self.ColNumber.setText( str( tc.positionInBlock() ) )
     tb = tc.block()
     if tb == self.last_text_block :
         return # still on same line, nothing more to do
     # Fill in line-number widget, line #s are origin-1
     self.LineNumber.setText( str( tb.blockNumber()+1 ) )
     # Fill in the image name and folio widgets
     pn = self.page_model.page_index(tc.position())
     if pn is not None : # the page model has info on this position
         self.ImageFilename.setText(self.page_model.filename(pn))
         self.Folio.setText(self.page_model.folio_string(pn))
     else: # no image data, or cursor is above page 1
         self.ImageFilename.setText('')
         self.Folio.setText('')
     # Change the current-line "extra selection" to the new current line.
     # Note: the cursor member of the extra selection may not have a
     # selection. If it does, the current line highlight disappears. The
     # cursor "tc" may or may not have a selection; to make sure, we clone
     # it and remove any selection from it.
     cltc = QTextCursor(tc)
     cltc.setPosition(tc.position(),QTextCursor.MoveAnchor)
     # Set the cloned cursor into the current line extra selection object.
     self.current_line_sel.cursor = cltc
     # Re-assign the list of extra selections to force update of display.
     self.Editor.setExtraSelections(self.extra_sel_list)