Example #1
0
    def __init__(self, parent, font=None, lexer=None):
        super(AdvancedCodeWidget, self).__init__(parent)

        self.code = CodeWidget(self, font=font, lexer=lexer)
        self.find = FindWidget(self)
        self.find.hide()
        self.replace = ReplaceWidget(self)
        self.replace.hide()
        self.replace.replace_button.setEnabled(False)
        self.replace.replace_all_button.setEnabled(False)

        self.active_find_widget = None
        self.previous_find_widget = None

        self.code.selectionChanged.connect(self._update_replace_enabled)

        self.find.line_edit.returnPressed.connect(self.find_next)
        self.find.next_button.clicked.connect(self.find_next)
        self.find.prev_button.clicked.connect(self.find_prev)

        self.replace.line_edit.returnPressed.connect(self.find_next)
        self.replace.line_edit.textChanged.connect(
            self._update_replace_all_enabled)
        self.replace.next_button.clicked.connect(self.find_next)
        self.replace.prev_button.clicked.connect(self.find_prev)
        self.replace.replace_button.clicked.connect(self.replace_next)
        self.replace.replace_all_button.clicked.connect(self.replace_all)

        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.code)
        layout.addWidget(self.find)
        layout.addWidget(self.replace)

        self.setLayout(layout)
Example #2
0
    def __init__(self, parent, font=None, lexer=None):
        super(AdvancedCodeWidget, self).__init__(parent)

        self.code = CodeWidget(self, font=font, lexer=lexer)
        self.find = FindWidget(self)
        self.find.hide()
        self.replace = ReplaceWidget(self)
        self.replace.hide()
        self.replace.replace_button.setEnabled(False)
        self.replace.replace_all_button.setEnabled(False)

        self.active_find_widget = None
        self.previous_find_widget = None

        self.code.selectionChanged.connect(self._update_replace_enabled)

        self.find.line_edit.returnPressed.connect(self.find_next)
        self.find.next_button.clicked.connect(self.find_next)
        self.find.prev_button.clicked.connect(self.find_prev)

        self.replace.line_edit.returnPressed.connect(self.find_next)
        self.replace.line_edit.textChanged.connect(
            self._update_replace_all_enabled)
        self.replace.next_button.clicked.connect(self.find_next)
        self.replace.prev_button.clicked.connect(self.find_prev)
        self.replace.replace_button.clicked.connect(self.replace_next)
        self.replace.replace_all_button.clicked.connect(self.replace_all)

        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.code)
        layout.addWidget(self.find)
        layout.addWidget(self.replace)

        self.setLayout(layout)
