eric7/WebBrowser/UrlBar/UrlBar.py

branch
eric7
changeset 8857
8191d15b8974
parent 8556
766e1566cb74
child 8881
54e42bc2437a
equal deleted inserted replaced
8856:df77fbfc150f 8857:8191d15b8974
5 5
6 """ 6 """
7 Module implementing the URL bar widget. 7 Module implementing the URL bar widget.
8 """ 8 """
9 9
10 from PyQt6.QtCore import pyqtSlot, Qt, QPointF, QUrl, QDateTime, QTimer, QPoint 10 from PyQt6.QtCore import pyqtSlot, Qt, QUrl, QDateTime, QTimer, QPoint
11 from PyQt6.QtGui import QColor, QPalette, QLinearGradient, QIcon 11 from PyQt6.QtGui import QColor, QPalette, QIcon
12 from PyQt6.QtWidgets import QDialog, QApplication, QLineEdit 12 from PyQt6.QtWidgets import QDialog, QApplication, QLineEdit
13 from PyQt6.QtWebEngineCore import QWebEnginePage 13 from PyQt6.QtWebEngineCore import QWebEnginePage
14 try: 14 try:
15 from PyQt6.QtNetwork import QSslCertificate # __IGNORE_EXCEPTION__ 15 from PyQt6.QtNetwork import QSslCertificate # __IGNORE_EXCEPTION__
16 except ImportError: 16 except ImportError:
36 """ 36 """
37 def __init__(self, mainWindow, parent=None): 37 def __init__(self, mainWindow, parent=None):
38 """ 38 """
39 Constructor 39 Constructor
40 40
41 @param mainWindow reference to the main window (WebBrowserWindow) 41 @param mainWindow reference to the main window
42 @param parent reference to the parent widget (WebBrowserView) 42 @type WebBrowserWindow
43 @param parent reference to the parent widget
44 @type WebBrowserView
43 """ 45 """
44 super().__init__(parent) 46 super().__init__(parent)
45 self.setPlaceholderText(self.tr("Enter the URL here.")) 47 self.setPlaceholderText(self.tr("Enter the URL here."))
46 self.setWhatsThis(self.tr("Enter the URL here.")) 48 self.setWhatsThis(self.tr("Enter the URL here."))
47 49
89 91
90 def setBrowser(self, browser): 92 def setBrowser(self, browser):
91 """ 93 """
92 Public method to set the browser connection. 94 Public method to set the browser connection.
93 95
94 @param browser reference to the browser widget (WebBrowserView) 96 @param browser reference to the browser widget
97 @type WebBrowserView
95 """ 98 """
96 self.__browser = browser 99 self.__browser = browser
97 self.__favicon.setBrowser(browser) 100 self.__favicon.setBrowser(browser)
98 101
99 self.__browser.urlChanged.connect(self.__browserUrlChanged) 102 self.__browser.urlChanged.connect(self.__browserUrlChanged)
100 self.__browser.loadProgress.connect(self.update) 103 self.__browser.loadProgress.connect(self.__loadProgress)
101 self.__browser.loadFinished.connect(self.__loadFinished) 104 self.__browser.loadFinished.connect(self.__loadFinished)
102 self.__browser.loadStarted.connect(self.__loadStarted) 105 self.__browser.loadStarted.connect(self.__loadStarted)
103 106
104 self.__browser.safeBrowsingBad.connect( 107 self.__browser.safeBrowsingBad.connect(
105 self.__safeBrowsingLabel.setThreatInfo) 108 self.__safeBrowsingLabel.setThreatInfo)
110 113
111 def browser(self): 114 def browser(self):
112 """ 115 """
113 Public method to get the associated browser. 116 Public method to get the associated browser.
114 117
115 @return reference to the associated browser (HelpBrowser) 118 @return reference to the associated browser
119 @rtype WebBrowserView
116 """ 120 """
117 return self.__browser 121 return self.__browser
118 122
123 @pyqtSlot(QUrl)
119 def __browserUrlChanged(self, url): 124 def __browserUrlChanged(self, url):
120 """ 125 """
121 Private slot to handle a URL change of the associated browser. 126 Private slot to handle a URL change of the associated browser.
122 127
123 @param url new URL of the browser (QUrl) 128 @param url new URL of the browser
129 @type QUrl
124 """ 130 """
125 strUrl = url.toString() 131 strUrl = url.toString()
126 if strUrl in ["eric:speeddial", "eric:home", 132 if strUrl in ["eric:speeddial", "eric:home",
127 "about:blank", "about:config"]: 133 "about:blank", "about:config"]:
128 strUrl = "" 134 strUrl = ""
129 135
130 if self.text() != strUrl: 136 if self.text() != strUrl:
131 self.setText(strUrl) 137 self.setText(strUrl)
132 self.setCursorPosition(0) 138 self.setCursorPosition(0)
133 139
134 def __loadStarted(self): 140 @pyqtSlot()
135 """
136 Private slot to perform actions before the page is loaded.
137 """
138 self.__bookmarkAction.setVisible(False)
139 self.__rssAction.setVisible(False)
140 self.__sslLabel.setVisible(False)
141
142 def __checkBookmark(self): 141 def __checkBookmark(self):
143 """ 142 """
144 Private slot to check the current URL for the bookmarked state. 143 Private slot to check the current URL for the bookmarked state.
145 """ 144 """
146 manager = self.__mw.bookmarksManager() 145 manager = self.__mw.bookmarksManager()
154 elif self.__mw.speedDial().pageForUrl(self.__browser.url()).url != "": 153 elif self.__mw.speedDial().pageForUrl(self.__browser.url()).url != "":
155 self.__bookmarkAction.setIcon(self.__bmActiveIcon) 154 self.__bookmarkAction.setIcon(self.__bmActiveIcon)
156 else: 155 else:
157 self.__bookmarkAction.setIcon(self.__bmInactiveIcon) 156 self.__bookmarkAction.setIcon(self.__bmInactiveIcon)
158 157
158 @pyqtSlot()
159 def __loadStarted(self):
160 """
161 Private slot to perform actions before the page is loaded.
162 """
163 self.__bookmarkAction.setVisible(False)
164 self.__rssAction.setVisible(False)
165 self.__sslLabel.setVisible(False)
166
167 @pyqtSlot(int)
168 def __loadProgress(self, progress):
169 """
170 Private slot to track the load progress.
171
172 @param progress load progress in percent
173 @type int
174 """
175 foregroundColor = QApplication.palette().color(QPalette.ColorRole.Text)
176
177 backgroundColor = (
178 Preferences.getWebBrowser("PrivateModeUrlColor")
179 if self.__privateMode else
180 QApplication.palette().color(QPalette.ColorRole.Base)
181 )
182
183 if not self.__browser.getSafeBrowsingStatus():
184 # malicious web site
185 backgroundColor = Preferences.getWebBrowser(
186 "MaliciousUrlColor")
187 elif self.__browser.url().scheme() == "https":
188 if WebBrowserWindow.networkManager().isInsecureHost(
189 self.__browser.url().host()
190 ):
191 backgroundColor = Preferences.getWebBrowser(
192 "InsecureUrlColor")
193 else:
194 backgroundColor = Preferences.getWebBrowser(
195 "SecureUrlColor")
196
197 if progress in (0, 100):
198 styleSheet = (
199 f"color: {foregroundColor.name()}; "
200 f"background-color: {backgroundColor.name()};"
201 )
202 else:
203 highlight = QApplication.palette().color(
204 QPalette.ColorRole.Highlight)
205 r = (highlight.red() + 2 * backgroundColor.red()) // 3
206 g = (highlight.green() + 2 * backgroundColor.green()) // 3
207 b = (highlight.blue() + 2 * backgroundColor.blue()) // 3
208
209 loadingColor = QColor(r, g, b)
210 if abs(loadingColor.lightness() -
211 backgroundColor.lightness()) < 20:
212 r = (2 * highlight.red() + backgroundColor.red()) // 3
213 g = (2 * highlight.green() + backgroundColor.green()) // 3
214 b = (2 * highlight.blue() + backgroundColor.blue()) // 3
215 loadingColor = QColor(r, g, b)
216
217 styleSheet = (
218 f"color: {foregroundColor.name()}; "
219 f"background-color: qlineargradient("
220 f"spread: pad, x1: 0, y1: 0, x2: 1, y2: 0, "
221 f"stop: 0 {loadingColor.name()}, "
222 f"stop: {progress / 100.0 - 0.001} {loadingColor.name()}, "
223 f"stop: {progress / 100.0 + 0.001} {backgroundColor.name()}, "
224 f"stop: 1 {backgroundColor.name()});"
225 )
226
227 self.setStyleSheet(styleSheet)
228 self.repaint()
229
230 @pyqtSlot(bool)
159 def __loadFinished(self, ok): 231 def __loadFinished(self, ok):
160 """ 232 """
161 Private slot to set some data after the page was loaded. 233 Private slot to set some data after the page was loaded.
162 234
163 @param ok flag indicating a successful load (boolean) 235 @param ok flag indicating a successful load
236 @type bool
164 """ 237 """
165 if self.__browser.url().scheme() in ["eric", "about"]: 238 if self.__browser.url().scheme() in ["eric", "about"]:
166 self.__bookmarkAction.setVisible(False) 239 self.__bookmarkAction.setVisible(False)
167 else: 240 else:
168 self.__checkBookmark() 241 self.__checkBookmark()
173 not self.__browser.getSafeBrowsingStatus()) 246 not self.__browser.getSafeBrowsingStatus())
174 247
175 if ok: 248 if ok:
176 QTimer.singleShot(0, self.__setRssButton) 249 QTimer.singleShot(0, self.__setRssButton)
177 250
251 @pyqtSlot()
178 def preferencesChanged(self): 252 def preferencesChanged(self):
179 """ 253 """
180 Public slot to handle a change of preferences. 254 Public slot to handle a change of preferences.
181 """ 255 """
182 self.update() 256 self.update()
213 """ 287 """
214 Private slot to handle bookmark or speed dial changes. 288 Private slot to handle bookmark or speed dial changes.
215 """ 289 """
216 self.__checkBookmark() 290 self.__checkBookmark()
217 291
218 def paintEvent(self, evt):
219 """
220 Protected method handling a paint event.
221
222 @param evt reference to the paint event (QPaintEvent)
223 """
224 foregroundColor = QApplication.palette().color(QPalette.ColorRole.Text)
225
226 backgroundColor = (
227 Preferences.getWebBrowser("PrivateModeUrlColor")
228 if self.__privateMode else
229 QApplication.palette().color(QPalette.ColorRole.Base)
230 )
231
232 if self.__browser is not None:
233 p = self.palette()
234 progress = self.__browser.progress()
235
236 if not self.__browser.getSafeBrowsingStatus():
237 # malicious web site
238 backgroundColor = Preferences.getWebBrowser(
239 "MaliciousUrlColor")
240 elif self.__browser.url().scheme() == "https":
241 if WebBrowserWindow.networkManager().isInsecureHost(
242 self.__browser.url().host()
243 ):
244 backgroundColor = Preferences.getWebBrowser(
245 "InsecureUrlColor")
246 else:
247 backgroundColor = Preferences.getWebBrowser(
248 "SecureUrlColor")
249
250 if progress in (0, 100):
251 p.setBrush(QPalette.ColorRole.Base, backgroundColor)
252 p.setBrush(QPalette.ColorRole.Text, foregroundColor)
253 else:
254 highlight = QApplication.palette().color(
255 QPalette.ColorRole.Highlight)
256 r = (highlight.red() + 2 * backgroundColor.red()) // 3
257 g = (highlight.green() + 2 * backgroundColor.green()) // 3
258 b = (highlight.blue() + 2 * backgroundColor.blue()) // 3
259
260 loadingColor = QColor(r, g, b)
261 if abs(loadingColor.lightness() -
262 backgroundColor.lightness()) < 20:
263 # special handling for special color schemes (e.g Gaia)
264 r = (2 * highlight.red() + backgroundColor.red()) // 3
265 g = (2 * highlight.green() + backgroundColor.green()) // 3
266 b = (2 * highlight.blue() + backgroundColor.blue()) // 3
267 loadingColor = QColor(r, g, b)
268
269 gradient = QLinearGradient(
270 QPointF(0, 0), QPointF(self.width(), 0))
271 gradient.setColorAt(0, loadingColor)
272 gradient.setColorAt(progress / 100.0 - 0.000001, loadingColor)
273 gradient.setColorAt(progress / 100.0, backgroundColor)
274 p.setBrush(QPalette.ColorRole.Base, gradient)
275
276 self.setPalette(p)
277
278 super().paintEvent(evt)
279
280 def focusOutEvent(self, evt): 292 def focusOutEvent(self, evt):
281 """ 293 """
282 Protected method to handle focus out event. 294 Protected method to handle focus out event.
283 295
284 @param evt reference to the focus event (QFocusEvent) 296 @param evt reference to the focus event
297 @type QFocusEvent
285 """ 298 """
286 if self.text() == "" and self.__browser is not None: 299 if self.text() == "" and self.__browser is not None:
287 self.__browserUrlChanged(self.__browser.url()) 300 self.__browserUrlChanged(self.__browser.url())
288 super().focusOutEvent(evt) 301 super().focusOutEvent(evt)
289 302
290 def mousePressEvent(self, evt): 303 def mousePressEvent(self, evt):
291 """ 304 """
292 Protected method called by a mouse press event. 305 Protected method called by a mouse press event.
293 306
294 @param evt reference to the mouse event (QMouseEvent) 307 @param evt reference to the mouse event
308 @type QMouseEvent
295 """ 309 """
296 if evt.button() == Qt.MouseButton.XButton1: 310 if evt.button() == Qt.MouseButton.XButton1:
297 self.__mw.currentBrowser().triggerPageAction( 311 self.__mw.currentBrowser().triggerPageAction(
298 QWebEnginePage.WebAction.Back) 312 QWebEnginePage.WebAction.Back)
299 elif evt.button() == Qt.MouseButton.XButton2: 313 elif evt.button() == Qt.MouseButton.XButton2:
304 318
305 def mouseDoubleClickEvent(self, evt): 319 def mouseDoubleClickEvent(self, evt):
306 """ 320 """
307 Protected method to handle mouse double click events. 321 Protected method to handle mouse double click events.
308 322
309 @param evt reference to the mouse event (QMouseEvent) 323 @param evt reference to the mouse event
324 @type QMouseEvent
310 """ 325 """
311 if evt.button() == Qt.MouseButton.LeftButton: 326 if evt.button() == Qt.MouseButton.LeftButton:
312 self.selectAll() 327 self.selectAll()
313 else: 328 else:
314 super().mouseDoubleClickEvent(evt) 329 super().mouseDoubleClickEvent(evt)
315 330
316 def keyPressEvent(self, evt): 331 def keyPressEvent(self, evt):
317 """ 332 """
318 Protected method to handle key presses. 333 Protected method to handle key presses.
319 334
320 @param evt reference to the key press event (QKeyEvent) 335 @param evt reference to the key press event
336 @type QKeyEvent
321 """ 337 """
322 if evt.key() == Qt.Key.Key_Escape: 338 if evt.key() == Qt.Key.Key_Escape:
323 if self.__browser is not None: 339 if self.__browser is not None:
324 self.setText( 340 self.setText(
325 str(self.__browser.url().toEncoded(), encoding="utf-8")) 341 str(self.__browser.url().toEncoded(), encoding="utf-8"))
359 375
360 def dragEnterEvent(self, evt): 376 def dragEnterEvent(self, evt):
361 """ 377 """
362 Protected method to handle drag enter events. 378 Protected method to handle drag enter events.
363 379
364 @param evt reference to the drag enter event (QDragEnterEvent) 380 @param evt reference to the drag enter event
381 @type QDragEnterEvent
365 """ 382 """
366 mimeData = evt.mimeData() 383 mimeData = evt.mimeData()
367 if mimeData.hasUrls() or mimeData.hasText(): 384 if mimeData.hasUrls() or mimeData.hasText():
368 evt.acceptProposedAction() 385 evt.acceptProposedAction()
369 386
371 388
372 def dropEvent(self, evt): 389 def dropEvent(self, evt):
373 """ 390 """
374 Protected method to handle drop events. 391 Protected method to handle drop events.
375 392
376 @param evt reference to the drop event (QDropEvent) 393 @param evt reference to the drop event
394 @type QDropEvent
377 """ 395 """
378 mimeData = evt.mimeData() 396 mimeData = evt.mimeData()
379 397
380 url = QUrl() 398 url = QUrl()
381 if mimeData.hasUrls(): 399 if mimeData.hasUrls():
391 self.setText(str(url.toEncoded(), encoding="utf-8")) 409 self.setText(str(url.toEncoded(), encoding="utf-8"))
392 self.selectAll() 410 self.selectAll()
393 411
394 evt.acceptProposedAction() 412 evt.acceptProposedAction()
395 413
414 @pyqtSlot()
396 def __setRssButton(self): 415 def __setRssButton(self):
397 """ 416 """
398 Private slot to show the RSS button. 417 Private slot to show the RSS button.
399 """ 418 """
400 self.__rssAction.setVisible(self.__browser.checkRSS()) 419 self.__rssAction.setVisible(self.__browser.checkRSS())

eric ide

mercurial