Ejemplo n.º 1
0
 def finish_execution(self, exitCode, exitStatus):
     """Print a message and hide the input line when the execution ends."""
     self.lblInput.hide()
     self.input.hide()
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     self.output.textCursor().insertText('\n\n')
     if exitStatus == QProcess.NormalExit:
         format_.setForeground(
             QBrush(
                 QColor(
                     resources.CUSTOM_SCHEME.get(
                         "keyword", resources.COLOR_SCHEME["keyword"]))))
         self.output.textCursor().insertText(
             self.tr("Execution Successful!"), format_)
     else:
         format_.setForeground(
             QBrush(
                 QColor(
                     resources.CUSTOM_SCHEME.get(
                         "error-underline",
                         resources.COLOR_SCHEME["error-underline"]))))
         self.output.textCursor().insertText(
             self.tr("Execution Interrupted"), format_)
     self.output.textCursor().insertText('\n\n')
     self.__post_execution()
Ejemplo n.º 2
0
 def __post_execution_message(self):
     """Print post execution message."""
     self.output.textCursor().insertText("\n\n")
     format = QTextCharFormat()
     format.setAnchor(True)
     format.setForeground(Qt.green)
     self.output.textCursor().insertText(self.tr("Post Execution Script Successfully executed."), format)
Ejemplo n.º 3
0
 def __post_execution_message(self):
     """Print post execution message."""
     self.output.textCursor().insertText('\n\n')
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     format_.setForeground(Qt.green)
     self.output.textCursor().insertText(
         self.tr("Post Execution Script Successfully executed."), format_)
Ejemplo n.º 4
0
 def _insertAnchors(self, cursor, plainText, matcher, hrefFunc):
     for start, end, matcher in self._iterMatchedRanges(matcher, plainText):
         cursor.setPosition(start);
         cursor.setPosition(end, QTextCursor.KeepAnchor)
 
         fmt = QTextCharFormat()
         fmt.setAnchor(True)
         fmt.setAnchorHref(hrefFunc(matcher.cap()))
         cursor.mergeCharFormat(fmt)
Ejemplo n.º 5
0
 def process_error(self, error):
     """Listen to the error signals from the running process."""
     self.lblInput.hide()
     self.input.hide()
     self._proc.kill()
     format = QTextCharFormat()
     format.setAnchor(True)
     format.setForeground(Qt.red)
     if error == 0:
         self.output.textCursor().insertText(self.tr("Failed to start"), format)
     else:
         self.output.textCursor().insertText(self.tr("Error during execution, QProcess error: %d" % error), format)
Ejemplo n.º 6
0
 def finish_execution(self, exitCode, exitStatus):
     self.lblInput.hide()
     self.input.hide()
     format = QTextCharFormat()
     format.setAnchor(True)
     self.output.textCursor().insertText('\n\n')
     if exitStatus == QProcess.NormalExit:
         format.setForeground(Qt.green)
         self.output.textCursor().insertText(
             self.tr("Execution Successful!"), format)
     else:
         format.setForeground(Qt.red)
         self.output.textCursor().insertText(
             self.tr("Execution Interrupted"), format)
Ejemplo n.º 7
0
 def process_error(self, error):
     self.lblInput.hide()
     self.input.hide()
     self._proc.kill()
     format = QTextCharFormat()
     format.setAnchor(True)
     format.setForeground(Qt.red)
     if error == 0:
         self.output.textCursor().insertText(self.tr('Failed to start'),
             format)
     else:
         self.output.textCursor().insertText(
             self.tr('Error during execution, QProcess error: %d' % error),
             format)
Ejemplo n.º 8
0
 def finish_execution(self, exitCode, exitStatus):
     self.lblInput.hide()
     self.input.hide()
     format = QTextCharFormat()
     format.setAnchor(True)
     self.output.textCursor().insertText('\n\n')
     if exitStatus == QProcess.NormalExit:
         format.setForeground(Qt.green)
         self.output.textCursor().insertText(
             self.tr("Execution Successful!"), format)
     else:
         format.setForeground(Qt.red)
         self.output.textCursor().insertText(
             self.tr("Execution Interrupted"), format)
