57 @signal safeBrowsingBad(threatType, threatMessages) emitted to indicate a |
73 @signal safeBrowsingBad(threatType, threatMessages) emitted to indicate a |
58 malicious web site as determined by safe browsing |
74 malicious web site as determined by safe browsing |
59 @signal showMessage(str) emitted to show a message in the main window |
75 @signal showMessage(str) emitted to show a message in the main window |
60 status bar |
76 status bar |
61 """ |
77 """ |
|
78 |
62 sourceChanged = pyqtSignal(QUrl) |
79 sourceChanged = pyqtSignal(QUrl) |
63 forwardAvailable = pyqtSignal(bool) |
80 forwardAvailable = pyqtSignal(bool) |
64 backwardAvailable = pyqtSignal(bool) |
81 backwardAvailable = pyqtSignal(bool) |
65 highlighted = pyqtSignal(str) |
82 highlighted = pyqtSignal(str) |
66 search = pyqtSignal(QUrl) |
83 search = pyqtSignal(QUrl) |
67 zoomValueChanged = pyqtSignal(int) |
84 zoomValueChanged = pyqtSignal(int) |
68 faviconChanged = pyqtSignal() |
85 faviconChanged = pyqtSignal() |
69 safeBrowsingAbort = pyqtSignal() |
86 safeBrowsingAbort = pyqtSignal() |
70 safeBrowsingBad = pyqtSignal(str, str) |
87 safeBrowsingBad = pyqtSignal(str, str) |
71 showMessage = pyqtSignal(str) |
88 showMessage = pyqtSignal(str) |
72 |
89 |
73 ZoomLevels = [ |
90 ZoomLevels = [ |
74 30, 40, 50, 67, 80, 90, |
91 30, |
|
92 40, |
|
93 50, |
|
94 67, |
|
95 80, |
|
96 90, |
75 100, |
97 100, |
76 110, 120, 133, 150, 170, 200, 220, 233, 250, 270, 285, 300, |
98 110, |
|
99 120, |
|
100 133, |
|
101 150, |
|
102 170, |
|
103 200, |
|
104 220, |
|
105 233, |
|
106 250, |
|
107 270, |
|
108 285, |
|
109 300, |
77 ] |
110 ] |
78 ZoomLevelDefault = 100 |
111 ZoomLevelDefault = 100 |
79 |
112 |
80 def __init__(self, mainWindow, parent=None, name=""): |
113 def __init__(self, mainWindow, parent=None, name=""): |
81 """ |
114 """ |
82 Constructor |
115 Constructor |
83 |
116 |
84 @param mainWindow reference to the main window (WebBrowserWindow) |
117 @param mainWindow reference to the main window (WebBrowserWindow) |
85 @param parent parent widget of this window (QWidget) |
118 @param parent parent widget of this window (QWidget) |
86 @param name name of this window (string) |
119 @param name name of this window (string) |
87 """ |
120 """ |
88 super().__init__(parent) |
121 super().__init__(parent) |
89 self.setObjectName(name) |
122 self.setObjectName(name) |
90 |
123 |
91 self.__rwhvqt = None |
124 self.__rwhvqt = None |
92 self.installEventFilter(self) |
125 self.installEventFilter(self) |
93 |
126 |
94 self.__speedDial = WebBrowserWindow.speedDial() |
127 self.__speedDial = WebBrowserWindow.speedDial() |
95 |
128 |
96 self.__page = None |
129 self.__page = None |
97 self.__createNewPage() |
130 self.__createNewPage() |
98 |
131 |
99 self.__mw = mainWindow |
132 self.__mw = mainWindow |
100 self.__tabWidget = parent |
133 self.__tabWidget = parent |
101 self.__isLoading = False |
134 self.__isLoading = False |
102 self.__progress = 0 |
135 self.__progress = 0 |
103 self.__siteIconLoader = None |
136 self.__siteIconLoader = None |
104 self.__siteIcon = QIcon() |
137 self.__siteIcon = QIcon() |
105 self.__menu = QMenu(self) |
138 self.__menu = QMenu(self) |
106 self.__clickedPos = QPoint() |
139 self.__clickedPos = QPoint() |
107 self.__firstLoad = False |
140 self.__firstLoad = False |
108 self.__preview = QPixmap() |
141 self.__preview = QPixmap() |
109 |
142 |
110 self.__currentZoom = 100 |
143 self.__currentZoom = 100 |
111 self.__zoomLevels = WebBrowserView.ZoomLevels[:] |
144 self.__zoomLevels = WebBrowserView.ZoomLevels[:] |
112 |
145 |
113 self.iconUrlChanged.connect(self.__iconUrlChanged) |
146 self.iconUrlChanged.connect(self.__iconUrlChanged) |
114 self.urlChanged.connect(self.__urlChanged) |
147 self.urlChanged.connect(self.__urlChanged) |
115 self.page().linkHovered.connect(self.__linkHovered) |
148 self.page().linkHovered.connect(self.__linkHovered) |
116 |
149 |
117 self.loadStarted.connect(self.__loadStarted) |
150 self.loadStarted.connect(self.__loadStarted) |
118 self.loadProgress.connect(self.__loadProgress) |
151 self.loadProgress.connect(self.__loadProgress) |
119 self.loadFinished.connect(self.__loadFinished) |
152 self.loadFinished.connect(self.__loadFinished) |
120 self.renderProcessTerminated.connect(self.__renderProcessTerminated) |
153 self.renderProcessTerminated.connect(self.__renderProcessTerminated) |
121 |
154 |
122 self.__mw.openSearchManager().currentEngineChanged.connect( |
155 self.__mw.openSearchManager().currentEngineChanged.connect( |
123 self.__currentEngineChanged) |
156 self.__currentEngineChanged |
124 |
157 ) |
|
158 |
125 self.setAcceptDrops(True) |
159 self.setAcceptDrops(True) |
126 |
160 |
127 self.__rss = [] |
161 self.__rss = [] |
128 |
162 |
129 self.__clickedFrame = None |
163 self.__clickedFrame = None |
130 |
164 |
131 self.__mw.personalInformationManager().connectPage(self.page()) |
165 self.__mw.personalInformationManager().connectPage(self.page()) |
132 |
166 |
133 self.__inspector = None |
167 self.__inspector = None |
134 WebInspector.registerView(self) |
168 WebInspector.registerView(self) |
135 |
169 |
136 self.__restoreData = None |
170 self.__restoreData = None |
137 |
171 |
138 if self.parentWidget() is not None: |
172 if self.parentWidget() is not None: |
139 self.parentWidget().installEventFilter(self) |
173 self.parentWidget().installEventFilter(self) |
140 |
174 |
141 self.grabGesture(Qt.GestureType.PinchGesture) |
175 self.grabGesture(Qt.GestureType.PinchGesture) |
142 |
176 |
143 def __createNewPage(self): |
177 def __createNewPage(self): |
144 """ |
178 """ |
145 Private method to create a new page object. |
179 Private method to create a new page object. |
146 """ |
180 """ |
147 self.__page = WebBrowserPage(self, self) |
181 self.__page = WebBrowserPage(self, self) |
148 self.setPage(self.__page) |
182 self.setPage(self.__page) |
149 |
183 |
150 self.__page.safeBrowsingAbort.connect(self.safeBrowsingAbort) |
184 self.__page.safeBrowsingAbort.connect(self.safeBrowsingAbort) |
151 self.__page.safeBrowsingBad.connect(self.safeBrowsingBad) |
185 self.__page.safeBrowsingBad.connect(self.safeBrowsingBad) |
152 self.__page.printPageRequested.connect(self.__printPage) |
186 self.__page.printPageRequested.connect(self.__printPage) |
153 self.__page.quotaRequested.connect(self.__quotaRequested) |
187 self.__page.quotaRequested.connect(self.__quotaRequested) |
154 # The registerProtocolHandlerRequested signal is handled in |
188 # The registerProtocolHandlerRequested signal is handled in |
155 # WebBrowserPage. |
189 # WebBrowserPage. |
156 self.__page.selectClientCertificate.connect( |
190 self.__page.selectClientCertificate.connect(self.__selectClientCertificate) |
157 self.__selectClientCertificate) |
|
158 self.__page.findTextFinished.connect(self.__findTextFinished) |
191 self.__page.findTextFinished.connect(self.__findTextFinished) |
159 |
192 |
160 def __setRwhvqt(self): |
193 def __setRwhvqt(self): |
161 """ |
194 """ |
162 Private slot to set widget that receives input events. |
195 Private slot to set widget that receives input events. |
163 """ |
196 """ |
164 self.grabGesture(Qt.GestureType.PinchGesture) |
197 self.grabGesture(Qt.GestureType.PinchGesture) |
165 self.__rwhvqt = self.focusProxy() |
198 self.__rwhvqt = self.focusProxy() |
166 if self.__rwhvqt: |
199 if self.__rwhvqt: |
167 self.__rwhvqt.grabGesture(Qt.GestureType.PinchGesture) |
200 self.__rwhvqt.grabGesture(Qt.GestureType.PinchGesture) |
168 self.__rwhvqt.installEventFilter(self) |
201 self.__rwhvqt.installEventFilter(self) |
169 else: |
202 else: |
170 print("Focus proxy is null!") # __IGNORE_WARNING_M801__ |
203 print("Focus proxy is null!") # __IGNORE_WARNING_M801__ |
171 |
204 |
172 def __currentEngineChanged(self): |
205 def __currentEngineChanged(self): |
173 """ |
206 """ |
174 Private slot to track a change of the current search engine. |
207 Private slot to track a change of the current search engine. |
175 """ |
208 """ |
176 if self.url().toString() == "eric:home": |
209 if self.url().toString() == "eric:home": |
177 self.reload() |
210 self.reload() |
178 |
211 |
179 def mainWindow(self): |
212 def mainWindow(self): |
180 """ |
213 """ |
181 Public method to get a reference to the main window. |
214 Public method to get a reference to the main window. |
182 |
215 |
183 @return reference to the main window |
216 @return reference to the main window |
184 @rtype WebBrowserWindow |
217 @rtype WebBrowserWindow |
185 """ |
218 """ |
186 return self.__mw |
219 return self.__mw |
187 |
220 |
188 def tabWidget(self): |
221 def tabWidget(self): |
189 """ |
222 """ |
190 Public method to get a reference to the tab widget containing this |
223 Public method to get a reference to the tab widget containing this |
191 view. |
224 view. |
192 |
225 |
193 @return reference to the tab widget |
226 @return reference to the tab widget |
194 @rtype WebBrowserTabWidget |
227 @rtype WebBrowserTabWidget |
195 """ |
228 """ |
196 return self.__tabWidget |
229 return self.__tabWidget |
197 |
230 |
198 def load(self, url): |
231 def load(self, url): |
199 """ |
232 """ |
200 Public method to load a web site. |
233 Public method to load a web site. |
201 |
234 |
202 @param url URL to be loaded |
235 @param url URL to be loaded |
203 @type QUrl |
236 @type QUrl |
204 """ |
237 """ |
205 if ( |
238 if self.__page is not None and not self.__page.acceptNavigationRequest( |
206 self.__page is not None and |
239 url, QWebEnginePage.NavigationType.NavigationTypeTyped, True |
207 not self.__page.acceptNavigationRequest( |
|
208 url, QWebEnginePage.NavigationType.NavigationTypeTyped, True) |
|
209 ): |
240 ): |
210 return |
241 return |
211 |
242 |
212 super().load(url) |
243 super().load(url) |
213 |
244 |
214 if not self.__firstLoad: |
245 if not self.__firstLoad: |
215 self.__firstLoad = True |
246 self.__firstLoad = True |
216 WebInspector.pushView(self) |
247 WebInspector.pushView(self) |
217 |
248 |
218 def setSource(self, name, newTab=False): |
249 def setSource(self, name, newTab=False): |
219 """ |
250 """ |
220 Public method used to set the source to be displayed. |
251 Public method used to set the source to be displayed. |
221 |
252 |
222 @param name filename to be shown (QUrl) |
253 @param name filename to be shown (QUrl) |
223 @param newTab flag indicating to open the URL in a new tab (bool) |
254 @param newTab flag indicating to open the URL in a new tab (bool) |
224 """ |
255 """ |
225 if name is None or not name.isValid(): |
256 if name is None or not name.isValid(): |
226 return |
257 return |
227 |
258 |
228 if newTab: |
259 if newTab: |
229 # open in a new tab |
260 # open in a new tab |
230 self.__mw.newTab(name) |
261 self.__mw.newTab(name) |
231 return |
262 return |
232 |
263 |
233 if not name.scheme(): |
264 if not name.scheme(): |
234 if not os.path.exists(name.toString()): |
265 if not os.path.exists(name.toString()): |
235 name.setScheme(Preferences.getWebBrowser("DefaultScheme")) |
266 name.setScheme(Preferences.getWebBrowser("DefaultScheme")) |
236 else: |
267 else: |
237 if Utilities.isWindowsPlatform(): |
268 if Utilities.isWindowsPlatform(): |
238 name.setUrl("file:///" + Utilities.fromNativeSeparators( |
269 name.setUrl( |
239 name.toString())) |
270 "file:///" + Utilities.fromNativeSeparators(name.toString()) |
|
271 ) |
240 else: |
272 else: |
241 name.setUrl("file://" + name.toString()) |
273 name.setUrl("file://" + name.toString()) |
242 |
274 |
243 if ( |
275 if len(name.scheme()) == 1 or name.scheme() == "file": |
244 len(name.scheme()) == 1 or |
|
245 name.scheme() == "file" |
|
246 ): |
|
247 # name is a local file |
276 # name is a local file |
248 if name.scheme() and len(name.scheme()) == 1: |
277 if name.scheme() and len(name.scheme()) == 1: |
249 # it is a local path on win os |
278 # it is a local path on win os |
250 name = QUrl.fromLocalFile(name.toString()) |
279 name = QUrl.fromLocalFile(name.toString()) |
251 |
280 |
252 if not pathlib.Path(name.toLocalFile()).exists(): |
281 if not pathlib.Path(name.toLocalFile()).exists(): |
253 EricMessageBox.critical( |
282 EricMessageBox.critical( |
254 self, |
283 self, |
255 self.tr("eric Web Browser"), |
284 self.tr("eric Web Browser"), |
256 self.tr( |
285 self.tr("""<p>The file <b>{0}</b> does not exist.</p>""").format( |
257 """<p>The file <b>{0}</b> does not exist.</p>""") |
286 name.toLocalFile() |
258 .format(name.toLocalFile())) |
287 ), |
|
288 ) |
259 return |
289 return |
260 |
290 |
261 if name.toLocalFile().lower().endswith((".pdf", ".chm")): |
291 if name.toLocalFile().lower().endswith((".pdf", ".chm")): |
262 started = QDesktopServices.openUrl(name) |
292 started = QDesktopServices.openUrl(name) |
263 if not started: |
293 if not started: |
264 EricMessageBox.critical( |
294 EricMessageBox.critical( |
265 self, |
295 self, |
266 self.tr("eric Web Browser"), |
296 self.tr("eric Web Browser"), |
267 self.tr( |
297 self.tr( |
268 """<p>Could not start a viewer""" |
298 """<p>Could not start a viewer""" |
269 """ for file <b>{0}</b>.</p>""") |
299 """ for file <b>{0}</b>.</p>""" |
270 .format(name.path())) |
300 ).format(name.path()), |
|
301 ) |
271 return |
302 return |
272 elif name.scheme() in ["mailto"]: |
303 elif name.scheme() in ["mailto"]: |
273 started = QDesktopServices.openUrl(name) |
304 started = QDesktopServices.openUrl(name) |
274 if not started: |
305 if not started: |
275 EricMessageBox.critical( |
306 EricMessageBox.critical( |
276 self, |
307 self, |
277 self.tr("eric Web Browser"), |
308 self.tr("eric Web Browser"), |
278 self.tr( |
309 self.tr( |
279 """<p>Could not start an application""" |
310 """<p>Could not start an application""" |
280 """ for URL <b>{0}</b>.</p>""") |
311 """ for URL <b>{0}</b>.</p>""" |
281 .format(name.toString())) |
312 ).format(name.toString()), |
|
313 ) |
282 return |
314 return |
283 else: |
315 else: |
284 if name.toString().lower().endswith((".pdf", ".chm")): |
316 if name.toString().lower().endswith((".pdf", ".chm")): |
285 started = QDesktopServices.openUrl(name) |
317 started = QDesktopServices.openUrl(name) |
286 if not started: |
318 if not started: |
287 EricMessageBox.critical( |
319 EricMessageBox.critical( |
288 self, |
320 self, |
289 self.tr("eric Web Browser"), |
321 self.tr("eric Web Browser"), |
290 self.tr( |
322 self.tr( |
291 """<p>Could not start a viewer""" |
323 """<p>Could not start a viewer""" |
292 """ for file <b>{0}</b>.</p>""") |
324 """ for file <b>{0}</b>.</p>""" |
293 .format(name.path())) |
325 ).format(name.path()), |
|
326 ) |
294 return |
327 return |
295 |
328 |
296 self.load(name) |
329 self.load(name) |
297 |
330 |
298 def source(self): |
331 def source(self): |
299 """ |
332 """ |
300 Public method to return the URL of the loaded page. |
333 Public method to return the URL of the loaded page. |
301 |
334 |
302 @return URL loaded in the help browser (QUrl) |
335 @return URL loaded in the help browser (QUrl) |
303 """ |
336 """ |
304 return self.url() |
337 return self.url() |
305 |
338 |
306 def documentTitle(self): |
339 def documentTitle(self): |
307 """ |
340 """ |
308 Public method to return the title of the loaded page. |
341 Public method to return the title of the loaded page. |
309 |
342 |
310 @return title (string) |
343 @return title (string) |
311 """ |
344 """ |
312 return self.title() |
345 return self.title() |
313 |
346 |
314 def backward(self): |
347 def backward(self): |
315 """ |
348 """ |
316 Public slot to move backwards in history. |
349 Public slot to move backwards in history. |
317 """ |
350 """ |
318 self.triggerPageAction(QWebEnginePage.WebAction.Back) |
351 self.triggerPageAction(QWebEnginePage.WebAction.Back) |
319 self.__urlChanged(self.history().currentItem().url()) |
352 self.__urlChanged(self.history().currentItem().url()) |
320 |
353 |
321 def forward(self): |
354 def forward(self): |
322 """ |
355 """ |
323 Public slot to move forward in history. |
356 Public slot to move forward in history. |
324 """ |
357 """ |
325 self.triggerPageAction(QWebEnginePage.WebAction.Forward) |
358 self.triggerPageAction(QWebEnginePage.WebAction.Forward) |
326 self.__urlChanged(self.history().currentItem().url()) |
359 self.__urlChanged(self.history().currentItem().url()) |
327 |
360 |
328 def home(self): |
361 def home(self): |
329 """ |
362 """ |
330 Public slot to move to the first page loaded. |
363 Public slot to move to the first page loaded. |
331 """ |
364 """ |
332 homeUrl = QUrl(Preferences.getWebBrowser("HomePage")) |
365 homeUrl = QUrl(Preferences.getWebBrowser("HomePage")) |
333 self.setSource(homeUrl) |
366 self.setSource(homeUrl) |
334 self.__urlChanged(self.history().currentItem().url()) |
367 self.__urlChanged(self.history().currentItem().url()) |
335 |
368 |
336 def reload(self): |
369 def reload(self): |
337 """ |
370 """ |
338 Public slot to reload the current page. |
371 Public slot to reload the current page. |
339 """ |
372 """ |
340 self.triggerPageAction(QWebEnginePage.WebAction.Reload) |
373 self.triggerPageAction(QWebEnginePage.WebAction.Reload) |
341 |
374 |
342 def reloadBypassingCache(self): |
375 def reloadBypassingCache(self): |
343 """ |
376 """ |
344 Public slot to reload the current page bypassing the cache. |
377 Public slot to reload the current page bypassing the cache. |
345 """ |
378 """ |
346 self.triggerPageAction(QWebEnginePage.WebAction.ReloadAndBypassCache) |
379 self.triggerPageAction(QWebEnginePage.WebAction.ReloadAndBypassCache) |
347 |
380 |
348 def copy(self): |
381 def copy(self): |
349 """ |
382 """ |
350 Public slot to copy the selected text. |
383 Public slot to copy the selected text. |
351 """ |
384 """ |
352 self.triggerPageAction(QWebEnginePage.WebAction.Copy) |
385 self.triggerPageAction(QWebEnginePage.WebAction.Copy) |
353 |
386 |
354 def cut(self): |
387 def cut(self): |
355 """ |
388 """ |
356 Public slot to cut the selected text. |
389 Public slot to cut the selected text. |
357 """ |
390 """ |
358 self.triggerPageAction(QWebEnginePage.WebAction.Cut) |
391 self.triggerPageAction(QWebEnginePage.WebAction.Cut) |
359 |
392 |
360 def paste(self): |
393 def paste(self): |
361 """ |
394 """ |
362 Public slot to paste text from the clipboard. |
395 Public slot to paste text from the clipboard. |
363 """ |
396 """ |
364 self.triggerPageAction(QWebEnginePage.WebAction.Paste) |
397 self.triggerPageAction(QWebEnginePage.WebAction.Paste) |
365 |
398 |
366 def undo(self): |
399 def undo(self): |
367 """ |
400 """ |
368 Public slot to undo the last edit action. |
401 Public slot to undo the last edit action. |
369 """ |
402 """ |
370 self.triggerPageAction(QWebEnginePage.WebAction.Undo) |
403 self.triggerPageAction(QWebEnginePage.WebAction.Undo) |
371 |
404 |
372 def redo(self): |
405 def redo(self): |
373 """ |
406 """ |
374 Public slot to redo the last edit action. |
407 Public slot to redo the last edit action. |
375 """ |
408 """ |
376 self.triggerPageAction(QWebEnginePage.WebAction.Redo) |
409 self.triggerPageAction(QWebEnginePage.WebAction.Redo) |
377 |
410 |
378 def selectAll(self): |
411 def selectAll(self): |
379 """ |
412 """ |
380 Public slot to select all text. |
413 Public slot to select all text. |
381 """ |
414 """ |
382 self.triggerPageAction(QWebEnginePage.WebAction.SelectAll) |
415 self.triggerPageAction(QWebEnginePage.WebAction.SelectAll) |
383 |
416 |
384 def unselect(self): |
417 def unselect(self): |
385 """ |
418 """ |
386 Public slot to clear the current selection. |
419 Public slot to clear the current selection. |
387 """ |
420 """ |
388 self.triggerPageAction(QWebEnginePage.WebAction.Unselect) |
421 self.triggerPageAction(QWebEnginePage.WebAction.Unselect) |
389 |
422 |
390 def isForwardAvailable(self): |
423 def isForwardAvailable(self): |
391 """ |
424 """ |
392 Public method to determine, if a forward move in history is possible. |
425 Public method to determine, if a forward move in history is possible. |
393 |
426 |
394 @return flag indicating move forward is possible (boolean) |
427 @return flag indicating move forward is possible (boolean) |
395 """ |
428 """ |
396 return self.history().canGoForward() |
429 return self.history().canGoForward() |
397 |
430 |
398 def isBackwardAvailable(self): |
431 def isBackwardAvailable(self): |
399 """ |
432 """ |
400 Public method to determine, if a backwards move in history is possible. |
433 Public method to determine, if a backwards move in history is possible. |
401 |
434 |
402 @return flag indicating move backwards is possible (boolean) |
435 @return flag indicating move backwards is possible (boolean) |
403 """ |
436 """ |
404 return self.history().canGoBack() |
437 return self.history().canGoBack() |
405 |
438 |
406 def __levelForZoom(self, zoom): |
439 def __levelForZoom(self, zoom): |
407 """ |
440 """ |
408 Private method determining the zoom level index given a zoom factor. |
441 Private method determining the zoom level index given a zoom factor. |
409 |
442 |
410 @param zoom zoom factor (integer) |
443 @param zoom zoom factor (integer) |
411 @return index of zoom factor (integer) |
444 @return index of zoom factor (integer) |
412 """ |
445 """ |
413 try: |
446 try: |
414 index = self.__zoomLevels.index(zoom) |
447 index = self.__zoomLevels.index(zoom) |
415 except ValueError: |
448 except ValueError: |
416 for index in range(len(self.__zoomLevels)): |
449 for index in range(len(self.__zoomLevels)): |
417 if zoom <= self.__zoomLevels[index]: |
450 if zoom <= self.__zoomLevels[index]: |
418 break |
451 break |
419 return index |
452 return index |
420 |
453 |
421 def setZoomValue(self, value, saveValue=True): |
454 def setZoomValue(self, value, saveValue=True): |
422 """ |
455 """ |
423 Public method to set the zoom value. |
456 Public method to set the zoom value. |
424 |
457 |
425 @param value zoom value (integer) |
458 @param value zoom value (integer) |
426 @param saveValue flag indicating to save the zoom value with the |
459 @param saveValue flag indicating to save the zoom value with the |
427 zoom manager |
460 zoom manager |
428 @type bool |
461 @type bool |
429 """ |
462 """ |
430 if value != self.__currentZoom: |
463 if value != self.__currentZoom: |
431 self.setZoomFactor(value / 100.0) |
464 self.setZoomFactor(value / 100.0) |
432 self.__currentZoom = value |
465 self.__currentZoom = value |
433 if saveValue and not self.__mw.isPrivate(): |
466 if saveValue and not self.__mw.isPrivate(): |
434 from .ZoomManager import ZoomManager |
467 from .ZoomManager import ZoomManager |
|
468 |
435 ZoomManager.instance().setZoomValue(self.url(), value) |
469 ZoomManager.instance().setZoomValue(self.url(), value) |
436 self.zoomValueChanged.emit(value) |
470 self.zoomValueChanged.emit(value) |
437 |
471 |
438 def zoomValue(self): |
472 def zoomValue(self): |
439 """ |
473 """ |
440 Public method to get the current zoom value. |
474 Public method to get the current zoom value. |
441 |
475 |
442 @return zoom value (integer) |
476 @return zoom value (integer) |
443 """ |
477 """ |
444 val = self.zoomFactor() * 100 |
478 val = self.zoomFactor() * 100 |
445 return int(val) |
479 return int(val) |
446 |
480 |
447 def zoomIn(self): |
481 def zoomIn(self): |
448 """ |
482 """ |
449 Public slot to zoom into the page. |
483 Public slot to zoom into the page. |
450 """ |
484 """ |
451 index = self.__levelForZoom(self.__currentZoom) |
485 index = self.__levelForZoom(self.__currentZoom) |
452 if index < len(self.__zoomLevels) - 1: |
486 if index < len(self.__zoomLevels) - 1: |
453 self.setZoomValue(self.__zoomLevels[index + 1]) |
487 self.setZoomValue(self.__zoomLevels[index + 1]) |
454 |
488 |
455 def zoomOut(self): |
489 def zoomOut(self): |
456 """ |
490 """ |
457 Public slot to zoom out of the page. |
491 Public slot to zoom out of the page. |
458 """ |
492 """ |
459 index = self.__levelForZoom(self.__currentZoom) |
493 index = self.__levelForZoom(self.__currentZoom) |
460 if index > 0: |
494 if index > 0: |
461 self.setZoomValue(self.__zoomLevels[index - 1]) |
495 self.setZoomValue(self.__zoomLevels[index - 1]) |
462 |
496 |
463 def zoomReset(self): |
497 def zoomReset(self): |
464 """ |
498 """ |
465 Public method to reset the zoom factor. |
499 Public method to reset the zoom factor. |
466 """ |
500 """ |
467 index = self.__levelForZoom(WebBrowserView.ZoomLevelDefault) |
501 index = self.__levelForZoom(WebBrowserView.ZoomLevelDefault) |
468 self.setZoomValue(self.__zoomLevels[index]) |
502 self.setZoomValue(self.__zoomLevels[index]) |
469 |
503 |
470 def mapToViewport(self, pos): |
504 def mapToViewport(self, pos): |
471 """ |
505 """ |
472 Public method to map a position to the viewport. |
506 Public method to map a position to the viewport. |
473 |
507 |
474 @param pos position to be mapped |
508 @param pos position to be mapped |
475 @type QPoint |
509 @type QPoint |
476 @return viewport position |
510 @return viewport position |
477 @rtype QPoint |
511 @rtype QPoint |
478 """ |
512 """ |
479 return self.page().mapToViewport(pos) |
513 return self.page().mapToViewport(pos) |
480 |
514 |
481 def hasSelection(self): |
515 def hasSelection(self): |
482 """ |
516 """ |
483 Public method to determine, if there is some text selected. |
517 Public method to determine, if there is some text selected. |
484 |
518 |
485 @return flag indicating text has been selected (boolean) |
519 @return flag indicating text has been selected (boolean) |
486 """ |
520 """ |
487 return self.selectedText() != "" |
521 return self.selectedText() != "" |
488 |
522 |
489 def findNextPrev(self, txt, case, backwards, callback): |
523 def findNextPrev(self, txt, case, backwards, callback): |
490 """ |
524 """ |
491 Public slot to find the next occurrence of a text. |
525 Public slot to find the next occurrence of a text. |
492 |
526 |
493 @param txt text to search for (string) |
527 @param txt text to search for (string) |
494 @param case flag indicating a case sensitive search (boolean) |
528 @param case flag indicating a case sensitive search (boolean) |
495 @param backwards flag indicating a backwards search (boolean) |
529 @param backwards flag indicating a backwards search (boolean) |
496 @param callback reference to a function with a bool parameter |
530 @param callback reference to a function with a bool parameter |
497 @type function(bool) or None |
531 @type function(bool) or None |
499 findFlags = QWebEnginePage.FindFlag(0) |
533 findFlags = QWebEnginePage.FindFlag(0) |
500 if case: |
534 if case: |
501 findFlags |= QWebEnginePage.FindFlag.FindCaseSensitively |
535 findFlags |= QWebEnginePage.FindFlag.FindCaseSensitively |
502 if backwards: |
536 if backwards: |
503 findFlags |= QWebEnginePage.FindFlag.FindBackward |
537 findFlags |= QWebEnginePage.FindFlag.FindBackward |
504 |
538 |
505 if callback is None: |
539 if callback is None: |
506 self.findText(txt, findFlags) |
540 self.findText(txt, findFlags) |
507 else: |
541 else: |
508 self.findText(txt, findFlags, callback) |
542 self.findText(txt, findFlags, callback) |
509 |
543 |
510 def __findTextFinished(self, result): |
544 def __findTextFinished(self, result): |
511 """ |
545 """ |
512 Private slot handling the findTextFinished signal of the web page. |
546 Private slot handling the findTextFinished signal of the web page. |
513 |
547 |
514 @param result reference to the QWebEngineFindTextResult object of the |
548 @param result reference to the QWebEngineFindTextResult object of the |
515 last search |
549 last search |
516 @type QWebEngineFindTextResult |
550 @type QWebEngineFindTextResult |
517 """ |
551 """ |
518 self.showMessage.emit(self.tr("Match {0} of {1}").format( |
552 self.showMessage.emit( |
519 result.activeMatch(), result.numberOfMatches()) |
553 self.tr("Match {0} of {1}").format( |
520 ) |
554 result.activeMatch(), result.numberOfMatches() |
521 |
555 ) |
|
556 ) |
|
557 |
522 def contextMenuEvent(self, evt): |
558 def contextMenuEvent(self, evt): |
523 """ |
559 """ |
524 Protected method called to create a context menu. |
560 Protected method called to create a context menu. |
525 |
561 |
526 This method is overridden from QWebEngineView. |
562 This method is overridden from QWebEngineView. |
527 |
563 |
528 @param evt reference to the context menu event object |
564 @param evt reference to the context menu event object |
529 (QContextMenuEvent) |
565 (QContextMenuEvent) |
530 """ |
566 """ |
531 pos = evt.pos() |
567 pos = evt.pos() |
532 reason = evt.reason() |
568 reason = evt.reason() |
533 QTimer.singleShot( |
569 QTimer.singleShot( |
534 0, functools.partial( |
570 0, functools.partial(self._contextMenuEvent, QContextMenuEvent(reason, pos)) |
535 self._contextMenuEvent, QContextMenuEvent(reason, pos))) |
571 ) |
536 # needs to be done this way because contextMenuEvent is blocking |
572 # needs to be done this way because contextMenuEvent is blocking |
537 # the main loop |
573 # the main loop |
538 |
574 |
539 def _contextMenuEvent(self, evt): |
575 def _contextMenuEvent(self, evt): |
540 """ |
576 """ |
541 Protected method called to create a context menu. |
577 Protected method called to create a context menu. |
542 |
578 |
543 @param evt reference to the context menu event object |
579 @param evt reference to the context menu event object |
544 (QContextMenuEvent) |
580 (QContextMenuEvent) |
545 """ |
581 """ |
546 self.__menu.clear() |
582 self.__menu.clear() |
547 |
583 |
548 hitTest = self.page().hitTestContent(evt.pos()) |
584 hitTest = self.page().hitTestContent(evt.pos()) |
549 |
585 |
550 self.__createContextMenu(self.__menu, hitTest) |
586 self.__createContextMenu(self.__menu, hitTest) |
551 |
587 |
552 if not hitTest.isContentEditable() and not hitTest.isContentSelected(): |
588 if not hitTest.isContentEditable() and not hitTest.isContentSelected(): |
553 self.__menu.addSeparator() |
589 self.__menu.addSeparator() |
554 self.__menu.addMenu(self.__mw.adBlockIcon().menu()) |
590 self.__menu.addMenu(self.__mw.adBlockIcon().menu()) |
555 |
591 |
556 self.__menu.addSeparator() |
592 self.__menu.addSeparator() |
557 self.__menu.addAction( |
593 self.__menu.addAction( |
558 UI.PixmapCache.getIcon("webInspector"), |
594 UI.PixmapCache.getIcon("webInspector"), |
559 self.tr("Inspect Element..."), self.__webInspector) |
595 self.tr("Inspect Element..."), |
560 |
596 self.__webInspector, |
|
597 ) |
|
598 |
561 if not self.__menu.isEmpty(): |
599 if not self.__menu.isEmpty(): |
562 pos = evt.globalPos() |
600 pos = evt.globalPos() |
563 self.__menu.popup(QPoint(pos.x(), pos.y() + 1)) |
601 self.__menu.popup(QPoint(pos.x(), pos.y() + 1)) |
564 |
602 |
565 def __createContextMenu(self, menu, hitTest): |
603 def __createContextMenu(self, menu, hitTest): |
566 """ |
604 """ |
567 Private method to populate the context menu. |
605 Private method to populate the context menu. |
568 |
606 |
569 @param menu reference to the menu to be populated |
607 @param menu reference to the menu to be populated |
570 @type QMenu |
608 @type QMenu |
571 @param hitTest reference to the hit test object |
609 @param hitTest reference to the hit test object |
572 @type WebHitTestResult |
610 @type WebHitTestResult |
573 """ |
611 """ |
574 spellCheckActionCount = 0 |
612 spellCheckActionCount = 0 |
575 contextMenuData = self.lastContextMenuRequest() |
613 contextMenuData = self.lastContextMenuRequest() |
576 hitTest.updateWithContextMenuData(contextMenuData) |
614 hitTest.updateWithContextMenuData(contextMenuData) |
577 |
615 |
578 if bool(contextMenuData.misspelledWord()): |
616 if bool(contextMenuData.misspelledWord()): |
579 boldFont = menu.font() |
617 boldFont = menu.font() |
580 boldFont.setBold(True) |
618 boldFont.setBold(True) |
581 |
619 |
582 for suggestion in contextMenuData.spellCheckerSuggestions(): |
620 for suggestion in contextMenuData.spellCheckerSuggestions(): |
583 act = menu.addAction(suggestion) |
621 act = menu.addAction(suggestion) |
584 act.setFont(boldFont) |
622 act.setFont(boldFont) |
585 act.triggered.connect( |
623 act.triggered.connect( |
586 functools.partial(self.__replaceMisspelledWord, act)) |
624 functools.partial(self.__replaceMisspelledWord, act) |
587 |
625 ) |
|
626 |
588 if not bool(menu.actions()): |
627 if not bool(menu.actions()): |
589 menu.addAction(self.tr("No suggestions")).setEnabled(False) |
628 menu.addAction(self.tr("No suggestions")).setEnabled(False) |
590 |
629 |
591 menu.addSeparator() |
630 menu.addSeparator() |
592 spellCheckActionCount = len(menu.actions()) |
631 spellCheckActionCount = len(menu.actions()) |
593 |
632 |
594 if ( |
633 if ( |
595 not hitTest.linkUrl().isEmpty() and |
634 not hitTest.linkUrl().isEmpty() |
596 hitTest.linkUrl().scheme() != "javascript" |
635 and hitTest.linkUrl().scheme() != "javascript" |
597 ): |
636 ): |
598 self.__createLinkContextMenu(menu, hitTest) |
637 self.__createLinkContextMenu(menu, hitTest) |
599 |
638 |
600 if not hitTest.imageUrl().isEmpty(): |
639 if not hitTest.imageUrl().isEmpty(): |
601 self.__createImageContextMenu(menu, hitTest) |
640 self.__createImageContextMenu(menu, hitTest) |
602 |
641 |
603 if not hitTest.mediaUrl().isEmpty(): |
642 if not hitTest.mediaUrl().isEmpty(): |
604 self.__createMediaContextMenu(menu, hitTest) |
643 self.__createMediaContextMenu(menu, hitTest) |
605 |
644 |
606 if hitTest.isContentEditable(): |
645 if hitTest.isContentEditable(): |
607 # check, if only spell checker actions were added |
646 # check, if only spell checker actions were added |
608 if len(menu.actions()) == spellCheckActionCount: |
647 if len(menu.actions()) == spellCheckActionCount: |
609 menu.addAction(self.__mw.undoAct) |
648 menu.addAction(self.__mw.undoAct) |
610 menu.addAction(self.__mw.redoAct) |
649 menu.addAction(self.__mw.redoAct) |
612 menu.addAction(self.__mw.cutAct) |
651 menu.addAction(self.__mw.cutAct) |
613 menu.addAction(self.__mw.copyAct) |
652 menu.addAction(self.__mw.copyAct) |
614 menu.addAction(self.__mw.pasteAct) |
653 menu.addAction(self.__mw.pasteAct) |
615 menu.addSeparator() |
654 menu.addSeparator() |
616 self.__mw.personalInformationManager().createSubMenu( |
655 self.__mw.personalInformationManager().createSubMenu( |
617 menu, self, hitTest) |
656 menu, self, hitTest |
618 |
657 ) |
|
658 |
619 if hitTest.tagName() == "input": |
659 if hitTest.tagName() == "input": |
620 menu.addSeparator() |
660 menu.addSeparator() |
621 act = menu.addAction("") |
661 act = menu.addAction("") |
622 act.setVisible(False) |
662 act.setVisible(False) |
623 self.__checkForForm(act, hitTest.pos()) |
663 self.__checkForForm(act, hitTest.pos()) |
624 |
664 |
625 if self.selectedText(): |
665 if self.selectedText(): |
626 self.__createSelectedTextContextMenu(menu, hitTest) |
666 self.__createSelectedTextContextMenu(menu, hitTest) |
627 |
667 |
628 if self.__menu.isEmpty(): |
668 if self.__menu.isEmpty(): |
629 self.__createPageContextMenu(menu) |
669 self.__createPageContextMenu(menu) |
630 |
670 |
631 def __createLinkContextMenu(self, menu, hitTest): |
671 def __createLinkContextMenu(self, menu, hitTest): |
632 """ |
672 """ |
633 Private method to populate the context menu for URLs. |
673 Private method to populate the context menu for URLs. |
634 |
674 |
635 @param menu reference to the menu to be populated |
675 @param menu reference to the menu to be populated |
636 @type QMenu |
676 @type QMenu |
637 @param hitTest reference to the hit test object |
677 @param hitTest reference to the hit test object |
638 @type WebHitTestResult |
678 @type WebHitTestResult |
639 """ |
679 """ |
640 if not menu.isEmpty(): |
680 if not menu.isEmpty(): |
641 menu.addSeparator() |
681 menu.addSeparator() |
642 |
682 |
643 act = menu.addAction( |
683 act = menu.addAction( |
644 UI.PixmapCache.getIcon("openNewTab"), |
684 UI.PixmapCache.getIcon("openNewTab"), |
645 self.tr("Open Link in New Tab\tCtrl+LMB")) |
685 self.tr("Open Link in New Tab\tCtrl+LMB"), |
|
686 ) |
646 act.setData(hitTest.linkUrl()) |
687 act.setData(hitTest.linkUrl()) |
647 act.triggered.connect( |
688 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
648 functools.partial(self.__openLinkInNewTab, act)) |
|
649 act = menu.addAction( |
689 act = menu.addAction( |
650 UI.PixmapCache.getIcon("newWindow"), |
690 UI.PixmapCache.getIcon("newWindow"), self.tr("Open Link in New Window") |
651 self.tr("Open Link in New Window")) |
691 ) |
652 act.setData(hitTest.linkUrl()) |
692 act.setData(hitTest.linkUrl()) |
653 act.triggered.connect( |
693 act.triggered.connect(functools.partial(self.__openLinkInNewWindow, act)) |
654 functools.partial(self.__openLinkInNewWindow, act)) |
|
655 act = menu.addAction( |
694 act = menu.addAction( |
656 UI.PixmapCache.getIcon("privateMode"), |
695 UI.PixmapCache.getIcon("privateMode"), |
657 self.tr("Open Link in New Private Window")) |
696 self.tr("Open Link in New Private Window"), |
|
697 ) |
658 act.setData(hitTest.linkUrl()) |
698 act.setData(hitTest.linkUrl()) |
659 act.triggered.connect( |
699 act.triggered.connect(functools.partial(self.__openLinkInNewPrivateWindow, act)) |
660 functools.partial(self.__openLinkInNewPrivateWindow, act)) |
|
661 menu.addSeparator() |
700 menu.addSeparator() |
662 menu.addAction( |
701 menu.addAction( |
663 UI.PixmapCache.getIcon("download"), |
702 UI.PixmapCache.getIcon("download"), |
664 self.tr("Save Lin&k"), self.__downloadLink) |
703 self.tr("Save Lin&k"), |
|
704 self.__downloadLink, |
|
705 ) |
665 act = menu.addAction( |
706 act = menu.addAction( |
666 UI.PixmapCache.getIcon("bookmark22"), |
707 UI.PixmapCache.getIcon("bookmark22"), self.tr("Bookmark this Link") |
667 self.tr("Bookmark this Link")) |
708 ) |
668 act.setData(hitTest.linkUrl()) |
709 act.setData(hitTest.linkUrl()) |
669 act.triggered.connect( |
710 act.triggered.connect(functools.partial(self.__bookmarkLink, act)) |
670 functools.partial(self.__bookmarkLink, act)) |
|
671 menu.addSeparator() |
711 menu.addSeparator() |
672 act = menu.addAction( |
712 act = menu.addAction( |
673 UI.PixmapCache.getIcon("editCopy"), |
713 UI.PixmapCache.getIcon("editCopy"), self.tr("Copy URL to Clipboard") |
674 self.tr("Copy URL to Clipboard")) |
714 ) |
675 act.setData(hitTest.linkUrl()) |
715 act.setData(hitTest.linkUrl()) |
676 act.triggered.connect( |
716 act.triggered.connect(functools.partial(self.__copyLink, act)) |
677 functools.partial(self.__copyLink, act)) |
717 act = menu.addAction(UI.PixmapCache.getIcon("mailSend"), self.tr("Send URL")) |
678 act = menu.addAction( |
|
679 UI.PixmapCache.getIcon("mailSend"), |
|
680 self.tr("Send URL")) |
|
681 act.setData(hitTest.linkUrl()) |
718 act.setData(hitTest.linkUrl()) |
682 act.triggered.connect( |
719 act.triggered.connect(functools.partial(self.__sendLink, act)) |
683 functools.partial(self.__sendLink, act)) |
|
684 if ( |
720 if ( |
685 Preferences.getWebBrowser("VirusTotalEnabled") and |
721 Preferences.getWebBrowser("VirusTotalEnabled") |
686 Preferences.getWebBrowser("VirusTotalServiceKey") != "" |
722 and Preferences.getWebBrowser("VirusTotalServiceKey") != "" |
687 ): |
723 ): |
688 act = menu.addAction( |
724 act = menu.addAction( |
689 UI.PixmapCache.getIcon("virustotal"), |
725 UI.PixmapCache.getIcon("virustotal"), |
690 self.tr("Scan Link with VirusTotal")) |
726 self.tr("Scan Link with VirusTotal"), |
|
727 ) |
691 act.setData(hitTest.linkUrl()) |
728 act.setData(hitTest.linkUrl()) |
692 act.triggered.connect( |
729 act.triggered.connect(functools.partial(self.__virusTotal, act)) |
693 functools.partial(self.__virusTotal, act)) |
730 |
694 |
|
695 def __createImageContextMenu(self, menu, hitTest): |
731 def __createImageContextMenu(self, menu, hitTest): |
696 """ |
732 """ |
697 Private method to populate the context menu for images. |
733 Private method to populate the context menu for images. |
698 |
734 |
699 @param menu reference to the menu to be populated |
735 @param menu reference to the menu to be populated |
700 @type QMenu |
736 @type QMenu |
701 @param hitTest reference to the hit test object |
737 @param hitTest reference to the hit test object |
702 @type WebHitTestResult |
738 @type WebHitTestResult |
703 """ |
739 """ |
704 if not menu.isEmpty(): |
740 if not menu.isEmpty(): |
705 menu.addSeparator() |
741 menu.addSeparator() |
706 |
742 |
707 act = menu.addAction( |
743 act = menu.addAction( |
708 UI.PixmapCache.getIcon("openNewTab"), |
744 UI.PixmapCache.getIcon("openNewTab"), self.tr("Open Image in New Tab") |
709 self.tr("Open Image in New Tab")) |
745 ) |
710 act.setData(hitTest.imageUrl()) |
746 act.setData(hitTest.imageUrl()) |
711 act.triggered.connect( |
747 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
712 functools.partial(self.__openLinkInNewTab, act)) |
|
713 menu.addSeparator() |
748 menu.addSeparator() |
714 menu.addAction( |
749 menu.addAction( |
715 UI.PixmapCache.getIcon("download"), |
750 UI.PixmapCache.getIcon("download"), |
716 self.tr("Save Image"), self.__downloadImage) |
751 self.tr("Save Image"), |
717 menu.addAction( |
752 self.__downloadImage, |
718 self.tr("Copy Image to Clipboard"), self.__copyImage) |
753 ) |
|
754 menu.addAction(self.tr("Copy Image to Clipboard"), self.__copyImage) |
719 act = menu.addAction( |
755 act = menu.addAction( |
720 UI.PixmapCache.getIcon("editCopy"), |
756 UI.PixmapCache.getIcon("editCopy"), self.tr("Copy Image URL to Clipboard") |
721 self.tr("Copy Image URL to Clipboard")) |
757 ) |
722 act.setData(hitTest.imageUrl()) |
758 act.setData(hitTest.imageUrl()) |
723 act.triggered.connect( |
759 act.triggered.connect(functools.partial(self.__copyLink, act)) |
724 functools.partial(self.__copyLink, act)) |
|
725 act = menu.addAction( |
760 act = menu.addAction( |
726 UI.PixmapCache.getIcon("mailSend"), |
761 UI.PixmapCache.getIcon("mailSend"), self.tr("Send Image URL") |
727 self.tr("Send Image URL")) |
762 ) |
728 act.setData(hitTest.imageUrl()) |
763 act.setData(hitTest.imageUrl()) |
729 act.triggered.connect( |
764 act.triggered.connect(functools.partial(self.__sendLink, act)) |
730 functools.partial(self.__sendLink, act)) |
765 |
731 |
|
732 if hitTest.imageUrl().scheme() in ["http", "https"]: |
766 if hitTest.imageUrl().scheme() in ["http", "https"]: |
733 menu.addSeparator() |
767 menu.addSeparator() |
734 engine = WebBrowserWindow.imageSearchEngine() |
768 engine = WebBrowserWindow.imageSearchEngine() |
735 searchEngineName = engine.searchEngine() |
769 searchEngineName = engine.searchEngine() |
736 act = menu.addAction( |
770 act = menu.addAction( |
737 UI.PixmapCache.getIcon("{0}".format( |
771 UI.PixmapCache.getIcon("{0}".format(searchEngineName.lower())), |
738 searchEngineName.lower())), |
772 self.tr("Search image in {0}").format(searchEngineName), |
739 self.tr("Search image in {0}").format(searchEngineName)) |
773 ) |
740 act.setData(engine.getSearchQuery(hitTest.imageUrl())) |
774 act.setData(engine.getSearchQuery(hitTest.imageUrl())) |
741 act.triggered.connect( |
775 act.triggered.connect(functools.partial(self.__searchImage, act)) |
742 functools.partial(self.__searchImage, act)) |
776 self.__imageSearchMenu = menu.addMenu(self.tr("Search image with...")) |
743 self.__imageSearchMenu = menu.addMenu( |
|
744 self.tr("Search image with...")) |
|
745 for searchEngineName in engine.searchEngineNames(): |
777 for searchEngineName in engine.searchEngineNames(): |
746 act = self.__imageSearchMenu.addAction( |
778 act = self.__imageSearchMenu.addAction( |
747 UI.PixmapCache.getIcon("{0}".format( |
779 UI.PixmapCache.getIcon("{0}".format(searchEngineName.lower())), |
748 searchEngineName.lower())), |
780 self.tr("Search image in {0}").format(searchEngineName), |
749 self.tr("Search image in {0}").format(searchEngineName)) |
781 ) |
750 act.setData(engine.getSearchQuery( |
782 act.setData(engine.getSearchQuery(hitTest.imageUrl(), searchEngineName)) |
751 hitTest.imageUrl(), searchEngineName)) |
783 act.triggered.connect(functools.partial(self.__searchImage, act)) |
752 act.triggered.connect( |
784 |
753 functools.partial(self.__searchImage, act)) |
|
754 |
|
755 menu.addSeparator() |
785 menu.addSeparator() |
756 act = menu.addAction( |
786 act = menu.addAction( |
757 UI.PixmapCache.getIcon("adBlockPlus"), |
787 UI.PixmapCache.getIcon("adBlockPlus"), self.tr("Block Image") |
758 self.tr("Block Image")) |
788 ) |
759 act.setData(hitTest.imageUrl().toString()) |
789 act.setData(hitTest.imageUrl().toString()) |
760 act.triggered.connect( |
790 act.triggered.connect(functools.partial(self.__blockImage, act)) |
761 functools.partial(self.__blockImage, act)) |
|
762 if ( |
791 if ( |
763 Preferences.getWebBrowser("VirusTotalEnabled") and |
792 Preferences.getWebBrowser("VirusTotalEnabled") |
764 Preferences.getWebBrowser("VirusTotalServiceKey") != "" |
793 and Preferences.getWebBrowser("VirusTotalServiceKey") != "" |
765 ): |
794 ): |
766 act = menu.addAction( |
795 act = menu.addAction( |
767 UI.PixmapCache.getIcon("virustotal"), |
796 UI.PixmapCache.getIcon("virustotal"), |
768 self.tr("Scan Image with VirusTotal")) |
797 self.tr("Scan Image with VirusTotal"), |
|
798 ) |
769 act.setData(hitTest.imageUrl()) |
799 act.setData(hitTest.imageUrl()) |
770 act.triggered.connect( |
800 act.triggered.connect(functools.partial(self.__virusTotal, act)) |
771 functools.partial(self.__virusTotal, act)) |
801 |
772 |
|
773 def __createMediaContextMenu(self, menu, hitTest): |
802 def __createMediaContextMenu(self, menu, hitTest): |
774 """ |
803 """ |
775 Private method to populate the context menu for media elements. |
804 Private method to populate the context menu for media elements. |
776 |
805 |
777 @param menu reference to the menu to be populated |
806 @param menu reference to the menu to be populated |
778 @type QMenu |
807 @type QMenu |
779 @param hitTest reference to the hit test object |
808 @param hitTest reference to the hit test object |
780 @type WebHitTestResult |
809 @type WebHitTestResult |
781 """ |
810 """ |
782 if not menu.isEmpty(): |
811 if not menu.isEmpty(): |
783 menu.addSeparator() |
812 menu.addSeparator() |
784 |
813 |
785 if hitTest.mediaPaused(): |
814 if hitTest.mediaPaused(): |
786 menu.addAction( |
815 menu.addAction( |
787 UI.PixmapCache.getIcon("mediaPlaybackStart"), |
816 UI.PixmapCache.getIcon("mediaPlaybackStart"), |
788 self.tr("Play"), self.__pauseMedia) |
817 self.tr("Play"), |
|
818 self.__pauseMedia, |
|
819 ) |
789 else: |
820 else: |
790 menu.addAction( |
821 menu.addAction( |
791 UI.PixmapCache.getIcon("mediaPlaybackPause"), |
822 UI.PixmapCache.getIcon("mediaPlaybackPause"), |
792 self.tr("Pause"), self.__pauseMedia) |
823 self.tr("Pause"), |
|
824 self.__pauseMedia, |
|
825 ) |
793 if hitTest.mediaMuted(): |
826 if hitTest.mediaMuted(): |
794 menu.addAction( |
827 menu.addAction( |
795 UI.PixmapCache.getIcon("audioVolumeHigh"), |
828 UI.PixmapCache.getIcon("audioVolumeHigh"), |
796 self.tr("Unmute"), self.__muteMedia) |
829 self.tr("Unmute"), |
|
830 self.__muteMedia, |
|
831 ) |
797 else: |
832 else: |
798 menu.addAction( |
833 menu.addAction( |
799 UI.PixmapCache.getIcon("audioVolumeMuted"), |
834 UI.PixmapCache.getIcon("audioVolumeMuted"), |
800 self.tr("Mute"), self.__muteMedia) |
835 self.tr("Mute"), |
|
836 self.__muteMedia, |
|
837 ) |
801 menu.addSeparator() |
838 menu.addSeparator() |
802 act = menu.addAction( |
839 act = menu.addAction( |
803 UI.PixmapCache.getIcon("editCopy"), |
840 UI.PixmapCache.getIcon("editCopy"), self.tr("Copy Media URL to Clipboard") |
804 self.tr("Copy Media URL to Clipboard")) |
841 ) |
805 act.setData(hitTest.mediaUrl()) |
842 act.setData(hitTest.mediaUrl()) |
806 act.triggered.connect( |
843 act.triggered.connect(functools.partial(self.__copyLink, act)) |
807 functools.partial(self.__copyLink, act)) |
|
808 act = menu.addAction( |
844 act = menu.addAction( |
809 UI.PixmapCache.getIcon("mailSend"), |
845 UI.PixmapCache.getIcon("mailSend"), self.tr("Send Media URL") |
810 self.tr("Send Media URL")) |
846 ) |
811 act.setData(hitTest.mediaUrl()) |
847 act.setData(hitTest.mediaUrl()) |
812 act.triggered.connect( |
848 act.triggered.connect(functools.partial(self.__sendLink, act)) |
813 functools.partial(self.__sendLink, act)) |
|
814 menu.addAction( |
849 menu.addAction( |
815 UI.PixmapCache.getIcon("download"), |
850 UI.PixmapCache.getIcon("download"), |
816 self.tr("Save Media"), self.__downloadMedia) |
851 self.tr("Save Media"), |
817 |
852 self.__downloadMedia, |
|
853 ) |
|
854 |
818 def __createSelectedTextContextMenu(self, menu, hitTest): |
855 def __createSelectedTextContextMenu(self, menu, hitTest): |
819 """ |
856 """ |
820 Private method to populate the context menu for selected text. |
857 Private method to populate the context menu for selected text. |
821 |
858 |
822 @param menu reference to the menu to be populated |
859 @param menu reference to the menu to be populated |
823 @type QMenu |
860 @type QMenu |
824 @param hitTest reference to the hit test object |
861 @param hitTest reference to the hit test object |
825 @type WebHitTestResult |
862 @type WebHitTestResult |
826 """ |
863 """ |
827 if not menu.isEmpty(): |
864 if not menu.isEmpty(): |
828 menu.addSeparator() |
865 menu.addSeparator() |
829 |
866 |
830 menu.addAction(self.__mw.copyAct) |
867 menu.addAction(self.__mw.copyAct) |
831 menu.addSeparator() |
868 menu.addSeparator() |
832 act = menu.addAction( |
869 act = menu.addAction(UI.PixmapCache.getIcon("mailSend"), self.tr("Send Text")) |
833 UI.PixmapCache.getIcon("mailSend"), |
|
834 self.tr("Send Text")) |
|
835 act.setData(self.selectedText()) |
870 act.setData(self.selectedText()) |
836 act.triggered.connect( |
871 act.triggered.connect(functools.partial(self.__sendLink, act)) |
837 functools.partial(self.__sendLink, act)) |
872 |
838 |
|
839 engineName = self.__mw.openSearchManager().currentEngineName() |
873 engineName = self.__mw.openSearchManager().currentEngineName() |
840 if engineName: |
874 if engineName: |
841 menu.addAction(self.tr("Search with '{0}'").format(engineName), |
875 menu.addAction( |
842 self.__searchDefaultRequested) |
876 self.tr("Search with '{0}'").format(engineName), |
843 |
877 self.__searchDefaultRequested, |
844 from .OpenSearch.OpenSearchEngineAction import ( |
878 ) |
845 OpenSearchEngineAction |
879 |
846 ) |
880 from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction |
847 |
881 |
848 self.__searchMenu = menu.addMenu(self.tr("Search with...")) |
882 self.__searchMenu = menu.addMenu(self.tr("Search with...")) |
849 engineNames = self.__mw.openSearchManager().allEnginesNames() |
883 engineNames = self.__mw.openSearchManager().allEnginesNames() |
850 for engineName in engineNames: |
884 for engineName in engineNames: |
851 engine = self.__mw.openSearchManager().engine(engineName) |
885 engine = self.__mw.openSearchManager().engine(engineName) |
852 act = OpenSearchEngineAction(engine, self.__searchMenu) |
886 act = OpenSearchEngineAction(engine, self.__searchMenu) |
853 act.setData(engineName) |
887 act.setData(engineName) |
854 self.__searchMenu.addAction(act) |
888 self.__searchMenu.addAction(act) |
855 self.__searchMenu.triggered.connect(self.__searchRequested) |
889 self.__searchMenu.triggered.connect(self.__searchRequested) |
856 |
890 |
857 menu.addSeparator() |
891 menu.addSeparator() |
858 |
892 |
859 from .WebBrowserLanguagesDialog import WebBrowserLanguagesDialog |
893 from .WebBrowserLanguagesDialog import WebBrowserLanguagesDialog |
|
894 |
860 languages = Preferences.toList( |
895 languages = Preferences.toList( |
861 Preferences.getSettings().value( |
896 Preferences.getSettings().value( |
862 "WebBrowser/AcceptLanguages", |
897 "WebBrowser/AcceptLanguages", |
863 WebBrowserLanguagesDialog.defaultAcceptLanguages())) |
898 WebBrowserLanguagesDialog.defaultAcceptLanguages(), |
|
899 ) |
|
900 ) |
864 if languages: |
901 if languages: |
865 language = languages[0] |
902 language = languages[0] |
866 langCode = language.split("[")[1][:2] |
903 langCode = language.split("[")[1][:2] |
867 googleTranslatorUrl = QUrl( |
904 googleTranslatorUrl = QUrl( |
868 "http://translate.google.com/#auto/{0}/{1}".format( |
905 "http://translate.google.com/#auto/{0}/{1}".format( |
869 langCode, self.selectedText())) |
906 langCode, self.selectedText() |
|
907 ) |
|
908 ) |
870 act = menu.addAction( |
909 act = menu.addAction( |
871 UI.PixmapCache.getIcon("translate"), |
910 UI.PixmapCache.getIcon("translate"), self.tr("Google Translate") |
872 self.tr("Google Translate")) |
911 ) |
873 act.setData(googleTranslatorUrl) |
912 act.setData(googleTranslatorUrl) |
874 act.triggered.connect( |
913 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
875 functools.partial(self.__openLinkInNewTab, act)) |
|
876 wiktionaryUrl = QUrl( |
914 wiktionaryUrl = QUrl( |
877 "http://{0}.wiktionary.org/wiki/Special:Search?search={1}" |
915 "http://{0}.wiktionary.org/wiki/Special:Search?search={1}".format( |
878 .format(langCode, self.selectedText())) |
916 langCode, self.selectedText() |
|
917 ) |
|
918 ) |
879 act = menu.addAction( |
919 act = menu.addAction( |
880 UI.PixmapCache.getIcon("wikipedia"), |
920 UI.PixmapCache.getIcon("wikipedia"), self.tr("Dictionary") |
881 self.tr("Dictionary")) |
921 ) |
882 act.setData(wiktionaryUrl) |
922 act.setData(wiktionaryUrl) |
883 act.triggered.connect( |
923 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
884 functools.partial(self.__openLinkInNewTab, act)) |
|
885 menu.addSeparator() |
924 menu.addSeparator() |
886 |
925 |
887 guessedUrl = QUrl.fromUserInput(self.selectedText().strip()) |
926 guessedUrl = QUrl.fromUserInput(self.selectedText().strip()) |
888 if self.__isUrlValid(guessedUrl): |
927 if self.__isUrlValid(guessedUrl): |
889 act = menu.addAction(self.tr("Go to web address")) |
928 act = menu.addAction(self.tr("Go to web address")) |
890 act.setData(guessedUrl) |
929 act.setData(guessedUrl) |
891 act.triggered.connect( |
930 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
892 functools.partial(self.__openLinkInNewTab, act)) |
931 |
893 |
|
894 def __createPageContextMenu(self, menu): |
932 def __createPageContextMenu(self, menu): |
895 """ |
933 """ |
896 Private method to populate the basic context menu. |
934 Private method to populate the basic context menu. |
897 |
935 |
898 @param menu reference to the menu to be populated |
936 @param menu reference to the menu to be populated |
899 @type QMenu |
937 @type QMenu |
900 """ |
938 """ |
901 menu.addAction(self.__mw.newTabAct) |
939 menu.addAction(self.__mw.newTabAct) |
902 menu.addAction(self.__mw.newAct) |
940 menu.addAction(self.__mw.newAct) |
903 menu.addSeparator() |
941 menu.addSeparator() |
904 if self.__mw.saveAsAct is not None: |
942 if self.__mw.saveAsAct is not None: |
905 menu.addAction(self.__mw.saveAsAct) |
943 menu.addAction(self.__mw.saveAsAct) |
906 menu.addAction(self.__mw.saveVisiblePageScreenAct) |
944 menu.addAction(self.__mw.saveVisiblePageScreenAct) |
907 menu.addSeparator() |
945 menu.addSeparator() |
908 |
946 |
909 if self.url().toString() == "eric:speeddial": |
947 if self.url().toString() == "eric:speeddial": |
910 # special menu for the spedd dial page |
948 # special menu for the spedd dial page |
911 menu.addAction(self.__mw.backAct) |
949 menu.addAction(self.__mw.backAct) |
912 menu.addAction(self.__mw.forwardAct) |
950 menu.addAction(self.__mw.forwardAct) |
913 menu.addSeparator() |
951 menu.addSeparator() |
914 menu.addAction( |
952 menu.addAction( |
915 UI.PixmapCache.getIcon("plus"), |
953 UI.PixmapCache.getIcon("plus"), |
916 self.tr("Add New Page"), self.__addSpeedDial) |
954 self.tr("Add New Page"), |
|
955 self.__addSpeedDial, |
|
956 ) |
917 menu.addAction( |
957 menu.addAction( |
918 UI.PixmapCache.getIcon("preferences-general"), |
958 UI.PixmapCache.getIcon("preferences-general"), |
919 self.tr("Configure Speed Dial"), self.__configureSpeedDial) |
959 self.tr("Configure Speed Dial"), |
|
960 self.__configureSpeedDial, |
|
961 ) |
920 menu.addSeparator() |
962 menu.addSeparator() |
921 menu.addAction( |
963 menu.addAction( |
922 UI.PixmapCache.getIcon("reload"), |
964 UI.PixmapCache.getIcon("reload"), |
923 self.tr("Reload All Dials"), self.__reloadAllSpeedDials) |
965 self.tr("Reload All Dials"), |
|
966 self.__reloadAllSpeedDials, |
|
967 ) |
924 menu.addSeparator() |
968 menu.addSeparator() |
925 menu.addAction( |
969 menu.addAction(self.tr("Reset to Default Dials"), self.__resetSpeedDials) |
926 self.tr("Reset to Default Dials"), self.__resetSpeedDials) |
|
927 return |
970 return |
928 |
971 |
929 menu.addAction( |
972 menu.addAction( |
930 UI.PixmapCache.getIcon("bookmark22"), |
973 UI.PixmapCache.getIcon("bookmark22"), |
931 self.tr("Bookmark this Page"), self.addBookmark) |
974 self.tr("Bookmark this Page"), |
|
975 self.addBookmark, |
|
976 ) |
932 act = menu.addAction( |
977 act = menu.addAction( |
933 UI.PixmapCache.getIcon("editCopy"), |
978 UI.PixmapCache.getIcon("editCopy"), self.tr("Copy Page URL to Clipboard") |
934 self.tr("Copy Page URL to Clipboard")) |
979 ) |
935 act.setData(self.url()) |
980 act.setData(self.url()) |
936 act.triggered.connect( |
981 act.triggered.connect(functools.partial(self.__copyLink, act)) |
937 functools.partial(self.__copyLink, act)) |
|
938 act = menu.addAction( |
982 act = menu.addAction( |
939 UI.PixmapCache.getIcon("mailSend"), |
983 UI.PixmapCache.getIcon("mailSend"), self.tr("Send Page URL") |
940 self.tr("Send Page URL")) |
984 ) |
941 act.setData(self.url()) |
985 act.setData(self.url()) |
942 act.triggered.connect( |
986 act.triggered.connect(functools.partial(self.__sendLink, act)) |
943 functools.partial(self.__sendLink, act)) |
|
944 menu.addSeparator() |
987 menu.addSeparator() |
945 |
988 |
946 from .UserAgent.UserAgentMenu import UserAgentMenu |
989 from .UserAgent.UserAgentMenu import UserAgentMenu |
947 self.__userAgentMenu = UserAgentMenu(self.tr("User Agent"), |
990 |
948 url=self.url()) |
991 self.__userAgentMenu = UserAgentMenu(self.tr("User Agent"), url=self.url()) |
949 menu.addMenu(self.__userAgentMenu) |
992 menu.addMenu(self.__userAgentMenu) |
950 menu.addSeparator() |
993 menu.addSeparator() |
951 menu.addAction(self.__mw.backAct) |
994 menu.addAction(self.__mw.backAct) |
952 menu.addAction(self.__mw.forwardAct) |
995 menu.addAction(self.__mw.forwardAct) |
953 menu.addAction(self.__mw.homeAct) |
996 menu.addAction(self.__mw.homeAct) |
965 menu.addAction(self.__mw.pageSourceAct) |
1008 menu.addAction(self.__mw.pageSourceAct) |
966 menu.addSeparator() |
1009 menu.addSeparator() |
967 menu.addAction(self.__mw.siteInfoAct) |
1010 menu.addAction(self.__mw.siteInfoAct) |
968 if self.url().scheme() in ["http", "https"]: |
1011 if self.url().scheme() in ["http", "https"]: |
969 menu.addSeparator() |
1012 menu.addSeparator() |
970 |
1013 |
971 w3url = QUrl.fromEncoded( |
1014 w3url = QUrl.fromEncoded( |
972 b"http://validator.w3.org/check?uri=" + |
1015 b"http://validator.w3.org/check?uri=" |
973 QUrl.toPercentEncoding(bytes(self.url().toEncoded()).decode())) |
1016 + QUrl.toPercentEncoding(bytes(self.url().toEncoded()).decode()) |
974 act = menu.addAction( |
1017 ) |
975 UI.PixmapCache.getIcon("w3"), |
1018 act = menu.addAction(UI.PixmapCache.getIcon("w3"), self.tr("Validate Page")) |
976 self.tr("Validate Page")) |
|
977 act.setData(w3url) |
1019 act.setData(w3url) |
978 act.triggered.connect( |
1020 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
979 functools.partial(self.__openLinkInNewTab, act)) |
1021 |
980 |
|
981 from .WebBrowserLanguagesDialog import WebBrowserLanguagesDialog |
1022 from .WebBrowserLanguagesDialog import WebBrowserLanguagesDialog |
|
1023 |
982 languages = Preferences.toList( |
1024 languages = Preferences.toList( |
983 Preferences.getSettings().value( |
1025 Preferences.getSettings().value( |
984 "WebBrowser/AcceptLanguages", |
1026 "WebBrowser/AcceptLanguages", |
985 WebBrowserLanguagesDialog.defaultAcceptLanguages())) |
1027 WebBrowserLanguagesDialog.defaultAcceptLanguages(), |
|
1028 ) |
|
1029 ) |
986 if languages: |
1030 if languages: |
987 language = languages[0] |
1031 language = languages[0] |
988 langCode = language.split("[")[1][:2] |
1032 langCode = language.split("[")[1][:2] |
989 googleTranslatorUrl = QUrl.fromEncoded( |
1033 googleTranslatorUrl = QUrl.fromEncoded( |
990 b"http://translate.google.com/translate?sl=auto&tl=" + |
1034 b"http://translate.google.com/translate?sl=auto&tl=" |
991 langCode.encode() + |
1035 + langCode.encode() |
992 b"&u=" + |
1036 + b"&u=" |
993 QUrl.toPercentEncoding( |
1037 + QUrl.toPercentEncoding(bytes(self.url().toEncoded()).decode()) |
994 bytes(self.url().toEncoded()).decode())) |
1038 ) |
995 act = menu.addAction( |
1039 act = menu.addAction( |
996 UI.PixmapCache.getIcon("translate"), |
1040 UI.PixmapCache.getIcon("translate"), self.tr("Google Translate") |
997 self.tr("Google Translate")) |
1041 ) |
998 act.setData(googleTranslatorUrl) |
1042 act.setData(googleTranslatorUrl) |
999 act.triggered.connect( |
1043 act.triggered.connect(functools.partial(self.__openLinkInNewTab, act)) |
1000 functools.partial(self.__openLinkInNewTab, act)) |
1044 |
1001 |
|
1002 def __checkForForm(self, act, pos): |
1045 def __checkForForm(self, act, pos): |
1003 """ |
1046 """ |
1004 Private method to check the given position for an open search form. |
1047 Private method to check the given position for an open search form. |
1005 |
1048 |
1006 @param act reference to the action to be populated upon success |
1049 @param act reference to the action to be populated upon success |
1007 @type QAction |
1050 @type QAction |
1008 @param pos position to be tested |
1051 @param pos position to be tested |
1009 @type QPoint |
1052 @type QPoint |
1010 """ |
1053 """ |
1011 self.__clickedPos = self.mapToViewport(pos) |
1054 self.__clickedPos = self.mapToViewport(pos) |
1012 |
1055 |
1013 from .Tools import Scripts |
1056 from .Tools import Scripts |
|
1057 |
1014 script = Scripts.getFormData(self.__clickedPos) |
1058 script = Scripts.getFormData(self.__clickedPos) |
1015 self.page().runJavaScript( |
1059 self.page().runJavaScript( |
1016 script, |
1060 script, |
1017 WebBrowserPage.SafeJsWorld, |
1061 WebBrowserPage.SafeJsWorld, |
1018 lambda res: self.__checkForFormCallback(res, act)) |
1062 lambda res: self.__checkForFormCallback(res, act), |
1019 |
1063 ) |
|
1064 |
1020 def __checkForFormCallback(self, res, act): |
1065 def __checkForFormCallback(self, res, act): |
1021 """ |
1066 """ |
1022 Private method handling the __checkForForm result. |
1067 Private method handling the __checkForForm result. |
1023 |
1068 |
1024 @param res result dictionary generated by JavaScript |
1069 @param res result dictionary generated by JavaScript |
1025 @type dict |
1070 @type dict |
1026 @param act reference to the action to be populated upon success |
1071 @param act reference to the action to be populated upon success |
1027 @type QAction |
1072 @type QAction |
1028 """ |
1073 """ |
1029 if act is None or not bool(res): |
1074 if act is None or not bool(res): |
1030 return |
1075 return |
1031 |
1076 |
1032 url = QUrl(res["action"]) |
1077 url = QUrl(res["action"]) |
1033 method = res["method"] |
1078 method = res["method"] |
1034 |
1079 |
1035 if not url.isEmpty() and method in ["get", "post"]: |
1080 if not url.isEmpty() and method in ["get", "post"]: |
1036 act.setVisible(True) |
1081 act.setVisible(True) |
1037 act.setText(self.tr("Add to web search toolbar")) |
1082 act.setText(self.tr("Add to web search toolbar")) |
1038 act.triggered.connect(self.__addSearchEngine) |
1083 act.triggered.connect(self.__addSearchEngine) |
1039 |
1084 |
1040 def __isUrlValid(self, url): |
1085 def __isUrlValid(self, url): |
1041 """ |
1086 """ |
1042 Private method to check a URL for validity. |
1087 Private method to check a URL for validity. |
1043 |
1088 |
1044 @param url URL to be checked (QUrl) |
1089 @param url URL to be checked (QUrl) |
1045 @return flag indicating a valid URL (boolean) |
1090 @return flag indicating a valid URL (boolean) |
1046 """ |
1091 """ |
1047 return ( |
1092 return ( |
1048 url.isValid() and |
1093 url.isValid() |
1049 bool(url.host()) and |
1094 and bool(url.host()) |
1050 bool(url.scheme()) and |
1095 and bool(url.scheme()) |
1051 "." in url.host() |
1096 and "." in url.host() |
1052 ) |
1097 ) |
1053 |
1098 |
1054 def __replaceMisspelledWord(self, act): |
1099 def __replaceMisspelledWord(self, act): |
1055 """ |
1100 """ |
1056 Private slot to replace a misspelled word under the context menu. |
1101 Private slot to replace a misspelled word under the context menu. |
1057 |
1102 |
1058 @param act reference to the action that triggered |
1103 @param act reference to the action that triggered |
1059 @type QAction |
1104 @type QAction |
1060 """ |
1105 """ |
1061 suggestion = act.text() |
1106 suggestion = act.text() |
1062 self.page().replaceMisspelledWord(suggestion) |
1107 self.page().replaceMisspelledWord(suggestion) |
1063 |
1108 |
1064 def __openLinkInNewTab(self, act): |
1109 def __openLinkInNewTab(self, act): |
1065 """ |
1110 """ |
1066 Private method called by the context menu to open a link in a new |
1111 Private method called by the context menu to open a link in a new |
1067 tab. |
1112 tab. |
1068 |
1113 |
1069 @param act reference to the action that triggered |
1114 @param act reference to the action that triggered |
1070 @type QAction |
1115 @type QAction |
1071 """ |
1116 """ |
1072 url = act.data() |
1117 url = act.data() |
1073 if url.isEmpty(): |
1118 if url.isEmpty(): |
1074 return |
1119 return |
1075 |
1120 |
1076 self.setSource(url, newTab=True) |
1121 self.setSource(url, newTab=True) |
1077 |
1122 |
1078 def __openLinkInNewWindow(self, act): |
1123 def __openLinkInNewWindow(self, act): |
1079 """ |
1124 """ |
1080 Private slot called by the context menu to open a link in a new |
1125 Private slot called by the context menu to open a link in a new |
1081 window. |
1126 window. |
1082 |
1127 |
1083 @param act reference to the action that triggered |
1128 @param act reference to the action that triggered |
1084 @type QAction |
1129 @type QAction |
1085 """ |
1130 """ |
1086 url = act.data() |
1131 url = act.data() |
1087 if url.isEmpty(): |
1132 if url.isEmpty(): |
1088 return |
1133 return |
1089 |
1134 |
1090 self.__mw.newWindow(url) |
1135 self.__mw.newWindow(url) |
1091 |
1136 |
1092 def __openLinkInNewPrivateWindow(self, act): |
1137 def __openLinkInNewPrivateWindow(self, act): |
1093 """ |
1138 """ |
1094 Private slot called by the context menu to open a link in a new |
1139 Private slot called by the context menu to open a link in a new |
1095 private window. |
1140 private window. |
1096 |
1141 |
1097 @param act reference to the action that triggered |
1142 @param act reference to the action that triggered |
1098 @type QAction |
1143 @type QAction |
1099 """ |
1144 """ |
1100 url = act.data() |
1145 url = act.data() |
1101 if url.isEmpty(): |
1146 if url.isEmpty(): |
1102 return |
1147 return |
1103 |
1148 |
1104 self.__mw.newPrivateWindow(url) |
1149 self.__mw.newPrivateWindow(url) |
1105 |
1150 |
1106 def __bookmarkLink(self, act): |
1151 def __bookmarkLink(self, act): |
1107 """ |
1152 """ |
1108 Private slot to bookmark a link via the context menu. |
1153 Private slot to bookmark a link via the context menu. |
1109 |
1154 |
1110 @param act reference to the action that triggered |
1155 @param act reference to the action that triggered |
1111 @type QAction |
1156 @type QAction |
1112 """ |
1157 """ |
1113 url = act.data() |
1158 url = act.data() |
1114 if url.isEmpty(): |
1159 if url.isEmpty(): |
1115 return |
1160 return |
1116 |
1161 |
1117 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog |
1162 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog |
|
1163 |
1118 dlg = AddBookmarkDialog() |
1164 dlg = AddBookmarkDialog() |
1119 dlg.setUrl(bytes(url.toEncoded()).decode()) |
1165 dlg.setUrl(bytes(url.toEncoded()).decode()) |
1120 dlg.exec() |
1166 dlg.exec() |
1121 |
1167 |
1122 def __sendLink(self, act): |
1168 def __sendLink(self, act): |
1123 """ |
1169 """ |
1124 Private slot to send a link via email. |
1170 Private slot to send a link via email. |
1125 |
1171 |
1126 @param act reference to the action that triggered |
1172 @param act reference to the action that triggered |
1127 @type QAction |
1173 @type QAction |
1128 """ |
1174 """ |
1129 data = act.data() |
1175 data = act.data() |
1130 if isinstance(data, QUrl) and data.isEmpty(): |
1176 if isinstance(data, QUrl) and data.isEmpty(): |
1131 return |
1177 return |
1132 |
1178 |
1133 if isinstance(data, QUrl): |
1179 if isinstance(data, QUrl): |
1134 data = data.toString() |
1180 data = data.toString() |
1135 QDesktopServices.openUrl(QUrl("mailto:?body=" + data)) |
1181 QDesktopServices.openUrl(QUrl("mailto:?body=" + data)) |
1136 |
1182 |
1137 def __copyLink(self, act): |
1183 def __copyLink(self, act): |
1138 """ |
1184 """ |
1139 Private slot to copy a link to the clipboard. |
1185 Private slot to copy a link to the clipboard. |
1140 |
1186 |
1141 @param act reference to the action that triggered |
1187 @param act reference to the action that triggered |
1142 @type QAction |
1188 @type QAction |
1143 """ |
1189 """ |
1144 data = act.data() |
1190 data = act.data() |
1145 if isinstance(data, QUrl) and data.isEmpty(): |
1191 if isinstance(data, QUrl) and data.isEmpty(): |
1146 return |
1192 return |
1147 |
1193 |
1148 if isinstance(data, QUrl): |
1194 if isinstance(data, QUrl): |
1149 data = data.toString() |
1195 data = data.toString() |
1150 |
1196 |
1151 # copy the URL to both clipboard areas |
1197 # copy the URL to both clipboard areas |
1152 QApplication.clipboard().setText(data, QClipboard.Mode.Clipboard) |
1198 QApplication.clipboard().setText(data, QClipboard.Mode.Clipboard) |
1153 QApplication.clipboard().setText(data, QClipboard.Mode.Selection) |
1199 QApplication.clipboard().setText(data, QClipboard.Mode.Selection) |
1154 |
1200 |
1155 def __downloadLink(self): |
1201 def __downloadLink(self): |
1156 """ |
1202 """ |
1157 Private slot to download a link and save it to disk. |
1203 Private slot to download a link and save it to disk. |
1158 """ |
1204 """ |
1159 self.triggerPageAction(QWebEnginePage.WebAction.DownloadLinkToDisk) |
1205 self.triggerPageAction(QWebEnginePage.WebAction.DownloadLinkToDisk) |
1160 |
1206 |
1161 def __downloadImage(self): |
1207 def __downloadImage(self): |
1162 """ |
1208 """ |
1163 Private slot to download an image and save it to disk. |
1209 Private slot to download an image and save it to disk. |
1164 """ |
1210 """ |
1165 self.triggerPageAction(QWebEnginePage.WebAction.DownloadImageToDisk) |
1211 self.triggerPageAction(QWebEnginePage.WebAction.DownloadImageToDisk) |
1166 |
1212 |
1167 def __copyImage(self): |
1213 def __copyImage(self): |
1168 """ |
1214 """ |
1169 Private slot to copy an image to the clipboard. |
1215 Private slot to copy an image to the clipboard. |
1170 """ |
1216 """ |
1171 self.triggerPageAction(QWebEnginePage.WebAction.CopyImageToClipboard) |
1217 self.triggerPageAction(QWebEnginePage.WebAction.CopyImageToClipboard) |
1172 |
1218 |
1173 def __blockImage(self, act): |
1219 def __blockImage(self, act): |
1174 """ |
1220 """ |
1175 Private slot to add a block rule for an image URL. |
1221 Private slot to add a block rule for an image URL. |
1176 |
1222 |
1177 @param act reference to the action that triggered |
1223 @param act reference to the action that triggered |
1178 @type QAction |
1224 @type QAction |
1179 """ |
1225 """ |
1180 url = act.data() |
1226 url = act.data() |
1181 dlg = WebBrowserWindow.adBlockManager().showDialog() |
1227 dlg = WebBrowserWindow.adBlockManager().showDialog() |
1182 dlg.addCustomRule(url) |
1228 dlg.addCustomRule(url) |
1183 |
1229 |
1184 def __searchImage(self, act): |
1230 def __searchImage(self, act): |
1185 """ |
1231 """ |
1186 Private slot to search for an image URL. |
1232 Private slot to search for an image URL. |
1187 |
1233 |
1188 @param act reference to the action that triggered |
1234 @param act reference to the action that triggered |
1189 @type QAction |
1235 @type QAction |
1190 """ |
1236 """ |
1191 url = act.data() |
1237 url = act.data() |
1192 self.setSource(url, newTab=True) |
1238 self.setSource(url, newTab=True) |
1193 |
1239 |
1194 def __downloadMedia(self): |
1240 def __downloadMedia(self): |
1195 """ |
1241 """ |
1196 Private slot to download a media and save it to disk. |
1242 Private slot to download a media and save it to disk. |
1197 """ |
1243 """ |
1198 self.triggerPageAction(QWebEnginePage.WebAction.DownloadMediaToDisk) |
1244 self.triggerPageAction(QWebEnginePage.WebAction.DownloadMediaToDisk) |
1199 |
1245 |
1200 def __pauseMedia(self): |
1246 def __pauseMedia(self): |
1201 """ |
1247 """ |
1202 Private slot to pause or play the selected media. |
1248 Private slot to pause or play the selected media. |
1203 """ |
1249 """ |
1204 self.triggerPageAction(QWebEnginePage.WebAction.ToggleMediaPlayPause) |
1250 self.triggerPageAction(QWebEnginePage.WebAction.ToggleMediaPlayPause) |
1205 |
1251 |
1206 def __muteMedia(self): |
1252 def __muteMedia(self): |
1207 """ |
1253 """ |
1208 Private slot to (un)mute the selected media. |
1254 Private slot to (un)mute the selected media. |
1209 """ |
1255 """ |
1210 self.triggerPageAction(QWebEnginePage.WebAction.ToggleMediaMute) |
1256 self.triggerPageAction(QWebEnginePage.WebAction.ToggleMediaMute) |
1211 |
1257 |
1212 def __virusTotal(self, act): |
1258 def __virusTotal(self, act): |
1213 """ |
1259 """ |
1214 Private slot to scan the selected URL with VirusTotal. |
1260 Private slot to scan the selected URL with VirusTotal. |
1215 |
1261 |
1216 @param act reference to the action that triggered |
1262 @param act reference to the action that triggered |
1217 @type QAction |
1263 @type QAction |
1218 """ |
1264 """ |
1219 url = act.data() |
1265 url = act.data() |
1220 self.__mw.requestVirusTotalScan(url) |
1266 self.__mw.requestVirusTotalScan(url) |
1221 |
1267 |
1222 def __searchDefaultRequested(self): |
1268 def __searchDefaultRequested(self): |
1223 """ |
1269 """ |
1224 Private slot to search for some text with the current search engine. |
1270 Private slot to search for some text with the current search engine. |
1225 """ |
1271 """ |
1226 searchText = self.selectedText() |
1272 searchText = self.selectedText() |
1227 |
1273 |
1228 if not searchText: |
1274 if not searchText: |
1229 return |
1275 return |
1230 |
1276 |
1231 engine = self.__mw.openSearchManager().currentEngine() |
1277 engine = self.__mw.openSearchManager().currentEngine() |
1232 if engine: |
1278 if engine: |
1233 self.search.emit(engine.searchUrl(searchText)) |
1279 self.search.emit(engine.searchUrl(searchText)) |
1234 |
1280 |
1235 def __searchRequested(self, act): |
1281 def __searchRequested(self, act): |
1236 """ |
1282 """ |
1237 Private slot to search for some text with a selected search engine. |
1283 Private slot to search for some text with a selected search engine. |
1238 |
1284 |
1239 @param act reference to the action that triggered this slot (QAction) |
1285 @param act reference to the action that triggered this slot (QAction) |
1240 """ |
1286 """ |
1241 searchText = self.selectedText() |
1287 searchText = self.selectedText() |
1242 |
1288 |
1243 if not searchText: |
1289 if not searchText: |
1244 return |
1290 return |
1245 |
1291 |
1246 engineName = act.data() |
1292 engineName = act.data() |
1247 engine = ( |
1293 engine = ( |
1248 self.__mw.openSearchManager().engine(engineName) |
1294 self.__mw.openSearchManager().engine(engineName) |
1249 if engineName else |
1295 if engineName |
1250 self.__mw.openSearchManager().currentEngine() |
1296 else self.__mw.openSearchManager().currentEngine() |
1251 ) |
1297 ) |
1252 if engine: |
1298 if engine: |
1253 self.search.emit(engine.searchUrl(searchText)) |
1299 self.search.emit(engine.searchUrl(searchText)) |
1254 |
1300 |
1255 def __addSearchEngine(self): |
1301 def __addSearchEngine(self): |
1256 """ |
1302 """ |
1257 Private slot to add a new search engine. |
1303 Private slot to add a new search engine. |
1258 """ |
1304 """ |
1259 from .Tools import Scripts |
1305 from .Tools import Scripts |
|
1306 |
1260 script = Scripts.getFormData(self.__clickedPos) |
1307 script = Scripts.getFormData(self.__clickedPos) |
1261 self.page().runJavaScript( |
1308 self.page().runJavaScript( |
1262 script, |
1309 script, |
1263 WebBrowserPage.SafeJsWorld, |
1310 WebBrowserPage.SafeJsWorld, |
1264 lambda res: self.__mw.openSearchManager().addEngineFromForm( |
1311 lambda res: self.__mw.openSearchManager().addEngineFromForm(res, self), |
1265 res, self)) |
1312 ) |
1266 |
1313 |
1267 def __webInspector(self): |
1314 def __webInspector(self): |
1268 """ |
1315 """ |
1269 Private slot to show the web inspector window. |
1316 Private slot to show the web inspector window. |
1270 """ |
1317 """ |
1271 from .WebInspector import WebInspector |
1318 from .WebInspector import WebInspector |
|
1319 |
1272 if WebInspector.isEnabled(): |
1320 if WebInspector.isEnabled(): |
1273 if self.__inspector is None: |
1321 if self.__inspector is None: |
1274 self.__inspector = WebInspector() |
1322 self.__inspector = WebInspector() |
1275 self.__inspector.setView(self, True) |
1323 self.__inspector.setView(self, True) |
1276 self.__inspector.inspectorClosed.connect( |
1324 self.__inspector.inspectorClosed.connect(self.closeWebInspector) |
1277 self.closeWebInspector) |
|
1278 self.__inspector.show() |
1325 self.__inspector.show() |
1279 else: |
1326 else: |
1280 self.closeWebInspector() |
1327 self.closeWebInspector() |
1281 |
1328 |
1282 def closeWebInspector(self): |
1329 def closeWebInspector(self): |
1283 """ |
1330 """ |
1284 Public slot to close the web inspector. |
1331 Public slot to close the web inspector. |
1285 """ |
1332 """ |
1286 if self.__inspector is not None: |
1333 if self.__inspector is not None: |
1287 if self.__inspector.isVisible(): |
1334 if self.__inspector.isVisible(): |
1288 self.__inspector.hide() |
1335 self.__inspector.hide() |
1289 WebInspector.unregisterView(self.__inspector) |
1336 WebInspector.unregisterView(self.__inspector) |
1290 self.__inspector.deleteLater() |
1337 self.__inspector.deleteLater() |
1291 self.__inspector = None |
1338 self.__inspector = None |
1292 |
1339 |
1293 def addBookmark(self): |
1340 def addBookmark(self): |
1294 """ |
1341 """ |
1295 Public slot to bookmark the current page. |
1342 Public slot to bookmark the current page. |
1296 """ |
1343 """ |
1297 from .Tools import Scripts |
1344 from .Tools import Scripts |
|
1345 |
1298 script = Scripts.getAllMetaAttributes() |
1346 script = Scripts.getAllMetaAttributes() |
1299 self.page().runJavaScript( |
1347 self.page().runJavaScript( |
1300 script, WebBrowserPage.SafeJsWorld, self.__addBookmarkCallback) |
1348 script, WebBrowserPage.SafeJsWorld, self.__addBookmarkCallback |
1301 |
1349 ) |
|
1350 |
1302 def __addBookmarkCallback(self, res): |
1351 def __addBookmarkCallback(self, res): |
1303 """ |
1352 """ |
1304 Private callback method of __addBookmark(). |
1353 Private callback method of __addBookmark(). |
1305 |
1354 |
1306 @param res reference to the result list containing all |
1355 @param res reference to the result list containing all |
1307 meta attributes |
1356 meta attributes |
1308 @type list |
1357 @type list |
1309 """ |
1358 """ |
1310 description = "" |
1359 description = "" |
1311 for meta in res: |
1360 for meta in res: |
1312 if meta["name"] == "description": |
1361 if meta["name"] == "description": |
1313 description = meta["content"] |
1362 description = meta["content"] |
1314 |
1363 |
1315 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog |
1364 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog |
|
1365 |
1316 dlg = AddBookmarkDialog() |
1366 dlg = AddBookmarkDialog() |
1317 dlg.setUrl(bytes(self.url().toEncoded()).decode()) |
1367 dlg.setUrl(bytes(self.url().toEncoded()).decode()) |
1318 dlg.setTitle(self.title()) |
1368 dlg.setTitle(self.title()) |
1319 dlg.setDescription(description) |
1369 dlg.setDescription(description) |
1320 dlg.exec() |
1370 dlg.exec() |
1321 |
1371 |
1322 def dragEnterEvent(self, evt): |
1372 def dragEnterEvent(self, evt): |
1323 """ |
1373 """ |
1324 Protected method called by a drag enter event. |
1374 Protected method called by a drag enter event. |
1325 |
1375 |
1326 @param evt reference to the drag enter event (QDragEnterEvent) |
1376 @param evt reference to the drag enter event (QDragEnterEvent) |
1327 """ |
1377 """ |
1328 evt.acceptProposedAction() |
1378 evt.acceptProposedAction() |
1329 |
1379 |
1330 def dragMoveEvent(self, evt): |
1380 def dragMoveEvent(self, evt): |
1331 """ |
1381 """ |
1332 Protected method called by a drag move event. |
1382 Protected method called by a drag move event. |
1333 |
1383 |
1334 @param evt reference to the drag move event (QDragMoveEvent) |
1384 @param evt reference to the drag move event (QDragMoveEvent) |
1335 """ |
1385 """ |
1336 evt.ignore() |
1386 evt.ignore() |
1337 if evt.source() != self: |
1387 if evt.source() != self: |
1338 if len(evt.mimeData().urls()) > 0: |
1388 if len(evt.mimeData().urls()) > 0: |
1339 evt.acceptProposedAction() |
1389 evt.acceptProposedAction() |
1340 else: |
1390 else: |
1341 url = QUrl(evt.mimeData().text()) |
1391 url = QUrl(evt.mimeData().text()) |
1342 if url.isValid(): |
1392 if url.isValid(): |
1343 evt.acceptProposedAction() |
1393 evt.acceptProposedAction() |
1344 |
1394 |
1345 if not evt.isAccepted(): |
1395 if not evt.isAccepted(): |
1346 super().dragMoveEvent(evt) |
1396 super().dragMoveEvent(evt) |
1347 |
1397 |
1348 def dropEvent(self, evt): |
1398 def dropEvent(self, evt): |
1349 """ |
1399 """ |
1350 Protected method called by a drop event. |
1400 Protected method called by a drop event. |
1351 |
1401 |
1352 @param evt reference to the drop event (QDropEvent) |
1402 @param evt reference to the drop event (QDropEvent) |
1353 """ |
1403 """ |
1354 super().dropEvent(evt) |
1404 super().dropEvent(evt) |
1355 if ( |
1405 if ( |
1356 not evt.isAccepted() and |
1406 not evt.isAccepted() |
1357 evt.source() != self and |
1407 and evt.source() != self |
1358 evt.possibleActions() & Qt.DropAction.CopyAction |
1408 and evt.possibleActions() & Qt.DropAction.CopyAction |
1359 ): |
1409 ): |
1360 url = QUrl() |
1410 url = QUrl() |
1361 if len(evt.mimeData().urls()) > 0: |
1411 if len(evt.mimeData().urls()) > 0: |
1362 url = evt.mimeData().urls()[0] |
1412 url = evt.mimeData().urls()[0] |
1363 if not url.isValid(): |
1413 if not url.isValid(): |
1364 url = QUrl(evt.mimeData().text()) |
1414 url = QUrl(evt.mimeData().text()) |
1365 if url.isValid(): |
1415 if url.isValid(): |
1366 self.setSource(url) |
1416 self.setSource(url) |
1367 evt.acceptProposedAction() |
1417 evt.acceptProposedAction() |
1368 |
1418 |
1369 def _mousePressEvent(self, evt): |
1419 def _mousePressEvent(self, evt): |
1370 """ |
1420 """ |
1371 Protected method called by a mouse press event. |
1421 Protected method called by a mouse press event. |
1372 |
1422 |
1373 @param evt reference to the mouse event (QMouseEvent) |
1423 @param evt reference to the mouse event (QMouseEvent) |
1374 """ |
1424 """ |
1375 if WebBrowserWindow.autoScroller().mousePress(self, evt): |
1425 if WebBrowserWindow.autoScroller().mousePress(self, evt): |
1376 evt.accept() |
1426 evt.accept() |
1377 return |
1427 return |
1378 |
1428 |
1379 def _mouseReleaseEvent(self, evt): |
1429 def _mouseReleaseEvent(self, evt): |
1380 """ |
1430 """ |
1381 Protected method called by a mouse release event. |
1431 Protected method called by a mouse release event. |
1382 |
1432 |
1383 @param evt reference to the mouse event (QMouseEvent) |
1433 @param evt reference to the mouse event (QMouseEvent) |
1384 """ |
1434 """ |
1385 if WebBrowserWindow.autoScroller().mouseRelease(evt): |
1435 if WebBrowserWindow.autoScroller().mouseRelease(evt): |
1386 evt.accept() |
1436 evt.accept() |
1387 return |
1437 return |
1388 |
1438 |
1389 accepted = evt.isAccepted() |
1439 accepted = evt.isAccepted() |
1390 self.__page.event(evt) |
1440 self.__page.event(evt) |
1391 if ( |
1441 if not evt.isAccepted() and evt.button() == Qt.MouseButton.MiddleButton: |
1392 not evt.isAccepted() and |
1442 url = QUrl(QApplication.clipboard().text(QClipboard.Mode.Selection)) |
1393 evt.button() == Qt.MouseButton.MiddleButton |
1443 if not url.isEmpty() and url.isValid() and url.scheme() != "": |
1394 ): |
|
1395 url = QUrl(QApplication.clipboard().text( |
|
1396 QClipboard.Mode.Selection)) |
|
1397 if ( |
|
1398 not url.isEmpty() and |
|
1399 url.isValid() and |
|
1400 url.scheme() != "" |
|
1401 ): |
|
1402 self.setSource(url) |
1444 self.setSource(url) |
1403 evt.setAccepted(accepted) |
1445 evt.setAccepted(accepted) |
1404 |
1446 |
1405 def _mouseMoveEvent(self, evt): |
1447 def _mouseMoveEvent(self, evt): |
1406 """ |
1448 """ |
1407 Protected method to handle mouse move events. |
1449 Protected method to handle mouse move events. |
1408 |
1450 |
1409 @param evt reference to the mouse event (QMouseEvent) |
1451 @param evt reference to the mouse event (QMouseEvent) |
1410 """ |
1452 """ |
1411 if self.__mw and self.__mw.isFullScreen(): |
1453 if self.__mw and self.__mw.isFullScreen(): |
1412 if self.__mw.isFullScreenNavigationVisible(): |
1454 if self.__mw.isFullScreenNavigationVisible(): |
1413 self.__mw.hideFullScreenNavigation() |
1455 self.__mw.hideFullScreenNavigation() |
1414 elif evt.y() < 10: |
1456 elif evt.y() < 10: |
1415 # mouse is within 10px to the top |
1457 # mouse is within 10px to the top |
1416 self.__mw.showFullScreenNavigation() |
1458 self.__mw.showFullScreenNavigation() |
1417 |
1459 |
1418 if WebBrowserWindow.autoScroller().mouseMove(evt): |
1460 if WebBrowserWindow.autoScroller().mouseMove(evt): |
1419 evt.accept() |
1461 evt.accept() |
1420 |
1462 |
1421 def _wheelEvent(self, evt): |
1463 def _wheelEvent(self, evt): |
1422 """ |
1464 """ |
1423 Protected method to handle wheel events. |
1465 Protected method to handle wheel events. |
1424 |
1466 |
1425 @param evt reference to the wheel event (QWheelEvent) |
1467 @param evt reference to the wheel event (QWheelEvent) |
1426 """ |
1468 """ |
1427 if WebBrowserWindow.autoScroller().wheel(): |
1469 if WebBrowserWindow.autoScroller().wheel(): |
1428 evt.accept() |
1470 evt.accept() |
1429 return |
1471 return |
1430 |
1472 |
1431 delta = evt.angleDelta().y() |
1473 delta = evt.angleDelta().y() |
1432 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier: |
1474 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier: |
1433 if delta < 0: |
1475 if delta < 0: |
1434 self.zoomOut() |
1476 self.zoomOut() |
1435 elif delta > 0: |
1477 elif delta > 0: |
1436 self.zoomIn() |
1478 self.zoomIn() |
1437 evt.accept() |
1479 evt.accept() |
1438 |
1480 |
1439 elif evt.modifiers() & Qt.KeyboardModifier.ShiftModifier: |
1481 elif evt.modifiers() & Qt.KeyboardModifier.ShiftModifier: |
1440 if delta < 0: |
1482 if delta < 0: |
1441 self.backward() |
1483 self.backward() |
1442 elif delta > 0: |
1484 elif delta > 0: |
1443 self.forward() |
1485 self.forward() |
1444 evt.accept() |
1486 evt.accept() |
1445 |
1487 |
1446 def _keyPressEvent(self, evt): |
1488 def _keyPressEvent(self, evt): |
1447 """ |
1489 """ |
1448 Protected method called by a key press. |
1490 Protected method called by a key press. |
1449 |
1491 |
1450 @param evt reference to the key event (QKeyEvent) |
1492 @param evt reference to the key event (QKeyEvent) |
1451 """ |
1493 """ |
1452 if self.__mw.personalInformationManager().viewKeyPressEvent(self, evt): |
1494 if self.__mw.personalInformationManager().viewKeyPressEvent(self, evt): |
1453 evt.accept() |
1495 evt.accept() |
1454 return |
1496 return |
1455 |
1497 |
1456 if evt.key() == Qt.Key.Key_ZoomIn: |
1498 if evt.key() == Qt.Key.Key_ZoomIn: |
1457 self.zoomIn() |
1499 self.zoomIn() |
1458 evt.accept() |
1500 evt.accept() |
1459 elif evt.key() == Qt.Key.Key_ZoomOut: |
1501 elif evt.key() == Qt.Key.Key_ZoomOut: |
1460 self.zoomOut() |
1502 self.zoomOut() |
1560 elif evt.type() == QEvent.Type.Gesture: |
1601 elif evt.type() == QEvent.Type.Gesture: |
1561 self._gestureEvent(evt) |
1602 self._gestureEvent(evt) |
1562 ret = evt.isAccepted() |
1603 ret = evt.isAccepted() |
1563 evt.setAccepted(wasAccepted) |
1604 evt.setAccepted(wasAccepted) |
1564 return ret |
1605 return ret |
1565 |
1606 |
1566 if ( |
1607 if obj is self.parentWidget() and evt.type() in [ |
1567 obj is self.parentWidget() and |
1608 QEvent.Type.KeyPress, |
1568 evt.type() in [QEvent.Type.KeyPress, QEvent.Type.KeyRelease] |
1609 QEvent.Type.KeyRelease, |
1569 ): |
1610 ]: |
1570 wasAccepted = evt.isAccepted() |
1611 wasAccepted = evt.isAccepted() |
1571 evt.setAccepted(False) |
1612 evt.setAccepted(False) |
1572 if evt.type() == QEvent.Type.KeyPress: |
1613 if evt.type() == QEvent.Type.KeyPress: |
1573 self._keyPressEvent(evt) |
1614 self._keyPressEvent(evt) |
1574 elif evt.type() == QEvent.Type.KeyRelease: |
1615 elif evt.type() == QEvent.Type.KeyRelease: |
1575 self._keyReleaseEvent(evt) |
1616 self._keyReleaseEvent(evt) |
1576 ret = evt.isAccepted() |
1617 ret = evt.isAccepted() |
1577 evt.setAccepted(wasAccepted) |
1618 evt.setAccepted(wasAccepted) |
1578 return ret |
1619 return ret |
1579 |
1620 |
1580 # block already handled events |
1621 # block already handled events |
1581 if obj is self: |
1622 if obj is self: |
1582 if evt.type() in [QEvent.Type.KeyPress, |
1623 if evt.type() in [ |
1583 QEvent.Type.KeyRelease, |
1624 QEvent.Type.KeyPress, |
1584 QEvent.Type.MouseButtonPress, |
1625 QEvent.Type.KeyRelease, |
1585 QEvent.Type.MouseButtonRelease, |
1626 QEvent.Type.MouseButtonPress, |
1586 QEvent.Type.MouseMove, |
1627 QEvent.Type.MouseButtonRelease, |
1587 QEvent.Type.Wheel, |
1628 QEvent.Type.MouseMove, |
1588 QEvent.Type.Gesture]: |
1629 QEvent.Type.Wheel, |
|
1630 QEvent.Type.Gesture, |
|
1631 ]: |
1589 return True |
1632 return True |
1590 |
1633 |
1591 elif evt.type() == QEvent.Type.Hide and self.isFullScreen(): |
1634 elif evt.type() == QEvent.Type.Hide and self.isFullScreen(): |
1592 self.triggerPageAction(QWebEnginePage.WebAction.ExitFullScreen) |
1635 self.triggerPageAction(QWebEnginePage.WebAction.ExitFullScreen) |
1593 |
1636 |
1594 return super().eventFilter(obj, evt) |
1637 return super().eventFilter(obj, evt) |
1595 |
1638 |
1596 def event(self, evt): |
1639 def event(self, evt): |
1597 """ |
1640 """ |
1598 Public method handling events. |
1641 Public method handling events. |
1599 |
1642 |
1600 @param evt reference to the event (QEvent) |
1643 @param evt reference to the event (QEvent) |
1601 @return flag indicating, if the event was handled (boolean) |
1644 @return flag indicating, if the event was handled (boolean) |
1602 """ |
1645 """ |
1603 if evt.type() == QEvent.Type.Gesture: |
1646 if evt.type() == QEvent.Type.Gesture: |
1604 self._gestureEvent(evt) |
1647 self._gestureEvent(evt) |
1605 return True |
1648 return True |
1606 |
1649 |
1607 return super().event(evt) |
1650 return super().event(evt) |
1608 |
1651 |
1609 def inputWidget(self): |
1652 def inputWidget(self): |
1610 """ |
1653 """ |
1611 Public method to get a reference to the render widget. |
1654 Public method to get a reference to the render widget. |
1612 |
1655 |
1613 @return reference to the render widget |
1656 @return reference to the render widget |
1614 @rtype QWidget |
1657 @rtype QWidget |
1615 """ |
1658 """ |
1616 return self.__rwhvqt |
1659 return self.__rwhvqt |
1617 |
1660 |
1618 def clearHistory(self): |
1661 def clearHistory(self): |
1619 """ |
1662 """ |
1620 Public slot to clear the history. |
1663 Public slot to clear the history. |
1621 """ |
1664 """ |
1622 self.history().clear() |
1665 self.history().clear() |
1623 self.__urlChanged(self.history().currentItem().url()) |
1666 self.__urlChanged(self.history().currentItem().url()) |
1624 |
1667 |
1625 ########################################################################### |
1668 ########################################################################### |
1626 ## Signal converters below |
1669 ## Signal converters below |
1627 ########################################################################### |
1670 ########################################################################### |
1628 |
1671 |
1629 def __urlChanged(self, url): |
1672 def __urlChanged(self, url): |
1630 """ |
1673 """ |
1631 Private slot to handle the urlChanged signal. |
1674 Private slot to handle the urlChanged signal. |
1632 |
1675 |
1633 @param url the new url (QUrl) |
1676 @param url the new url (QUrl) |
1634 """ |
1677 """ |
1635 self.sourceChanged.emit(url) |
1678 self.sourceChanged.emit(url) |
1636 |
1679 |
1637 self.forwardAvailable.emit(self.isForwardAvailable()) |
1680 self.forwardAvailable.emit(self.isForwardAvailable()) |
1638 self.backwardAvailable.emit(self.isBackwardAvailable()) |
1681 self.backwardAvailable.emit(self.isBackwardAvailable()) |
1639 |
1682 |
1640 def __iconUrlChanged(self, url): |
1683 def __iconUrlChanged(self, url): |
1641 """ |
1684 """ |
1642 Private slot to handle the iconUrlChanged signal. |
1685 Private slot to handle the iconUrlChanged signal. |
1643 |
1686 |
1644 @param url URL to get web site icon from |
1687 @param url URL to get web site icon from |
1645 @type QUrl |
1688 @type QUrl |
1646 """ |
1689 """ |
1647 self.__siteIcon = QIcon() |
1690 self.__siteIcon = QIcon() |
1648 if self.__siteIconLoader is not None: |
1691 if self.__siteIconLoader is not None: |
1649 self.__siteIconLoader.deleteLater() |
1692 self.__siteIconLoader.deleteLater() |
1650 self.__siteIconLoader = WebIconLoader(url, self) |
1693 self.__siteIconLoader = WebIconLoader(url, self) |
1651 self.__siteIconLoader.iconLoaded.connect(self.__iconLoaded) |
1694 self.__siteIconLoader.iconLoaded.connect(self.__iconLoaded) |
1652 with contextlib.suppress(AttributeError): |
1695 with contextlib.suppress(AttributeError): |
1653 self.__siteIconLoader.sslConfiguration.connect( |
1696 self.__siteIconLoader.sslConfiguration.connect( |
1654 self.page().setSslConfiguration) |
1697 self.page().setSslConfiguration |
|
1698 ) |
1655 self.__siteIconLoader.clearSslConfiguration.connect( |
1699 self.__siteIconLoader.clearSslConfiguration.connect( |
1656 self.page().clearSslConfiguration) |
1700 self.page().clearSslConfiguration |
1657 |
1701 ) |
|
1702 |
1658 def __iconLoaded(self, icon): |
1703 def __iconLoaded(self, icon): |
1659 """ |
1704 """ |
1660 Private slot handling the loaded web site icon. |
1705 Private slot handling the loaded web site icon. |
1661 |
1706 |
1662 @param icon web site icon |
1707 @param icon web site icon |
1663 @type QIcon |
1708 @type QIcon |
1664 """ |
1709 """ |
1665 self.__siteIcon = icon |
1710 self.__siteIcon = icon |
1666 |
1711 |
1667 from .Tools import WebIconProvider |
1712 from .Tools import WebIconProvider |
|
1713 |
1668 WebIconProvider.instance().saveIcon(self) |
1714 WebIconProvider.instance().saveIcon(self) |
1669 |
1715 |
1670 self.faviconChanged.emit() |
1716 self.faviconChanged.emit() |
1671 |
1717 |
1672 def icon(self): |
1718 def icon(self): |
1673 """ |
1719 """ |
1674 Public method to get the web site icon. |
1720 Public method to get the web site icon. |
1675 |
1721 |
1676 @return web site icon |
1722 @return web site icon |
1677 @rtype QIcon |
1723 @rtype QIcon |
1678 """ |
1724 """ |
1679 if not self.__siteIcon.isNull(): |
1725 if not self.__siteIcon.isNull(): |
1680 return QIcon(self.__siteIcon) |
1726 return QIcon(self.__siteIcon) |
1681 |
1727 |
1682 from .Tools import WebIconProvider |
1728 from .Tools import WebIconProvider |
|
1729 |
1683 return WebIconProvider.instance().iconForUrl(self.url()) |
1730 return WebIconProvider.instance().iconForUrl(self.url()) |
1684 |
1731 |
1685 def title(self): |
1732 def title(self): |
1686 """ |
1733 """ |
1687 Public method to get the view title. |
1734 Public method to get the view title. |
1688 |
1735 |
1689 @return view title |
1736 @return view title |
1690 @rtype str |
1737 @rtype str |
1691 """ |
1738 """ |
1692 titleStr = super().title() |
1739 titleStr = super().title() |
1693 if not titleStr: |
1740 if not titleStr: |
1694 if self.url().isEmpty(): |
1741 if self.url().isEmpty(): |
1695 url = self.__page.requestedUrl() |
1742 url = self.__page.requestedUrl() |
1696 else: |
1743 else: |
1697 url = self.url() |
1744 url = self.url() |
1698 |
1745 |
1699 titleStr = url.host() |
1746 titleStr = url.host() |
1700 if not titleStr: |
1747 if not titleStr: |
1701 titleStr = url.toString( |
1748 titleStr = url.toString(QUrl.UrlFormattingOption.RemoveFragment) |
1702 QUrl.UrlFormattingOption.RemoveFragment) |
1749 |
1703 |
|
1704 if not titleStr or titleStr == "about:blank": |
1750 if not titleStr or titleStr == "about:blank": |
1705 titleStr = self.tr("Empty Page") |
1751 titleStr = self.tr("Empty Page") |
1706 |
1752 |
1707 return titleStr |
1753 return titleStr |
1708 |
1754 |
1709 def __linkHovered(self, link): |
1755 def __linkHovered(self, link): |
1710 """ |
1756 """ |
1711 Private slot to handle the linkHovered signal. |
1757 Private slot to handle the linkHovered signal. |
1712 |
1758 |
1713 @param link the URL of the link (string) |
1759 @param link the URL of the link (string) |
1714 """ |
1760 """ |
1715 self.highlighted.emit(link) |
1761 self.highlighted.emit(link) |
1716 |
1762 |
1717 ########################################################################### |
1763 ########################################################################### |
1718 ## Signal handlers below |
1764 ## Signal handlers below |
1719 ########################################################################### |
1765 ########################################################################### |
1720 |
1766 |
1721 def __renderProcessTerminated(self, status, exitCode): |
1767 def __renderProcessTerminated(self, status, exitCode): |
1722 """ |
1768 """ |
1723 Private slot handling a crash of the web page render process. |
1769 Private slot handling a crash of the web page render process. |
1724 |
1770 |
1725 @param status termination status |
1771 @param status termination status |
1726 @type QWebEnginePage.RenderProcessTerminationStatus |
1772 @type QWebEnginePage.RenderProcessTerminationStatus |
1727 @param exitCode exit code of the process |
1773 @param exitCode exit code of the process |
1728 @type int |
1774 @type int |
1729 """ |
1775 """ |
1730 if ( |
1776 if ( |
1731 status == |
1777 status |
1732 QWebEnginePage.RenderProcessTerminationStatus |
1778 == QWebEnginePage.RenderProcessTerminationStatus.NormalTerminationStatus |
1733 .NormalTerminationStatus |
|
1734 ): |
1779 ): |
1735 return |
1780 return |
1736 |
1781 |
1737 QTimer.singleShot(0, |
1782 QTimer.singleShot(0, functools.partial(self.__showTabCrashPage, status)) |
1738 functools.partial(self.__showTabCrashPage, status)) |
1783 |
1739 |
|
1740 def __showTabCrashPage(self, status): |
1784 def __showTabCrashPage(self, status): |
1741 """ |
1785 """ |
1742 Private slot to show the tab crash page. |
1786 Private slot to show the tab crash page. |
1743 |
1787 |
1744 @param status termination status |
1788 @param status termination status |
1745 @type QWebEnginePage.RenderProcessTerminationStatus |
1789 @type QWebEnginePage.RenderProcessTerminationStatus |
1746 """ |
1790 """ |
1747 self.page().deleteLater() |
1791 self.page().deleteLater() |
1748 self.__createNewPage() |
1792 self.__createNewPage() |
1749 |
1793 |
1750 html = getHtmlPage("tabCrashPage.html") |
1794 html = getHtmlPage("tabCrashPage.html") |
1751 html = html.replace("@IMAGE@", pixmapToDataUrl( |
|
1752 ericApp().style().standardIcon( |
|
1753 QStyle.StandardPixmap.SP_MessageBoxWarning).pixmap(48, 48) |
|
1754 ).toString()) |
|
1755 html = html.replace("@FAVICON@", pixmapToDataUrl( |
|
1756 ericApp().style() .standardIcon( |
|
1757 QStyle.StandardPixmap.SP_MessageBoxWarning).pixmap(16, 16) |
|
1758 ).toString()) |
|
1759 html = html.replace( |
1795 html = html.replace( |
1760 "@TITLE@", self.tr("Render Process terminated abnormally")) |
1796 "@IMAGE@", |
|
1797 pixmapToDataUrl( |
|
1798 ericApp() |
|
1799 .style() |
|
1800 .standardIcon(QStyle.StandardPixmap.SP_MessageBoxWarning) |
|
1801 .pixmap(48, 48) |
|
1802 ).toString(), |
|
1803 ) |
1761 html = html.replace( |
1804 html = html.replace( |
1762 "@H1@", self.tr("Render Process terminated abnormally")) |
1805 "@FAVICON@", |
|
1806 pixmapToDataUrl( |
|
1807 ericApp() |
|
1808 .style() |
|
1809 .standardIcon(QStyle.StandardPixmap.SP_MessageBoxWarning) |
|
1810 .pixmap(16, 16) |
|
1811 ).toString(), |
|
1812 ) |
|
1813 html = html.replace("@TITLE@", self.tr("Render Process terminated abnormally")) |
|
1814 html = html.replace("@H1@", self.tr("Render Process terminated abnormally")) |
1763 if ( |
1815 if ( |
1764 status == |
1816 status |
1765 QWebEnginePage.RenderProcessTerminationStatus |
1817 == QWebEnginePage.RenderProcessTerminationStatus.CrashedTerminationStatus |
1766 .CrashedTerminationStatus |
|
1767 ): |
1818 ): |
1768 msg = self.tr("The render process crashed while" |
1819 msg = self.tr("The render process crashed while" " loading this page.") |
1769 " loading this page.") |
|
1770 elif ( |
1820 elif ( |
1771 status == |
1821 status |
1772 QWebEnginePage.RenderProcessTerminationStatus |
1822 == QWebEnginePage.RenderProcessTerminationStatus.KilledTerminationStatus |
1773 .KilledTerminationStatus |
|
1774 ): |
1823 ): |
1775 msg = self.tr("The render process was killed.") |
1824 msg = self.tr("The render process was killed.") |
1776 else: |
1825 else: |
1777 msg = self.tr("The render process terminated while" |
1826 msg = self.tr("The render process terminated while" " loading this page.") |
1778 " loading this page.") |
|
1779 html = html.replace("@LI-1@", msg) |
1827 html = html.replace("@LI-1@", msg) |
1780 html = html.replace( |
1828 html = html.replace( |
1781 "@LI-2@", |
1829 "@LI-2@", |
1782 self.tr( |
1830 self.tr( |
1783 "Try reloading the page or closing some tabs to make more" |
1831 "Try reloading the page or closing some tabs to make more" |
1784 " memory available.")) |
1832 " memory available." |
|
1833 ), |
|
1834 ) |
1785 self.page().setHtml(html, self.url()) |
1835 self.page().setHtml(html, self.url()) |
1786 |
1836 |
1787 def __loadStarted(self): |
1837 def __loadStarted(self): |
1788 """ |
1838 """ |
1789 Private method to handle the loadStarted signal. |
1839 Private method to handle the loadStarted signal. |
1790 """ |
1840 """ |
1791 # reset search |
1841 # reset search |
1792 self.findText("") |
1842 self.findText("") |
1793 self.__isLoading = True |
1843 self.__isLoading = True |
1794 self.__progress = 0 |
1844 self.__progress = 0 |
1795 |
1845 |
1796 def __loadProgress(self, progress): |
1846 def __loadProgress(self, progress): |
1797 """ |
1847 """ |
1798 Private method to handle the loadProgress signal. |
1848 Private method to handle the loadProgress signal. |
1799 |
1849 |
1800 @param progress progress value (integer) |
1850 @param progress progress value (integer) |
1801 """ |
1851 """ |
1802 self.__progress = progress |
1852 self.__progress = progress |
1803 |
1853 |
1804 def __loadFinished(self, ok): |
1854 def __loadFinished(self, ok): |
1805 """ |
1855 """ |
1806 Private method to handle the loadFinished signal. |
1856 Private method to handle the loadFinished signal. |
1807 |
1857 |
1808 @param ok flag indicating the result (boolean) |
1858 @param ok flag indicating the result (boolean) |
1809 """ |
1859 """ |
1810 self.__isLoading = False |
1860 self.__isLoading = False |
1811 self.__progress = 0 |
1861 self.__progress = 0 |
1812 |
1862 |
1813 QApplication.processEvents() |
1863 QApplication.processEvents() |
1814 QTimer.singleShot(200, self.__renderPreview) |
1864 QTimer.singleShot(200, self.__renderPreview) |
1815 |
1865 |
1816 from .ZoomManager import ZoomManager |
1866 from .ZoomManager import ZoomManager |
|
1867 |
1817 zoomValue = ZoomManager.instance().zoomValue(self.url()) |
1868 zoomValue = ZoomManager.instance().zoomValue(self.url()) |
1818 self.setZoomValue(zoomValue) |
1869 self.setZoomValue(zoomValue) |
1819 |
1870 |
1820 if ok: |
1871 if ok: |
1821 self.__mw.historyManager().addHistoryEntry(self) |
1872 self.__mw.historyManager().addHistoryEntry(self) |
1822 self.__mw.adBlockManager().page().hideBlockedPageEntries( |
1873 self.__mw.adBlockManager().page().hideBlockedPageEntries(self.page()) |
1823 self.page()) |
|
1824 self.__mw.passwordManager().completePage(self.page()) |
1874 self.__mw.passwordManager().completePage(self.page()) |
1825 |
1875 |
1826 self.page().runJavaScript( |
1876 self.page().runJavaScript( |
1827 "document.lastModified", WebBrowserPage.SafeJsWorld, |
1877 "document.lastModified", |
1828 lambda res: self.__adjustBookmark(res)) |
1878 WebBrowserPage.SafeJsWorld, |
1829 |
1879 lambda res: self.__adjustBookmark(res), |
|
1880 ) |
|
1881 |
1830 def __adjustBookmark(self, lastModified): |
1882 def __adjustBookmark(self, lastModified): |
1831 """ |
1883 """ |
1832 Private slot to adjust the 'lastModified' value of bookmarks. |
1884 Private slot to adjust the 'lastModified' value of bookmarks. |
1833 |
1885 |
1834 @param lastModified last modified value |
1886 @param lastModified last modified value |
1835 @type str |
1887 @type str |
1836 """ |
1888 """ |
1837 modified = QDateTime.fromString(lastModified, "MM/dd/yyyy hh:mm:ss") |
1889 modified = QDateTime.fromString(lastModified, "MM/dd/yyyy hh:mm:ss") |
1838 if modified.isValid(): |
1890 if modified.isValid(): |
1839 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
1891 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
1840 from .Bookmarks.BookmarkNode import BookmarkNode |
1892 from .Bookmarks.BookmarkNode import BookmarkNode |
|
1893 |
1841 manager = WebBrowserWindow.bookmarksManager() |
1894 manager = WebBrowserWindow.bookmarksManager() |
1842 for bookmark in manager.bookmarksForUrl(self.url()): |
1895 for bookmark in manager.bookmarksForUrl(self.url()): |
1843 manager.setTimestamp(bookmark, BookmarkNode.TsModified, |
1896 manager.setTimestamp(bookmark, BookmarkNode.TsModified, modified) |
1844 modified) |
1897 |
1845 |
|
1846 def isLoading(self): |
1898 def isLoading(self): |
1847 """ |
1899 """ |
1848 Public method to get the loading state. |
1900 Public method to get the loading state. |
1849 |
1901 |
1850 @return flag indicating the loading state (boolean) |
1902 @return flag indicating the loading state (boolean) |
1851 """ |
1903 """ |
1852 return self.__isLoading |
1904 return self.__isLoading |
1853 |
1905 |
1854 def progress(self): |
1906 def progress(self): |
1855 """ |
1907 """ |
1856 Public method to get the load progress. |
1908 Public method to get the load progress. |
1857 |
1909 |
1858 @return load progress (integer) |
1910 @return load progress (integer) |
1859 """ |
1911 """ |
1860 return self.__progress |
1912 return self.__progress |
1861 |
1913 |
1862 def __renderPreview(self): |
1914 def __renderPreview(self): |
1863 """ |
1915 """ |
1864 Private slot to render a preview pixmap after the page was loaded. |
1916 Private slot to render a preview pixmap after the page was loaded. |
1865 """ |
1917 """ |
1866 from .WebBrowserSnap import renderTabPreview |
1918 from .WebBrowserSnap import renderTabPreview |
1867 w = 600 # some default width, the preview gets scaled when shown |
1919 |
|
1920 w = 600 # some default width, the preview gets scaled when shown |
1868 h = int(w * self.height() / self.width()) |
1921 h = int(w * self.height() / self.width()) |
1869 self.__preview = renderTabPreview(self, w, h) |
1922 self.__preview = renderTabPreview(self, w, h) |
1870 |
1923 |
1871 def getPreview(self): |
1924 def getPreview(self): |
1872 """ |
1925 """ |
1873 Public method to get the preview pixmap. |
1926 Public method to get the preview pixmap. |
1874 |
1927 |
1875 @return preview pixmap |
1928 @return preview pixmap |
1876 @rtype QPixmap |
1929 @rtype QPixmap |
1877 """ |
1930 """ |
1878 return self.__preview |
1931 return self.__preview |
1879 |
1932 |
1880 def saveAs(self): |
1933 def saveAs(self): |
1881 """ |
1934 """ |
1882 Public method to save the current page to a file. |
1935 Public method to save the current page to a file. |
1883 """ |
1936 """ |
1884 url = self.url() |
1937 url = self.url() |
1885 if url.isEmpty(): |
1938 if url.isEmpty(): |
1886 return |
1939 return |
1887 |
1940 |
1888 fileName, savePageFormat = self.__getSavePageFileNameAndFormat() |
1941 fileName, savePageFormat = self.__getSavePageFileNameAndFormat() |
1889 if fileName: |
1942 if fileName: |
1890 self.page().save(fileName, savePageFormat) |
1943 self.page().save(fileName, savePageFormat) |
1891 |
1944 |
1892 def __getSavePageFileNameAndFormat(self): |
1945 def __getSavePageFileNameAndFormat(self): |
1893 """ |
1946 """ |
1894 Private method to get the file name to save the page to. |
1947 Private method to get the file name to save the page to. |
1895 |
1948 |
1896 @return tuple containing the file name to save to and the |
1949 @return tuple containing the file name to save to and the |
1897 save page format |
1950 save page format |
1898 @rtype tuple of (str, QWebEngineDownloadRequest.SavePageFormat) |
1951 @rtype tuple of (str, QWebEngineDownloadRequest.SavePageFormat) |
1899 """ |
1952 """ |
1900 documentLocation = QStandardPaths.writableLocation( |
1953 documentLocation = QStandardPaths.writableLocation( |
1901 QStandardPaths.StandardLocation.DocumentsLocation) |
1954 QStandardPaths.StandardLocation.DocumentsLocation |
|
1955 ) |
1902 filterList = [ |
1956 filterList = [ |
1903 self.tr("Web Archive (*.mhtml *.mht)"), |
1957 self.tr("Web Archive (*.mhtml *.mht)"), |
1904 self.tr("HTML File (*.html *.htm)"), |
1958 self.tr("HTML File (*.html *.htm)"), |
1905 self.tr("HTML File with all resources (*.html *.htm)"), |
1959 self.tr("HTML File with all resources (*.html *.htm)"), |
1906 ] |
1960 ] |
1910 (".mhtml", ".mht"), |
1964 (".mhtml", ".mht"), |
1911 (".html", ".htm"), |
1965 (".html", ".htm"), |
1912 (".html", ".htm"), |
1966 (".html", ".htm"), |
1913 ] |
1967 ] |
1914 if self.url().fileName(): |
1968 if self.url().fileName(): |
1915 defaultFileName = os.path.join(documentLocation, |
1969 defaultFileName = os.path.join(documentLocation, self.url().fileName()) |
1916 self.url().fileName()) |
|
1917 else: |
1970 else: |
1918 defaultFileName = os.path.join(documentLocation, |
1971 defaultFileName = os.path.join(documentLocation, self.page().title()) |
1919 self.page().title()) |
|
1920 if Utilities.isWindowsPlatform(): |
1972 if Utilities.isWindowsPlatform(): |
1921 defaultFileName += ".mht" |
1973 defaultFileName += ".mht" |
1922 else: |
1974 else: |
1923 defaultFileName += ".mhtml" |
1975 defaultFileName += ".mhtml" |
1924 |
1976 |
1925 fileName = "" |
1977 fileName = "" |
1926 saveFormat = ( |
1978 saveFormat = QWebEngineDownloadRequest.SavePageFormat.MimeHtmlSaveFormat |
1927 QWebEngineDownloadRequest.SavePageFormat.MimeHtmlSaveFormat |
1979 |
1928 ) |
|
1929 |
|
1930 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
1980 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
1931 None, |
1981 None, self.tr("Save Web Page"), defaultFileName, ";;".join(filterList), None |
1932 self.tr("Save Web Page"), |
1982 ) |
1933 defaultFileName, |
|
1934 ";;".join(filterList), |
|
1935 None) |
|
1936 if fileName: |
1983 if fileName: |
1937 index = filterList.index(selectedFilter) |
1984 index = filterList.index(selectedFilter) |
1938 if index == 0: |
1985 if index == 0: |
1939 saveFormat = ( |
1986 saveFormat = QWebEngineDownloadRequest.SavePageFormat.MimeHtmlSaveFormat |
1940 QWebEngineDownloadRequest.SavePageFormat.MimeHtmlSaveFormat |
|
1941 ) |
|
1942 elif index == 1: |
1987 elif index == 1: |
1943 saveFormat = ( |
1988 saveFormat = ( |
1944 QWebEngineDownloadRequest.SavePageFormat |
1989 QWebEngineDownloadRequest.SavePageFormat.SingleHtmlSaveFormat |
1945 .SingleHtmlSaveFormat |
|
1946 ) |
1990 ) |
1947 else: |
1991 else: |
1948 saveFormat = ( |
1992 saveFormat = ( |
1949 QWebEngineDownloadRequest.SavePageFormat |
1993 QWebEngineDownloadRequest.SavePageFormat.CompleteHtmlSaveFormat |
1950 .CompleteHtmlSaveFormat |
|
1951 ) |
1994 ) |
1952 |
1995 |
1953 extension = os.path.splitext(fileName)[1] |
1996 extension = os.path.splitext(fileName)[1] |
1954 if not extension: |
1997 if not extension: |
1955 # add the platform specific default extension |
1998 # add the platform specific default extension |
1956 if Utilities.isWindowsPlatform(): |
1999 if Utilities.isWindowsPlatform(): |
1957 extensionsIndex = 1 |
2000 extensionsIndex = 1 |
1958 else: |
2001 else: |
1959 extensionsIndex = 0 |
2002 extensionsIndex = 0 |
1960 extensions = extensionsList[index] |
2003 extensions = extensionsList[index] |
1961 fileName += extensions[extensionsIndex] |
2004 fileName += extensions[extensionsIndex] |
1962 |
2005 |
1963 return fileName, saveFormat |
2006 return fileName, saveFormat |
1964 |
2007 |
1965 ########################################################################### |
2008 ########################################################################### |
1966 ## Miscellaneous methods below |
2009 ## Miscellaneous methods below |
1967 ########################################################################### |
2010 ########################################################################### |
1968 |
2011 |
1969 def createWindow(self, windowType): |
2012 def createWindow(self, windowType): |
1970 """ |
2013 """ |
1971 Public method called, when a new window should be created. |
2014 Public method called, when a new window should be created. |
1972 |
2015 |
1973 @param windowType type of the requested window |
2016 @param windowType type of the requested window |
1974 (QWebEnginePage.WebWindowType) |
2017 (QWebEnginePage.WebWindowType) |
1975 @return reference to the created browser window (WebBrowserView) |
2018 @return reference to the created browser window (WebBrowserView) |
1976 """ |
2019 """ |
1977 if windowType in [QWebEnginePage.WebWindowType.WebBrowserTab, |
2020 if windowType in [ |
1978 QWebEnginePage.WebWindowType.WebDialog]: |
2021 QWebEnginePage.WebWindowType.WebBrowserTab, |
|
2022 QWebEnginePage.WebWindowType.WebDialog, |
|
2023 ]: |
1979 return self.__mw.newTab(addNextTo=self) |
2024 return self.__mw.newTab(addNextTo=self) |
1980 elif windowType == QWebEnginePage.WebWindowType.WebBrowserWindow: |
2025 elif windowType == QWebEnginePage.WebWindowType.WebBrowserWindow: |
1981 return self.__mw.newWindow().currentBrowser() |
2026 return self.__mw.newWindow().currentBrowser() |
1982 elif ( |
2027 elif windowType == QWebEnginePage.WebWindowType.WebBrowserBackgroundTab: |
1983 windowType == QWebEnginePage.WebWindowType.WebBrowserBackgroundTab |
|
1984 ): |
|
1985 return self.__mw.newTab(addNextTo=self, background=True) |
2028 return self.__mw.newTab(addNextTo=self, background=True) |
1986 else: |
2029 else: |
1987 # default for unknow/new window types |
2030 # default for unknow/new window types |
1988 return self.__mw.newTab(addNextTo=self) |
2031 return self.__mw.newTab(addNextTo=self) |
1989 |
2032 |
1990 def preferencesChanged(self): |
2033 def preferencesChanged(self): |
1991 """ |
2034 """ |
1992 Public method to indicate a change of the settings. |
2035 Public method to indicate a change of the settings. |
1993 """ |
2036 """ |
1994 self.reload() |
2037 self.reload() |
1995 |
2038 |
1996 ########################################################################### |
2039 ########################################################################### |
1997 ## RSS related methods below |
2040 ## RSS related methods below |
1998 ########################################################################### |
2041 ########################################################################### |
1999 |
2042 |
2000 def checkRSS(self): |
2043 def checkRSS(self): |
2001 """ |
2044 """ |
2002 Public method to check, if the loaded page contains feed links. |
2045 Public method to check, if the loaded page contains feed links. |
2003 |
2046 |
2004 @return flag indicating the existence of feed links (boolean) |
2047 @return flag indicating the existence of feed links (boolean) |
2005 """ |
2048 """ |
2006 self.__rss = [] |
2049 self.__rss = [] |
2007 |
2050 |
2008 script = Scripts.getFeedLinks() |
2051 script = Scripts.getFeedLinks() |
2009 feeds = self.page().execJavaScript(script) |
2052 feeds = self.page().execJavaScript(script) |
2010 |
2053 |
2011 if feeds is not None: |
2054 if feeds is not None: |
2012 for feed in feeds: |
2055 for feed in feeds: |
2013 if feed["url"] and feed["title"]: |
2056 if feed["url"] and feed["title"]: |
2014 self.__rss.append((feed["title"], feed["url"])) |
2057 self.__rss.append((feed["title"], feed["url"])) |
2015 |
2058 |
2016 return len(self.__rss) > 0 |
2059 return len(self.__rss) > 0 |
2017 |
2060 |
2018 def getRSS(self): |
2061 def getRSS(self): |
2019 """ |
2062 """ |
2020 Public method to get the extracted RSS feeds. |
2063 Public method to get the extracted RSS feeds. |
2021 |
2064 |
2022 @return list of RSS feeds (list of tuples of two strings) |
2065 @return list of RSS feeds (list of tuples of two strings) |
2023 """ |
2066 """ |
2024 return self.__rss |
2067 return self.__rss |
2025 |
2068 |
2026 def hasRSS(self): |
2069 def hasRSS(self): |
2027 """ |
2070 """ |
2028 Public method to check, if the loaded page has RSS links. |
2071 Public method to check, if the loaded page has RSS links. |
2029 |
2072 |
2030 @return flag indicating the presence of RSS links (boolean) |
2073 @return flag indicating the presence of RSS links (boolean) |
2031 """ |
2074 """ |
2032 return len(self.__rss) > 0 |
2075 return len(self.__rss) > 0 |
2033 |
2076 |
2034 ########################################################################### |
2077 ########################################################################### |
2035 ## Full Screen handling below |
2078 ## Full Screen handling below |
2036 ########################################################################### |
2079 ########################################################################### |
2037 |
2080 |
2038 def isFullScreen(self): |
2081 def isFullScreen(self): |
2039 """ |
2082 """ |
2040 Public method to check, if full screen mode is active. |
2083 Public method to check, if full screen mode is active. |
2041 |
2084 |
2042 @return flag indicating full screen mode |
2085 @return flag indicating full screen mode |
2043 @rtype bool |
2086 @rtype bool |
2044 """ |
2087 """ |
2045 return self.__mw.isFullScreen() |
2088 return self.__mw.isFullScreen() |
2046 |
2089 |
2047 def requestFullScreen(self, enable): |
2090 def requestFullScreen(self, enable): |
2048 """ |
2091 """ |
2049 Public method to request full screen mode. |
2092 Public method to request full screen mode. |
2050 |
2093 |
2051 @param enable flag indicating full screen mode on or off |
2094 @param enable flag indicating full screen mode on or off |
2052 @type bool |
2095 @type bool |
2053 """ |
2096 """ |
2054 if enable: |
2097 if enable: |
2055 self.__mw.enterHtmlFullScreen() |
2098 self.__mw.enterHtmlFullScreen() |
2056 else: |
2099 else: |
2057 self.__mw.showNormal() |
2100 self.__mw.showNormal() |
2058 |
2101 |
2059 ########################################################################### |
2102 ########################################################################### |
2060 ## Speed Dial slots below |
2103 ## Speed Dial slots below |
2061 ########################################################################### |
2104 ########################################################################### |
2062 |
2105 |
2063 def __addSpeedDial(self): |
2106 def __addSpeedDial(self): |
2064 """ |
2107 """ |
2065 Private slot to add a new speed dial. |
2108 Private slot to add a new speed dial. |
2066 """ |
2109 """ |
2067 self.__page.runJavaScript("addSpeedDial();", |
2110 self.__page.runJavaScript("addSpeedDial();", WebBrowserPage.SafeJsWorld) |
2068 WebBrowserPage.SafeJsWorld) |
2111 |
2069 |
|
2070 def __configureSpeedDial(self): |
2112 def __configureSpeedDial(self): |
2071 """ |
2113 """ |
2072 Private slot to configure the speed dial. |
2114 Private slot to configure the speed dial. |
2073 """ |
2115 """ |
2074 self.page().runJavaScript("configureSpeedDial();", |
2116 self.page().runJavaScript("configureSpeedDial();", WebBrowserPage.SafeJsWorld) |
2075 WebBrowserPage.SafeJsWorld) |
2117 |
2076 |
|
2077 def __reloadAllSpeedDials(self): |
2118 def __reloadAllSpeedDials(self): |
2078 """ |
2119 """ |
2079 Private slot to reload all speed dials. |
2120 Private slot to reload all speed dials. |
2080 """ |
2121 """ |
2081 self.page().runJavaScript("reloadAll();", WebBrowserPage.SafeJsWorld) |
2122 self.page().runJavaScript("reloadAll();", WebBrowserPage.SafeJsWorld) |
2082 |
2123 |
2083 def __resetSpeedDials(self): |
2124 def __resetSpeedDials(self): |
2084 """ |
2125 """ |
2085 Private slot to reset all speed dials to the default pages. |
2126 Private slot to reset all speed dials to the default pages. |
2086 """ |
2127 """ |
2087 self.__speedDial.resetDials() |
2128 self.__speedDial.resetDials() |
2088 |
2129 |
2089 ########################################################################### |
2130 ########################################################################### |
2090 ## Methods below implement session related functions |
2131 ## Methods below implement session related functions |
2091 ########################################################################### |
2132 ########################################################################### |
2092 |
2133 |
2093 def storeSessionData(self, data): |
2134 def storeSessionData(self, data): |
2094 """ |
2135 """ |
2095 Public method to store session data to be restored later on. |
2136 Public method to store session data to be restored later on. |
2096 |
2137 |
2097 @param data dictionary with session data to be restored |
2138 @param data dictionary with session data to be restored |
2098 @type dict |
2139 @type dict |
2099 """ |
2140 """ |
2100 self.__restoreData = data |
2141 self.__restoreData = data |
2101 |
2142 |
2102 def __showEventSlot(self): |
2143 def __showEventSlot(self): |
2103 """ |
2144 """ |
2104 Private slot to perform actions when the view is shown and the event |
2145 Private slot to perform actions when the view is shown and the event |
2105 loop is running. |
2146 loop is running. |
2106 """ |
2147 """ |
2107 if self.__restoreData: |
2148 if self.__restoreData: |
2108 sessionData, self.__restoreData = self.__restoreData, None |
2149 sessionData, self.__restoreData = self.__restoreData, None |
2109 self.loadFromSessionData(sessionData) |
2150 self.loadFromSessionData(sessionData) |
2110 |
2151 |
2111 def showEvent(self, evt): |
2152 def showEvent(self, evt): |
2112 """ |
2153 """ |
2113 Protected method to handle show events. |
2154 Protected method to handle show events. |
2114 |
2155 |
2115 @param evt reference to the show event object |
2156 @param evt reference to the show event object |
2116 @type QShowEvent |
2157 @type QShowEvent |
2117 """ |
2158 """ |
2118 super().showEvent(evt) |
2159 super().showEvent(evt) |
2119 self.activateSession() |
2160 self.activateSession() |
2120 |
2161 |
2121 def activateSession(self): |
2162 def activateSession(self): |
2122 """ |
2163 """ |
2123 Public slot to activate a restored session. |
2164 Public slot to activate a restored session. |
2124 """ |
2165 """ |
2125 if self.__restoreData and not self.__mw.isClosing(): |
2166 if self.__restoreData and not self.__mw.isClosing(): |
2126 QTimer.singleShot(0, self.__showEventSlot) |
2167 QTimer.singleShot(0, self.__showEventSlot) |
2127 |
2168 |
2128 def getSessionData(self): |
2169 def getSessionData(self): |
2129 """ |
2170 """ |
2130 Public method to populate the session data. |
2171 Public method to populate the session data. |
2131 |
2172 |
2132 @return dictionary containing the session data |
2173 @return dictionary containing the session data |
2133 @rtype dict |
2174 @rtype dict |
2134 """ |
2175 """ |
2135 if self.__restoreData: |
2176 if self.__restoreData: |
2136 # page has not been shown yet |
2177 # page has not been shown yet |
2137 return self.__restoreData |
2178 return self.__restoreData |
2138 |
2179 |
2139 sessionData = {} |
2180 sessionData = {} |
2140 page = self.page() |
2181 page = self.page() |
2141 |
2182 |
2142 # 1. zoom factor |
2183 # 1. zoom factor |
2143 sessionData["ZoomFactor"] = page.zoomFactor() |
2184 sessionData["ZoomFactor"] = page.zoomFactor() |
2144 |
2185 |
2145 # 2. scroll position |
2186 # 2. scroll position |
2146 scrollPos = page.scrollPosition() |
2187 scrollPos = page.scrollPosition() |
2147 sessionData["ScrollPosition"] = { |
2188 sessionData["ScrollPosition"] = { |
2148 "x": scrollPos.x(), |
2189 "x": scrollPos.x(), |
2149 "y": scrollPos.y(), |
2190 "y": scrollPos.y(), |
2150 } |
2191 } |
2151 |
2192 |
2152 # 3. page history |
2193 # 3. page history |
2153 historyArray = QByteArray() |
2194 historyArray = QByteArray() |
2154 stream = QDataStream(historyArray, QIODevice.OpenModeFlag.WriteOnly) |
2195 stream = QDataStream(historyArray, QIODevice.OpenModeFlag.WriteOnly) |
2155 stream << page.history() |
2196 stream << page.history() |
2156 sessionData["History"] = str( |
2197 sessionData["History"] = str( |
2157 historyArray.toBase64(QByteArray.Base64Option.Base64UrlEncoding), |
2198 historyArray.toBase64(QByteArray.Base64Option.Base64UrlEncoding), |
2158 encoding="ascii") |
2199 encoding="ascii", |
|
2200 ) |
2159 sessionData["HistoryIndex"] = page.history().currentItemIndex() |
2201 sessionData["HistoryIndex"] = page.history().currentItemIndex() |
2160 |
2202 |
2161 # 4. current URL and title |
2203 # 4. current URL and title |
2162 sessionData["Url"] = self.url().toString() |
2204 sessionData["Url"] = self.url().toString() |
2163 sessionData["Title"] = self.title() |
2205 sessionData["Title"] = self.title() |
2164 |
2206 |
2165 # 5. web icon |
2207 # 5. web icon |
2166 iconArray = QByteArray() |
2208 iconArray = QByteArray() |
2167 stream = QDataStream(iconArray, QIODevice.OpenModeFlag.WriteOnly) |
2209 stream = QDataStream(iconArray, QIODevice.OpenModeFlag.WriteOnly) |
2168 stream << page.icon() |
2210 stream << page.icon() |
2169 sessionData["Icon"] = str(iconArray.toBase64(), encoding="ascii") |
2211 sessionData["Icon"] = str(iconArray.toBase64(), encoding="ascii") |
2170 |
2212 |
2171 return sessionData |
2213 return sessionData |
2172 |
2214 |
2173 def loadFromSessionData(self, sessionData): |
2215 def loadFromSessionData(self, sessionData): |
2174 """ |
2216 """ |
2175 Public method to load the session data. |
2217 Public method to load the session data. |
2176 |
2218 |
2177 @param sessionData dictionary containing the session data as |
2219 @param sessionData dictionary containing the session data as |
2178 generated by getSessionData() |
2220 generated by getSessionData() |
2179 @type dict |
2221 @type dict |
2180 """ |
2222 """ |
2181 page = self.page() |
2223 page = self.page() |
2182 # blank the page |
2224 # blank the page |
2183 page.setUrl(QUrl("about:blank")) |
2225 page.setUrl(QUrl("about:blank")) |
2184 |
2226 |
2185 # 1. page history |
2227 # 1. page history |
2186 if "History" in sessionData: |
2228 if "History" in sessionData: |
2187 historyArray = QByteArray.fromBase64( |
2229 historyArray = QByteArray.fromBase64( |
2188 sessionData["History"].encode("ascii"), |
2230 sessionData["History"].encode("ascii"), |
2189 QByteArray.Base64Option.Base64UrlEncoding) |
2231 QByteArray.Base64Option.Base64UrlEncoding, |
|
2232 ) |
2190 stream = QDataStream(historyArray, QIODevice.OpenModeFlag.ReadOnly) |
2233 stream = QDataStream(historyArray, QIODevice.OpenModeFlag.ReadOnly) |
2191 stream >> page.history() |
2234 stream >> page.history() |
2192 |
2235 |
2193 if "HistoryIndex" in sessionData: |
2236 if "HistoryIndex" in sessionData: |
2194 item = page.history().itemAt(sessionData["HistoryIndex"]) |
2237 item = page.history().itemAt(sessionData["HistoryIndex"]) |
2195 if item is not None: |
2238 if item is not None: |
2196 page.history().goToItem(item) |
2239 page.history().goToItem(item) |
2197 |
2240 |
2198 # 2. zoom factor |
2241 # 2. zoom factor |
2199 if "ZoomFactor" in sessionData: |
2242 if "ZoomFactor" in sessionData: |
2200 page.setZoomFactor(sessionData["ZoomFactor"]) |
2243 page.setZoomFactor(sessionData["ZoomFactor"]) |
2201 |
2244 |
2202 # 3. scroll position |
2245 # 3. scroll position |
2203 if "ScrollPosition" in sessionData: |
2246 if "ScrollPosition" in sessionData: |
2204 scrollPos = sessionData["ScrollPosition"] |
2247 scrollPos = sessionData["ScrollPosition"] |
2205 page.scrollTo(QPointF(scrollPos["x"], scrollPos["y"])) |
2248 page.scrollTo(QPointF(scrollPos["x"], scrollPos["y"])) |
2206 |
2249 |
2207 def extractSessionMetaData(self, sessionData): |
2250 def extractSessionMetaData(self, sessionData): |
2208 """ |
2251 """ |
2209 Public method to extract some session meta data elements needed by the |
2252 Public method to extract some session meta data elements needed by the |
2210 tab widget in case of deferred loading. |
2253 tab widget in case of deferred loading. |
2211 |
2254 |
2212 @param sessionData dictionary containing the session data as |
2255 @param sessionData dictionary containing the session data as |
2213 generated by getSessionData() |
2256 generated by getSessionData() |
2214 @type dict |
2257 @type dict |
2215 @return tuple containing the title, URL and web icon |
2258 @return tuple containing the title, URL and web icon |
2216 @rtype tuple of (str, str, QIcon) |
2259 @rtype tuple of (str, str, QIcon) |
2217 """ |
2260 """ |
2218 title = sessionData.get("Title", "") |
2261 title = sessionData.get("Title", "") |
2219 urlStr = sessionData.get("Url", "") |
2262 urlStr = sessionData.get("Url", "") |
2220 |
2263 |
2221 if "Icon" in sessionData: |
2264 if "Icon" in sessionData: |
2222 iconArray = QByteArray.fromBase64( |
2265 iconArray = QByteArray.fromBase64(sessionData["Icon"].encode("ascii")) |
2223 sessionData["Icon"].encode("ascii")) |
|
2224 stream = QDataStream(iconArray, QIODevice.OpenModeFlag.ReadOnly) |
2266 stream = QDataStream(iconArray, QIODevice.OpenModeFlag.ReadOnly) |
2225 icon = QIcon() |
2267 icon = QIcon() |
2226 stream >> icon |
2268 stream >> icon |
2227 else: |
2269 else: |
2228 from .Tools import WebIconProvider |
2270 from .Tools import WebIconProvider |
2229 icon = WebIconProvider.instance().iconForUrl( |
2271 |
2230 QUrl.fromUserInput(urlStr)) |
2272 icon = WebIconProvider.instance().iconForUrl(QUrl.fromUserInput(urlStr)) |
2231 |
2273 |
2232 return title, urlStr, icon |
2274 return title, urlStr, icon |
2233 |
2275 |
2234 ########################################################################### |
2276 ########################################################################### |
2235 ## Methods below implement safe browsing related functions |
2277 ## Methods below implement safe browsing related functions |
2236 ########################################################################### |
2278 ########################################################################### |
2237 |
2279 |
2238 def getSafeBrowsingStatus(self): |
2280 def getSafeBrowsingStatus(self): |
2239 """ |
2281 """ |
2240 Public method to get the safe browsing status of the current page. |
2282 Public method to get the safe browsing status of the current page. |
2241 |
2283 |
2242 @return flag indicating a safe site |
2284 @return flag indicating a safe site |
2243 @rtype bool |
2285 @rtype bool |
2244 """ |
2286 """ |
2245 if self.__page: |
2287 if self.__page: |
2246 return self.__page.getSafeBrowsingStatus() |
2288 return self.__page.getSafeBrowsingStatus() |
2247 else: |
2289 else: |
2248 return True |
2290 return True |
2249 |
2291 |
2250 ########################################################################### |
2292 ########################################################################### |
2251 ## Methods below implement print support from the page |
2293 ## Methods below implement print support from the page |
2252 ########################################################################### |
2294 ########################################################################### |
2253 |
2295 |
2254 @pyqtSlot() |
2296 @pyqtSlot() |
2255 def __printPage(self): |
2297 def __printPage(self): |
2256 """ |
2298 """ |
2257 Private slot to support printing from the web page. |
2299 Private slot to support printing from the web page. |
2258 """ |
2300 """ |
2259 self.__mw.tabWidget.printBrowser(browser=self) |
2301 self.__mw.tabWidget.printBrowser(browser=self) |
2260 |
2302 |
2261 ########################################################################### |
2303 ########################################################################### |
2262 ## Methods below implement slots for Qt 5.11+ |
2304 ## Methods below implement slots for Qt 5.11+ |
2263 ########################################################################### |
2305 ########################################################################### |
2264 |
2306 |
2265 @pyqtSlot("QWebEngineQuotaRequest") |
2307 @pyqtSlot("QWebEngineQuotaRequest") |
2266 def __quotaRequested(self, quotaRequest): |
2308 def __quotaRequested(self, quotaRequest): |
2267 """ |
2309 """ |
2268 Private slot to handle quota requests of the web page. |
2310 Private slot to handle quota requests of the web page. |
2269 |
2311 |
2270 @param quotaRequest reference to the quota request object |
2312 @param quotaRequest reference to the quota request object |
2271 @type QWebEngineQuotaRequest |
2313 @type QWebEngineQuotaRequest |
2272 """ |
2314 """ |
2273 acceptRequest = Preferences.getWebBrowser("AcceptQuotaRequest") |
2315 acceptRequest = Preferences.getWebBrowser("AcceptQuotaRequest") |
2274 # map yes/no/ask from (0, 1, 2) |
2316 # map yes/no/ask from (0, 1, 2) |