Beispiel #1
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)
Beispiel #2
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 #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
    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.setPositionInBlock(min(realStartCol, block.length() - 1))
                cursor.setPositionInBlock(min(realCurrentCol, block.length() - 1), QTextCursor.KeepAnchor)
                
                cursors.append(cursor)

        return cursors
Beispiel #5
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 #6
0
 def cursorAt(self, position, in_active_area=True):
     c = QTextCursor(self.block)
     p = min(position, self.length-1)
     if in_active_area:
         p = max(p, self.active_area_start)
     c.movePosition(QTextCursor.Right, QTextCursor.MoveAnchor, p)
     return c
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))
    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 #9
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 #10
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
    def highlightMarkdown(self, text, strt):
        cursor = QTextCursor(self.document())
        bf = cursor.blockFormat()
        self.setFormat(0, len(text), QColor(self.theme['color']))
        #bf.clearBackground()
        #cursor.movePosition(QTextCursor.End)
        #cursor.setBlockFormat(bf)

        #Block quotes can contain all elements so process it first
        self.highlightBlockQuote(text, cursor, bf, strt)

        #If empty line no need to check for below elements just return
        if self.highlightEmptyLine(text, cursor, bf, strt):
            return

        #If horizontal line, look at pevious line to see if its a header, process and return
        if self.highlightHorizontalLine(text, cursor, bf, strt):
            return

        if self.highlightAtxHeader(text, cursor, bf, strt):
            return

        self.highlightList(text, cursor, bf, strt)

        self.highlightLink(text, cursor, bf, strt)

        self.highlightImage(text, cursor, bf, strt)

        self.highlightCodeSpan(text, cursor, bf, strt)

        self.highlightEmphasis(text, cursor, bf, strt)

        self.highlightBold(text, cursor, bf, strt)

        self.highlightCodeBlock(text, cursor, bf, strt)
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 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 #14
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
Beispiel #15
0
def main():
    """Main function."""
    options, files = parse_commandline()
    urls = list(map(url, files))
    
    if not app.qApp.isSessionRestored():
        if not options.new and remote.enabled():
            api = remote.get()
            if api:
                api.command_line(options, urls)
                api.close()
                sys.exit(0)
    
        if QSettings().value("splash_screen", True) not in ("false", False):
            import splashscreen
            splashscreen.show()

    QTimer.singleShot(0, remote.setup)  # Start listening for IPC
    
    import mainwindow       # contains MainWindow class
    import session          # Initialize QSessionManager support
    import sessions         # Initialize our own named session support
    import document         # contains Document class

    # boot Frescobaldi-specific stuff that should be running on startup
    import viewhighlighter  # highlight arbitrary ranges in text
    import matcher          # matches braces etc in active text window
    import progress         # creates progress bar in view space
    import autocomplete     # auto-complete input
    
    if app.qApp.isSessionRestored():
        # Restore session, we are started by the session manager
        session.restoreSession()
        return

    # load specified session
    doc = None
    if options.session and options.session != "none":
        doc = sessions.loadSession(options.session)
        
    # Just create one MainWindow
    win = mainwindow.MainWindow()
    win.show()
    
    if urls:
        for u in urls:
            doc = win.openUrl(u, options.encoding)
    elif not options.session:
        # no docs, load default session
        doc = sessions.loadDefaultSession()
    win.setCurrentDocument(doc or document.Document())
    if urls and options.line is not None:
        # set the last loaded document active and apply navigation if requested
        pos = doc.findBlockByNumber(options.line - 1).position() + options.column
        cursor = QTextCursor(doc)
        cursor.setPosition(pos)
        win.currentView().setTextCursor(cursor)
        win.currentView().centerCursor()
Beispiel #16
0
def isBlankBefore(cursor):
    """Returns True if there's no text on the current line before the cursor."""
    if cursor.hasSelection():
        return False
    if cursor.atBlockStart():
        return True
    c = QTextCursor(cursor)
    c.movePosition(QTextCursor.StartOfBlock, QTextCursor.KeepAnchor)
    return c.selection().toPlainText().isspace()