Ejemplo n.º 9
0
 def finish_execution(self, exitCode, exitStatus):
     """Print a message and hide the input line when the execution ends."""
     self.lblInput.hide()
     self.input.hide()
     format = QTextCharFormat()
     format.setAnchor(True)
     self.output.textCursor().insertText("\n\n")
     if exitStatus == QProcess.NormalExit:
         format.setForeground(Qt.green)
         self.output.textCursor().insertText(self.tr("Execution Successful!"), format)
     else:
         format.setForeground(Qt.red)
         self.output.textCursor().insertText(self.tr("Execution Interrupted"), format)
     self.output.textCursor().insertText("\n\n")
     self.__post_execution()
Ejemplo n.º 10
0
 def process_error(self, error):
     """Listen to the error signals from the running process."""
     self.lblInput.hide()
     self.input.hide()
     self._proc.kill()
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     format_.setForeground(Qt.red)
     if error == 0:
         self.output.textCursor().insertText(self.tr('Failed to start'),
             format_)
     else:
         self.output.textCursor().insertText(
             self.tr('Error during execution, QProcess error: %d' % error),
             format_)
Ejemplo n.º 11
0
 def process_error(self, error):
     """Listen to the error signals from the running process."""
     self.lblInput.hide()
     self.input.hide()
     self._proc.kill()
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     format_.setForeground(QBrush(QColor(resources.CUSTOM_SCHEME.get(
         "error-underline", resources.COLOR_SCHEME["error-underline"]))))
     if error == 0:
         self.output.textCursor().insertText(self.tr('Failed to start'),
             format_)
     else:
         self.output.textCursor().insertText(
             (self.tr('Error during execution, QProcess error: %d') % error),
             format_)
Ejemplo n.º 12
0
 def finish_execution(self, exitCode, exitStatus):
     """Print a message and hide the input line when the execution ends."""
     self.lblInput.hide()
     self.input.hide()
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     self.output.textCursor().insertText('\n\n')
     if exitStatus == QProcess.NormalExit:
         format_.setForeground(Qt.green)
         self.output.textCursor().insertText(
             self.tr("Execution Successful!"), format_)
     else:
         format_.setForeground(Qt.red)
         self.output.textCursor().insertText(
             self.tr("Execution Interrupted"), format_)
     self.output.textCursor().insertText('\n\n')
     self.__post_execution()
Ejemplo n.º 13
0
 def process_error(self, error):
     """Listen to the error signals from the running process."""
     self.lblInput.hide()
     self.input.hide()
     self._proc.kill()
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     font = settings.FONT
     format_.setFont(font)
     format_.setForeground(QBrush(QColor(resources.CUSTOM_SCHEME.get(
         "error-underline", resources.COLOR_SCHEME["error-underline"]))))
     if error == 0:
         self.output.textCursor().insertText(self.tr('Failed to start'),
                                             format_)
     else:
         self.output.textCursor().insertText(
             (self.tr('Error during execution, QProcess error: %d') % error),
             format_)
Ejemplo n.º 14
0
 def finish_execution(self, exitCode, exitStatus):
     """Print a message and hide the input line when the execution ends."""
     self.lblInput.hide()
     self.input.hide()
     format_ = QTextCharFormat()
     format_.setAnchor(True)
     self.output.textCursor().insertText('\n\n')
     if exitStatus == QProcess.NormalExit:
         format_.setForeground(QBrush(QColor(resources.CUSTOM_SCHEME.get(
         "keyword", resources.COLOR_SCHEME["keyword"]))))
         self.output.textCursor().insertText(
             self.tr("Execution Successful!"), format_)
     else:
         format_.setForeground(QBrush(QColor(resources.CUSTOM_SCHEME.get(
         "error-underline", resources.COLOR_SCHEME["error-underline"]))))
         self.output.textCursor().insertText(
             self.tr("Execution Interrupted"), format_)
     self.output.textCursor().insertText('\n\n')
     self.__post_execution()
Ejemplo n.º 15
0
def textFormats():
    """ Return a dict with text formats for the log view """
    log = QTextCharFormat()
    log.setFontFamily("monospace")
    
    url = QTextCharFormat(log)
    url.setForeground(QBrush(QColor("blue")))
    url.setFontUnderline(True)
    url.setAnchor(True)
    
    msg = QTextCharFormat()
    msg.setFontFamily("sans-serif")
    msg.setFontWeight(QFont.Bold)
    
    msgok = QTextCharFormat(msg)
    msgok.setForeground(QBrush(QColor("green")))
    
    msgerr = QTextCharFormat(msg)
    msgerr.setForeground(QBrush(QColor("red")))
    
    return locals()
