38 from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction |
38 from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction |
39 from .OpenSearch.OpenSearchEngine import OpenSearchEngine |
39 from .OpenSearch.OpenSearchEngine import OpenSearchEngine |
40 |
40 |
41 ########################################################################################## |
41 ########################################################################################## |
42 |
42 |
|
43 |
43 class JavaScriptExternalObject(QObject): |
44 class JavaScriptExternalObject(QObject): |
44 """ |
45 """ |
45 Class implementing an external javascript object to add search providers. |
46 Class implementing an external javascript object to add search providers. |
46 """ |
47 """ |
47 def __init__(self, mw, parent = None): |
48 def __init__(self, mw, parent=None): |
48 """ |
49 """ |
49 Constructor |
50 Constructor |
50 |
51 |
51 @param mw reference to the main window 8HelpWindow) |
52 @param mw reference to the main window 8HelpWindow) |
52 @param parent reference to the parent object (QObject) |
53 @param parent reference to the parent object (QObject) |
76 self.type_ = "" |
78 self.type_ = "" |
77 self.href = "" |
79 self.href = "" |
78 self.title = "" |
80 self.title = "" |
79 |
81 |
80 ########################################################################################## |
82 ########################################################################################## |
|
83 |
81 |
84 |
82 class JavaScriptEricObject(QObject): |
85 class JavaScriptEricObject(QObject): |
83 """ |
86 """ |
84 Class implementing an external javascript object to search via the startpage. |
87 Class implementing an external javascript object to search via the startpage. |
85 """ |
88 """ |
86 # these must be in line with the strings used by the javascript part of the start page |
89 # these must be in line with the strings used by the javascript part of the start page |
87 translations = [ |
90 translations = [ |
88 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Welcome to Eric Web Browser!"), |
91 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Welcome to Eric Web Browser!"), |
89 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Eric Web Browser"), |
92 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Eric Web Browser"), |
90 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), |
93 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), |
91 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About Eric"), |
94 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About Eric"), |
92 ] |
95 ] |
93 |
96 |
94 def __init__(self, mw, parent = None): |
97 def __init__(self, mw, parent=None): |
95 """ |
98 """ |
96 Constructor |
99 Constructor |
97 |
100 |
98 @param mw reference to the main window 8HelpWindow) |
101 @param mw reference to the main window 8HelpWindow) |
99 @param parent reference to the parent object (QObject) |
102 @param parent reference to the parent object (QObject) |
100 """ |
103 """ |
101 QObject.__init__(self, parent) |
104 QObject.__init__(self, parent) |
102 |
105 |
103 self.__mw = mw |
106 self.__mw = mw |
104 |
107 |
105 @pyqtSlot(str, result = str) |
108 @pyqtSlot(str, result=str) |
106 def translate(self, trans): |
109 def translate(self, trans): |
107 """ |
110 """ |
108 Public method to translate the given string. |
111 Public method to translate the given string. |
109 |
112 |
110 @param trans string to be translated (string) |
113 @param trans string to be translated (string) |
117 else: |
120 else: |
118 return "RTL" |
121 return "RTL" |
119 |
122 |
120 return self.trUtf8(trans) |
123 return self.trUtf8(trans) |
121 |
124 |
122 @pyqtSlot(result = str) |
125 @pyqtSlot(result=str) |
123 def providerString(self): |
126 def providerString(self): |
124 """ |
127 """ |
125 Public method to get a string for the search provider. |
128 Public method to get a string for the search provider. |
126 |
129 |
127 @return string for the search provider (string) |
130 @return string for the search provider (string) |
128 """ |
131 """ |
129 return self.trUtf8("Search results provided by {0}")\ |
132 return self.trUtf8("Search results provided by {0}")\ |
130 .format(self.__mw.openSearchManager().currentEngineName()) |
133 .format(self.__mw.openSearchManager().currentEngineName()) |
131 |
134 |
132 @pyqtSlot(str, result = str) |
135 @pyqtSlot(str, result=str) |
133 def searchUrl(self, searchStr): |
136 def searchUrl(self, searchStr): |
134 """ |
137 """ |
135 Public method to get the search URL for the given search term. |
138 Public method to get the search URL for the given search term. |
136 |
139 |
137 @param searchStr search term (string) |
140 @param searchStr search term (string) |
140 return bytes( |
143 return bytes( |
141 self.__mw.openSearchManager().currentEngine()\ |
144 self.__mw.openSearchManager().currentEngine()\ |
142 .searchUrl(searchStr).toEncoded()).decode() |
145 .searchUrl(searchStr).toEncoded()).decode() |
143 |
146 |
144 ########################################################################################## |
147 ########################################################################################## |
|
148 |
145 |
149 |
146 class HelpWebPage(QWebPage): |
150 class HelpWebPage(QWebPage): |
147 """ |
151 """ |
148 Class implementing an enhanced web page. |
152 Class implementing an enhanced web page. |
149 """ |
153 """ |
150 def __init__(self, parent = None): |
154 def __init__(self, parent=None): |
151 """ |
155 """ |
152 Constructor |
156 Constructor |
153 |
157 |
154 @param parent parent widget of this window (QWidget) |
158 @param parent parent widget of this window (QWidget) |
155 """ |
159 """ |
190 self.trUtf8("""In order to display the site, the request along with""" |
194 self.trUtf8("""In order to display the site, the request along with""" |
191 """ all the data must be sent once again, which may lead""" |
195 """ all the data must be sent once again, which may lead""" |
192 """ to some unexpected behaviour of the site e.g. the""" |
196 """ to some unexpected behaviour of the site e.g. the""" |
193 """ same action might be performed once again. Do you want""" |
197 """ same action might be performed once again. Do you want""" |
194 """ to continue anyway?"""), |
198 """ to continue anyway?"""), |
195 icon = E5MessageBox.Warning) |
199 icon=E5MessageBox.Warning) |
196 if not res: |
200 if not res: |
197 return False |
201 return False |
198 |
202 |
199 return QWebPage.acceptNavigationRequest(self, frame, request, type_) |
203 return QWebPage.acceptNavigationRequest(self, frame, request, type_) |
200 |
204 |
254 .standardIcon(QStyle.SP_MessageBoxWarning, None, self.parent())\ |
258 .standardIcon(QStyle.SP_MessageBoxWarning, None, self.parent())\ |
255 .pixmap(32, 32) |
259 .pixmap(32, 32) |
256 imageBuffer = QBuffer() |
260 imageBuffer = QBuffer() |
257 imageBuffer.open(QIODevice.ReadWrite) |
261 imageBuffer.open(QIODevice.ReadWrite) |
258 if pixmap.save(imageBuffer, "PNG"): |
262 if pixmap.save(imageBuffer, "PNG"): |
259 html = html.replace("IMAGE_BINARY_DATA_HERE", |
263 html = html.replace("IMAGE_BINARY_DATA_HERE", |
260 str(imageBuffer.buffer().toBase64(), encoding="ascii")) |
264 str(imageBuffer.buffer().toBase64(), encoding="ascii")) |
261 errorPage.content = QByteArray(html.format( |
265 errorPage.content = QByteArray(html.format( |
262 title, |
266 title, |
263 info.errorString, |
267 info.errorString, |
264 self.trUtf8("When connecting to: {0}.").format(urlString), |
268 self.trUtf8("When connecting to: {0}.").format(urlString), |
265 self.trUtf8("Check the address for errors such as " |
269 self.trUtf8("Check the address for errors such as " |
266 "<b>ww</b>.example.org instead of " |
270 "<b>ww</b>.example.org instead of " |
267 "<b>www</b>.example.org"), |
271 "<b>www</b>.example.org"), |
268 self.trUtf8("If the address is correct, try checking the network " |
272 self.trUtf8("If the address is correct, try checking the network " |
269 "connection."), |
273 "connection."), |
270 self.trUtf8("If your computer or network is protected by a firewall " |
274 self.trUtf8("If your computer or network is protected by a firewall " |
271 "or proxy, make sure that the browser is permitted to " |
275 "or proxy, make sure that the browser is permitted to " |
272 "access the network."), |
276 "access the network."), |
273 self.trUtf8("If your cache policy is set to offline browsing," |
277 self.trUtf8("If your cache policy is set to offline browsing," |
274 "only pages in the local cache are available.") |
278 "only pages in the local cache are available.") |
275 ).encode("utf8")) |
279 ).encode("utf8")) |
276 return True |
280 return True |
277 except AttributeError: |
281 except AttributeError: |
278 pass |
282 pass |
279 |
283 |
280 return QWebPage.extension(self, extension, option, output) |
284 return QWebPage.extension(self, extension, option, output) |
281 |
285 |
282 def userAgent(self, resolveEmpty = False): |
286 def userAgent(self, resolveEmpty=False): |
283 """ |
287 """ |
284 Public method to get the current user agent setting. |
288 Public method to get the current user agent setting. |
285 |
289 |
286 @param resolveEmpty flag indicating to resolve an empty |
290 @param resolveEmpty flag indicating to resolve an empty |
287 user agent (boolean) |
291 user agent (boolean) |
288 @return user agent string (string) |
292 @return user agent string (string) |
289 """ |
293 """ |
290 agent = Preferences.getHelp("UserAgent") |
294 agent = Preferences.getHelp("UserAgent") |
291 if agent == "" and resolveEmpty: |
295 if agent == "" and resolveEmpty: |
354 """ |
358 """ |
355 if SSL_AVAILABLE and self.__sslInfo is not None: |
359 if SSL_AVAILABLE and self.__sslInfo is not None: |
356 dlg = SslInfoDialog(self.__sslInfo, self.view()) |
360 dlg = SslInfoDialog(self.__sslInfo, self.view()) |
357 dlg.exec_() |
361 dlg.exec_() |
358 else: |
362 else: |
359 E5MessageBox.warning(self.view(), |
363 E5MessageBox.warning(self.view(), |
360 self.trUtf8("SSL Certificate Info"), |
364 self.trUtf8("SSL Certificate Info"), |
361 self.trUtf8("""There is no SSL Certificate Info available.""")) |
365 self.trUtf8("""There is no SSL Certificate Info available.""")) |
362 |
366 |
363 ########################################################################################## |
367 ########################################################################################## |
|
368 |
364 |
369 |
365 class HelpBrowser(QWebView): |
370 class HelpBrowser(QWebView): |
366 """ |
371 """ |
367 Class implementing the helpbrowser widget. |
372 Class implementing the helpbrowser widget. |
368 |
373 |
379 forwardAvailable = pyqtSignal(bool) |
384 forwardAvailable = pyqtSignal(bool) |
380 backwardAvailable = pyqtSignal(bool) |
385 backwardAvailable = pyqtSignal(bool) |
381 highlighted = pyqtSignal(str) |
386 highlighted = pyqtSignal(str) |
382 search = pyqtSignal(QUrl) |
387 search = pyqtSignal(QUrl) |
383 |
388 |
384 def __init__(self, mainWindow, parent = None, name = ""): |
389 def __init__(self, mainWindow, parent=None, name=""): |
385 """ |
390 """ |
386 Constructor |
391 Constructor |
387 |
392 |
388 @param mainWindow reference to the main window (HelpWindow) |
393 @param mainWindow reference to the main window (HelpWindow) |
389 @param parent parent widget of this window (QWidget) |
394 @param parent parent widget of this window (QWidget) |
404 self.__isLoading = False |
409 self.__isLoading = False |
405 self.__progress = 0 |
410 self.__progress = 0 |
406 |
411 |
407 self.__currentZoom = 100 |
412 self.__currentZoom = 100 |
408 self.__zoomLevels = [ |
413 self.__zoomLevels = [ |
409 30, 50, 67, 80, 90, |
414 30, 50, 67, 80, 90, |
410 100, |
415 100, |
411 110, 120, 133, 150, 170, 200, 240, 300, |
416 110, 120, 133, 150, 170, 200, 240, 300, |
412 ] |
417 ] |
413 |
418 |
414 self.__javaScriptBinding = None |
419 self.__javaScriptBinding = None |
415 self.__javaScriptEricObject = None |
420 self.__javaScriptEricObject = None |
416 |
421 |
437 self.page().databaseQuotaExceeded.connect(self.__databaseQuotaExceeded) |
442 self.page().databaseQuotaExceeded.connect(self.__databaseQuotaExceeded) |
438 |
443 |
439 self.mw.openSearchManager().currentEngineChanged.connect( |
444 self.mw.openSearchManager().currentEngineChanged.connect( |
440 self.__currentEngineChanged) |
445 self.__currentEngineChanged) |
441 |
446 |
442 def __addExternalBinding(self, frame = None): |
447 def __addExternalBinding(self, frame=None): |
443 """ |
448 """ |
444 Private slot to add javascript bindings for adding search providers. |
449 Private slot to add javascript bindings for adding search providers. |
445 |
450 |
446 @param frame reference to the web frame (QWebFrame) |
451 @param frame reference to the web frame (QWebFrame) |
447 """ |
452 """ |
465 else: |
470 else: |
466 # called from QWebPage.frameCreated |
471 # called from QWebPage.frameCreated |
467 frame.javaScriptWindowObjectCleared.connect(self.__addExternalBinding) |
472 frame.javaScriptWindowObjectCleared.connect(self.__addExternalBinding) |
468 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding) |
473 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding) |
469 |
474 |
470 def linkedResources(self, relation = ""): |
475 def linkedResources(self, relation=""): |
471 """ |
476 """ |
472 Public method to extract linked resources. |
477 Public method to extract linked resources. |
473 |
478 |
474 @param relation relation to extract (string) |
479 @param relation relation to extract (string) |
475 @return list of linked resources (list of LinkedResource) |
480 @return list of linked resources (list of LinkedResource) |
790 menu.addAction(self.trUtf8("Copy Link to Clipboard"), self.__copyLink) |
795 menu.addAction(self.trUtf8("Copy Link to Clipboard"), self.__copyLink) |
791 |
796 |
792 if not hit.imageUrl().isEmpty(): |
797 if not hit.imageUrl().isEmpty(): |
793 if not menu.isEmpty(): |
798 if not menu.isEmpty(): |
794 menu.addSeparator() |
799 menu.addSeparator() |
795 act = menu.addAction(self.trUtf8("Open Image in New Tab"), |
800 act = menu.addAction(self.trUtf8("Open Image in New Tab"), |
796 self.__openLinkInNewTab) |
801 self.__openLinkInNewTab) |
797 act.setData(hit.imageUrl()) |
802 act.setData(hit.imageUrl()) |
798 menu.addSeparator() |
803 menu.addSeparator() |
799 menu.addAction(self.trUtf8("Save Image"), self.__downloadImage) |
804 menu.addAction(self.trUtf8("Save Image"), self.__downloadImage) |
800 menu.addAction(self.trUtf8("Copy Image to Clipboard"), self.__copyImage) |
805 menu.addAction(self.trUtf8("Copy Image to Clipboard"), self.__copyImage) |
801 act = menu.addAction(self.trUtf8("Copy Image Location to Clipboard"), |
806 act = menu.addAction(self.trUtf8("Copy Image Location to Clipboard"), |
802 self.__copyImageLocation) |
807 self.__copyImageLocation) |
803 act.setData(hit.imageUrl().toString()) |
808 act.setData(hit.imageUrl().toString()) |
804 menu.addSeparator() |
809 menu.addSeparator() |
805 act = menu.addAction(self.trUtf8("Block Image"), self.__blockImage) |
810 act = menu.addAction(self.trUtf8("Block Image"), self.__blockImage) |
806 act.setData(hit.imageUrl().toString()) |
811 act.setData(hit.imageUrl().toString()) |
841 if hasattr(QtWebKit, 'QWebElement'): |
846 if hasattr(QtWebKit, 'QWebElement'): |
842 element = hit.element() |
847 element = hit.element() |
843 if not element.isNull() and \ |
848 if not element.isNull() and \ |
844 element.tagName().lower() == "input" and \ |
849 element.tagName().lower() == "input" and \ |
845 element.attribute("type", "text") == "text": |
850 element.attribute("type", "text") == "text": |
846 act = menu.addAction(self.trUtf8("Add to web search toolbar"), |
851 act = menu.addAction(self.trUtf8("Add to web search toolbar"), |
847 self.__addSearchEngine) |
852 self.__addSearchEngine) |
848 act.setData(element) |
853 act.setData(element) |
849 menu.addSeparator() |
854 menu.addSeparator() |
850 |
855 |
851 menu.addAction(self.trUtf8("Web Inspector..."), self.__webInspector) |
856 menu.addAction(self.trUtf8("Web Inspector..."), self.__webInspector) |
996 searchUrl.addQueryItem(name, value) |
1001 searchUrl.addQueryItem(name, value) |
997 |
1002 |
998 ok = True |
1003 ok = True |
999 if len(searchEngines) > 1: |
1004 if len(searchEngines) > 1: |
1000 searchEngine, ok = QInputDialog.getItem( |
1005 searchEngine, ok = QInputDialog.getItem( |
1001 self, |
1006 self, |
1002 self.trUtf8("Search engine"), |
1007 self.trUtf8("Search engine"), |
1003 self.trUtf8("Choose the desired search engine"), |
1008 self.trUtf8("Choose the desired search engine"), |
1004 sorted(searchEngines.keys()), 0, False) |
1009 sorted(searchEngines.keys()), 0, False) |
1005 |
1010 |
1006 if not ok: |
1011 if not ok: |
1007 return |
1012 return |
1008 |
1013 |
1162 if url.isEmpty(): |
1167 if url.isEmpty(): |
1163 return |
1168 return |
1164 |
1169 |
1165 self.mw.downloadManager().download(url, True) |
1170 self.mw.downloadManager().download(url, True) |
1166 |
1171 |
1167 def __unsupportedContent(self, reply, requestFilename = None, download = False): |
1172 def __unsupportedContent(self, reply, requestFilename=None, download=False): |
1168 """ |
1173 """ |
1169 Private slot to handle the unsupportedContent signal. |
1174 Private slot to handle the unsupportedContent signal. |
1170 |
1175 |
1171 @param reply reference to the reply object (QNetworkReply) |
1176 @param reply reference to the reply object (QNetworkReply) |
1172 @keyparam requestFilename indicating to ask for a filename |
1177 @keyparam requestFilename indicating to ask for a filename |
1173 (boolean or None). If it is None, the behavior is determined |
1178 (boolean or None). If it is None, the behavior is determined |
1174 by a configuration option. |
1179 by a configuration option. |
1175 @keyparam download flag indicating a download operation (boolean) |
1180 @keyparam download flag indicating a download operation (boolean) |
1176 """ |
1181 """ |
1177 if reply is None: |
1182 if reply is None: |
1197 return |
1202 return |
1198 |
1203 |
1199 if reply.header(QNetworkRequest.ContentTypeHeader): |
1204 if reply.header(QNetworkRequest.ContentTypeHeader): |
1200 data = reply.readAll() |
1205 data = reply.readAll() |
1201 if contentSniff(data): |
1206 if contentSniff(data): |
1202 notFoundFrame.setHtml(str(data, encoding = "utf-8"), replyUrl) |
1207 notFoundFrame.setHtml(str(data, encoding="utf-8"), replyUrl) |
1203 return |
1208 return |
1204 |
1209 |
1205 html = notFoundPage_html |
1210 html = notFoundPage_html |
1206 urlString = bytes(replyUrl.toEncoded()).decode() |
1211 urlString = bytes(replyUrl.toEncoded()).decode() |
1207 title = self.trUtf8("Error loading page: {0}").format(urlString) |
1212 title = self.trUtf8("Error loading page: {0}").format(urlString) |
1209 .standardIcon(QStyle.SP_MessageBoxWarning, None, self)\ |
1214 .standardIcon(QStyle.SP_MessageBoxWarning, None, self)\ |
1210 .pixmap(32, 32) |
1215 .pixmap(32, 32) |
1211 imageBuffer = QBuffer() |
1216 imageBuffer = QBuffer() |
1212 imageBuffer.open(QIODevice.ReadWrite) |
1217 imageBuffer.open(QIODevice.ReadWrite) |
1213 if pixmap.save(imageBuffer, "PNG"): |
1218 if pixmap.save(imageBuffer, "PNG"): |
1214 html = html.replace("IMAGE_BINARY_DATA_HERE", |
1219 html = html.replace("IMAGE_BINARY_DATA_HERE", |
1215 str(imageBuffer.buffer().toBase64(), encoding="ascii")) |
1220 str(imageBuffer.buffer().toBase64(), encoding="ascii")) |
1216 html = html.format( |
1221 html = html.format( |
1217 title, |
1222 title, |
1218 reply.errorString(), |
1223 reply.errorString(), |
1219 self.trUtf8("When connecting to: {0}.").format(urlString), |
1224 self.trUtf8("When connecting to: {0}.").format(urlString), |
1220 self.trUtf8("Check the address for errors such as <b>ww</b>.example.org " |
1225 self.trUtf8("Check the address for errors such as <b>ww</b>.example.org " |
1221 "instead of <b>www</b>.example.org"), |
1226 "instead of <b>www</b>.example.org"), |
1222 self.trUtf8("If the address is correct, try checking the network " |
1227 self.trUtf8("If the address is correct, try checking the network " |
1223 "connection."), |
1228 "connection."), |
1224 self.trUtf8("If your computer or network is protected by a firewall or " |
1229 self.trUtf8("If your computer or network is protected by a firewall or " |
1225 "proxy, make sure that the browser is permitted to access " |
1230 "proxy, make sure that the browser is permitted to access " |
1226 "the network."), |
1231 "the network."), |
1227 self.trUtf8("If your cache policy is set to offline browsing," |
1232 self.trUtf8("If your cache policy is set to offline browsing," |
1228 "only pages in the local cache are available.") |
1233 "only pages in the local cache are available.") |
1229 ) |
1234 ) |
1230 notFoundFrame.setHtml(html, replyUrl) |
1235 notFoundFrame.setHtml(html, replyUrl) |
1231 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title()) |
1236 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title()) |
1257 self.trUtf8("Web Database Quota"), |
1262 self.trUtf8("Web Database Quota"), |
1258 self.trUtf8("""<p>The database quota of <strong>{0}</strong> has""" |
1263 self.trUtf8("""<p>The database quota of <strong>{0}</strong> has""" |
1259 """ been exceeded while accessing database <strong>{1}""" |
1264 """ been exceeded while accessing database <strong>{1}""" |
1260 """</strong>.</p><p>Shall it be changed?</p>""")\ |
1265 """</strong>.</p><p>Shall it be changed?</p>""")\ |
1261 .format(self.__dataString(securityOrigin.databaseQuota()), databaseName), |
1266 .format(self.__dataString(securityOrigin.databaseQuota()), databaseName), |
1262 yesDefault = True) |
1267 yesDefault=True) |
1263 if res: |
1268 if res: |
1264 newQuota, ok = QInputDialog.getInteger( |
1269 newQuota, ok = QInputDialog.getInteger( |
1265 self, |
1270 self, |
1266 self.trUtf8("New Web Database Quota"), |
1271 self.trUtf8("New Web Database Quota"), |
1267 self.trUtf8("Enter the new quota in MB (current = {0}, used = {1}; " |
1272 self.trUtf8("Enter the new quota in MB (current = {0}, used = {1}; " |
1268 "step size = 5 MB):"\ |
1273 "step size = 5 MB):"\ |
1269 .format(self.__dataString(securityOrigin.databaseQuota()), |
1274 .format(self.__dataString(securityOrigin.databaseQuota()), |
1270 self.__dataString(securityOrigin.databaseUsage()))), |
1275 self.__dataString(securityOrigin.databaseUsage()))), |
1271 securityOrigin.databaseQuota() // (1024 * 1024), 0, 2147483647, 5) |
1276 securityOrigin.databaseQuota() // (1024 * 1024), 0, 2147483647, 5) |
1272 if ok: |
1277 if ok: |
1273 securityOrigin.setDatabaseQuota(newQuota * 1024 * 1024) |
1278 securityOrigin.setDatabaseQuota(newQuota * 1024 * 1024) |
1274 |
1279 |