Example #1
0
class ReplaceWidget(FindReplaceBase):
    """ Find and replace in the current file widget """
    def __init__(self, editorsManager, parent=None):

        FindReplaceBase.__init__(self, editorsManager, parent)
        self._skip = True
        prj = GlobalData().project
        self.findHistory = prj.findHistory
        self.replaceHistory = prj.replaceHistory

        # Additional UI elements
        self.replaceLabel = QLabel(self)
        self.replaceLabel.setText("Replace:")

        self.replaceCombo = ComboBoxNoUndo(self)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.replaceCombo.sizePolicy().hasHeightForWidth())
        self.replaceCombo.setSizePolicy(sizePolicy)
        self.replaceCombo.setEditable(True)
        self.replaceCombo.setInsertPolicy(QComboBox.InsertAtTop)
        self.replaceCombo.setAutoCompletion(False)
        self.replaceCombo.setDuplicatesEnabled(False)
        self.replaceCombo.setEnabled(False)

        self.replaceButton = QToolButton(self)
        self.replaceButton.setToolTip("Replace current occurrence")
        self.replaceButton.setIcon(PixmapCache().getIcon("replace.png"))
        self.replaceButton.setEnabled(False)
        self.replaceButton.clicked.connect(self.__onReplace)
        self.replaceButton.setIconSize(QSize(24, 16))

        self.replaceAllButton = QToolButton(self)
        self.replaceAllButton.setToolTip("Replace all occurrences")
        self.replaceAllButton.setIcon(PixmapCache().getIcon("replace-all.png"))
        self.replaceAllButton.setIconSize(QSize(24, 16))
        self.replaceAllButton.setEnabled(False)
        self.replaceAllButton.clicked.connect(self.__onReplaceAll)

        self.replaceAndMoveButton = QToolButton(self)
        self.replaceAndMoveButton.setToolTip(
            "Replace current occurrence and move to the next match")
        self.replaceAndMoveButton.setIcon(
            PixmapCache().getIcon("replace-move.png"))
        self.replaceAndMoveButton.setIconSize(QSize(24, 16))
        self.replaceAndMoveButton.setEnabled(False)
        self.replaceAndMoveButton.clicked.connect(self.__onReplaceAndMove)

        self.gridLayout = QGridLayout(self)
        self.gridLayout.setMargin(0)

        self.gridLayout.addWidget(self.closeButton, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.findLabel, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.findtextCombo, 0, 2, 1, 1)
        self.gridLayout.addWidget(self.findPrevButton, 0, 3, 1, 1)
        self.gridLayout.addWidget(self.findNextButton, 0, 4, 1, 1)
        self.gridLayout.addWidget(self.caseCheckBox, 0, 5, 1, 1)
        self.gridLayout.addWidget(self.wordCheckBox, 0, 6, 1, 1)
        self.gridLayout.addWidget(self.regexpCheckBox, 0, 7, 1, 1)

        self.gridLayout.addWidget(self.replaceLabel, 1, 1, 1, 1)
        self.gridLayout.addWidget(self.replaceCombo, 1, 2, 1, 1)
        self.gridLayout.addWidget(self.replaceButton, 1, 3, 1, 1)
        self.gridLayout.addWidget(self.replaceAndMoveButton, 1, 4, 1, 1)
        self.gridLayout.addWidget(self.replaceAllButton, 1, 5, 1, 1)

        self.setTabOrder(self.findtextCombo, self.replaceCombo)
        self.setTabOrder(self.replaceCombo, self.caseCheckBox)
        self.setTabOrder(self.caseCheckBox, self.wordCheckBox)
        self.setTabOrder(self.wordCheckBox, self.regexpCheckBox)
        self.setTabOrder(self.regexpCheckBox, self.findNextButton)
        self.setTabOrder(self.findNextButton, self.findPrevButton)
        self.setTabOrder(self.findPrevButton, self.replaceAndMoveButton)
        self.setTabOrder(self.replaceButton, self.replaceAllButton)
        self.setTabOrder(self.replaceAndMoveButton, self.replaceAllButton)
        self.setTabOrder(self.replaceAllButton, self.closeButton)

        GlobalData().project.projectChanged.connect(self.__onProjectChanged)
        self.findNextButton.clicked.connect(self.onNext)
        self.findPrevButton.clicked.connect(self.onPrev)
        self.incSearchDone.connect(self.__onSearchDone)
        self.replaceCombo.editTextChanged.connect(self.__onReplaceTextChanged)
        self.replaceCombo.lineEdit().returnPressed.connect(
            self.__onReplaceAndMove)
        self.__connected = False
        self.__replaceCouldBeEnabled = False
        self._skip = False

        return

    def updateStatus(self):
        " Triggered when the current tab is changed "

        FindReplaceBase.updateStatus(self)
        if self._currentWidget.getType(
        ) == MainWindowTabWidgetBase.VCSAnnotateViewer:
            self.findtextCombo.setEnabled(False)
            self.findPrevButton.setEnabled(False)
            self.findNextButton.setEnabled(False)
            self.caseCheckBox.setEnabled(False)
            self.wordCheckBox.setEnabled(False)
            self.regexpCheckBox.setEnabled(False)
            self.replaceCombo.setEnabled(False)
            self.replaceAllButton.setEnabled(False)
            self.replaceButton.setEnabled(False)
            self.replaceAndMoveButton.setEnabled(False)
            return

        self.__updateReplaceAllButtonStatus()

        if self._isTextEditor:
            self.__cursorPositionChanged(self._currentWidget.getLine(),
                                         self._currentWidget.getPos())
        else:
            self.replaceButton.setEnabled(False)
            self.replaceAndMoveButton.setEnabled(False)
            self.__replaceCouldBeEnabled = False

        if self.__connected:
            self.__unsubscribeFromCursorChange()
        self.__subscribeToCursorChangePos()
        return

    def __updateReplaceAllButtonStatus(self):
        " Updates the replace all button status "
        self.replaceCombo.setEnabled(self._isTextEditor)
        textAvailable = self.findtextCombo.currentText() != ""
        self.replaceAllButton.setEnabled(self._isTextEditor and textAvailable)
        return

    def show(self, text=''):
        " Overriden show method "
        self._skip = True
        self.replaceCombo.clear()
        self.replaceCombo.addItems(self.replaceHistory)
        self.replaceCombo.setEditText('')
        self._skip = False

        FindReplaceBase.show(self, text)
        self.__subscribeToCursorChangePos()
        return

    def hide(self):
        " Overriden hide method "
        if self.__connected:
            self.__unsubscribeFromCursorChange()
        FindReplaceBase.hide(self)
        return

    def __onProjectChanged(self, what):
        " Triggered when a project is changed "
        if what == CodimensionProject.CompleteProject:
            prj = GlobalData().project
            self._skip = True
            self.findHistory = prj.findHistory
            self.findtextCombo.clear()
            self.findtextCombo.setEditText('')
            self.findtextCombo.addItems(self.findHistory)
            self.replaceHistory = prj.replaceHistory
            self.replaceCombo.clear()
            self.replaceCombo.setEditText('')
            self.replaceCombo.addItems(self.replaceHistory)
            self._skip = False
        return

    def __onSearchDone(self, found):
        " Triggered when incremental search is done "

        self.replaceButton.setEnabled(found)
        self.replaceAndMoveButton.setEnabled(found)
        self.replaceAllButton.setEnabled(found)
        self.__replaceCouldBeEnabled = True
        return

    def __onReplaceTextChanged(self, text):
        " Triggered when replace with text is changed "
        self.__updateReplaceAllButtonStatus()
        self.replaceButton.setEnabled(self.__replaceCouldBeEnabled)
        self.replaceAndMoveButton.setEnabled(self.__replaceCouldBeEnabled)
        return

    def __subscribeToCursorChangePos(self):
        " Subscribes for the cursor position notification "
        if self._editor is not None:
            self._editor.cursorPositionChanged.connect(
                self.__cursorPositionChanged)
            self.__connected = True
        return

    def __unsubscribeFromCursorChange(self):
        " Unsubscribes from the cursor position notification "
        if self._editor is not None:
            try:
                self._editor.cursorPositionChanged.disconnect(
                    self.__cursorPositionChanged)
            except:
                pass
            self.__connected = False
        return

    def __cursorPositionChanged(self, line, pos):
        " Triggered when the cursor position is changed "
        if self._searchSupport.hasEditor(self._editorUUID):
            searchAttributes = self._searchSupport.get(self._editorUUID)
            enable = line == searchAttributes.match[ 0 ] and \
                     pos == searchAttributes.match[ 1 ]
        else:
            enable = False

        self.replaceButton.setEnabled(enable)
        self.replaceAndMoveButton.setEnabled(enable)
        self.__replaceCouldBeEnabled = enable
        return

    def __onReplaceAll(self):
        " Triggered when replace all button is clicked "

        text = self.findtextCombo.currentText()
        isRegexp = self.regexpCheckBox.isChecked()
        isCase = self.caseCheckBox.isChecked()
        isWord = self.wordCheckBox.isChecked()
        replaceText = self.replaceCombo.currentText()

        self.__updateReplaceHistory(text, replaceText)

        # Check that there is at least one target to replace
        found = self._editor.findFirstTarget(text, isRegexp, isCase, isWord, 0,
                                             0)
        if not found:
            GlobalData().mainWindow.showStatusBarMessage(
                "No occurrences of '" + text + "' found. Nothing is replaced.",
                0)
            return

        # There is something matching
        count = 0
        self._editor.beginUndoAction()
        while found:
            self._editor.replaceTarget(str(replaceText))
            count += 1
            found = self._editor.findNextTarget()
        self._editor.endUndoAction()
        self.replaceButton.setEnabled(False)
        self.replaceAndMoveButton.setEnabled(False)
        self.__replaceCouldBeEnabled = False

        suffix = ""
        if count > 1:
            suffix = "s"
        GlobalData().mainWindow.showStatusBarMessage(
            str(count) + " occurrence" + suffix + " replaced.", 0)
        GlobalData().mainWindow.clearStatusBarMessage(1)
        return

    def __onReplace(self):
        " Triggered when replace current occurrence button is clicked "
        replaceText = self.replaceCombo.currentText()
        text = self.findtextCombo.currentText()
        isRegexp = self.regexpCheckBox.isChecked()
        isCase = self.caseCheckBox.isChecked()
        isWord = self.wordCheckBox.isChecked()
        searchAttributes = self._searchSupport.get(self._editorUUID)

        self.__updateReplaceHistory(text, replaceText)

        found = self._editor.findFirstTarget(text, isRegexp, isCase, isWord,
                                             searchAttributes.match[0],
                                             searchAttributes.match[1])
        if found:
            if self._editor.replaceTarget(str(replaceText)):
                GlobalData().mainWindow.showStatusBarMessage(
                    "1 occurrence "
                    "replaced.", 0)
                GlobalData().mainWindow.clearStatusBarMessage(1)
                # Positioning cursor to the end of the replaced text helps
                # to avoid problems of replacing 'text' with 'prefix_text'
                searchAttributes.match[1] += len(replaceText)
                self._editor.setCursorPosition(searchAttributes.match[0],
                                               searchAttributes.match[1])
                self.replaceButton.setEnabled(False)
                self.replaceAndMoveButton.setEnabled(False)
            else:
                GlobalData().mainWindow.showStatusBarMessage(
                    "No occurrences "
                    "replaced.", 0)
            # This will prevent highlighting the improper editor positions
            searchAttributes.match = [-1, -1, -1]
        return

    def __onReplaceAndMove(self):
        " Triggered when replace-and-move button is clicked "
        buttonFocused = self.replaceAndMoveButton.hasFocus()
        self.__onReplace()
        self.onNext(False)

        if buttonFocused:
            self.replaceAndMoveButton.setFocus()
        return

    def __updateReplaceHistory(self, text, replaceText):
        " Updates the history in the project and in the combo boxes "

        changedWhat = self._addToHistory(self.findtextCombo, self.findHistory,
                                         text)
        changedReplace = self._addToHistory(self.replaceCombo,
                                            self.replaceHistory, replaceText)
        if changedWhat or changedReplace:
            prj = GlobalData().project
            prj.setReplaceHistory(self.findHistory, self.replaceHistory)
        return

    def onNext(self, clearSBMessage=True):
        " Triggered when the find next button is clicked "
        oldLine = self._currentWidget.getLine()
        oldPos = self._currentWidget.getPos()
        FindReplaceBase.onNext(self, clearSBMessage)
        if oldLine == self._currentWidget.getLine() and \
           oldPos == self._currentWidget.getPos():
            FindReplaceBase.onNext(self, clearSBMessage)

        self.__updateReplaceHistory(self.findtextCombo.currentText(),
                                    self.replaceCombo.currentText())
        return

    def onPrev(self):
        " Triggered when the find previous button is clicked "
        FindReplaceBase.onPrev(self)
        self.__updateReplaceHistory(self.findtextCombo.currentText(),
                                    self.replaceCombo.currentText())
        return