Ejemplo n.º 16
0
    def writeMessage(self, message, type):
        """This writes both status and output messages to the log.
        
        For output messages also the correct encoding is re-applied:
        LilyPond writes filenames out in the system's filesystemencoding,
        while the messages are always written in UTF-8 encoding...
        
        """
        if type == job.STDERR:
            # find filenames in message:
            parts = iter(errors.message_re.split(message.encode("latin1")))
            msg = next(parts).decode("utf-8", "replace")
            self.cursor.insertText(msg, self.textFormat(type))
            enc = sys.getfilesystemencoding()

            for url, path, line, col, msg in zip(*itertools.repeat(parts, 5)):
                url = url.decode(enc)
                path = path.decode(enc)
                msg = msg.decode("utf-8", "replace")
                if self._rawView:
                    fmt = QTextCharFormat(self.textFormat(type))
                    display_url = url
                else:
                    fmt = QTextCharFormat(self.textFormat("link"))
                    display_url = os.path.basename(path)
                fmt.setAnchor(True)
                fmt.setAnchorHref(str(len(self._errors)))
                fmt.setToolTip(_("Click to edit this file"))

                pos = self.cursor.position()
                self.cursor.insertText(display_url, fmt)
                self.cursor.insertText(msg, self.textFormat(type))
                self._errors.append((pos, self.cursor.position(), url))
        else:
            if type == job.STDOUT:
                message = message.encode("latin1").decode("utf-8")
            super(LogWidget, self).writeMessage(message, type)
Ejemplo n.º 17
0
 def writeMessage(self, message, type):
     """This writes both status and output messages to the log.
     
     For output messages also the correct encoding is re-applied:
     LilyPond writes filenames out in the system's filesystemencoding,
     while the messages are always written in UTF-8 encoding...
     
     """
     if type == job.STDERR:
         # find filenames in message:
         parts = iter(errors.message_re.split(message.encode('latin1')))
         msg = next(parts).decode('utf-8', 'replace')
         self.cursor.insertText(msg, self.textFormat(type))
         enc = sys.getfilesystemencoding()
         
         for url, path, line, col, msg in zip(*itertools.repeat(parts, 5)):
             url = url.decode(enc)
             path = path.decode(enc)
             msg = msg.decode('utf-8', 'replace')
             if self._rawView:
                 fmt = QTextCharFormat(self.textFormat(type))
                 display_url = url
             else:
                 fmt = QTextCharFormat(self.textFormat("link"))
                 display_url = os.path.basename(path)
             fmt.setAnchor(True)
             fmt.setAnchorHref(str(len(self._errors)))
             fmt.setToolTip(_("Click to edit this file"))
             
             pos = self.cursor.position()
             self.cursor.insertText(display_url, fmt)
             self.cursor.insertText(msg, self.textFormat(type))
             self._errors.append((pos, self.cursor.position(), url))
     else:
         if type == job.STDOUT:
             message = message.encode('latin1').decode('utf-8')
         super(LogWidget, self).writeMessage(message, type)
