|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2009 - 2016 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the search bar for the web browser. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import pyqtSlot, Qt |
|
13 from PyQt5.QtGui import QPalette, QBrush, QColor |
|
14 from PyQt5.QtWidgets import QWidget |
|
15 ##from PyQt5.QtWebKitWidgets import QWebPage |
|
16 |
|
17 from .Ui_SearchWidget import Ui_SearchWidget |
|
18 |
|
19 import UI.PixmapCache |
|
20 |
|
21 |
|
22 class SearchWidget(QWidget, Ui_SearchWidget): |
|
23 """ |
|
24 Class implementing the search bar for the web browser. |
|
25 """ |
|
26 def __init__(self, mainWindow, parent=None): |
|
27 """ |
|
28 Constructor |
|
29 |
|
30 @param mainWindow reference to the main window (QMainWindow) |
|
31 @param parent parent widget of this dialog (QWidget) |
|
32 """ |
|
33 super(SearchWidget, self).__init__(parent) |
|
34 self.setupUi(self) |
|
35 |
|
36 self.__mainWindow = mainWindow |
|
37 |
|
38 # TODO: Check what Qt 5.6 can offer (maybe using JavaScript) |
|
39 self.wrapCheckBox.setVisible(False) |
|
40 self.highlightAllCheckBox.setVisible(False) |
|
41 ## self.wrapCheckBox.setChecked(True) |
|
42 self.closeButton.setIcon(UI.PixmapCache.getIcon("close.png")) |
|
43 self.findPrevButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png")) |
|
44 self.findNextButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png")) |
|
45 |
|
46 self.__defaultBaseColor = \ |
|
47 self.findtextCombo.lineEdit().palette().color(QPalette.Base) |
|
48 self.__defaultTextColor = \ |
|
49 self.findtextCombo.lineEdit().palette().color(QPalette.Text) |
|
50 |
|
51 self.__findHistory = [] |
|
52 self.__havefound = False |
|
53 self.__findBackwards = False |
|
54 |
|
55 self.findtextCombo.setCompleter(None) |
|
56 self.findtextCombo.lineEdit().returnPressed.connect( |
|
57 self.__findByReturnPressed) |
|
58 self.findtextCombo.lineEdit().textEdited.connect( |
|
59 self.__searchTextEdited) |
|
60 |
|
61 def on_findtextCombo_editTextChanged(self, txt): |
|
62 """ |
|
63 Private slot to enable/disable the find buttons. |
|
64 |
|
65 @param txt text of the combobox (string) |
|
66 """ |
|
67 self.findPrevButton.setEnabled(txt != "") |
|
68 self.findNextButton.setEnabled(txt != "") |
|
69 |
|
70 def __searchTextEdited(self, txt): |
|
71 """ |
|
72 Private slot to perform an incremental search. |
|
73 |
|
74 @param txt current text of the search combos line edit (string) |
|
75 (unused) |
|
76 """ |
|
77 self.on_highlightAllCheckBox_toggled(True) |
|
78 self.__findNextPrev() |
|
79 |
|
80 def __findNextPrev(self): |
|
81 """ |
|
82 Private slot to find the next occurrence of text. |
|
83 """ |
|
84 self.infoLabel.clear() |
|
85 self.__setFindtextComboBackground(False) |
|
86 |
|
87 if not self.findtextCombo.currentText(): |
|
88 return |
|
89 |
|
90 # TODO: adjust this to the browser API |
|
91 # TODO: use the callback interface of QWebEnginePage |
|
92 if not self.__mainWindow.currentBrowser().findNextPrev( |
|
93 self.findtextCombo.currentText(), |
|
94 self.caseCheckBox.isChecked(), |
|
95 self.__findBackwards, |
|
96 self.wrapCheckBox.isChecked(), |
|
97 False): |
|
98 self.infoLabel.setText(self.tr("Expression was not found.")) |
|
99 self.__setFindtextComboBackground(True) |
|
100 ## |
|
101 ## @pyqtSlot(bool) |
|
102 ## def on_highlightAllCheckBox_toggled(self, checked): |
|
103 ## """ |
|
104 ## Private slot to toggle the highlight of all occurrences. |
|
105 ## |
|
106 ## @param checked flag indicating the check box toggle state (boolean) |
|
107 ## """ |
|
108 ## cbr = self.__mainWindow.currentBrowser() |
|
109 ## if cbr is None: |
|
110 ## return |
|
111 ## cbr.findNextPrev( |
|
112 ## "", False, False, False, True) |
|
113 ## if self.highlightAllCheckBox.isChecked(): |
|
114 ## cbr.findNextPrev( |
|
115 ## self.findtextCombo.currentText(), |
|
116 ## self.caseCheckBox.isChecked(), |
|
117 ## False, False, True) |
|
118 |
|
119 @pyqtSlot() |
|
120 def on_findNextButton_clicked(self): |
|
121 """ |
|
122 Private slot to find the next occurrence. |
|
123 """ |
|
124 txt = self.findtextCombo.currentText() |
|
125 |
|
126 # This moves any previous occurrence of this statement to the head |
|
127 # of the list and updates the combobox |
|
128 if txt in self.__findHistory: |
|
129 self.__findHistory.remove(txt) |
|
130 self.__findHistory.insert(0, txt) |
|
131 self.findtextCombo.clear() |
|
132 self.findtextCombo.addItems(self.__findHistory) |
|
133 |
|
134 self.__findBackwards = False |
|
135 self.__findNextPrev() |
|
136 |
|
137 def findNext(self): |
|
138 """ |
|
139 Public slot to find the next occurrence. |
|
140 """ |
|
141 if not self.__havefound or not self.findtextCombo.currentText(): |
|
142 self.showFind() |
|
143 return |
|
144 |
|
145 self.on_findNextButton_clicked() |
|
146 |
|
147 @pyqtSlot() |
|
148 def on_findPrevButton_clicked(self): |
|
149 """ |
|
150 Private slot to find the previous occurrence. |
|
151 """ |
|
152 txt = self.findtextCombo.currentText() |
|
153 |
|
154 # This moves any previous occurrence of this statement to the head |
|
155 # of the list and updates the combobox |
|
156 if txt in self.__findHistory: |
|
157 self.__findHistory.remove(txt) |
|
158 self.__findHistory.insert(0, txt) |
|
159 self.findtextCombo.clear() |
|
160 self.findtextCombo.addItems(self.__findHistory) |
|
161 |
|
162 self.__findBackwards = True |
|
163 self.__findNextPrev() |
|
164 |
|
165 def findPrevious(self): |
|
166 """ |
|
167 Public slot to find the previous occurrence. |
|
168 """ |
|
169 if not self.__havefound or not self.findtextCombo.currentText(): |
|
170 self.showFind() |
|
171 return |
|
172 |
|
173 self.on_findPrevButton_clicked() |
|
174 |
|
175 def __findByReturnPressed(self): |
|
176 """ |
|
177 Private slot to handle the returnPressed signal of the findtext |
|
178 combobox. |
|
179 """ |
|
180 if self.__findBackwards: |
|
181 self.on_findPrevButton_clicked() |
|
182 else: |
|
183 self.on_findNextButton_clicked() |
|
184 |
|
185 def showFind(self): |
|
186 """ |
|
187 Public method to display this dialog. |
|
188 """ |
|
189 self.__havefound = True |
|
190 self.__findBackwards = False |
|
191 |
|
192 self.findtextCombo.clear() |
|
193 self.findtextCombo.addItems(self.__findHistory) |
|
194 self.findtextCombo.setEditText('') |
|
195 self.findtextCombo.setFocus() |
|
196 |
|
197 self.caseCheckBox.setChecked(False) |
|
198 |
|
199 if self.__mainWindow.currentBrowser().hasSelection(): |
|
200 self.findtextCombo.setEditText( |
|
201 self.__mainWindow.currentBrowser().selectedText()) |
|
202 |
|
203 self.__setFindtextComboBackground(False) |
|
204 self.show() |
|
205 |
|
206 @pyqtSlot() |
|
207 def on_closeButton_clicked(self): |
|
208 """ |
|
209 Private slot to close the widget. |
|
210 """ |
|
211 self.close() |
|
212 |
|
213 def keyPressEvent(self, event): |
|
214 """ |
|
215 Protected slot to handle key press events. |
|
216 |
|
217 @param event reference to the key press event (QKeyEvent) |
|
218 """ |
|
219 if event.key() == Qt.Key_Escape: |
|
220 cb = self.__mainWindow.currentBrowser() |
|
221 if cb: |
|
222 cb.setFocus(Qt.ActiveWindowFocusReason) |
|
223 event.accept() |
|
224 self.close() |
|
225 |
|
226 def __setFindtextComboBackground(self, error): |
|
227 """ |
|
228 Private slot to change the findtext combo background to indicate |
|
229 errors. |
|
230 |
|
231 @param error flag indicating an error condition (boolean) |
|
232 """ |
|
233 le = self.findtextCombo.lineEdit() |
|
234 p = le.palette() |
|
235 if error: |
|
236 p.setBrush(QPalette.Base, QBrush(QColor("#FF6666"))) |
|
237 p.setBrush(QPalette.Text, QBrush(QColor("#000000"))) |
|
238 else: |
|
239 p.setBrush(QPalette.Base, self.__defaultBaseColor) |
|
240 p.setBrush(QPalette.Text, self.__defaultTextColor) |
|
241 le.setPalette(p) |
|
242 le.update() |