WebBrowser/UrlBar/UrlBar.py

branch
QtWebEngine
changeset 4709
8612533a223f
parent 4631
5c1a96925da4
child 4715
79009bc4acd5
equal deleted inserted replaced
4702:bd7d781db729 4709:8612533a223f
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2010 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the URL bar widget.
8 """
9
10 from __future__ import unicode_literals
11 try:
12 str = unicode
13 except NameError:
14 pass
15
16 from PyQt5.QtCore import pyqtSlot, Qt, QPointF, QUrl, QDateTime, qVersion
17 from PyQt5.QtGui import QColor, QPalette, QLinearGradient, QIcon
18 from PyQt5.QtWidgets import QDialog, QApplication
19 try:
20 from PyQt5.QtNetwork import QSslCertificate # __IGNORE_EXCEPTION__
21 except ImportError:
22 QSslCertificate = None # __IGNORE_WARNING__
23 from PyQt5.QtWebEngineWidgets import QWebEnginePage
24
25 from E5Gui.E5LineEdit import E5LineEdit
26 from E5Gui.E5LineEditButton import E5LineEditButton
27
28 import WebBrowser.WebBrowserWindow
29
30 ##from .FavIconLabel import FavIconLabel
31 ##from .SslLabel import SslLabel
32 ##
33 import UI.PixmapCache
34 import Preferences
35 import Utilities
36
37
38 class UrlBar(E5LineEdit):
39 """
40 Class implementing a line edit for entering URLs.
41 """
42 def __init__(self, mainWindow, parent=None):
43 """
44 Constructor
45
46 @param mainWindow reference to the main window (HelpWindow)
47 @param parent reference to the parent widget (HelpBrowser)
48 """
49 E5LineEdit.__init__(self, parent)
50 self.setInactiveText(self.tr("Enter the URL here."))
51 self.setWhatsThis(self.tr("Enter the URL here."))
52
53 self.__mw = mainWindow
54 self.__browser = None
55 ## self.__privateMode = QWebSettings.globalSettings().testAttribute(
56 ## QWebSettings.PrivateBrowsingEnabled)
57
58 # TODO: re-enable once bookmarks are done
59 ## self.__bmActiveIcon = UI.PixmapCache.getIcon("bookmark16.png")
60 ## self.__bmInactiveIcon = QIcon(
61 ## self.__bmActiveIcon.pixmap(16, 16, QIcon.Disabled))
62
63 ## self.__favicon = FavIconLabel(self)
64 ## self.addWidget(self.__favicon, E5LineEdit.LeftSide)
65 ##
66 ## self.__sslLabel = SslLabel(self)
67 ## self.addWidget(self.__sslLabel, E5LineEdit.LeftSide)
68 ## self.__sslLabel.setVisible(False)
69 ##
70 ## self.__privacyButton = E5LineEditButton(self)
71 ## self.__privacyButton.setIcon(
72 ## UI.PixmapCache.getIcon("privateBrowsing.png"))
73 ## self.addWidget(self.__privacyButton, E5LineEdit.RightSide)
74 ## self.__privacyButton.setVisible(self.__privateMode)
75 ##
76 ## self.__rssButton = E5LineEditButton(self)
77 ## self.__rssButton.setIcon(UI.PixmapCache.getIcon("rss16.png"))
78 ## self.addWidget(self.__rssButton, E5LineEdit.RightSide)
79 ## self.__rssButton.setVisible(False)
80
81 ## self.__bookmarkButton = E5LineEditButton(self)
82 ## self.addWidget(self.__bookmarkButton, E5LineEdit.RightSide)
83 ## self.__bookmarkButton.setVisible(False)
84
85 self.__clearButton = E5LineEditButton(self)
86 self.__clearButton.setIcon(UI.PixmapCache.getIcon("clearLeft.png"))
87 self.addWidget(self.__clearButton, E5LineEdit.RightSide)
88 self.__clearButton.setVisible(False)
89
90 ## self.__bookmarkButton.clicked.connect(self.__showBookmarkInfo)
91 ## self.__privacyButton.clicked.connect(self.__privacyClicked)
92 ## self.__rssButton.clicked.connect(self.__rssClicked)
93 self.__clearButton.clicked.connect(self.clear)
94 ## self.__mw.privacyChanged.connect(self.__privacyButton.setVisible)
95 self.textChanged.connect(self.__textChanged)
96
97 ## Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\
98 ## .entryChanged.connect(self.__bookmarkChanged)
99 ## Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\
100 ## .entryAdded.connect(self.__bookmarkChanged)
101 ## Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\
102 ## .entryRemoved.connect(self.__bookmarkChanged)
103 ## Helpviewer.HelpWindow.HelpWindow.speedDial().pagesChanged.connect(
104 ## self.__bookmarkChanged)
105
106 def setBrowser(self, browser):
107 """
108 Public method to set the browser connection.
109
110 @param browser reference to the browser widget (WebBrowserView)
111 """
112 self.__browser = browser
113 ## self.__favicon.setBrowser(browser)
114
115 self.__browser.urlChanged.connect(self.__browserUrlChanged)
116 self.__browser.loadProgress.connect(self.update)
117 self.__browser.loadFinished.connect(self.__loadFinished)
118 self.__browser.loadStarted.connect(self.__loadStarted)
119 ##
120 ## self.__sslLabel.clicked.connect(self.__browser.page().showSslInfo)
121
122 def browser(self):
123 """
124 Public method to get the associated browser.
125
126 @return reference to the associated browser (HelpBrowser)
127 """
128 return self.__browser
129
130 def __browserUrlChanged(self, url):
131 """
132 Private slot to handle a URL change of the associated browser.
133
134 @param url new URL of the browser (QUrl)
135 """
136 strUrl = url.toString()
137 if strUrl in ["eric:speeddial", "eric:home",
138 "about:blank", "about:config"]:
139 strUrl = ""
140
141 if self.text() != strUrl:
142 self.setText(strUrl)
143 self.setCursorPosition(0)
144
145 def __loadStarted(self):
146 """
147 Private slot to perform actions before the page is loaded.
148 """
149 pass
150 ## self.__sslLabel.setVisible(False)
151 ## self.__bookmarkButton.setVisible(False)
152
153 ## def __checkBookmark(self):
154 ## """
155 ## Private slot to check the current URL for the bookmarked state.
156 ## """
157 ## manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager()
158 ## if manager.bookmarkForUrl(self.__browser.url()) is not None:
159 ## self.__bookmarkButton.setIcon(self.__bmActiveIcon)
160 ## bookmarks = manager.bookmarksForUrl(self.__browser.url())
161 ## from Helpviewer.Bookmarks.BookmarkNode import BookmarkNode
162 ## for bookmark in bookmarks:
163 ## manager.setTimestamp(bookmark, BookmarkNode.TsVisited,
164 ## QDateTime.currentDateTime())
165 ## elif Helpviewer.HelpWindow.HelpWindow.speedDial()\
166 ## .pageForUrl(self.__browser.url()).url != "":
167 ## self.__bookmarkButton.setIcon(self.__bmActiveIcon)
168 ## else:
169 ## self.__bookmarkButton.setIcon(self.__bmInactiveIcon)
170 ##
171 def __loadFinished(self, ok):
172 """
173 Private slot to set some data after the page was loaded.
174
175 @param ok flag indicating a successful load (boolean)
176 """
177 pass
178 ## try:
179 # TODO: re-enable once Bookmarks are done
180 ## if self.__browser.url().scheme() in ["eric", "about"]:
181 ## self.__bookmarkButton.setVisible(False)
182 ## else:
183 ## self.__checkBookmark()
184 ## self.__bookmarkButton.setVisible(True)
185
186 # TODO: re-enable once RSS is done
187 ## if ok:
188 ## self.__rssButton.setVisible(self.__browser.checkRSS())
189
190 # TODO: do the SSL certificate stuff (if possible)
191 ## if ok and \
192 ## self.__browser.url().scheme() == "https" and \
193 ## QSslCertificate is not None:
194 ## sslInfo = self.__browser.page().getSslCertificate()
195 ## if sslInfo is not None:
196 ## org = Utilities.decodeString(", ".join(
197 ## sslInfo.subjectInfo(QSslCertificate.Organization)))
198 ## if org == "":
199 ## cn = Utilities.decodeString(", ".join(
200 ## sslInfo.subjectInfo(
201 ## QSslCertificate.CommonName)))
202 ## if cn != "":
203 ## org = cn.split(".", 1)[1]
204 ## if org == "":
205 ## org = self.tr("Unknown")
206 ## self.__sslLabel.setText(" {0} ".format(org))
207 ## self.__sslLabel.setVisible(True)
208 ## valid = not sslInfo.isBlacklisted()
209 ## if valid:
210 ## config = self.__browser.page().getSslConfiguration()
211 ## if config is None or config.sessionCipher().isNull():
212 ## valid = False
213 ## self.__sslLabel.setValidity(valid)
214 ## return
215 ##
216 ## self.__sslLabel.setVisible(False)
217 ## except RuntimeError:
218 ## pass
219
220 ## def setPrivateMode(self, on):
221 ## """
222 ## Public method to set the private mode.
223 ##
224 ## @param on flag indicating the privacy state (boolean)
225 ## """
226 ## self.__privateMode = on
227 ## self.__privacyButton.setVisible(on)
228 ##
229 ## def __privacyClicked(self):
230 ## """
231 ## Private slot to handle the click of the private mode button.
232 ## """
233 ## self.__mw.setPrivateMode(False)
234 ##
235 def __textChanged(self, txt):
236 """
237 Private slot to handle changes of the text.
238
239 @param txt current text (string)
240 """
241 self.__clearButton.setVisible(txt != "")
242
243 def preferencesChanged(self):
244 """
245 Public slot to handle a change of preferences.
246 """
247 self.update()
248
249 ## def __showBookmarkInfo(self):
250 ## """
251 ## Private slot to show a dialog with some bookmark info.
252 ## """
253 ## from .BookmarkActionSelectionDialog import \
254 ## BookmarkActionSelectionDialog
255 ## url = self.__browser.url()
256 ## dlg = BookmarkActionSelectionDialog(url)
257 ## if dlg.exec_() == QDialog.Accepted:
258 ## action = dlg.getAction()
259 ## if action == BookmarkActionSelectionDialog.AddBookmark:
260 ## self.__browser.addBookmark()
261 ## elif action == BookmarkActionSelectionDialog.EditBookmark:
262 ## bookmark = Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\
263 ## .bookmarkForUrl(url)
264 ## from .BookmarkInfoDialog import BookmarkInfoDialog
265 ## dlg = BookmarkInfoDialog(bookmark, self.__browser)
266 ## dlg.exec_()
267 ## elif action == BookmarkActionSelectionDialog.AddSpeeddial:
268 ## Helpviewer.HelpWindow.HelpWindow.speedDial().addPage(
269 ## url, self.__browser.title())
270 ## elif action == BookmarkActionSelectionDialog.RemoveSpeeddial:
271 ## Helpviewer.HelpWindow.HelpWindow.speedDial().removePage(url)
272 ##
273 ## @pyqtSlot()
274 ## def __bookmarkChanged(self):
275 ## """
276 ## Private slot to handle bookmark or speed dial changes.
277 ## """
278 ## self.__checkBookmark()
279 ##
280 def paintEvent(self, evt):
281 """
282 Protected method handling a paint event.
283
284 @param evt reference to the paint event (QPaintEvent)
285 """
286 ## if self.__privateMode:
287 ## backgroundColor = QColor(220, 220, 220) # light gray
288 ## foregroundColor = Qt.black
289 ## else:
290 backgroundColor = QApplication.palette().color(QPalette.Base)
291 foregroundColor = QApplication.palette().color(QPalette.Text)
292
293 if self.__browser is not None:
294 p = self.palette()
295 progress = self.__browser.progress()
296 if progress == 0 or progress == 100:
297 if self.__browser.url().scheme() == "https":
298 if QSslCertificate is not None:
299 if self.__browser.page().hasValidSslInfo():
300 backgroundColor = Preferences.getWebBrowser(
301 "SaveUrlColor")
302 else:
303 backgroundColor = Preferences.getWebBrowser(
304 "SaveUrlColor")
305 p.setBrush(QPalette.Base, backgroundColor)
306 p.setBrush(QPalette.Text, foregroundColor)
307 else:
308 if self.__browser.url().scheme() == "https":
309 if QSslCertificate is not None:
310 if self.__browser.page().hasValidSslInfo():
311 backgroundColor = Preferences.getWebBrowser(
312 "SaveUrlColor")
313 else:
314 backgroundColor = Preferences.getWebBrowser(
315 "SaveUrlColor")
316 highlight = QApplication.palette().color(QPalette.Highlight)
317 r = (highlight.red() + 2 * backgroundColor.red()) // 3
318 g = (highlight.green() + 2 * backgroundColor.green()) // 3
319 b = (highlight.blue() + 2 * backgroundColor.blue()) // 3
320
321 loadingColor = QColor(r, g, b)
322 if abs(loadingColor.lightness() -
323 backgroundColor.lightness()) < 20:
324 # special handling for special color schemes (e.g Gaia)
325 r = (2 * highlight.red() + backgroundColor.red()) // 3
326 g = (2 * highlight.green() + backgroundColor.green()) // 3
327 b = (2 * highlight.blue() + backgroundColor.blue()) // 3
328 loadingColor = QColor(r, g, b)
329
330 gradient = QLinearGradient(
331 QPointF(0, 0), QPointF(self.width(), 0))
332 gradient.setColorAt(0, loadingColor)
333 gradient.setColorAt(progress / 100.0 - 0.000001, loadingColor)
334 gradient.setColorAt(progress / 100.0, backgroundColor)
335 p.setBrush(QPalette.Base, gradient)
336
337 self.setPalette(p)
338
339 E5LineEdit.paintEvent(self, evt)
340
341 def focusOutEvent(self, evt):
342 """
343 Protected method to handle focus out event.
344
345 @param evt reference to the focus event (QFocusEvent)
346 """
347 if self.text() == "" and self.__browser is not None:
348 self.__browserUrlChanged(self.__browser.url())
349 E5LineEdit.focusOutEvent(self, evt)
350
351 def mousePressEvent(self, evt):
352 """
353 Protected method called by a mouse press event.
354
355 @param evt reference to the mouse event (QMouseEvent)
356 """
357 if evt.button() == Qt.XButton1:
358 self.__mw.currentBrowser().triggerPageAction(
359 QWebEnginePage.Back)
360 elif evt.button() == Qt.XButton2:
361 self.__mw.currentBrowser().triggerPageAction(
362 QWebEnginePage.Forward)
363 else:
364 super(UrlBar, self).mousePressEvent(evt)
365
366 def mouseDoubleClickEvent(self, evt):
367 """
368 Protected method to handle mouse double click events.
369
370 @param evt reference to the mouse event (QMouseEvent)
371 """
372 if evt.button() == Qt.LeftButton:
373 self.selectAll()
374 else:
375 E5LineEdit.mouseDoubleClickEvent(self, evt)
376
377 def keyPressEvent(self, evt):
378 """
379 Protected method to handle key presses.
380
381 @param evt reference to the key press event (QKeyEvent)
382 """
383 if evt.key() == Qt.Key_Escape:
384 if self.__browser is not None:
385 self.setText(
386 str(self.__browser.url().toEncoded(), encoding="utf-8"))
387 self.selectAll()
388 completer = self.completer()
389 if completer:
390 completer.popup().hide()
391 return
392
393 currentText = self.text().strip()
394 if evt.key() in [Qt.Key_Enter, Qt.Key_Return] and \
395 not currentText.lower().startswith("http://"):
396 append = ""
397 if evt.modifiers() == Qt.KeyboardModifiers(Qt.ControlModifier):
398 append = ".com"
399 elif evt.modifiers() == Qt.KeyboardModifiers(
400 Qt.ControlModifier | Qt.ShiftModifier):
401 append = ".org"
402 elif evt.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier):
403 append = ".net"
404
405 if append != "":
406 url = QUrl("http://www." + currentText)
407 host = url.host()
408 if not host.lower().endswith(append):
409 host += append
410 url.setHost(host)
411 self.setText(url.toString())
412
413 E5LineEdit.keyPressEvent(self, evt)
414
415 def dragEnterEvent(self, evt):
416 """
417 Protected method to handle drag enter events.
418
419 @param evt reference to the drag enter event (QDragEnterEvent)
420 """
421 mimeData = evt.mimeData()
422 if mimeData.hasUrls() or mimeData.hasText():
423 evt.acceptProposedAction()
424
425 E5LineEdit.dragEnterEvent(self, evt)
426
427 def dropEvent(self, evt):
428 """
429 Protected method to handle drop events.
430
431 @param evt reference to the drop event (QDropEvent)
432 """
433 mimeData = evt.mimeData()
434
435 url = QUrl()
436 if mimeData.hasUrls():
437 url = mimeData.urls()[0]
438 elif mimeData.hasText():
439 url = QUrl.fromEncoded(mimeData.text().encode("utf-8"),
440 QUrl.TolerantMode)
441
442 if url.isEmpty() or not url.isValid():
443 E5LineEdit.dropEvent(self, evt)
444 return
445
446 self.setText(str(url.toEncoded(), encoding="utf-8"))
447 self.selectAll()
448
449 evt.acceptProposedAction()
450 ##
451 ## def __rssClicked(self):
452 ## """
453 ## Private slot to handle clicking the RSS icon.
454 ## """
455 ## from Helpviewer.Feeds.FeedsDialog import FeedsDialog
456 ## feeds = self.__browser.getRSS()
457 ## dlg = FeedsDialog(feeds, self.__browser)
458 ## dlg.exec_()

eric ide

mercurial