Ejemplo n.º 18
0
class OutputWidget(QPlainTextEdit):

    def __init__(self, parent):
        QPlainTextEdit.__init__(self, parent)
        self._parent = parent
        self.setReadOnly(True)
        self.maxValue = 0
        self.actualValue = 0
        #traceback pattern
        self.patLink = re.compile(r'(\s)*File "(.*?)", line \d.+')
        #formats
        self.plain_format = QTextCharFormat()
        self.error_format = QTextCharFormat()
        self.error_format.setAnchor(True)
        self.error_format.setFontUnderline(True)
        self.error_format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
        self.error_format.setUnderlineColor(Qt.red)
        self.error_format.setForeground(Qt.blue)
        self.error_format.setToolTip(self.tr("Click to show the source"))

        self.connect(self, SIGNAL("blockCountChanged(int)"), self._scroll_area)

    def _scroll_area(self):
        """When new text is added to the widget, move the scroll to the end."""
        if self.actualValue == self.maxValue:
            self.moveCursor(QTextCursor.End)

    def mousePressEvent(self, event):
        """
        When the execution fail, allow to press the links in the traceback,
        to go to the line when the error occur.
        """
        QPlainTextEdit.mousePressEvent(self, event)
        self.go_to_error(event)

    def _refresh_output(self):
        """Read the output buffer from the process and append the text."""
        #we should decode the bytes!
        currentProcess = self._parent.currentProcess
        text = currentProcess.readAllStandardOutput().data().decode('utf8')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        self.textCursor().insertText(text, self.plain_format)

    def _refresh_error(self):
        """Read the error buffer from the process and append the text."""
        #we should decode the bytes!
        cursor = self.textCursor()
        currentProcess = self._parent.currentProcess
        text = currentProcess.readAllStandardError().data().decode('utf8')
        text_lines = text.split('\n')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        for t in text_lines:
            cursor.insertBlock()
            if self.patLink.match(t):
                cursor.insertText(t, self.error_format)
            else:
                cursor.insertText(t, self.plain_format)

    def go_to_error(self, event):
        """Resolve the link and take the user to the error line."""
        cursor = self.cursorForPosition(event.pos())
        text = cursor.block().text()
        if self.patLink.match(text):
            file_path, lineno = self._parse_traceback(text)
            main = main_container.MainContainer()
            main.open_file(file_path)
            main.editor_jump_to_line(lineno=int(lineno) - 1)

    def _parse_traceback(self, text):
        """
        Parse a line of python traceback and returns
        a tuple with (file_name, lineno)
        """
        file_word_index = text.find('File')
        comma_min_index = text.find(',')
        comma_max_index = text.rfind(',')
        file_name = text[file_word_index + 6:comma_min_index - 1]
        lineno = text[comma_min_index + 7:comma_max_index]
        return (file_name, lineno)

    def contextMenuEvent(self, event):
        """Show a context menu for the Plain Text widget."""
        popup_menu = self.createStandardContextMenu()

        menuOutput = QMenu(self.tr("Output"))
        cleanAction = menuOutput.addAction(self.tr("Clean"))
        popup_menu.insertSeparator(popup_menu.actions()[0])
        popup_menu.insertMenu(popup_menu.actions()[0], menuOutput)

        # This is a hack because if we leave the widget text empty
        # it throw a violent segmentation fault in start_process
        self.connect(cleanAction, SIGNAL("triggered()"),
            lambda: self.setPlainText('\n\n'))

        popup_menu.exec_(event.globalPos())