Beispiel #17
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 #18
0
def isBlankAfter(cursor):
    """Returns True if there's no text on the current line after the cursor."""
    if cursor.hasSelection():
        return False
    if cursor.atBlockEnd():
        return True
    c = QTextCursor(cursor)
    c.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
    return c.selection().toPlainText().isspace()
 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 #20
0
	def select_range(self, s, e):
		cursor = QTextCursor(self)

		spos = self.findBlockByLineNumber(s[0] - 1).position() + s[1]
		epos = self.findBlockByLineNumber(e[0] - 1).position() + e[1]
		cursor.setPosition(spos, QTextCursor.MoveAnchor)
		cursor.setPosition(epos, QTextCursor.KeepAnchor)

		return cursor
Beispiel #21
0
def cut_assign(cursor):
    """Cuts selected text and assigns it to a LilyPond variable."""
    # ask the variable name
    name = inputdialog.getText(None, _("Cut and Assign"), _(
        "Please enter the name for the variable to assign the selected "
        "text to:"), regexp="[A-Za-z]+")
    if not name:
        return
    
    cursortools.strip(cursor)
    
    # determine state at cursor
    block = cursortools.block(cursor)
    state = tokeniter.state(block)
    for t in tokeniter.partition(cursor).left:
        state.follow(t)
    
    mode = ""
    for p in state.parsers():
        if isinstance(p, ly.lex.lilypond.ParseInputMode):
            if isinstance(p, ly.lex.lilypond.ParseLyricMode):
                mode = " \\lyricmode"
            elif isinstance(p, ly.lex.lilypond.ParseChordMode):
                mode = " \\chordmode"
            elif isinstance(p, ly.lex.lilypond.ParseFigureMode):
                mode = " \\figuremode"
            elif isinstance(p, ly.lex.lilypond.ParseDrumMode):
                mode = " \\drummode"
            break

    # find insertion place:
    found = False
    while block.previous().isValid():
        block = block.previous()
        state = tokeniter.state(block)
        if isinstance(state.parser(), ly.lex.lilypond.ParseGlobal):
            found = True
            break
        tokens = tokeniter.tokens(block)
        for t in tokens:
            if isinstance(t, ly.lex.lilypond.Name):
                found = True
                break
            elif not isinstance(t, (ly.lex.Space, ly.lex.Comment)):
                break
        if found:
            break
    insert = QTextCursor(block)
    text = cursor.selection().toPlainText()
    space = '\n' if '\n' in text else ' '
    text = ''.join((name, ' =', mode, ' {', space, text, space, '}\n\n'))
    with cursortools.editBlock(cursor):
        cursor.insertText('\\' + name)
        if metainfo.info(cursor.document()).autoindent:
            indent.insertText(insert, text)
        else:
            insert.insertText(text)
Beispiel #22
0
def startmain():
    import optparse
    optparse._ = _ # let optparse use our translations
    parser = optparse.OptionParser(
        usage = _("{appname} [options] file ...").format(appname=info.name),
        version = "{0} {1}".format(info.appname, info.version),
        description = _("A LilyPond Music Editor"))
    parser.add_option('-e', '--encoding', metavar=_("ENC"),
        help=_("Encoding to use"))
    parser.add_option('-l', '--line', type="int", metavar=_("NUM"),
        help=_("Line number to go to, starting at 1"))
    parser.add_option('-c', '--column', type="int", metavar=_("NUM"),
        help=_("Column to go to, starting at 0"), default=0)
    parser.add_option('--start', metavar=_("NAME"),
        help=_("Session to start ('{none}' for empty session)").format(none="none"),
        dest="session")

    args = QApplication.arguments()
    if os.name == 'nt' and args and 'python' in os.path.basename(args[0]).lower():
        args = args[2:]
    else:
        args = args[1:]
    options, files = parser.parse_args(args)

    # load specified session
    doc = None
    if options.session and options.session != "none":
        doc = sessions.loadSession(options.session)
        
    # Just create one MainWindow
    win = mainwindow.MainWindow()
    win.show()
    
    if files:
        # make urls
        for arg in files:
            if re.match(r'^(https?|s?ftp)://', arg):
                url = QUrl(arg)
            elif arg.startswith('file://'):
                url = QUrl.fromLocalFile(arg[7:])
            elif arg.startswith('file:'):
                url = QUrl.fromLocalFile(os.path.abspath(arg[5:]))
            else:
                url = QUrl.fromLocalFile(os.path.abspath(arg))
            doc = win.openUrl(url, options.encoding)
    elif not options.session:
        # no docs, load default session
        doc = sessions.loadDefaultSession()
    win.setCurrentDocument(doc or document.Document())
    if files and options.line is not None:
        # set the last loaded document active and apply navigation if requested
        pos = doc.findBlockByNumber(options.line - 1).position() + options.column
        cursor = QTextCursor(doc)
        cursor.setPosition(pos)
        win.currentView().setTextCursor(cursor)
        win.currentView().centerCursor()