Example #3
0
class AdvancedCodeWidget(QtGui.QWidget):
    """ Advanced widget for viewing and editing code, with support
        for search & replace
    """

    ###########################################################################
    # AdvancedCodeWidget interface
    ###########################################################################

    def __init__(self, parent, font=None, lexer=None):
        super(AdvancedCodeWidget, self).__init__(parent)

        self.code = CodeWidget(self, font=font, lexer=lexer)
        self.find = FindWidget(self)
        self.find.hide()
        self.replace = ReplaceWidget(self)
        self.replace.hide()
        self.replace.replace_button.setEnabled(False)
        self.replace.replace_all_button.setEnabled(False)

        self.active_find_widget = None
        self.previous_find_widget = None

        self.code.selectionChanged.connect(self._update_replace_enabled)

        self.find.line_edit.returnPressed.connect(self.find_next)
        self.find.next_button.clicked.connect(self.find_next)
        self.find.prev_button.clicked.connect(self.find_prev)

        self.replace.line_edit.returnPressed.connect(self.find_next)
        self.replace.line_edit.textChanged.connect(
            self._update_replace_all_enabled)
        self.replace.next_button.clicked.connect(self.find_next)
        self.replace.prev_button.clicked.connect(self.find_prev)
        self.replace.replace_button.clicked.connect(self.replace_next)
        self.replace.replace_all_button.clicked.connect(self.replace_all)

        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.code)
        layout.addWidget(self.find)
        layout.addWidget(self.replace)

        self.setLayout(layout)

    def lines(self):
        """ Return the number of lines.
        """
        return self.code.lines()

    def set_line_column(self, line, column):
        """ Move the cursor to a particular line/column position.
        """
        self.code.set_line_column(line, column)

    def get_line_column(self):
        """ Get the current line and column numbers.
        """
        return self.code.get_line_column()

    def get_selected_text(self):
        """ Return the currently selected text.
        """
        return self.code.get_selected_text()

    def set_info_lines(self, info_lines):
        self.code.set_info_lines(info_lines)

    def set_warn_lines(self, warn_lines):
        self.code.set_warn_lines(warn_lines)

    def set_error_lines(self, error_lines):
        self.code.set_error_lines(error_lines)

    def enable_find(self):
        self.replace.hide()
        self.find.show()
        self.find.setFocus()
        if (self.active_find_widget == self.replace
                or (not self.active_find_widget
                    and self.previous_find_widget == self.replace)):
            self.find.line_edit.setText(self.replace.line_edit.text())
        self.find.line_edit.selectAll()
        self.active_find_widget = self.find

    def enable_replace(self):
        self.find.hide()
        self.replace.show()
        self.replace.setFocus()
        if (self.active_find_widget == self.find
                or (not self.active_find_widget
                    and self.previous_find_widget == self.find)):
            self.replace.line_edit.setText(self.find.line_edit.text())
        self.replace.line_edit.selectAll()
        self.active_find_widget = self.replace

    def find_in_document(self, search_text, direction='forward', replace=None):
        """ Finds the next occurance of the desired text and optionally
            replaces it. If 'replace' is None, a regular search will
            be executed, otherwise it will replace the occurance with
            the value of 'replace'.

            Returns the number of occurances found (0 or 1)
        """

        if not search_text:
            return
        wrap = self.active_find_widget.wrap_action.isChecked()

        document = self.code.document()
        find_cursor = None

        flags = QtGui.QTextDocument.FindFlags(0)
        if self.active_find_widget.case_action.isChecked():
            flags |= QtGui.QTextDocument.FindCaseSensitively
        if self.active_find_widget.word_action.isChecked():
            flags |= QtGui.QTextDocument.FindWholeWords
        if direction == 'backward':
            flags |= QtGui.QTextDocument.FindBackward

        find_cursor = document.find(search_text, self.code.textCursor(), flags)
        if find_cursor.isNull() and wrap:
            if direction == 'backward':
                find_cursor = document.find(search_text,
                                            document.characterCount() - 1,
                                            flags)
            else:
                find_cursor = document.find(search_text, 0, flags)

        if not find_cursor.isNull():
            if replace is not None:
                find_cursor.beginEditBlock()
                find_cursor.removeSelectedText()
                find_cursor.insertText(replace)
                find_cursor.endEditBlock()
                find_cursor.movePosition(QtGui.QTextCursor.Left,
                                         QtGui.QTextCursor.MoveAnchor,
                                         len(replace))
                find_cursor.movePosition(QtGui.QTextCursor.Right,
                                         QtGui.QTextCursor.KeepAnchor,
                                         len(replace))
                self.code.setTextCursor(find_cursor)
            else:
                self.code.setTextCursor(find_cursor)
            return find_cursor
        else:
            #else not found: beep or indicate?
            return None

    def find_next(self):
        if not self.active_find_widget:
            self.enable_find()
        search_text = unicode(self.active_find_widget.line_edit.text())
        cursor = self.find_in_document(search_text=search_text)

        if cursor:
            return 1
        return 0

    def find_prev(self):
        if not self.active_find_widget:
            self.enable_find()
        search_text = unicode(self.active_find_widget.line_edit.text())
        cursor = self.find_in_document(search_text=search_text,
                                       direction='backward')
        if cursor:
            return 1
        return 0

    def replace_next(self):
        search_text = self.replace.line_edit.text()
        replace_text = self.replace.replace_edit.text()

        cursor = self.code.textCursor()
        if cursor.selectedText() == search_text:
            cursor.beginEditBlock()
            cursor.removeSelectedText()
            cursor.insertText(replace_text)
            cursor.endEditBlock()
            return self.find_next()
        return 0

    def replace_all(self):
        search_text = unicode(self.replace.line_edit.text())
        replace_text = unicode(self.replace.replace_edit.text())

        count = 0
        cursor = self.code.textCursor()
        cursor.beginEditBlock()
        while self.find_in_document(search_text=search_text,
                                    replace=replace_text) != None:
            count += 1
        cursor.endEditBlock()
        return count

    def print_(self, printer):
        """ Convenience method to call 'print_' on the CodeWidget.
        """
        self.code.print_(printer)

    def ensureCursorVisible(self):
        self.code.ensureCursorVisible()

    def centerCursor(self):
        self.code.centerCursor()

    ###########################################################################
    # QWidget interface
    ###########################################################################

    def keyPressEvent(self, event):
        key_sequence = QtGui.QKeySequence(event.key() + int(event.modifiers()))

        if key_sequence.matches(QtGui.QKeySequence.Find):
            self.enable_find()
        elif key_sequence.matches(QtGui.QKeySequence.Replace):
            self.enable_replace()
        elif key_sequence.matches(QtCore.Qt.Key_Escape):
            if self.active_find_widget:
                self.find.hide()
                self.replace.hide()
                self.code.setFocus()
                self.previous_find_widget = self.active_find_widget
                self.active_find_widget = None

        return super(AdvancedCodeWidget, self).keyPressEvent(event)

    ###########################################################################
    # Private methods
    ###########################################################################

    def _update_replace_enabled(self):
        selection = self.code.textCursor().selectedText()
        find_text = self.replace.line_edit.text()
        self.replace.replace_button.setEnabled(selection == find_text)

    def _update_replace_all_enabled(self, text):
        self.replace.replace_all_button.setEnabled(len(text))
