44 SSL_AVAILABLE = True |
39 SSL_AVAILABLE = True |
45 except ImportError: |
40 except ImportError: |
46 SSL_AVAILABLE = False |
41 SSL_AVAILABLE = False |
47 |
42 |
48 ############################################################################### |
43 ############################################################################### |
49 |
44 ## |
50 |
45 ## |
51 class JavaScriptExternalObject(QObject): |
46 ##class JavaScriptExternalObject(QObject): |
52 """ |
47 ## """ |
53 Class implementing an external javascript object to add search providers. |
48 ## Class implementing an external javascript object to add search providers. |
54 """ |
49 ## """ |
55 def __init__(self, mw, parent=None): |
50 ## def __init__(self, mw, parent=None): |
56 """ |
51 ## """ |
57 Constructor |
52 ## Constructor |
58 |
53 ## |
59 @param mw reference to the main window 8HelpWindow) |
54 ## @param mw reference to the main window 8HelpWindow) |
60 @param parent reference to the parent object (QObject) |
55 ## @param parent reference to the parent object (QObject) |
61 """ |
56 ## """ |
62 super(JavaScriptExternalObject, self).__init__(parent) |
57 ## super(JavaScriptExternalObject, self).__init__(parent) |
63 |
58 ## |
64 self.__mw = mw |
59 ## self.__mw = mw |
65 |
60 ## |
66 @pyqtSlot(str) |
61 ## @pyqtSlot(str) |
67 def AddSearchProvider(self, url): |
62 ## def AddSearchProvider(self, url): |
68 """ |
63 ## """ |
69 Public slot to add a search provider. |
64 ## Public slot to add a search provider. |
70 |
65 ## |
71 @param url url of the XML file defining the search provider (string) |
66 ## @param url url of the XML file defining the search provider (string) |
72 """ |
67 ## """ |
73 self.__mw.openSearchManager().addEngine(QUrl(url)) |
68 ## self.__mw.openSearchManager().addEngine(QUrl(url)) |
74 |
69 ## |
75 |
70 ## |
76 class LinkedResource(object): |
71 ##class LinkedResource(object): |
77 """ |
72 ## """ |
78 Class defining a data structure for linked resources. |
73 ## Class defining a data structure for linked resources. |
79 """ |
74 ## """ |
80 def __init__(self): |
75 ## def __init__(self): |
81 """ |
76 ## """ |
82 Constructor |
77 ## Constructor |
83 """ |
78 ## """ |
84 self.rel = "" |
79 ## self.rel = "" |
85 self.type_ = "" |
80 ## self.type_ = "" |
86 self.href = "" |
81 ## self.href = "" |
87 self.title = "" |
82 ## self.title = "" |
88 |
83 ## |
|
84 ############################################################################### |
|
85 ## |
|
86 ## |
|
87 ##class JavaScriptEricObject(QObject): |
|
88 ## """ |
|
89 ## Class implementing an external javascript object to search via the |
|
90 ## startpage. |
|
91 ## """ |
|
92 ## # these must be in line with the strings used by the javascript part of |
|
93 ## # the start page |
|
94 ## translations = [ |
|
95 ## QT_TRANSLATE_NOOP("JavaScriptEricObject", |
|
96 ## "Welcome to eric6 Web Browser!"), |
|
97 ## QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric6 Web Browser"), |
|
98 ## QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), |
|
99 ## QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric6"), |
|
100 ## ] |
|
101 ## |
|
102 ## def __init__(self, mw, parent=None): |
|
103 ## """ |
|
104 ## Constructor |
|
105 ## |
|
106 ## @param mw reference to the main window 8HelpWindow) |
|
107 ## @param parent reference to the parent object (QObject) |
|
108 ## """ |
|
109 ## super(JavaScriptEricObject, self).__init__(parent) |
|
110 ## |
|
111 ## self.__mw = mw |
|
112 ## |
|
113 ## @pyqtSlot(str, result=str) |
|
114 ## def translate(self, trans): |
|
115 ## """ |
|
116 ## Public method to translate the given string. |
|
117 ## |
|
118 ## @param trans string to be translated (string) |
|
119 ## @return translation (string) |
|
120 ## """ |
|
121 ## if trans == "QT_LAYOUT_DIRECTION": |
|
122 ## # special handling to detect layout direction |
|
123 ## if qApp.isLeftToRight(): |
|
124 ## return "LTR" |
|
125 ## else: |
|
126 ## return "RTL" |
|
127 ## |
|
128 ## return self.tr(trans) |
|
129 ## |
|
130 ## @pyqtSlot(result=str) |
|
131 ## def providerString(self): |
|
132 ## """ |
|
133 ## Public method to get a string for the search provider. |
|
134 ## |
|
135 ## @return string for the search provider (string) |
|
136 ## """ |
|
137 ## return self.tr("Search results provided by {0}")\ |
|
138 ## .format(self.__mw.openSearchManager().currentEngineName()) |
|
139 ## |
|
140 ## @pyqtSlot(str, result=str) |
|
141 ## def searchUrl(self, searchStr): |
|
142 ## """ |
|
143 ## Public method to get the search URL for the given search term. |
|
144 ## |
|
145 ## @param searchStr search term (string) |
|
146 ## @return search URL (string) |
|
147 ## """ |
|
148 ## return bytes( |
|
149 ## self.__mw.openSearchManager().currentEngine() |
|
150 ## .searchUrl(searchStr).toEncoded()).decode() |
|
151 ## |
89 ############################################################################### |
152 ############################################################################### |
90 |
153 |
91 |
154 |
92 class JavaScriptEricObject(QObject): |
155 class WebBrowserView(QWebEngineView): |
93 """ |
156 """ |
94 Class implementing an external javascript object to search via the |
157 Class implementing the web browser view widget. |
95 startpage. |
|
96 """ |
|
97 # these must be in line with the strings used by the javascript part of |
|
98 # the start page |
|
99 translations = [ |
|
100 QT_TRANSLATE_NOOP("JavaScriptEricObject", |
|
101 "Welcome to eric6 Web Browser!"), |
|
102 QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric6 Web Browser"), |
|
103 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), |
|
104 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric6"), |
|
105 ] |
|
106 |
|
107 def __init__(self, mw, parent=None): |
|
108 """ |
|
109 Constructor |
|
110 |
|
111 @param mw reference to the main window 8HelpWindow) |
|
112 @param parent reference to the parent object (QObject) |
|
113 """ |
|
114 super(JavaScriptEricObject, self).__init__(parent) |
|
115 |
|
116 self.__mw = mw |
|
117 |
|
118 @pyqtSlot(str, result=str) |
|
119 def translate(self, trans): |
|
120 """ |
|
121 Public method to translate the given string. |
|
122 |
|
123 @param trans string to be translated (string) |
|
124 @return translation (string) |
|
125 """ |
|
126 if trans == "QT_LAYOUT_DIRECTION": |
|
127 # special handling to detect layout direction |
|
128 if qApp.isLeftToRight(): |
|
129 return "LTR" |
|
130 else: |
|
131 return "RTL" |
|
132 |
|
133 return self.tr(trans) |
|
134 |
|
135 @pyqtSlot(result=str) |
|
136 def providerString(self): |
|
137 """ |
|
138 Public method to get a string for the search provider. |
|
139 |
|
140 @return string for the search provider (string) |
|
141 """ |
|
142 return self.tr("Search results provided by {0}")\ |
|
143 .format(self.__mw.openSearchManager().currentEngineName()) |
|
144 |
|
145 @pyqtSlot(str, result=str) |
|
146 def searchUrl(self, searchStr): |
|
147 """ |
|
148 Public method to get the search URL for the given search term. |
|
149 |
|
150 @param searchStr search term (string) |
|
151 @return search URL (string) |
|
152 """ |
|
153 return bytes( |
|
154 self.__mw.openSearchManager().currentEngine() |
|
155 .searchUrl(searchStr).toEncoded()).decode() |
|
156 |
|
157 ############################################################################### |
|
158 |
|
159 |
|
160 class HelpWebPage(QWebPage): |
|
161 """ |
|
162 Class implementing an enhanced web page. |
|
163 """ |
|
164 _webPluginFactory = None |
|
165 |
|
166 def __init__(self, parent=None): |
|
167 """ |
|
168 Constructor |
|
169 |
|
170 @param parent parent widget of this window (QWidget) |
|
171 """ |
|
172 super(HelpWebPage, self).__init__(parent) |
|
173 |
|
174 self.setPluginFactory(self.webPluginFactory()) |
|
175 |
|
176 self.__lastRequest = None |
|
177 self.__lastRequestType = QWebPage.NavigationTypeOther |
|
178 |
|
179 import Helpviewer.HelpWindow |
|
180 from .Network.NetworkAccessManagerProxy import \ |
|
181 NetworkAccessManagerProxy |
|
182 self.__proxy = NetworkAccessManagerProxy(self) |
|
183 self.__proxy.setWebPage(self) |
|
184 self.__proxy.setPrimaryNetworkAccessManager( |
|
185 Helpviewer.HelpWindow.HelpWindow.networkAccessManager()) |
|
186 self.setNetworkAccessManager(self.__proxy) |
|
187 |
|
188 self.__sslConfiguration = None |
|
189 self.__proxy.finished.connect(self.__managerFinished) |
|
190 |
|
191 self.__adBlockedEntries = [] |
|
192 self.loadStarted.connect(self.__loadStarted) |
|
193 |
|
194 self.saveFrameStateRequested.connect( |
|
195 self.__saveFrameStateRequested) |
|
196 self.restoreFrameStateRequested.connect( |
|
197 self.__restoreFrameStateRequested) |
|
198 |
|
199 def acceptNavigationRequest(self, frame, request, type_): |
|
200 """ |
|
201 Public method to determine, if a request may be accepted. |
|
202 |
|
203 @param frame reference to the frame sending the request (QWebFrame) |
|
204 @param request reference to the request object (QNetworkRequest) |
|
205 @param type_ type of the navigation request (QWebPage.NavigationType) |
|
206 @return flag indicating acceptance (boolean) |
|
207 """ |
|
208 self.__lastRequest = request |
|
209 if self.__lastRequest.url() != request.url() or \ |
|
210 type_ != QWebPage.NavigationTypeOther: |
|
211 self.__lastRequestType = type_ |
|
212 |
|
213 scheme = request.url().scheme() |
|
214 if scheme == "mailto": |
|
215 QDesktopServices.openUrl(request.url()) |
|
216 return False |
|
217 |
|
218 if type_ == QWebPage.NavigationTypeFormResubmitted: |
|
219 res = E5MessageBox.yesNo( |
|
220 self.view(), |
|
221 self.tr("Resending POST request"), |
|
222 self.tr( |
|
223 """In order to display the site, the request along with""" |
|
224 """ all the data must be sent once again, which may lead""" |
|
225 """ to some unexpected behaviour of the site e.g. the""" |
|
226 """ same action might be performed once again. Do you""" |
|
227 """ want to continue anyway?"""), |
|
228 icon=E5MessageBox.Warning) |
|
229 if not res: |
|
230 return False |
|
231 |
|
232 return QWebPage.acceptNavigationRequest(self, frame, request, type_) |
|
233 |
|
234 def populateNetworkRequest(self, request): |
|
235 """ |
|
236 Public method to add data to a network request. |
|
237 |
|
238 @param request reference to the network request object |
|
239 (QNetworkRequest) |
|
240 """ |
|
241 try: |
|
242 request.setAttribute(QNetworkRequest.User + 100, self) |
|
243 if self.__lastRequest.url() == request.url(): |
|
244 request.setAttribute(QNetworkRequest.User + 101, |
|
245 self.__lastRequestType) |
|
246 if self.__lastRequestType == \ |
|
247 QWebPage.NavigationTypeLinkClicked: |
|
248 request.setRawHeader(b"X-Eric6-UserLoadAction", |
|
249 QByteArray(b"1")) |
|
250 except TypeError: |
|
251 pass |
|
252 |
|
253 def pageAttributeId(self): |
|
254 """ |
|
255 Public method to get the attribute id of the page attribute. |
|
256 |
|
257 @return attribute id of the page attribute (integer) |
|
258 """ |
|
259 return QNetworkRequest.User + 100 |
|
260 |
|
261 def supportsExtension(self, extension): |
|
262 """ |
|
263 Public method to check the support for an extension. |
|
264 |
|
265 @param extension extension to test for (QWebPage.Extension) |
|
266 @return flag indicating the support of extension (boolean) |
|
267 """ |
|
268 try: |
|
269 if extension in [QWebPage.ErrorPageExtension, |
|
270 QWebPage.ChooseMultipleFilesExtension]: |
|
271 return True |
|
272 except AttributeError: |
|
273 pass |
|
274 |
|
275 return QWebPage.supportsExtension(self, extension) |
|
276 |
|
277 def extension(self, extension, option, output): |
|
278 """ |
|
279 Public method to implement a specific extension. |
|
280 |
|
281 @param extension extension to be executed (QWebPage.Extension) |
|
282 @param option provides input to the extension |
|
283 (QWebPage.ExtensionOption) |
|
284 @param output stores the output results (QWebPage.ExtensionReturn) |
|
285 @return flag indicating a successful call of the extension (boolean) |
|
286 """ |
|
287 if extension == QWebPage.ChooseMultipleFilesExtension: |
|
288 info = sip.cast(option, |
|
289 QWebPage.ChooseMultipleFilesExtensionOption) |
|
290 files = sip.cast(output, |
|
291 QWebPage.ChooseMultipleFilesExtensionReturn) |
|
292 if info is None or files is None: |
|
293 return super(HelpWebPage, self).extension( |
|
294 extension, option, output) |
|
295 |
|
296 suggestedFileName = "" |
|
297 if info.suggestedFileNames: |
|
298 suggestedFileName = info.suggestedFileNames[0] |
|
299 |
|
300 files.fileNames = E5FileDialog.getOpenFileNames( |
|
301 None, |
|
302 self.tr("Select files to upload..."), |
|
303 suggestedFileName) |
|
304 return True |
|
305 |
|
306 if extension == QWebPage.ErrorPageExtension: |
|
307 info = sip.cast(option, QWebPage.ErrorPageExtensionOption) |
|
308 |
|
309 errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn) |
|
310 urlString = bytes(info.url.toEncoded()).decode() |
|
311 errorPage.baseUrl = info.url |
|
312 if info.domain == QWebPage.QtNetwork and \ |
|
313 info.error == QNetworkReply.ProtocolUnknownError: |
|
314 url = QUrl(info.url) |
|
315 res = E5MessageBox.yesNo( |
|
316 None, |
|
317 self.tr("Protocol Error"), |
|
318 self.tr("""Open external application for {0}-link?\n""" |
|
319 """URL: {1}""").format( |
|
320 url.scheme(), url.toString( |
|
321 QUrl.PrettyDecoded | QUrl.RemovePassword)), |
|
322 yesDefault=True) |
|
323 |
|
324 if res: |
|
325 QDesktopServices.openUrl(url) |
|
326 return True |
|
327 elif info.domain == QWebPage.QtNetwork and \ |
|
328 info.error == QNetworkReply.ContentAccessDenied and \ |
|
329 info.errorString.startswith("AdBlockRule:"): |
|
330 if info.frame != info.frame.page().mainFrame(): |
|
331 # content in <iframe> |
|
332 docElement = info.frame.page().mainFrame()\ |
|
333 .documentElement() |
|
334 for element in docElement.findAll("iframe"): |
|
335 src = element.attribute("src") |
|
336 if src in info.url.toString(): |
|
337 element.setAttribute("style", "display:none;") |
|
338 return False |
|
339 else: |
|
340 # the whole page is blocked |
|
341 rule = info.errorString.replace("AdBlockRule:", "") |
|
342 title = self.tr("Content blocked by AdBlock Plus") |
|
343 message = self.tr( |
|
344 "Blocked by rule: <i>{0}</i>").format(rule) |
|
345 |
|
346 htmlFile = QFile(":/html/adblockPage.html") |
|
347 htmlFile.open(QFile.ReadOnly) |
|
348 html = htmlFile.readAll() |
|
349 html = html.replace( |
|
350 "@FAVICON@", "qrc:icons/adBlockPlus16.png") |
|
351 html = html.replace( |
|
352 "@IMAGE@", "qrc:icons/adBlockPlus64.png") |
|
353 html = html.replace("@TITLE@", title.encode("utf8")) |
|
354 html = html.replace("@MESSAGE@", message.encode("utf8")) |
|
355 errorPage.content = html |
|
356 return True |
|
357 |
|
358 if info.domain == QWebPage.QtNetwork and \ |
|
359 info.error == QNetworkReply.OperationCanceledError and \ |
|
360 info.errorString == "eric6:No Error": |
|
361 return False |
|
362 |
|
363 if info.domain == QWebPage.WebKit and info.error == 203: |
|
364 # "Loading is handled by the media engine" |
|
365 return False |
|
366 |
|
367 title = self.tr("Error loading page: {0}").format(urlString) |
|
368 htmlFile = QFile(":/html/notFoundPage.html") |
|
369 htmlFile.open(QFile.ReadOnly) |
|
370 html = htmlFile.readAll() |
|
371 pixmap = qApp.style()\ |
|
372 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48) |
|
373 imageBuffer = QBuffer() |
|
374 imageBuffer.open(QIODevice.ReadWrite) |
|
375 if pixmap.save(imageBuffer, "PNG"): |
|
376 html = html.replace("@IMAGE@", imageBuffer.buffer().toBase64()) |
|
377 pixmap = qApp.style()\ |
|
378 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16) |
|
379 imageBuffer = QBuffer() |
|
380 imageBuffer.open(QIODevice.ReadWrite) |
|
381 if pixmap.save(imageBuffer, "PNG"): |
|
382 html = html.replace( |
|
383 "@FAVICON@", imageBuffer.buffer().toBase64()) |
|
384 html = html.replace("@TITLE@", title.encode("utf8")) |
|
385 html = html.replace("@H1@", info.errorString.encode("utf8")) |
|
386 html = html.replace( |
|
387 "@H2@", self.tr("When connecting to: {0}.") |
|
388 .format(urlString).encode("utf8")) |
|
389 html = html.replace( |
|
390 "@LI-1@", |
|
391 self.tr("Check the address for errors such as " |
|
392 "<b>ww</b>.example.org instead of " |
|
393 "<b>www</b>.example.org").encode("utf8")) |
|
394 html = html.replace( |
|
395 "@LI-2@", |
|
396 self.tr( |
|
397 "If the address is correct, try checking the network " |
|
398 "connection.").encode("utf8")) |
|
399 html = html.replace( |
|
400 "@LI-3@", |
|
401 self.tr( |
|
402 "If your computer or network is protected by a firewall " |
|
403 "or proxy, make sure that the browser is permitted to " |
|
404 "access the network.").encode("utf8")) |
|
405 html = html.replace( |
|
406 "@LI-4@", |
|
407 self.tr("If your cache policy is set to offline browsing," |
|
408 "only pages in the local cache are available.") |
|
409 .encode("utf8")) |
|
410 html = html.replace( |
|
411 "@BUTTON@", self.tr("Try Again").encode("utf8")) |
|
412 errorPage.content = html |
|
413 return True |
|
414 |
|
415 return QWebPage.extension(self, extension, option, output) |
|
416 |
|
417 def __loadStarted(self): |
|
418 """ |
|
419 Private method to handle the loadStarted signal. |
|
420 """ |
|
421 self.__adBlockedEntries = [] |
|
422 |
|
423 def addAdBlockRule(self, rule, url): |
|
424 """ |
|
425 Public slot to add an AdBlock rule to the page. |
|
426 |
|
427 @param rule AdBlock rule to add (AdBlockRule) |
|
428 @param url URL that matched the rule (QUrl) |
|
429 """ |
|
430 from .AdBlock.AdBlockPage import AdBlockedPageEntry |
|
431 entry = AdBlockedPageEntry(rule, url) |
|
432 if entry not in self.__adBlockedEntries: |
|
433 self.__adBlockedEntries.append(entry) |
|
434 |
|
435 def getAdBlockedPageEntries(self): |
|
436 """ |
|
437 Public method to get the list of AdBlock page entries. |
|
438 |
|
439 @return list of AdBlock page entries (list of AdBlockedPageEntry) |
|
440 """ |
|
441 return self.__adBlockedEntries |
|
442 |
|
443 def url(self): |
|
444 """ |
|
445 Public method to get the URL of the page. |
|
446 |
|
447 @return URL of the page (QUrl) |
|
448 """ |
|
449 return self.mainFrame().url() |
|
450 |
|
451 def userAgent(self, resolveEmpty=False): |
|
452 """ |
|
453 Public method to get the global user agent setting. |
|
454 |
|
455 @param resolveEmpty flag indicating to resolve an empty |
|
456 user agent (boolean) |
|
457 @return user agent string (string) |
|
458 """ |
|
459 agent = Preferences.getHelp("UserAgent") |
|
460 if agent == "" and resolveEmpty: |
|
461 agent = self.userAgentForUrl(QUrl()) |
|
462 return agent |
|
463 |
|
464 def setUserAgent(self, agent): |
|
465 """ |
|
466 Public method to set the global user agent string. |
|
467 |
|
468 @param agent new current user agent string (string) |
|
469 """ |
|
470 Preferences.setHelp("UserAgent", agent) |
|
471 |
|
472 def userAgentForUrl(self, url): |
|
473 """ |
|
474 Public method to determine the user agent for the given URL. |
|
475 |
|
476 @param url URL to determine user agent for (QUrl) |
|
477 @return user agent string (string) |
|
478 """ |
|
479 import Helpviewer.HelpWindow |
|
480 agent = Helpviewer.HelpWindow.HelpWindow.userAgentsManager()\ |
|
481 .userAgentForUrl(url) |
|
482 if agent == "": |
|
483 # no agent string specified for the given host -> use global one |
|
484 agent = Preferences.getHelp("UserAgent") |
|
485 if agent == "": |
|
486 # no global agent string specified -> use default one |
|
487 agent = QWebPage.userAgentForUrl(self, url) |
|
488 return agent |
|
489 |
|
490 def __managerFinished(self, reply): |
|
491 """ |
|
492 Private slot to handle a finished reply. |
|
493 |
|
494 This slot is used to get SSL related information for a reply. |
|
495 |
|
496 @param reply reference to the finished reply (QNetworkReply) |
|
497 """ |
|
498 try: |
|
499 frame = reply.request().originatingObject() |
|
500 except AttributeError: |
|
501 frame = None |
|
502 |
|
503 mainFrameRequest = frame == self.mainFrame() |
|
504 |
|
505 if mainFrameRequest and \ |
|
506 self.__sslConfiguration is not None and \ |
|
507 reply.url() == self.mainFrame().url(): |
|
508 self.__sslConfiguration = None |
|
509 |
|
510 if reply.error() == QNetworkReply.NoError and \ |
|
511 mainFrameRequest and \ |
|
512 self.__sslConfiguration is None and \ |
|
513 reply.url().scheme().lower() == "https" and \ |
|
514 reply.url() == self.mainFrame().url(): |
|
515 self.__sslConfiguration = reply.sslConfiguration() |
|
516 self.__sslConfiguration.url = QUrl(reply.url()) |
|
517 |
|
518 if reply.error() == QNetworkReply.NoError and \ |
|
519 mainFrameRequest and \ |
|
520 reply.url() == self.mainFrame().url(): |
|
521 modified = reply.header(QNetworkRequest.LastModifiedHeader) |
|
522 if modified and modified.isValid(): |
|
523 import Helpviewer.HelpWindow |
|
524 manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager() |
|
525 from .Bookmarks.BookmarkNode import BookmarkNode |
|
526 for bookmark in manager.bookmarksForUrl(reply.url()): |
|
527 manager.setTimestamp(bookmark, BookmarkNode.TsModified, |
|
528 modified) |
|
529 |
|
530 def getSslCertificate(self): |
|
531 """ |
|
532 Public method to get a reference to the SSL certificate. |
|
533 |
|
534 @return amended SSL certificate (QSslCertificate) |
|
535 """ |
|
536 if self.__sslConfiguration is None: |
|
537 return None |
|
538 |
|
539 sslInfo = self.__sslConfiguration.peerCertificate() |
|
540 sslInfo.url = QUrl(self.__sslConfiguration.url) |
|
541 return sslInfo |
|
542 |
|
543 def getSslCertificateChain(self): |
|
544 """ |
|
545 Public method to get a reference to the SSL certificate chain. |
|
546 |
|
547 @return SSL certificate chain (list of QSslCertificate) |
|
548 """ |
|
549 if self.__sslConfiguration is None: |
|
550 return [] |
|
551 |
|
552 chain = self.__sslConfiguration.peerCertificateChain() |
|
553 return chain |
|
554 |
|
555 def getSslConfiguration(self): |
|
556 """ |
|
557 Public method to return a reference to the current SSL configuration. |
|
558 |
|
559 @return reference to the SSL configuration in use (QSslConfiguration) |
|
560 """ |
|
561 return self.__sslConfiguration |
|
562 |
|
563 def showSslInfo(self, pos): |
|
564 """ |
|
565 Public slot to show some SSL information for the loaded page. |
|
566 |
|
567 @param pos position to show the info at (QPoint) |
|
568 """ |
|
569 if SSL_AVAILABLE and self.__sslConfiguration is not None: |
|
570 from E5Network.E5SslInfoWidget import E5SslInfoWidget |
|
571 widget = E5SslInfoWidget( |
|
572 self.mainFrame().url(), self.__sslConfiguration, self.view()) |
|
573 widget.showAt(pos) |
|
574 else: |
|
575 E5MessageBox.warning( |
|
576 self.view(), |
|
577 self.tr("SSL Info"), |
|
578 self.tr("""This site does not contain SSL information.""")) |
|
579 |
|
580 def hasValidSslInfo(self): |
|
581 """ |
|
582 Public method to check, if the page has a valid SSL certificate. |
|
583 |
|
584 @return flag indicating a valid SSL certificate (boolean) |
|
585 """ |
|
586 if self.__sslConfiguration is None: |
|
587 return False |
|
588 |
|
589 certList = self.__sslConfiguration.peerCertificateChain() |
|
590 if not certList: |
|
591 return False |
|
592 |
|
593 certificateDict = Globals.toDict( |
|
594 Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) |
|
595 for server in certificateDict: |
|
596 localCAList = QSslCertificate.fromData(certificateDict[server]) |
|
597 for cert in certList: |
|
598 if cert in localCAList: |
|
599 return True |
|
600 |
|
601 if qVersion() >= "5.0.0": |
|
602 for cert in certList: |
|
603 if cert.isBlacklisted(): |
|
604 return False |
|
605 else: |
|
606 for cert in certList: |
|
607 if not cert.isValid(): |
|
608 return False |
|
609 |
|
610 return True |
|
611 |
|
612 @classmethod |
|
613 def webPluginFactory(cls): |
|
614 """ |
|
615 Class method to get a reference to the web plug-in factory |
|
616 instance. |
|
617 |
|
618 @return reference to the web plug-in factory instance (WebPluginFactory |
|
619 """ |
|
620 if cls._webPluginFactory is None: |
|
621 from .WebPlugins.WebPluginFactory import WebPluginFactory |
|
622 cls._webPluginFactory = WebPluginFactory() |
|
623 |
|
624 return cls._webPluginFactory |
|
625 |
|
626 def event(self, evt): |
|
627 """ |
|
628 Public method implementing the event handler. |
|
629 |
|
630 @param evt reference to the event (QEvent) |
|
631 @return flag indicating that the event was handled (boolean) |
|
632 """ |
|
633 if evt.type() == QEvent.Leave: |
|
634 # Fake a mouse move event just outside of the widget to trigger |
|
635 # the WebKit event handler's mouseMoved function. This implements |
|
636 # the interesting mouse-out behavior like invalidating scrollbars. |
|
637 fakeEvent = QMouseEvent(QEvent.MouseMove, QPoint(0, -1), |
|
638 Qt.NoButton, Qt.NoButton, Qt.NoModifier) |
|
639 return super(HelpWebPage, self).event(fakeEvent) |
|
640 |
|
641 return super(HelpWebPage, self).event(evt) |
|
642 |
|
643 def __saveFrameStateRequested(self, frame, itm): |
|
644 """ |
|
645 Private slot to save the page state (i.e. zoom level and scroll |
|
646 position). |
|
647 |
|
648 Note: Code is based on qutebrowser. |
|
649 |
|
650 @param frame frame to be saved |
|
651 @type QWebFrame |
|
652 @param itm web history item to be saved |
|
653 @type QWebHistoryItem |
|
654 """ |
|
655 try: |
|
656 if frame != self.mainFrame(): |
|
657 return |
|
658 except RuntimeError: |
|
659 # With Qt 5.2.1 (Ubuntu Trusty) we get this when closing a tab: |
|
660 # RuntimeError: wrapped C/C++ object of type BrowserPage has |
|
661 # been deleted |
|
662 # Since the information here isn't that important for closing web |
|
663 # views anyways, we ignore this error. |
|
664 return |
|
665 data = { |
|
666 'zoom': frame.zoomFactor(), |
|
667 'scrollPos': frame.scrollPosition(), |
|
668 } |
|
669 itm.setUserData(data) |
|
670 |
|
671 def __restoreFrameStateRequested(self, frame): |
|
672 """ |
|
673 Private slot to restore scroll position and zoom level from |
|
674 history. |
|
675 |
|
676 Note: Code is based on qutebrowser. |
|
677 |
|
678 @param frame frame to be restored |
|
679 @type QWebFrame |
|
680 """ |
|
681 if frame != self.mainFrame(): |
|
682 return |
|
683 |
|
684 data = self.history().currentItem().userData() |
|
685 if data is None: |
|
686 return |
|
687 |
|
688 if 'zoom' in data: |
|
689 frame.page().view().setZoomValue(int(data['zoom'] * 100), |
|
690 saveValue=False) |
|
691 |
|
692 if 'scrollPos' in data and frame.scrollPosition() == QPoint(0, 0): |
|
693 frame.setScrollPosition(data['scrollPos']) |
|
694 |
|
695 ############################################################################### |
|
696 |
|
697 |
|
698 class HelpBrowser(QWebView): |
|
699 """ |
|
700 Class implementing the helpbrowser widget. |
|
701 |
|
702 This is a subclass of the Qt QWebView to implement an |
|
703 interface compatible with the QTextBrowser based variant. |
|
704 |
158 |
705 @signal sourceChanged(QUrl) emitted after the current URL has changed |
159 @signal sourceChanged(QUrl) emitted after the current URL has changed |
706 @signal forwardAvailable(bool) emitted after the current URL has changed |
160 @signal forwardAvailable(bool) emitted after the current URL has changed |
707 @signal backwardAvailable(bool) emitted after the current URL has changed |
161 @signal backwardAvailable(bool) emitted after the current URL has changed |
708 @signal highlighted(str) emitted, when the mouse hovers over a link |
162 @signal highlighted(str) emitted, when the mouse hovers over a link |
715 highlighted = pyqtSignal(str) |
169 highlighted = pyqtSignal(str) |
716 search = pyqtSignal(QUrl) |
170 search = pyqtSignal(QUrl) |
717 zoomValueChanged = pyqtSignal(int) |
171 zoomValueChanged = pyqtSignal(int) |
718 |
172 |
719 ZoomLevels = [ |
173 ZoomLevels = [ |
720 30, 50, 67, 80, 90, |
174 30, 40, 50, 67, 80, 90, |
721 100, |
175 100, |
722 110, 120, 133, 150, 170, 200, 240, 300, |
176 110, 120, 133, 150, 170, 200, 220, 233, 250, 270, 285, 300, |
723 ] |
177 ] |
724 ZoomLevelDefault = 100 |
178 ZoomLevelDefault = 100 |
725 |
179 |
726 def __init__(self, mainWindow, parent=None, name=""): |
180 def __init__(self, mainWindow, parent=None, name=""): |
727 """ |
181 """ |
728 Constructor |
182 Constructor |
729 |
183 |
730 @param mainWindow reference to the main window (HelpWindow) |
184 @param mainWindow reference to the main window (WebBrowserWindow) |
731 @param parent parent widget of this window (QWidget) |
185 @param parent parent widget of this window (QWidget) |
732 @param name name of this window (string) |
186 @param name name of this window (string) |
733 """ |
187 """ |
734 super(HelpBrowser, self).__init__(parent) |
188 super(WebBrowserView, self).__init__(parent) |
735 self.setObjectName(name) |
189 self.setObjectName(name) |
736 self.setWhatsThis(self.tr( |
190 ## |
737 """<b>Help Window</b>""" |
191 ## import Helpviewer.HelpWindow |
738 """<p>This window displays the selected help information.</p>""" |
192 ## self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial() |
739 )) |
193 |
740 |
194 self.__page = WebBrowserPage(self) |
741 import Helpviewer.HelpWindow |
|
742 self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial() |
|
743 |
|
744 self.__page = HelpWebPage(self) |
|
745 self.setPage(self.__page) |
195 self.setPage(self.__page) |
746 |
196 |
747 self.mw = mainWindow |
197 self.__mw = mainWindow |
748 self.ctrlPressed = False |
198 self.__ctrlPressed = False |
749 self.__isLoading = False |
199 self.__isLoading = False |
750 self.__progress = 0 |
200 self.__progress = 0 |
751 |
201 |
752 self.__currentZoom = 100 |
202 self.__currentZoom = 100 |
753 self.__zoomLevels = HelpBrowser.ZoomLevels[:] |
203 self.__zoomLevels = WebBrowserView.ZoomLevels[:] |
754 |
204 ## |
755 self.__javaScriptBinding = None |
205 ## self.__javaScriptBinding = None |
756 self.__javaScriptEricObject = None |
206 ## self.__javaScriptEricObject = None |
757 |
207 |
758 self.mw.zoomTextOnlyChanged.connect(self.__applyZoom) |
208 ## self.__mw.zoomTextOnlyChanged.connect(self.__applyZoom) |
759 |
209 |
760 self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) |
210 ## self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) |
761 self.linkClicked.connect(self.setSource) |
211 ## self.linkClicked.connect(self.setSource) |
762 |
212 ## |
763 self.urlChanged.connect(self.__urlChanged) |
213 self.urlChanged.connect(self.__urlChanged) |
764 self.statusBarMessage.connect(self.__statusBarMessage) |
214 ## self.statusBarMessage.connect(self.__statusBarMessage) |
765 self.page().linkHovered.connect(self.__linkHovered) |
215 self.page().linkHovered.connect(self.__linkHovered) |
766 |
216 |
767 self.loadStarted.connect(self.__loadStarted) |
217 self.loadStarted.connect(self.__loadStarted) |
768 self.loadProgress.connect(self.__loadProgress) |
218 self.loadProgress.connect(self.__loadProgress) |
769 self.loadFinished.connect(self.__loadFinished) |
219 self.loadFinished.connect(self.__loadFinished) |
770 |
220 |
771 self.page().setForwardUnsupportedContent(True) |
221 ## self.page().setForwardUnsupportedContent(True) |
772 self.page().unsupportedContent.connect(self.__unsupportedContent) |
222 ## self.page().unsupportedContent.connect(self.__unsupportedContent) |
773 |
223 |
774 self.page().featurePermissionRequested.connect( |
224 # TODO: this was moved to QWebEngineProfile |
775 self.__featurePermissionRequested) |
225 ## self.page().downloadRequested.connect(self.__downloadRequested) |
776 |
226 ## self.page().frameCreated.connect(self.__addExternalBinding) |
777 self.page().downloadRequested.connect(self.__downloadRequested) |
227 ## self.__addExternalBinding(self.page().mainFrame()) |
778 self.page().frameCreated.connect(self.__addExternalBinding) |
228 |
779 self.__addExternalBinding(self.page().mainFrame()) |
229 ## self.page().databaseQuotaExceeded.connect(self.__databaseQuotaExceeded) |
780 |
230 |
781 self.page().databaseQuotaExceeded.connect(self.__databaseQuotaExceeded) |
231 # TODO: re-enable onece Open Search is done |
782 |
232 ## self.__mw.openSearchManager().currentEngineChanged.connect( |
783 self.mw.openSearchManager().currentEngineChanged.connect( |
233 ## self.__currentEngineChanged) |
784 self.__currentEngineChanged) |
|
785 |
234 |
786 self.setAcceptDrops(True) |
235 self.setAcceptDrops(True) |
787 |
236 |
788 self.__enableAccessKeys = Preferences.getHelp("AccessKeysEnabled") |
237 # TODO: re-enable for Access Keys |
789 self.__accessKeysPressed = False |
238 ## self.__enableAccessKeys = Preferences.getHelp("AccessKeysEnabled") |
790 self.__accessKeyLabels = [] |
239 ## self.__accessKeysPressed = False |
791 self.__accessKeyNodes = {} |
240 ## self.__accessKeyLabels = [] |
792 |
241 ## self.__accessKeyNodes = {} |
793 self.page().loadStarted.connect(self.__hideAccessKeys) |
242 ## |
794 self.page().scrollRequested.connect(self.__hideAccessKeys) |
243 ## self.page().loadStarted.connect(self.__hideAccessKeys) |
|
244 ## self.page().scrollRequested.connect(self.__hideAccessKeys) |
795 |
245 |
796 self.__rss = [] |
246 self.__rss = [] |
797 |
247 |
798 self.__clickedFrame = None |
248 self.__clickedFrame = None |
799 |
249 |
800 self.mw.personalInformationManager().connectPage(self.page()) |
250 # TODO: re-enable once done |
801 self.mw.greaseMonkeyManager().connectPage(self.page()) |
251 ## self.__mw.personalInformationManager().connectPage(self.page()) |
802 |
252 ## self.__mw.greaseMonkeyManager().connectPage(self.page()) |
803 self.__inspector = None |
253 ## |
|
254 ## self.__inspector = None |
804 |
255 |
805 self.grabGesture(Qt.PinchGesture) |
256 self.grabGesture(Qt.PinchGesture) |
806 |
257 |
807 def __addExternalBinding(self, frame=None): |
258 ## def __addExternalBinding(self, frame=None): |
808 """ |
259 ## """ |
809 Private slot to add javascript bindings for adding search providers. |
260 ## Private slot to add javascript bindings for adding search providers. |
810 |
261 ## |
811 @param frame reference to the web frame (QWebFrame) |
262 ## @param frame reference to the web frame (QWebFrame) |
812 """ |
263 ## """ |
813 self.page().settings().setAttribute(QWebSettings.JavascriptEnabled, |
264 ## self.page().settings().setAttribute(QWebSettings.JavascriptEnabled, |
814 True) |
265 ## True) |
815 if self.__javaScriptBinding is None: |
266 ## if self.__javaScriptBinding is None: |
816 self.__javaScriptBinding = JavaScriptExternalObject(self.mw, self) |
267 ## self.__javaScriptBinding = JavaScriptExternalObject(self.__mw, self) |
817 |
268 ## |
818 if frame is None: |
269 ## if frame is None: |
819 # called from QWebFrame.javaScriptWindowObjectCleared |
270 ## # called from QWebFrame.javaScriptWindowObjectCleared |
820 frame = self.sender() |
271 ## frame = self.sender() |
821 if isinstance(frame, HelpWebPage): |
272 ## if isinstance(frame, HelpWebPage): |
822 frame = frame.mainFrame() |
273 ## frame = frame.mainFrame() |
823 if frame.url().scheme() == "eric" and frame.url().path() == "home": |
274 ## if frame.url().scheme() == "eric" and frame.url().path() == "home": |
824 if self.__javaScriptEricObject is None: |
275 ## if self.__javaScriptEricObject is None: |
825 self.__javaScriptEricObject = JavaScriptEricObject( |
276 ## self.__javaScriptEricObject = JavaScriptEricObject( |
826 self.mw, self) |
277 ## self.__mw, self) |
827 frame.addToJavaScriptWindowObject( |
278 ## frame.addToJavaScriptWindowObject( |
828 "eric", self.__javaScriptEricObject) |
279 ## "eric", self.__javaScriptEricObject) |
829 elif frame.url().scheme() == "eric" and \ |
280 ## elif frame.url().scheme() == "eric" and \ |
830 frame.url().path() == "speeddial": |
281 ## frame.url().path() == "speeddial": |
831 frame.addToJavaScriptWindowObject( |
282 ## frame.addToJavaScriptWindowObject( |
832 "speeddial", self.__speedDial) |
283 ## "speeddial", self.__speedDial) |
833 self.__speedDial.addWebFrame(frame) |
284 ## self.__speedDial.addWebFrame(frame) |
834 else: |
285 ## else: |
835 # called from QWebPage.frameCreated |
286 ## # called from QWebPage.frameCreated |
836 frame.javaScriptWindowObjectCleared.connect( |
287 ## frame.javaScriptWindowObjectCleared.connect( |
837 self.__addExternalBinding) |
288 ## self.__addExternalBinding) |
838 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding) |
289 ## frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding) |
839 |
290 ## |
840 def linkedResources(self, relation=""): |
291 ## def linkedResources(self, relation=""): |
841 """ |
292 ## """ |
842 Public method to extract linked resources. |
293 ## Public method to extract linked resources. |
843 |
294 ## |
844 @param relation relation to extract (string) |
295 ## @param relation relation to extract (string) |
845 @return list of linked resources (list of LinkedResource) |
296 ## @return list of linked resources (list of LinkedResource) |
846 """ |
297 ## """ |
847 resources = [] |
298 ## resources = [] |
848 |
299 ## |
849 baseUrl = self.page().mainFrame().baseUrl() |
300 ## baseUrl = self.page().mainFrame().baseUrl() |
850 |
301 ## |
851 linkElements = self.page().mainFrame().findAllElements( |
302 ## linkElements = self.page().mainFrame().findAllElements( |
852 "html > head > link") |
303 ## "html > head > link") |
853 |
304 ## |
854 for linkElement in linkElements.toList(): |
305 ## for linkElement in linkElements.toList(): |
855 rel = linkElement.attribute("rel") |
306 ## rel = linkElement.attribute("rel") |
856 href = linkElement.attribute("href") |
307 ## href = linkElement.attribute("href") |
857 type_ = linkElement.attribute("type") |
308 ## type_ = linkElement.attribute("type") |
858 title = linkElement.attribute("title") |
309 ## title = linkElement.attribute("title") |
859 |
310 ## |
860 if href == "" or type_ == "": |
311 ## if href == "" or type_ == "": |
861 continue |
312 ## continue |
862 if relation and rel != relation: |
313 ## if relation and rel != relation: |
863 continue |
314 ## continue |
864 |
315 ## |
865 resource = LinkedResource() |
316 ## resource = LinkedResource() |
866 resource.rel = rel |
317 ## resource.rel = rel |
867 resource.type_ = type_ |
318 ## resource.type_ = type_ |
868 resource.href = baseUrl.resolved( |
319 ## resource.href = baseUrl.resolved( |
869 QUrl.fromEncoded(href.encode("utf-8"))) |
320 ## QUrl.fromEncoded(href.encode("utf-8"))) |
870 resource.title = title |
321 ## resource.title = title |
871 |
322 ## |
872 resources.append(resource) |
323 ## resources.append(resource) |
873 |
324 ## |
874 return resources |
325 ## return resources |
875 |
326 ## |
876 def __currentEngineChanged(self): |
327 ## def __currentEngineChanged(self): |
877 """ |
328 ## """ |
878 Private slot to track a change of the current search engine. |
329 ## Private slot to track a change of the current search engine. |
879 """ |
330 ## """ |
880 if self.url().toString() == "eric:home": |
331 ## if self.url().toString() == "eric:home": |
881 self.reload() |
332 ## self.reload() |
882 |
333 |
|
334 # TODO: eliminate requestData |
883 def setSource(self, name, requestData=None): |
335 def setSource(self, name, requestData=None): |
884 """ |
336 """ |
885 Public method used to set the source to be displayed. |
337 Public method used to set the source to be displayed. |
886 |
338 |
887 @param name filename to be shown (QUrl) |
339 @param name filename to be shown (QUrl) |
888 @param requestData tuple containing the request data (QNetworkRequest, |
340 @param requestData tuple containing the request data (QNetworkRequest, |
889 QNetworkAccessManager.Operation, QByteArray) |
341 QNetworkAccessManager.Operation, QByteArray) |
890 """ |
342 """ |
891 if (name is None or not name.isValid()) and requestData is None: |
343 ## if (name is None or not name.isValid()) and requestData is None: |
|
344 if name is None or not name.isValid(): |
892 return |
345 return |
893 |
346 |
894 if name is None and requestData is not None: |
347 ## if name is None and requestData is not None: |
895 name = requestData[0].url() |
348 ## name = requestData[0].url() |
896 |
349 ## |
897 if self.ctrlPressed: |
350 if self.__ctrlPressed: |
898 # open in a new window |
351 # open in a new window |
899 self.mw.newTab(name) |
352 self.__mw.newTab(name) |
900 self.ctrlPressed = False |
353 self.__ctrlPressed = False |
901 return |
354 return |
902 |
355 |
903 if not name.scheme(): |
356 if not name.scheme(): |
904 name.setUrl(Preferences.getHelp("DefaultScheme") + name.toString()) |
357 name.setUrl(Preferences.getWebBrowser("DefaultScheme") + |
905 |
358 name.toString()) |
|
359 |
|
360 # TODO: move some of this to web page |
906 if len(name.scheme()) == 1 or \ |
361 if len(name.scheme()) == 1 or \ |
907 name.scheme() == "file": |
362 name.scheme() == "file": |
908 # name is a local file |
363 # name is a local file |
909 if name.scheme() and len(name.scheme()) == 1: |
364 if name.scheme() and len(name.scheme()) == 1: |
910 # it is a local path on win os |
365 # it is a local path on win os |
2036 """ |
1487 """ |
2037 url = self.url() |
1488 url = self.url() |
2038 if url.isEmpty(): |
1489 if url.isEmpty(): |
2039 return |
1490 return |
2040 |
1491 |
2041 self.mw.downloadManager().download(url, True, mainWindow=self.mw) |
1492 self.__mw.downloadManager().download(url, True, mainWindow=self.__mw) |
2042 |
1493 |
2043 def __unsupportedContent(self, reply, requestFilename=None, |
1494 ## def __unsupportedContent(self, reply, requestFilename=None, |
2044 download=False): |
1495 ## download=False): |
2045 """ |
1496 ## """ |
2046 Private slot to handle the unsupportedContent signal. |
1497 ## Private slot to handle the unsupportedContent signal. |
2047 |
1498 ## |
2048 @param reply reference to the reply object (QNetworkReply) |
1499 ## @param reply reference to the reply object (QNetworkReply) |
2049 @keyparam requestFilename indicating to ask for a filename |
1500 ## @keyparam requestFilename indicating to ask for a filename |
2050 (boolean or None). If it is None, the behavior is determined |
1501 ## (boolean or None). If it is None, the behavior is determined |
2051 by a configuration option. |
1502 ## by a configuration option. |
2052 @keyparam download flag indicating a download operation (boolean) |
1503 ## @keyparam download flag indicating a download operation (boolean) |
2053 """ |
1504 ## """ |
2054 if reply is None: |
1505 ## if reply is None: |
2055 return |
1506 ## return |
2056 |
1507 ## |
2057 replyUrl = reply.url() |
1508 ## replyUrl = reply.url() |
2058 |
1509 ## |
2059 if replyUrl.scheme() == "abp": |
1510 ## if replyUrl.scheme() == "abp": |
2060 return |
1511 ## return |
2061 |
1512 ## |
2062 if reply.error() == QNetworkReply.NoError: |
1513 ## if reply.error() == QNetworkReply.NoError: |
2063 if reply.header(QNetworkRequest.ContentTypeHeader): |
1514 ## if reply.header(QNetworkRequest.ContentTypeHeader): |
2064 self.mw.downloadManager().handleUnsupportedContent( |
1515 ## self.__mw.downloadManager().handleUnsupportedContent( |
2065 reply, webPage=self.page(), mainWindow=self.mw) |
1516 ## reply, webPage=self.page(), mainWindow=self.__mw) |
2066 return |
1517 ## return |
2067 |
1518 ## |
2068 replyUrl = reply.url() |
1519 ## replyUrl = reply.url() |
2069 if replyUrl.isEmpty(): |
1520 ## if replyUrl.isEmpty(): |
2070 return |
1521 ## return |
2071 |
1522 ## |
2072 notFoundFrame = self.page().mainFrame() |
1523 ## notFoundFrame = self.page().mainFrame() |
2073 if notFoundFrame is None: |
1524 ## if notFoundFrame is None: |
2074 return |
1525 ## return |
2075 |
1526 ## |
2076 if reply.header(QNetworkRequest.ContentTypeHeader): |
1527 ## if reply.header(QNetworkRequest.ContentTypeHeader): |
2077 data = reply.readAll() |
1528 ## data = reply.readAll() |
2078 if contentSniff(data): |
1529 ## if contentSniff(data): |
2079 notFoundFrame.setHtml(str(data, encoding="utf-8"), replyUrl) |
1530 ## notFoundFrame.setHtml(str(data, encoding="utf-8"), replyUrl) |
2080 return |
1531 ## return |
2081 |
1532 ## |
2082 urlString = bytes(replyUrl.toEncoded()).decode() |
1533 ## urlString = bytes(replyUrl.toEncoded()).decode() |
2083 title = self.tr("Error loading page: {0}").format(urlString) |
1534 ## title = self.tr("Error loading page: {0}").format(urlString) |
2084 htmlFile = QFile(":/html/notFoundPage.html") |
1535 ## htmlFile = QFile(":/html/notFoundPage.html") |
2085 htmlFile.open(QFile.ReadOnly) |
1536 ## htmlFile.open(QFile.ReadOnly) |
2086 html = htmlFile.readAll() |
1537 ## html = htmlFile.readAll() |
2087 pixmap = qApp.style()\ |
1538 ## pixmap = qApp.style()\ |
2088 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48) |
1539 ## .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48) |
2089 imageBuffer = QBuffer() |
1540 ## imageBuffer = QBuffer() |
2090 imageBuffer.open(QIODevice.ReadWrite) |
1541 ## imageBuffer.open(QIODevice.ReadWrite) |
2091 if pixmap.save(imageBuffer, "PNG"): |
1542 ## if pixmap.save(imageBuffer, "PNG"): |
2092 html = html.replace("@IMAGE@", imageBuffer.buffer().toBase64()) |
1543 ## html = html.replace("@IMAGE@", imageBuffer.buffer().toBase64()) |
2093 pixmap = qApp.style()\ |
1544 ## pixmap = qApp.style()\ |
2094 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16) |
1545 ## .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16) |
2095 imageBuffer = QBuffer() |
1546 ## imageBuffer = QBuffer() |
2096 imageBuffer.open(QIODevice.ReadWrite) |
1547 ## imageBuffer.open(QIODevice.ReadWrite) |
2097 if pixmap.save(imageBuffer, "PNG"): |
1548 ## if pixmap.save(imageBuffer, "PNG"): |
2098 html = html.replace("@FAVICON@", imageBuffer.buffer().toBase64()) |
1549 ## html = html.replace("@FAVICON@", imageBuffer.buffer().toBase64()) |
2099 html = html.replace("@TITLE@", title.encode("utf8")) |
1550 ## html = html.replace("@TITLE@", title.encode("utf8")) |
2100 html = html.replace("@H1@", reply.errorString().encode("utf8")) |
1551 ## html = html.replace("@H1@", reply.errorString().encode("utf8")) |
2101 html = html.replace( |
1552 ## html = html.replace( |
2102 "@H2@", self.tr("When connecting to: {0}.") |
1553 ## "@H2@", self.tr("When connecting to: {0}.") |
2103 .format(urlString).encode("utf8")) |
1554 ## .format(urlString).encode("utf8")) |
2104 html = html.replace( |
1555 ## html = html.replace( |
2105 "@LI-1@", |
1556 ## "@LI-1@", |
2106 self.tr("Check the address for errors such as " |
1557 ## self.tr("Check the address for errors such as " |
2107 "<b>ww</b>.example.org instead of " |
1558 ## "<b>ww</b>.example.org instead of " |
2108 "<b>www</b>.example.org").encode("utf8")) |
1559 ## "<b>www</b>.example.org").encode("utf8")) |
2109 html = html.replace( |
1560 ## html = html.replace( |
2110 "@LI-2@", |
1561 ## "@LI-2@", |
2111 self.tr("If the address is correct, try checking the network " |
1562 ## self.tr("If the address is correct, try checking the network " |
2112 "connection.").encode("utf8")) |
1563 ## "connection.").encode("utf8")) |
2113 html = html.replace( |
1564 ## html = html.replace( |
2114 "@LI-3@", |
1565 ## "@LI-3@", |
2115 self.tr( |
1566 ## self.tr( |
2116 "If your computer or network is protected by a firewall " |
1567 ## "If your computer or network is protected by a firewall " |
2117 "or proxy, make sure that the browser is permitted to " |
1568 ## "or proxy, make sure that the browser is permitted to " |
2118 "access the network.").encode("utf8")) |
1569 ## "access the network.").encode("utf8")) |
2119 html = html.replace( |
1570 ## html = html.replace( |
2120 "@LI-4@", |
1571 ## "@LI-4@", |
2121 self.tr("If your cache policy is set to offline browsing," |
1572 ## self.tr("If your cache policy is set to offline browsing," |
2122 "only pages in the local cache are available.") |
1573 ## "only pages in the local cache are available.") |
2123 .encode("utf8")) |
1574 ## .encode("utf8")) |
2124 html = html.replace( |
1575 ## html = html.replace( |
2125 "@BUTTON@", self.tr("Try Again").encode("utf8")) |
1576 ## "@BUTTON@", self.tr("Try Again").encode("utf8")) |
2126 notFoundFrame.setHtml(bytes(html).decode("utf8"), replyUrl) |
1577 ## notFoundFrame.setHtml(bytes(html).decode("utf8"), replyUrl) |
2127 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title()) |
1578 ## self.__mw.historyManager().removeHistoryEntry(replyUrl, self.title()) |
2128 self.loadFinished.emit(False) |
1579 ## self.loadFinished.emit(False) |
2129 |
1580 ## |
2130 def __featurePermissionRequested(self, frame, feature): |
|
2131 """ |
|
2132 Private slot handling a feature permission request. |
|
2133 |
|
2134 @param frame frame sending the request |
|
2135 @type QWebFrame |
|
2136 @param feature requested feature |
|
2137 @type QWebPage.Feature |
|
2138 """ |
|
2139 manager = Helpviewer.HelpWindow.HelpWindow.featurePermissionManager() |
|
2140 manager.requestFeaturePermission(self.page(), frame, feature) |
|
2141 |
1581 |
2142 def __downloadRequested(self, request): |
1582 def __downloadRequested(self, request): |
2143 """ |
1583 """ |
2144 Private slot to handle a download request. |
1584 Private slot to handle a download request. |
2145 |
1585 |
2146 @param request reference to the request object (QNetworkRequest) |
1586 @param request reference to the request object (QNetworkRequest) |
2147 """ |
1587 """ |
2148 self.mw.downloadManager().download(request, mainWindow=self.mw) |
1588 self.__mw.downloadManager().download(request, mainWindow=self.__mw) |
2149 |
1589 |
2150 def __databaseQuotaExceeded(self, frame, databaseName): |
1590 def __databaseQuotaExceeded(self, frame, databaseName): |
2151 """ |
1591 """ |
2152 Private slot to handle the case, where the database quota is exceeded. |
1592 Private slot to handle the case, where the database quota is exceeded. |
2153 |
1593 |