Beispiel #23
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)
Beispiel #24
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)
 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 #26
0
 def focus_line(self, line_no):
     """ highlight the line"""
     line_no -= 1
     cursor = QTextCursor(self.document().findBlockByLineNumber(line_no))
     cursor.clearSelection()
     highlight = QTextEdit.ExtraSelection()
     highlight.cursor = cursor
     highlight.format.setProperty(QTextFormat.FullWidthSelection, True)
     highlight.format.setBackground(QBrush(QColor("#657b83")))
     self.setExtraSelections([highlight])
     self.setTextCursor(cursor)
Beispiel #27
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 #28
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
Beispiel #29
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)
Beispiel #30
0
 def on_log_filter(self):
     log_lvl_name = str(self.sender().iconText()).upper()
     self.log_lvl = log_levels[log_lvl_name]
     cursor = QTextCursor(self.document())
     current_block = cursor.block()
     while current_block.isValid() and current_block.userData():
         block_log_lvl = current_block.userData().log_lvl
         if block_log_lvl <= self.log_lvl:
             current_block.setVisible(True)
         else:
             current_block.setVisible(False)
         current_block = current_block.next()
     self.viewport().update()
Beispiel #31
0
 def on_log_received(self, data):
     time_info = datetime.fromtimestamp((data['time']/1000)).isoformat()
     log_message = '%s: %s : %s' % (
         time_info, data['level'], data['message'])
     message_document = self.document()
     cursor_to_add = QTextCursor(message_document)
     cursor_to_add.movePosition(cursor_to_add.End)
     cursor_to_add.insertText(log_message + '\n')
     if data['level'] in COLORS:
         fmt = QTextCharFormat()
         fmt.setForeground(COLORS[data['level']])
         cursor_to_add.movePosition(cursor_to_add.PreviousBlock)
         cursor_to_add_fmt = message_document.find(data['level'],
                                                   cursor_to_add.position())
         cursor_to_add_fmt.mergeCharFormat(fmt)
     self.ensureCursorVisible()
Beispiel #32
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 #33
0
 def toggleMark(self, linenum, type):
     """Toggles the mark of the given type on the given line."""
     nums = [mark.blockNumber() for mark in self._marks[type]]
     index = bisect.bisect_left(nums, linenum)
     if linenum in nums:
         # remove double occurrences
         while True:
             del self._marks[type][index]
             del nums[index]
             if linenum not in nums:
                 break
             index = bisect.bisect_left(nums, linenum)
     else:
         mark = QTextCursor(self.document().findBlockByNumber(linenum))
         try:
             # only available in very recent PyQt4 versions
             mark.setKeepPositionOnInsert(True)
         except AttributeError:
             pass
         self._marks[type].insert(index, mark)
     self.marksChanged()
Beispiel #34
0
 def goto(self, line_no):
     cursor = self.textCursor()
     block = cursor.block()
     row = cursor.blockNumber()
     while row > line_no:
         block = block.previous()
         row -= 1
     while row < line_no:
         block = block.next()
         row += 1
     cursor = QTextCursor(block)
     self.setTextCursor(cursor)