Ejemplo n.º 19
0
class OutputWidget(QPlainTextEdit):

    """Widget to handle the output of the running process."""

    def __init__(self, parent):
        super(OutputWidget, self).__init__(parent)
        self._parent = parent
        self.setReadOnly(True)
        #traceback pattern
        self.patLink = re.compile(r'(\s)*File "(.*?)", line \d.+')
        #formats
        font = settings.FONT
        self.plain_format = QTextCharFormat()
        self.plain_format.setFont(font)
        self.plain_format.setForeground(
            QBrush(QColor(resources.CUSTOM_SCHEME.get(
                "editor-text", resources.COLOR_SCHEME["editor-text"]))))
        self.error_format = QTextCharFormat()
        self.error_format.setFont(font)
        self.error_format.setAnchor(True)
        self.error_format.setForeground(QColor(resources.CUSTOM_SCHEME.get(
            "pep8-underline", resources.COLOR_SCHEME["pep8-underline"])))
        self.error_format.setBackground(QColor(resources.CUSTOM_SCHEME.get(
            "error-underline", resources.COLOR_SCHEME["error-underline"])))
        self.error_format.setToolTip(self.tr("Click to show the source"))
        self.error_format2 = QTextCharFormat()
        self.error_format2.setAnchor(True)
        self.error_format2.setFont(font)
        self.error_format2.setForeground(
            QBrush(
                QColor(resources.CUSTOM_SCHEME.get(
                    "error-underline",
                    resources.COLOR_SCHEME["error-underline"]))))

        self.connect(self, SIGNAL("blockCountChanged(int)"),
                     lambda: self.moveCursor(QTextCursor.End))

        css = 'QPlainTextEdit {color: %s; background-color: %s;' \
            'selection-color: %s; selection-background-color: %s;}' \
            % (resources.CUSTOM_SCHEME.get('editor-text',
               resources.COLOR_SCHEME['editor-text']),
               resources.CUSTOM_SCHEME.get('editor-background',
               resources.COLOR_SCHEME['editor-background']),
               resources.CUSTOM_SCHEME.get('editor-selection-color',
               resources.COLOR_SCHEME['editor-selection-color']),
               resources.CUSTOM_SCHEME.get('editor-selection-background',
               resources.COLOR_SCHEME['editor-selection-background']))
        self.setStyleSheet(css)

    def mousePressEvent(self, event):
        """
        When the execution fail, allow to press the links in the traceback,
        to go to the line when the error occur.
        """
        QPlainTextEdit.mousePressEvent(self, event)
        self.go_to_error(event)

    def refresh_output(self):
        """Read the output buffer from the process and append the text."""
        #we should decode the bytes!
        currentProcess = self._parent.currentProcess
        text = currentProcess.readAllStandardOutput().data().decode('utf8')
        self.textCursor().insertText(text, self.plain_format)

    def refresh_error(self):
        """Read the error buffer from the process and append the text."""
        #we should decode the bytes!
        cursor = self.textCursor()
        currentProcess = self._parent.currentProcess
        text = currentProcess.readAllStandardError().data().decode('utf8')
        text_lines = text.split('\n')
        for t in text_lines:
            cursor.insertBlock()
            if self.patLink.match(t):
                cursor.insertText(t, self.error_format)
            else:
                cursor.insertText(t, self.error_format2)

    def go_to_error(self, event):
        """Resolve the link and take the user to the error line."""
        cursor = self.cursorForPosition(event.pos())
        text = cursor.block().text()
        if self.patLink.match(text):
            file_path, lineno = self._parse_traceback(text)
            main_container = IDE.get_service('main_container')
            if main_container:
                main_container.open_file(
                    file_path,
                    cursorPosition=int(lineno) - 1,
                    positionIsLineNumber=True)

    def _parse_traceback(self, text):
        """
        Parse a line of python traceback and returns
        a tuple with (file_name, lineno)
        """
        file_word_index = text.find('File')
        comma_min_index = text.find(',')
        comma_max_index = text.rfind(',')
        file_name = text[file_word_index + 6:comma_min_index - 1]
        lineno = text[comma_min_index + 7:comma_max_index]
        return (file_name, lineno)

    def contextMenuEvent(self, event):
        """Show a context menu for the Plain Text widget."""
        popup_menu = self.createStandardContextMenu()

        menuOutput = QMenu(self.tr("Output"))
        cleanAction = menuOutput.addAction(self.tr("Clean"))
        popup_menu.insertSeparator(popup_menu.actions()[0])
        popup_menu.insertMenu(popup_menu.actions()[0], menuOutput)

        # This is a hack because if we leave the widget text empty
        # it throw a violent segmentation fault in start_process
        self.connect(cleanAction, SIGNAL("triggered()"),
                     lambda: self.setPlainText('\n\n'))

        popup_menu.exec_(event.globalPos())