Example #4
0
class AdvancedCodeWidget(QtGui.QWidget):
    """ Advanced widget for viewing and editing code, with support
        for search & replace
    """

    ###########################################################################
    # AdvancedCodeWidget interface
    ###########################################################################

    def __init__(self, parent, font=None, lexer=None):
        super(AdvancedCodeWidget, self).__init__(parent)

        self.code = CodeWidget(self, font=font, lexer=lexer)
        self.find = FindWidget(self)
        self.find.hide()
        self.replace = ReplaceWidget(self)
        self.replace.hide()
        self.replace.replace_button.setEnabled(False)
        self.replace.replace_all_button.setEnabled(False)

        self.active_find_widget = None
        self.previous_find_widget = None

        self.code.selectionChanged.connect(self._update_replace_enabled)

        self.find.line_edit.returnPressed.connect(self.find_next)
        self.find.next_button.clicked.connect(self.find_next)
        self.find.prev_button.clicked.connect(self.find_prev)

        self.replace.line_edit.returnPressed.connect(self.find_next)
        self.replace.line_edit.textChanged.connect(
            self._update_replace_all_enabled)
        self.replace.next_button.clicked.connect(self.find_next)
        self.replace.prev_button.clicked.connect(self.find_prev)
        self.replace.replace_button.clicked.connect(self.replace_next)
        self.replace.replace_all_button.clicked.connect(self.replace_all)

        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.code)
        layout.addWidget(self.find)
        layout.addWidget(self.replace)

        self.setLayout(layout)

    def lines(self):
        """ Return the number of lines.
        """
        return self.code.lines()

    def set_line_column(self, line, column):
        """ Move the cursor to a particular line/column position.
        """
        self.code.set_line_column(line, column)

    def get_line_column(self):
        """ Get the current line and column numbers.
        """
        return self.code.get_line_column()

    def get_selected_text(self):
        """ Return the currently selected text.
        """
        return self.code.get_selected_text()

    def set_info_lines(self, info_lines):
        self.code.set_info_lines(info_lines)

    def set_warn_lines(self, warn_lines):
        self.code.set_warn_lines(warn_lines)

    def set_error_lines(self, error_lines):
        self.code.set_error_lines(error_lines)

    def enable_find(self):
        self.replace.hide()
        self.find.show()
        self.find.setFocus()
        if (self.active_find_widget == self.replace or
            (not self.active_find_widget and
             self.previous_find_widget == self.replace)):
            self.find.line_edit.setText(self.replace.line_edit.text())
        self.find.line_edit.selectAll()
        self.active_find_widget = self.find

    def enable_replace(self):
        self.find.hide()
        self.replace.show()
        self.replace.setFocus()
        if (self.active_find_widget == self.find or
            (not self.active_find_widget and
             self.previous_find_widget == self.find)):
            self.replace.line_edit.setText(self.find.line_edit.text())
        self.replace.line_edit.selectAll()
        self.active_find_widget = self.replace

    def find_in_document(self, search_text, direction='forward', replace=None):
        """ Finds the next occurance of the desired text and optionally
            replaces it. If 'replace' is None, a regular search will
            be executed, otherwise it will replace the occurance with
            the value of 'replace'.

            Returns the number of occurances found (0 or 1)
        """

        if not search_text:
            return
        wrap = self.active_find_widget.wrap_action.isChecked()

        document = self.code.document()
        find_cursor = None

        flags = QtGui.QTextDocument.FindFlags(0)
        if self.active_find_widget.case_action.isChecked():
            flags |= QtGui.QTextDocument.FindCaseSensitively
        if self.active_find_widget.word_action.isChecked():
            flags |= QtGui.QTextDocument.FindWholeWords
        if direction == 'backward':
            flags |= QtGui.QTextDocument.FindBackward

        find_cursor = document.find(search_text, self.code.textCursor(), flags)
        if find_cursor.isNull() and wrap:
            if direction == 'backward':
                find_cursor = document.find(search_text, document.characterCount()-1, flags)
            else:
                find_cursor = document.find(search_text, 0, flags)

        if not find_cursor.isNull():
            if replace is not None:
                find_cursor.beginEditBlock()
                find_cursor.removeSelectedText()
                find_cursor.insertText(replace)
                find_cursor.endEditBlock()
                find_cursor.movePosition(
                    QtGui.QTextCursor.Left, QtGui.QTextCursor.MoveAnchor,len(replace))
                find_cursor.movePosition(
                    QtGui.QTextCursor.Right, QtGui.QTextCursor.KeepAnchor,len(replace))
                self.code.setTextCursor(find_cursor)
            else:
                self.code.setTextCursor(find_cursor)
            return find_cursor
        else:
            #else not found: beep or indicate?
            return None

    def find_next(self):
        if not self.active_find_widget:
            self.enable_find()
        search_text = unicode(self.active_find_widget.line_edit.text())
        cursor = self.find_in_document(search_text=search_text)

        if cursor:
            return 1
        return 0

    def find_prev(self):
        if not self.active_find_widget:
            self.enable_find()
        search_text = unicode(self.active_find_widget.line_edit.text())
        cursor = self.find_in_document(search_text=search_text,
                                       direction='backward')
        if cursor:
            return 1
        return 0

    def replace_next(self):
        search_text = self.replace.line_edit.text()
        replace_text = self.replace.replace_edit.text()

        cursor = self.code.textCursor()
        if cursor.selectedText() == search_text:
            cursor.beginEditBlock()
            cursor.removeSelectedText()
            cursor.insertText(replace_text)
            cursor.endEditBlock()
            return self.find_next()
        return 0

    def replace_all(self):
        search_text = unicode(self.replace.line_edit.text())
        replace_text = unicode(self.replace.replace_edit.text())

        count = 0
        cursor = self.code.textCursor()
        cursor.beginEditBlock()
        while self.find_in_document(search_text=search_text,
                                    replace=replace_text) != None:
            count += 1
        cursor.endEditBlock()
        return count

    def print_(self, printer):
        """ Convenience method to call 'print_' on the CodeWidget.
        """
        self.code.print_(printer)

    def ensureCursorVisible(self):
        self.code.ensureCursorVisible()

    def centerCursor(self):
        self.code.centerCursor()

    ###########################################################################
    # QWidget interface
    ###########################################################################

    def keyPressEvent(self, event):
        key_sequence = QtGui.QKeySequence(event.key() + int(event.modifiers()))

        if key_sequence.matches(QtGui.QKeySequence.Find):
            self.enable_find()
        elif key_sequence.matches(QtGui.QKeySequence.Replace):
            self.enable_replace()
        elif key_sequence.matches(QtGui.QKeySequence(QtCore.Qt.Key_Escape)):
            if self.active_find_widget:
                self.find.hide()
                self.replace.hide()
                self.code.setFocus()
                self.previous_find_widget = self.active_find_widget
                self.active_find_widget = None

        return super(AdvancedCodeWidget, self).keyPressEvent(event)

    ###########################################################################
    # Private methods
    ###########################################################################

    def _update_replace_enabled(self):
        selection = self.code.textCursor().selectedText()
        find_text = self.replace.line_edit.text()
        self.replace.replace_button.setEnabled(selection == find_text)

    def _update_replace_all_enabled(self, text):
        self.replace.replace_all_button.setEnabled(len(text))