Beispiel #35
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))
    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 #37
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 #38
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)
Beispiel #39
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 #40
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 #41
0
 def _makeBraceExtraSelection(self, block, pos, matched):
     """Make QTextEdit.ExtraSelection for highlighted brace
     """
     sel = QTextEdit.ExtraSelection()
     sel.cursor = QTextCursor(block)
     sel.cursor.setPosition(block.position() + pos, QTextCursor.MoveAnchor)
     sel.cursor.setPosition(block.position() + pos + 1,
                            QTextCursor.KeepAnchor)
     if matched:
         sel.format = DEFAULT_STYLE['matchedBrace']
     else:
         sel.format = DEFAULT_STYLE['unMatchedBrace']
     return sel
Beispiel #42
0
 def insertMarkers(self):
     # Copy the text and if it is empty, complain and exit.
     qi = QString(self.insertText.text())
     if qi.isEmpty():
         pqMsgs.warningMsg("No insert text specified")
         return
     # See how many pages are involved: all the ones that aren't marked skip
     n = 0
     for i in range(IMC.pageTable.size()):
         if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip:
             n += 1
     if n == 0:  # page table empty or all rows marked skip
         pqMsgs.warningMsg("No pages to give folios to")
         return
     m = "Insert this string at the top of {0} pages?".format(n)
     b = pqMsgs.okCancelMsg(QString(m), pqMsgs.trunc(qi, 35))
     if b:
         # Convert any '\n' in the text to the QT line delimiter char
         # we do this in the copy so the lineEdit text doesn't change
         qi.replace(QString(u'\\n'), QString(IMC.QtLineDelim))
         # get a cursor on the edit document
         tc = QTextCursor(IMC.editWidget.textCursor())
         tc.beginEditBlock()  # start single undoable operation
         # Working from the end of the document backward, go to the
         # top of each page and insert the string
         for i in reversed(range(IMC.pageTable.size())):
             if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip:
                 # Note the page's start position and set our work cursor to it
                 pos = IMC.pageTable.getCursor(i).position()
                 tc.setPosition(pos)
                 # Make a copy of the insert string replacing %f with this folio
                 f = IMC.pageTable.getDisplay(i)
                 qf = QString(qi)
                 qf.replace(QString(u'%f'), f, Qt.CaseInsensitive)
                 tc.insertText(qf)
                 # The insertion goes in ahead of the saved cursor position so now
                 # it points after the inserted string. Put it back where it was.
                 IMC.pageTable.setPosition(i, pos)
         tc.endEditBlock()  # wrap up the undo op
Beispiel #43
0
def insert(name, view):
    """Insert named snippet into the view."""
    text, variables = snippets.get(name)
    cursor = view.textCursor()

    selection = variables.get('selection', '')
    if 'yes' in selection and not cursor.hasSelection():
        return
    if 'strip' in selection:
        cursortools.strip_selection(cursor)

    pos = cursor.selectionStart()
    with cursortools.compress_undo(cursor):

        # insert the snippet, might return a new cursor
        if 'python' in variables:
            new = insert_python(text, cursor, name, view)
        elif 'macro' in variables:
            new = insert_macro(text, view)
        else:
            new = insert_snippet(text, cursor, variables)

    # QTextBlocks the snippet starts and ends
    block = cursor.document().findBlock(pos)
    last = cursor.block()

    # re-indent if not explicitly suppressed by a 'indent: no' variable
    if last != block and 'no' not in variables.get('indent', ''):
        c = QTextCursor(last)
        c.setPosition(block.position(), QTextCursor.KeepAnchor)
        with cursortools.compress_undo(c, True):
            indent.re_indent(c, True)

    if not new and 'keep' in selection:
        end = cursor.position()
        cursor.setPosition(pos)
        cursor.setPosition(end, QTextCursor.KeepAnchor)
    view.setTextCursor(new or cursor)
Beispiel #44
0
 def previousMark(self, cursor, type=None):
     """Finds the first mark before the cursor (of the type if specified)."""
     if type is None:
         marks = []
         for type in types:
             marks += self._marks[type]
         # sort the marks on line number
         marks.sort(key=lambda mark: mark.blockNumber())
     else:
         marks = self._marks[type]
     nums = [mark.blockNumber() for mark in marks]
     index = bisect.bisect_left(nums, cursor.blockNumber())
     if index > 0:
         return QTextCursor(marks[index - 1].block())