Ejemplo n.º 20
0
class OutputWidget(QPlainTextEdit):

    def __init__(self, parent):
        QPlainTextEdit.__init__(self, parent)
        self._parent = parent
        self.setReadOnly(True)
        styles.set_style(self, 'editor')
        self.maxValue = 0
        self.actualValue = 0
        #traceback pattern
        self.patLink = re.compile(r'(\s)*File "(.*?)", line \d.+')
        #formats
        self.plain_format = QTextCharFormat()
        self.error_format = QTextCharFormat()
        self.error_format.setAnchor(True)
        self.error_format.setFontUnderline(True)
        self.error_format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
        self.error_format.setUnderlineColor(Qt.red)
        self.error_format.setForeground(Qt.blue)
        self.error_format.setToolTip(self.tr("Click to show the source"))

        self.connect(self, SIGNAL("blockCountChanged(int)"), self._scroll_area)

    def _scroll_area(self):
        if self.actualValue == self.maxValue:
            self.moveCursor(QTextCursor.End)

    def mousePressEvent(self, event):
        QPlainTextEdit.mousePressEvent(self, event)
        self.go_to_error(event)

    def _refresh_output(self):
        #we should decode the bytes!
        text = self._parent._proc.readAllStandardOutput().data().decode('utf8')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        self.textCursor().insertText(text)

    def _refresh_error(self):
        #we should decode the bytes!
        cursor = self.textCursor()
        text = self._parent._proc.readAllStandardError().data().decode('utf8')
        text_lines = text.split('\n')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        for t in text_lines:
            cursor.insertBlock()
            if self.patLink.match(t):
                cursor.insertText(t, self.error_format)
            else:
                cursor.insertText(t, self.plain_format)

    def insert_input(self, text):
        self.textCursor().insertText(text)

    def go_to_error(self, event):
        cursor = self.cursorForPosition(event.pos())
        text = cursor.block().text()
        if self.patLink.match(text):
            file_path, lineno = self._parse_traceback(unicode(text))
            main = main_container.MainContainer()
            main.open_file(file_path)
            main.editor_jump_to_line(lineno=int(lineno) - 1)

    def _parse_traceback(self, text):
        """
        Parse a line of python traceback and returns
        a tuple with (file_name, lineno)
        """
        file_word_index = text.find('File')
        comma_min_index = text.find(',')
        comma_max_index = text.rfind(',')
        file_name = text[file_word_index + 6:comma_min_index - 1]
        lineno = text[comma_min_index + 7:comma_max_index]
        return (file_name, lineno)

    def contextMenuEvent(self, event):
        popup_menu = self.createStandardContextMenu()

        menuOutput = QMenu(self.tr("Output"))
        cleanAction = menuOutput.addAction(self.tr("Clean"))
        popup_menu.insertSeparator(popup_menu.actions()[0])
        popup_menu.insertMenu(popup_menu.actions()[0], menuOutput)

        self.connect(cleanAction, SIGNAL("triggered()"), self.clear)

        popup_menu.exec_(event.globalPos())
Ejemplo n.º 21
0
class OutputWidget(QPlainTextEdit):

    def __init__(self, parent):
        QPlainTextEdit.__init__(self, parent)
        self._parent = parent
        self.setReadOnly(True)
        self.maxValue = 0
        self.actualValue = 0
        #traceback pattern
        self.patLink = re.compile(r'(\s)*File "(.*?)", line \d.+')
        #formats
        self.plain_format = QTextCharFormat()
        self.error_format = QTextCharFormat()
        self.error_format.setAnchor(True)
        self.error_format.setFontUnderline(True)
        self.error_format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
        self.error_format.setUnderlineColor(Qt.red)
        self.error_format.setForeground(Qt.blue)
        self.error_format.setToolTip(self.tr("Click to show the source"))

        self.connect(self, SIGNAL("blockCountChanged(int)"), self._scroll_area)

    def _scroll_area(self):
        """When new text is added to the widget, move the scroll to the end."""
        if self.actualValue == self.maxValue:
            self.moveCursor(QTextCursor.End)

    def mousePressEvent(self, event):
        """
        When the execution fail, allow to press the links in the traceback,
        to go to the line when the error occur.
        """
        QPlainTextEdit.mousePressEvent(self, event)
        self.go_to_error(event)

    def _refresh_output(self):
        """Read the output buffer from the process and append the text."""
        #we should decode the bytes!
        currentProcess = self._parent.currentProcess
        text = currentProcess.readAllStandardOutput().data().decode('utf8')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        self.textCursor().insertText(text, self.plain_format)

    def _refresh_error(self):
        """Read the error buffer from the process and append the text."""
        #we should decode the bytes!
        cursor = self.textCursor()
        currentProcess = self._parent.currentProcess
        text = currentProcess.readAllStandardError().data().decode('utf8')
        text_lines = text.split('\n')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        for t in text_lines:
            cursor.insertBlock()
            if self.patLink.match(t):
                cursor.insertText(t, self.error_format)
            else:
                cursor.insertText(t, self.plain_format)

    def go_to_error(self, event):
        """Resolve the link and take the user to the error line."""
        cursor = self.cursorForPosition(event.pos())
        text = cursor.block().text()
        if self.patLink.match(text):
            file_path, lineno = self._parse_traceback(unicode(text))
            main = main_container.MainContainer()
            main.open_file(file_path)
            main.editor_jump_to_line(lineno=int(lineno) - 1)

    def _parse_traceback(self, text):
        """
        Parse a line of python traceback and returns
        a tuple with (file_name, lineno)
        """
        file_word_index = text.find('File')
        comma_min_index = text.find(',')
        comma_max_index = text.rfind(',')
        file_name = text[file_word_index + 6:comma_min_index - 1]
        lineno = text[comma_min_index + 7:comma_max_index]
        return (file_name, lineno)

    def contextMenuEvent(self, event):
        """Show a context menu for the Plain Text widget."""
        popup_menu = self.createStandardContextMenu()

        menuOutput = QMenu(self.tr("Output"))
        cleanAction = menuOutput.addAction(self.tr("Clean"))
        popup_menu.insertSeparator(popup_menu.actions()[0])
        popup_menu.insertMenu(popup_menu.actions()[0], menuOutput)

        # This is a hack because if we leave the widget text empty
        # it throw a violent segmentation fault in start_process
        self.connect(cleanAction, SIGNAL("triggered()"),
            lambda: self.setPlainText('\n\n'))

        popup_menu.exec_(event.globalPos())