class ReplaceWidget(FindReplaceBase):
    """ Find and replace in the current file widget """

    def __init__(self, editorsManager, parent=None):

        FindReplaceBase.__init__(self, editorsManager, parent)
        self._skip = True
        prj = GlobalData().project
        self.findHistory = prj.findHistory
        self.replaceHistory = prj.replaceHistory

        # Additional UI elements
        self.replaceLabel = QLabel(self)
        self.replaceLabel.setText("Replace:")

        self.replaceCombo = ComboBoxNoUndo(self)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.replaceCombo.sizePolicy().hasHeightForWidth())
        self.replaceCombo.setSizePolicy(sizePolicy)
        self.replaceCombo.setEditable(True)
        self.replaceCombo.setInsertPolicy(QComboBox.InsertAtTop)
        self.replaceCombo.setAutoCompletion(False)
        self.replaceCombo.setDuplicatesEnabled(False)
        self.replaceCombo.setEnabled(False)

        self.replaceButton = QToolButton(self)
        self.replaceButton.setToolTip("Replace current occurrence")
        self.replaceButton.setIcon(PixmapCache().getIcon("replace.png"))
        self.replaceButton.setEnabled(False)
        self.replaceButton.clicked.connect(self.__onReplace)
        self.replaceButton.setIconSize(QSize(24, 16))

        self.replaceAllButton = QToolButton(self)
        self.replaceAllButton.setToolTip("Replace all occurrences")
        self.replaceAllButton.setIcon(PixmapCache().getIcon("replace-all.png"))
        self.replaceAllButton.setIconSize(QSize(24, 16))
        self.replaceAllButton.setEnabled(False)
        self.replaceAllButton.clicked.connect(self.__onReplaceAll)

        self.replaceAndMoveButton = QToolButton(self)
        self.replaceAndMoveButton.setToolTip("Replace current occurrence and move to the next match")
        self.replaceAndMoveButton.setIcon(PixmapCache().getIcon("replace-move.png"))
        self.replaceAndMoveButton.setIconSize(QSize(24, 16))
        self.replaceAndMoveButton.setEnabled(False)
        self.replaceAndMoveButton.clicked.connect(self.__onReplaceAndMove)

        self.gridLayout = QGridLayout(self)
        self.gridLayout.setMargin(0)

        self.gridLayout.addWidget(self.closeButton, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.findLabel, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.findtextCombo, 0, 2, 1, 1)
        self.gridLayout.addWidget(self.findPrevButton, 0, 3, 1, 1)
        self.gridLayout.addWidget(self.findNextButton, 0, 4, 1, 1)
        self.gridLayout.addWidget(self.caseCheckBox, 0, 5, 1, 1)
        self.gridLayout.addWidget(self.wordCheckBox, 0, 6, 1, 1)
        self.gridLayout.addWidget(self.regexpCheckBox, 0, 7, 1, 1)

        self.gridLayout.addWidget(self.replaceLabel, 1, 1, 1, 1)
        self.gridLayout.addWidget(self.replaceCombo, 1, 2, 1, 1)
        self.gridLayout.addWidget(self.replaceButton, 1, 3, 1, 1)
        self.gridLayout.addWidget(self.replaceAndMoveButton, 1, 4, 1, 1)
        self.gridLayout.addWidget(self.replaceAllButton, 1, 5, 1, 1)

        self.setTabOrder(self.findtextCombo, self.replaceCombo)
        self.setTabOrder(self.replaceCombo, self.caseCheckBox)
        self.setTabOrder(self.caseCheckBox, self.wordCheckBox)
        self.setTabOrder(self.wordCheckBox, self.regexpCheckBox)
        self.setTabOrder(self.regexpCheckBox, self.findNextButton)
        self.setTabOrder(self.findNextButton, self.findPrevButton)
        self.setTabOrder(self.findPrevButton, self.replaceAndMoveButton)
        self.setTabOrder(self.replaceButton, self.replaceAllButton)
        self.setTabOrder(self.replaceAndMoveButton, self.replaceAllButton)
        self.setTabOrder(self.replaceAllButton, self.closeButton)

        GlobalData().project.projectChanged.connect(self.__onProjectChanged)
        self.findNextButton.clicked.connect(self.onNext)
        self.findPrevButton.clicked.connect(self.onPrev)
        self.incSearchDone.connect(self.__onSearchDone)
        self.replaceCombo.editTextChanged.connect(self.__onReplaceTextChanged)
        self.replaceCombo.lineEdit().returnPressed.connect(self.__onReplaceAndMove)
        self.__connected = False
        self.__replaceCouldBeEnabled = False
        self._skip = False

        return

    def updateStatus(self):
        " Triggered when the current tab is changed "

        FindReplaceBase.updateStatus(self)
        if self._currentWidget.getType() == MainWindowTabWidgetBase.VCSAnnotateViewer:
            self.findtextCombo.setEnabled(False)
            self.findPrevButton.setEnabled(False)
            self.findNextButton.setEnabled(False)
            self.caseCheckBox.setEnabled(False)
            self.wordCheckBox.setEnabled(False)
            self.regexpCheckBox.setEnabled(False)
            self.replaceCombo.setEnabled(False)
            self.replaceAllButton.setEnabled(False)
            self.replaceButton.setEnabled(False)
            self.replaceAndMoveButton.setEnabled(False)
            return

        self.__updateReplaceAllButtonStatus()

        if self._isTextEditor:
            self.__cursorPositionChanged(self._currentWidget.getLine(), self._currentWidget.getPos())
        else:
            self.replaceButton.setEnabled(False)
            self.replaceAndMoveButton.setEnabled(False)
            self.__replaceCouldBeEnabled = False

        if self.__connected:
            self.__unsubscribeFromCursorChange()
        self.__subscribeToCursorChangePos()
        return

    def __updateReplaceAllButtonStatus(self):
        " Updates the replace all button status "
        self.replaceCombo.setEnabled(self._isTextEditor)
        textAvailable = self.findtextCombo.currentText() != ""
        self.replaceAllButton.setEnabled(self._isTextEditor and textAvailable)
        return

    def show(self, text=""):
        " Overriden show method "
        self._skip = True
        self.replaceCombo.clear()
        self.replaceCombo.addItems(self.replaceHistory)
        self.replaceCombo.setEditText("")
        self._skip = False

        FindReplaceBase.show(self, text)
        self.__subscribeToCursorChangePos()
        return

    def hide(self):
        " Overriden hide method "
        if self.__connected:
            self.__unsubscribeFromCursorChange()
        FindReplaceBase.hide(self)
        return

    def __onProjectChanged(self, what):
        " Triggered when a project is changed "
        if what == CodimensionProject.CompleteProject:
            prj = GlobalData().project
            self._skip = True
            self.findHistory = prj.findHistory
            self.findtextCombo.clear()
            self.findtextCombo.setEditText("")
            self.findtextCombo.addItems(self.findHistory)
            self.replaceHistory = prj.replaceHistory
            self.replaceCombo.clear()
            self.replaceCombo.setEditText("")
            self.replaceCombo.addItems(self.replaceHistory)
            self._skip = False
        return

    def __onSearchDone(self, found):
        " Triggered when incremental search is done "

        self.replaceButton.setEnabled(found)
        self.replaceAndMoveButton.setEnabled(found)
        self.replaceAllButton.setEnabled(found)
        self.__replaceCouldBeEnabled = True
        return

    def __onReplaceTextChanged(self, text):
        " Triggered when replace with text is changed "
        self.__updateReplaceAllButtonStatus()
        self.replaceButton.setEnabled(self.__replaceCouldBeEnabled)
        self.replaceAndMoveButton.setEnabled(self.__replaceCouldBeEnabled)
        return

    def __subscribeToCursorChangePos(self):
        " Subscribes for the cursor position notification "
        if self._editor is not None:
            self._editor.cursorPositionChanged.connect(self.__cursorPositionChanged)
            self.__connected = True
        return

    def __unsubscribeFromCursorChange(self):
        " Unsubscribes from the cursor position notification "
        if self._editor is not None:
            try:
                self._editor.cursorPositionChanged.disconnect(self.__cursorPositionChanged)
            except:
                pass
            self.__connected = False
        return

    def __cursorPositionChanged(self, line, pos):
        " Triggered when the cursor position is changed "
        if self._searchSupport.hasEditor(self._editorUUID):
            searchAttributes = self._searchSupport.get(self._editorUUID)
            enable = line == searchAttributes.match[0] and pos == searchAttributes.match[1]
        else:
            enable = False

        self.replaceButton.setEnabled(enable)
        self.replaceAndMoveButton.setEnabled(enable)
        self.__replaceCouldBeEnabled = enable
        return

    def __onReplaceAll(self):
        " Triggered when replace all button is clicked "

        text = self.findtextCombo.currentText()
        isRegexp = self.regexpCheckBox.isChecked()
        isCase = self.caseCheckBox.isChecked()
        isWord = self.wordCheckBox.isChecked()
        replaceText = self.replaceCombo.currentText()

        self.__updateReplaceHistory(text, replaceText)

        # Check that there is at least one target to replace
        found = self._editor.findFirstTarget(text, isRegexp, isCase, isWord, 0, 0)
        if not found:
            GlobalData().mainWindow.showStatusBarMessage(
                "No occurrences of '" + text + "' found. Nothing is replaced.", 0
            )
            return

        # There is something matching
        count = 0
        self._editor.beginUndoAction()
        while found:
            self._editor.replaceTarget(str(replaceText))
            count += 1
            found = self._editor.findNextTarget()
        self._editor.endUndoAction()
        self.replaceButton.setEnabled(False)
        self.replaceAndMoveButton.setEnabled(False)
        self.__replaceCouldBeEnabled = False

        suffix = ""
        if count > 1:
            suffix = "s"
        GlobalData().mainWindow.showStatusBarMessage(str(count) + " occurrence" + suffix + " replaced.", 0)
        GlobalData().mainWindow.clearStatusBarMessage(1)
        return

    def __onReplace(self):
        " Triggered when replace current occurrence button is clicked "
        replaceText = self.replaceCombo.currentText()
        text = self.findtextCombo.currentText()
        isRegexp = self.regexpCheckBox.isChecked()
        isCase = self.caseCheckBox.isChecked()
        isWord = self.wordCheckBox.isChecked()
        searchAttributes = self._searchSupport.get(self._editorUUID)

        self.__updateReplaceHistory(text, replaceText)

        found = self._editor.findFirstTarget(
            text, isRegexp, isCase, isWord, searchAttributes.match[0], searchAttributes.match[1]
        )
        if found:
            if self._editor.replaceTarget(str(replaceText)):
                GlobalData().mainWindow.showStatusBarMessage("1 occurrence " "replaced.", 0)
                GlobalData().mainWindow.clearStatusBarMessage(1)
                # Positioning cursor to the end of the replaced text helps
                # to avoid problems of replacing 'text' with 'prefix_text'
                searchAttributes.match[1] += len(replaceText)
                self._editor.setCursorPosition(searchAttributes.match[0], searchAttributes.match[1])
                self.replaceButton.setEnabled(False)
                self.replaceAndMoveButton.setEnabled(False)
            else:
                GlobalData().mainWindow.showStatusBarMessage("No occurrences " "replaced.", 0)
            # This will prevent highlighting the improper editor positions
            searchAttributes.match = [-1, -1, -1]
        return

    def __onReplaceAndMove(self):
        " Triggered when replace-and-move button is clicked "
        buttonFocused = self.replaceAndMoveButton.hasFocus()
        self.__onReplace()
        self.onNext(False)

        if buttonFocused:
            self.replaceAndMoveButton.setFocus()
        return

    def __updateReplaceHistory(self, text, replaceText):
        " Updates the history in the project and in the combo boxes "

        changedWhat = self._addToHistory(self.findtextCombo, self.findHistory, text)
        changedReplace = self._addToHistory(self.replaceCombo, self.replaceHistory, replaceText)
        if changedWhat or changedReplace:
            prj = GlobalData().project
            prj.setReplaceHistory(self.findHistory, self.replaceHistory)
        return

    def onNext(self, clearSBMessage=True):
        " Triggered when the find next button is clicked "
        oldLine = self._currentWidget.getLine()
        oldPos = self._currentWidget.getPos()
        FindReplaceBase.onNext(self, clearSBMessage)
        if oldLine == self._currentWidget.getLine() and oldPos == self._currentWidget.getPos():
            FindReplaceBase.onNext(self, clearSBMessage)

        self.__updateReplaceHistory(self.findtextCombo.currentText(), self.replaceCombo.currentText())
        return

    def onPrev(self):
        " Triggered when the find previous button is clicked "
        FindReplaceBase.onPrev(self)
        self.__updateReplaceHistory(self.findtextCombo.currentText(), self.replaceCombo.currentText())
        return