Beispiel #45
0
 def load(self):
     """Loads the marks from the metainfo."""
     self._marks = dict((type, []) for type in types)
     marks = metainfo.info(self.document()).bookmarks
     try:
         d = json.loads(marks) or {}
     except ValueError:
         return  # No JSON object could be decoded
     for type in types:
         self._marks[type] = [
             QTextCursor(self.document().findBlockByNumber(num))
             for num in d.get(type, [])
         ]
     self.marksChanged()
Beispiel #46
0
    def cursorPosition(self, pos):
        line, col = pos

        line = min(line, len(self.lines) - 1)
        lineText = self.lines[line]

        if col is not None:
            col = min(col, len(lineText))
        else:
            col = len(lineText) - len(lineText.lstrip())

        cursor = QTextCursor(self.document().findBlockByNumber(line))
        setPositionInBlock(cursor, col)
        self.setTextCursor(cursor)
Beispiel #47
0
 def metaStringIn(self, qline):
     parts = unicode(qline).split(' ')
     tc = QTextCursor(IMC.editWidget.document())
     tc.setPosition(int(parts[0]))
     # see comments on proofer string in loadPsep above.
     qs_proofers = QString(parts[2])
     qs_proofers = qs_proofers.remove(0, 1)
     qs_proofers = qs_proofers.replace(QChar(u'\\'), QChar(u','))
     proofers = unicode(qs_proofers).split(',')
     row = [tc, QString(parts[1]), proofers, 0, 0, 0, 0]
     index = self.size()  # index of row to be
     row[self._Foact] = int(parts[3])
     fcode = int(parts[4])
     if fcode != self._last_format:
         # either row 0 and self._last_format is None, or a change of format
         self._last_format = fcode
         # put index of row we are about to add, into set of explicit formats
         self._explict_formats.add(self.size())
     else:
         fcode = IMC.FolioFormatSame
     row[self._Fofor] = fcode
     self._TheDB.append(row)
     self.setValue(index, int(parts[5]))  # also updates display
Beispiel #48
0
 def nextMark(self, cursor, type=None):
     """Finds the first mark after the cursor (of the type if specified)."""
     if type is None:
         marks = []
         for type in types:
             marks += self._marks[type]
         # sort the marks on line number
         marks.sort(key=lambda mark: mark.blockNumber())
     else:
         marks = self._marks[type]
     nums = [mark.blockNumber() for mark in marks]
     index = bisect.bisect_right(nums, cursor.blockNumber())
     if index < len(nums):
         return QTextCursor(marks[index].block())
Beispiel #49
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 #50
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
Beispiel #51
0
    def saveDocument(self, doc, save_as=False):
        """ Saves the document, asking for a name if necessary.
        
        If save_as is True, a name is always asked.
        Returns True if saving succeeded.
        
        """
        if save_as or doc.url().isEmpty():
            filename = doc.url().toLocalFile()
            if filename:
                filetypes = app.filetypes(os.path.splitext(filename)[1])
            else:
                directory = app.basedir()  # default directory to save to
                import documentinfo
                import ly.lex
                filename = os.path.join(directory,
                                        documentinfo.defaultfilename(doc))
                filetypes = app.filetypes(
                    ly.lex.extensions[documentinfo.mode(doc)])
            caption = app.caption(_("dialog title", "Save File"))
            filename = QFileDialog.getSaveFileName(self, caption, filename,
                                                   filetypes)
            if not filename:
                return False  # cancelled
            url = QUrl.fromLocalFile(filename)
        else:
            url = doc.url()

        if QSettings().value("strip_trailing_whitespace", False, bool):
            import reformat
            reformat.remove_trailing_whitespace(QTextCursor(doc))

        # we only support local files for now
        filename = url.toLocalFile()
        b = backup.backup(filename)
        try:
            doc.save(url)
        except IOError as e:
            msg = _("{message}\n\n{strerror} ({errno})").format(
                message=_("Could not write to: {url}").format(url=filename),
                strerror=e.strerror,
                errno=e.errno)
            QMessageBox.critical(self, app.caption(_("Error")), msg)
            return False
        else:
            if b:
                backup.removeBackup(filename)
            recentfiles.add(doc.url())
        return True