Ejemplo n.º 22
0
class OutputWidget(QPlainTextEdit):

    def __init__(self, parent):
        QPlainTextEdit.__init__(self, parent)
        self._parent = parent
        self.setReadOnly(True)
        styles.set_style(self, 'editor')
        self.maxValue = 0
        self.actualValue = 0
        #traceback pattern
        self.patLink = re.compile(r'(\s)*File "(.*?)", line \d.+')
        #formats
        self.plain_format = QTextCharFormat()
        self.error_format = QTextCharFormat()
        self.error_format.setAnchor(True)
        self.error_format.setFontUnderline(True)
        self.error_format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
        self.error_format.setUnderlineColor(Qt.red)
        self.error_format.setForeground(Qt.blue)
        self.error_format.setToolTip(self.tr("Click to show the source"))

        self.connect(self, SIGNAL("blockCountChanged(int)"), self._scroll_area)

    def _scroll_area(self):
        if self.actualValue == self.maxValue:
            self.moveCursor(QTextCursor.End)

    def mousePressEvent(self, event):
        QPlainTextEdit.mousePressEvent(self, event)
        self.go_to_error(event)

    def _refresh_output(self):
        #we should decode the bytes!
        text = self._parent._proc.readAllStandardOutput().data().decode('utf8')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        self.textCursor().insertText(text)

    def _refresh_error(self):
        #we should decode the bytes!
        cursor = self.textCursor()
        text = self._parent._proc.readAllStandardError().data().decode('utf8')
        text_lines = text.split('\n')
        verticalScroll = self.verticalScrollBar()
        self.actualValue = verticalScroll.value()
        self.maxValue = verticalScroll.maximum()
        for t in text_lines:
            cursor.insertBlock()
            if self.patLink.match(t):
                cursor.insertText(t, self.error_format)
            else:
                cursor.insertText(t, self.plain_format)

    def insert_input(self, text):
        self.textCursor().insertText(text)

    def go_to_error(self, event):
        cursor = self.cursorForPosition(event.pos())
        text = cursor.block().text()
        if self.patLink.match(text):
            file_path, lineno = self._parse_traceback(unicode(text))
            main = main_container.MainContainer()
            main.open_file(file_path)
            main.editor_jump_to_line(lineno=int(lineno) - 1)

    def _parse_traceback(self, text):
        """
        Parse a line of python traceback and returns
        a tuple with (file_name, lineno)
        """
        file_word_index = text.find('File')
        comma_min_index = text.find(',')
        comma_max_index = text.rfind(',')
        file_name = text[file_word_index + 6:comma_min_index - 1]
        lineno = text[comma_min_index + 7:comma_max_index]
        return (file_name, lineno)

    def contextMenuEvent(self, event):
        popup_menu = self.createStandardContextMenu()

        menuOutput = QMenu(self.tr("Output"))
        cleanAction = menuOutput.addAction(self.tr("Clean"))
        popup_menu.insertSeparator(popup_menu.actions()[0])
        popup_menu.insertMenu(popup_menu.actions()[0], menuOutput)

        self.connect(cleanAction, SIGNAL("triggered()"), self.clear)

        popup_menu.exec_(event.globalPos())