--- a/E5Gui/E5TextEditSearchWidget.py Tue Oct 17 19:40:32 2017 +0200 +++ b/E5Gui/E5TextEditSearchWidget.py Wed Oct 18 19:16:28 2017 +0200 @@ -10,11 +10,9 @@ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt -from PyQt5.QtGui import QTextDocument +from PyQt5.QtGui import QPalette, QBrush, QColor, QTextDocument, QTextCursor from PyQt5.QtWidgets import QWidget -from E5Gui import E5MessageBox - from .Ui_E5TextEditSearchWidget import Ui_E5TextEditSearchWidget import UI.PixmapCache @@ -34,11 +32,17 @@ self.setupUi(self) self.__textedit = None + self.__texteditType = "" self.__findBackwards = True self.findPrevButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png")) self.findNextButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png")) + self.__defaultBaseColor = \ + self.findtextCombo.lineEdit().palette().color(QPalette.Base) + self.__defaultTextColor = \ + self.findtextCombo.lineEdit().palette().color(QPalette.Text) + self.findHistory = [] self.findtextCombo.setCompleter(None) @@ -46,16 +50,25 @@ self.__findByReturnPressed) self.__setSearchButtons(False) + self.infoLabel.hide() self.setFocusProxy(self.findtextCombo) - def attachTextEdit(self, textedit): + def attachTextEdit(self, textedit, editType="QTextEdit"): """ Public method to attach a QTextEdit widget. - @param textedit reference to the QTextEdit to be attached (QTextEdit) + @param textedit reference to the edit widget to be attached + @type QTextEdit, QWebEngineView or QWebView + @param editType type of the attached edit widget + @type str (one of "QTextEdit", "QWebEngineView" or "QWebView") """ + assert editType in ["QTextEdit", "QWebEngineView", "QWebView"] + self.__textedit = textedit + self.__texteditType = editType + + self.wordCheckBox.setVisible(editType == "QTextEdit") def keyPressEvent(self, event): """ @@ -75,6 +88,9 @@ @param txt text of the combobox (string) """ self.__setSearchButtons(txt != "") + + self.infoLabel.hide() + self.__setFindtextComboBackground(False) def __setSearchButtons(self, enabled): """ @@ -115,7 +131,13 @@ if not self.__textedit: return + self.infoLabel.clear() + self.infoLabel.hide() + self.__setFindtextComboBackground(False) + txt = self.findtextCombo.currentText() + if not txt: + return self.__findBackwards = backwards # This moves any previous occurrence of this statement to the head @@ -126,6 +148,25 @@ self.findtextCombo.clear() self.findtextCombo.addItems(self.findHistory) + if self.__texteditType == "QTextEdit": + ok = self.__findPrevNextQTextEdit(backwards) + self.__findNextPrevCallback(ok) + elif self.__texteditType == "QWebEngineView": + self.__findPrevNextQWebEngineView(backwards) + elif self.__texteditType == "QWebView": + ok = self.__findPrevNextQWebView(backwards) + self.__findNextPrevCallback(ok) + + def __findPrevNextQTextEdit(self, backwards): + """ + Private method to to search the associated edit widget of + type QTextEdit. + + @param backwards flag indicating a backwards search + @type bool + @return flag indicating the search result + @rtype bool + """ if backwards: flags = QTextDocument.FindFlags(QTextDocument.FindBackward) else: @@ -134,10 +175,87 @@ flags |= QTextDocument.FindCaseSensitively if self.wordCheckBox.isChecked(): flags |= QTextDocument.FindWholeWords - ok = self.__textedit.find(txt, flags) + ok = self.__textedit.find(self.findtextCombo.currentText(), flags) if not ok: - E5MessageBox.information( - self, - self.tr("Find"), - self.tr("""'{0}' was not found.""").format(txt)) + # wrap around once + cursor = self.__textedit.textCursor() + if backwards: + moveOp = QTextCursor.End # move to end of document + else: + moveOp = QTextCursor.Start # move to start of document + cursor.movePosition(moveOp) + self.__textedit.setTextCursor(cursor) + ok = self.__textedit.find(self.findtextCombo.currentText(), flags) + + return ok + + def __findPrevNextQWebView(self, backwards): + """ + Private method to to search the associated edit widget of + type QWebView. + + @param backwards flag indicating a backwards search + @type bool + @return flag indicating the search result + @rtype bool + """ + from PyQt5.QtWebKitWidgets import QWebPage + + findFlags = QWebPage.FindFlags(QWebPage.HighlightAllOccurrences) + if self.caseCheckBox.isChecked(): + findFlags |= QWebPage.FindCaseSensitively + if backwards: + findFlags |= QWebPage.FindBackward + + return self.findText(self.findtextCombo.currentText(), findFlags) + + def __findPrevNextQWebEngineView(self, backwards): + """ + Private method to to search the associated edit widget of + type QWebEngineView. + + @param backwards flag indicating a backwards search + @type bool + """ + from PyQt5.QtWebEngineWidgets import QWebEnginePage + + findFlags = QWebEnginePage.FindFlags() + if self.caseCheckBox.isChecked(): + findFlags |= QWebEnginePage.FindCaseSensitively + if backwards: + findFlags |= QWebEnginePage.FindBackward + self.__textedit.findText(self.findtextCombo.currentText(), + findFlags, self.__findNextPrevCallback) + + def __findNextPrevCallback(self, found): + """ + Private method to process the result of the last search. + + @param found flag indicating if the last search succeeded + @type bool + """ + if not found: + txt = self.findtextCombo.currentText() + self.infoLabel.setText( + self.tr("'{0}' was not found.").format(txt)) + self.infoLabel.show() + self.__setFindtextComboBackground(True) + + def __setFindtextComboBackground(self, error): + """ + Private slot to change the findtext combo background to indicate + errors. + + @param error flag indicating an error condition (boolean) + """ + le = self.findtextCombo.lineEdit() + p = le.palette() + if error: + p.setBrush(QPalette.Base, QBrush(QColor("#FF6666"))) + p.setBrush(QPalette.Text, QBrush(QColor("#000000"))) + else: + p.setBrush(QPalette.Base, self.__defaultBaseColor) + p.setBrush(QPalette.Text, self.__defaultTextColor) + le.setPalette(p) + le.update()