Beispiel #52
0
 def __init__(self, doc, links):
     """Creates QTextCursor instances for every link, keeps a reference to the document."""
     self.document = doc
     # make a sorted list of cursors with their [destination, ...] destinations list
     self._cursor_dict = d = {}              # mapping from (line, col) to QTextCursor
     self._cursors = cursors = []            # sorted list of the cursors
     self._destinations = destinations = []  # corresponding list of destinations
     for pos, dest in sorted(links.items()):
         line, column = pos
         b = doc.findBlockByNumber(line - 1)
         if b.isValid():
             c = d[pos] = QTextCursor(doc)
             c.setPosition(b.position() + column)
             cursors.append(c)
             destinations.append(dest)
Beispiel #53
0
 def bind(self, document):
     """Called when a document is loaded this Reference points to.
     
     Creates a QTextCursor so the position is maintained even if the document
     changes.
     
     """
     b = document.findBlockByNumber(max(0, self._line - 1))
     if b.isValid():
         self._cursor = c = QTextCursor(document)
         c.setPosition(b.position() + self._column)
         document.closed.connect(self.unbind)
         if self._line > 0:
             bookmarks.bookmarks(document).setMark(self._line - 1, "error")
     else:
         self._cursor = None
Beispiel #54
0
    def notify(self, text, textHighlight=None):
        # highlightRange is range in passed text.
        length = len(self.notifyBox.toPlainText())
        self.notifyBox.append(text)
        self.notifyBox.verticalScrollBar().setValue(
            self.notifyBox.verticalScrollBar().maximum())

        if textHighlight != None:
            begin = length + text.find(textHighlight) + 1
            end = begin + len(textHighlight)
            fmt = QTextCharFormat()
            col = QColor(Qt.red)
            col.setAlpha(130)
            fmt.setBackground(col)
            cursor = QTextCursor(self.notifyBox.document())
            cursor.setPosition(begin)
            cursor.setPosition(end, QTextCursor.KeepAnchor)
            cursor.setCharFormat(fmt)
Beispiel #55
0
    def _makeMatchSelection(self, block, columnIndex, matched):
        """Make matched or unmatched QTextEdit.ExtraSelection
        """
        selection = QTextEdit.ExtraSelection()

        if matched:
            bgColor = Qt.green
        else:
            bgColor = Qt.red

        selection.format.setBackground(bgColor)
        selection.cursor = QTextCursor(block)
        selection.cursor.setPosition(block.position() + columnIndex)
        selection.cursor.movePosition(QTextCursor.Right,
                                      QTextCursor.KeepAnchor)

        return selection
Beispiel #56
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)
    def updateDescAndQL(self):
        # get the name of the selected dataset
        dataset_name, dataset_serviceType = self.getSelectedNameAndType()

        #custom web service object
        dataset = self.selectdataSets(dataset_name, dataset_serviceType)

        quicklook = os.path.join(self.quicklooks_dir, dataset.QLname + ".jpg")
        desc = dataset.getDescription(self.language)
        name = dataset.getName(self.language)

        #update decription
        self.dlg.textEdit.clear()
        #creation and last update
        if self.language == "EN":
            crDate = "Creation date : " + dataset.creationDate
            update = "Last update : " + dataset.lastUpdate
        elif self.language == "GR":
            crDate = unicode(
                "Ημερομηνια δημιουργιας : " + dataset.creationDate, 'utf-8')
            update = unicode("Τελευταία ενημέρωση : " + dataset.lastUpdate,
                             'utf-8')

        cursor = QTextCursor(self.dlg.textEdit.document())
        cursor.insertHtml("<h3> " + name + " <br><br></h3>")
        cursor.insertHtml("<p> " + desc + " <br><br><br></p>")
        cursor.insertHtml("<p><i> " + crDate + " <br></i></p>")
        #cursor.insertHtml("<p><i> "+update+" <br></i></p>")

        self.dlg.textEdit.setReadOnly(True)
        #update quicklook

        #GET DIMENSIONS OF THE IMAGE
        img = Image.open(quicklook)
        w, h = img.size

        scene = QGraphicsScene()
        pic = QPixmap(quicklook)
        scene.addItem(QGraphicsPixmapItem(pic))

        self.dlg.graphicsView.setScene(scene)
        self.dlg.graphicsView.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
        self.dlg.graphicsView.show()
Beispiel #58
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 #59
0
 def centerCursor(self):
     tc = QTextCursor(
         self.textCursor())  # copy the working cursor with its selection
     top_point = tc.position()  # one end of selection, in character units
     bot_point = tc.anchor()  # ..and the other end
     if top_point > bot_point:  # often the position is > the anchor
         (top_point, bot_point) = (bot_point, top_point)
     tc.setPosition(top_point)  # cursor for the top of the selection
     selection_top = self.cursorRect(tc).top()  # ..get its top pixel
     line_height = self.cursorRect(
         tc).height()  # and save height of one line
     tc.setPosition(bot_point)  # cursor for the end of the selection
     selection_bot = self.cursorRect(
         tc).bottom()  # ..selection's bottom pixel
     selection_height = selection_bot - selection_top + 1  # selection height in pixels
     view_height = self.viewport().geometry().height(
     )  # scrolled area's height in px
     view_half = view_height >> 1  # int(view_height/2)
     pixel_adjustment = 0
     if selection_height < view_half:
         # selected text is less than half the window height: center the top of the
         # selection, i.e., make the cursor_top equal to view_half.
         pixel_adjustment = selection_top - view_half  # may be negative
     else:
         # selected text is taller than half the window, can we show it all?
         if selection_height < (view_height - line_height):
             # all selected text fits in the viewport (with a little free): center it.
             pixel_adjustment = (selection_top +
                                 (selection_height / 2)) - view_half
         else:
             # not all selected text fits the window, put text top near window top
             pixel_adjustment = selection_top - line_height
     # OK, convert the pixel adjustment to a line-adjustment based on the assumption
     # that a scrollbar pageStep is the height of the viewport in lines.
     adjust_fraction = pixel_adjustment / view_height
     vscroller = self.verticalScrollBar()
     page_step = vscroller.pageStep(
     )  # lines in a viewport page, actually less 1
     adjust_lines = int(page_step * adjust_fraction)
     target = vscroller.value() + adjust_lines
     if (target >= 0) and (target <= vscroller.maximum()):
         vscroller.setValue(target)
Beispiel #60
0
def handle_exception(name, view):
    """Called when a snippet raises a Python exception.
    
    Shows the error message and offers the option to edit the offending snippet.
    
    """
    import sys, traceback
    exc_type, exc_value, exc_traceback = sys.exc_info()
    tb = traceback.extract_tb(exc_traceback)
    while tb and tb[0][0] != "<snippet>":
        del tb[0]
    msg = ''.join(
        traceback.format_list(tb) +
        traceback.format_exception_only(exc_type, exc_value))
    dlg = QMessageBox(QMessageBox.Critical, _("Snippet error"), msg,
                      QMessageBox.Ok | QMessageBox.Cancel)
    dlg.button(QMessageBox.Ok).setText(_("Edit Snippet"))
    dlg.setDefaultButton(QMessageBox.Cancel)
    dlg.setEscapeButton(QMessageBox.Cancel)
    if dlg.exec_() != QMessageBox.Ok:
        return

    # determine line number
    if exc_type is SyntaxError:
        lineno = exc_value.lineno
    elif tb:
        lineno = tb[0][1]
    else:
        lineno = None

    import panelmanager
    from . import edit
    widget = panelmanager.manager(view.window()).snippettool.widget()
    textedit = edit.Edit(widget, name).text
    if lineno is not None:
        # convert to line number in full snippet text
        for block in cursortools.all_blocks(textedit.document()):
            if block.text().startswith('-*- '):
                lineno += 1
            else:
                break
        block = textedit.document().findBlockByNumber(lineno - 1)
        if block.isValid():
            textedit.setTextCursor(QTextCursor(block))