WebBrowser/WebBrowserTabWidget.py

branch
QtWebEngine
changeset 4709
8612533a223f
parent 4631
5c1a96925da4
child 4713
8dca047daf4b
equal deleted inserted replaced
4702:bd7d781db729 4709:8612533a223f
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2010 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the central widget showing the web pages.
8 """
9
10 from __future__ import unicode_literals
11
12 import os
13
14 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl
15 from PyQt5.QtGui import QIcon
16 from PyQt5.QtWidgets import QWidget, QHBoxLayout, QMenu, QToolButton, QDialog
17 ##from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
18 ##from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
19
20 from E5Gui.E5TabWidget import E5TabWidget
21 from E5Gui import E5MessageBox
22 from E5Gui.E5Application import e5App
23
24 # TODO: implement this
25 from .WebBrowserView import WebBrowserView
26
27 import UI.PixmapCache
28
29 import Utilities
30 import Preferences
31
32 from eric6config import getConfig
33
34
35 class WebBrowserTabWidget(E5TabWidget):
36 """
37 Class implementing the central widget showing the web pages.
38
39 @signal sourceChanged(WebBrowserView, QUrl) emitted after the URL of a
40 browser has changed
41 @signal titleChanged(WebBrowserView, str) emitted after the title of a
42 browser has changed
43 @signal showMessage(str) emitted to show a message in the main window
44 status bar
45 @signal browserClosed(QWidget) emitted after a browser was closed
46 @signal browserZoomValueChanged(int) emitted to signal a change of the
47 current browser's zoom level
48 """
49 sourceChanged = pyqtSignal(WebBrowserView, QUrl)
50 titleChanged = pyqtSignal(WebBrowserView, str)
51 showMessage = pyqtSignal(str)
52 browserClosed = pyqtSignal(QWidget)
53 browserZoomValueChanged = pyqtSignal(int)
54
55 def __init__(self, parent):
56 """
57 Constructor
58
59 @param parent reference to the parent widget (QWidget)
60 """
61 super(WebBrowserTabWidget, self).__init__(self, parent, dnd=True)
62
63 # TODO: implement this
64 from .WebBrowserTabBar import WebBrowserTabBar
65 self.__tabBar = WebBrowserTabBar(self)
66 self.setCustomTabBar(True, self.__tabBar)
67
68 self.__mainWindow = parent
69
70 self.setUsesScrollButtons(True)
71 self.setDocumentMode(True)
72 self.setElideMode(Qt.ElideNone)
73
74 # TODO: re-enable once Closed Tabs Manager is done
75 ## from .ClosedTabsManager import ClosedTabsManager
76 ## self.__closedTabsManager = ClosedTabsManager(self)
77 ## self.__closedTabsManager.closedTabAvailable.connect(
78 ## self.__closedTabAvailable)
79
80 from .UrlBar.StackedUrlBar import StackedUrlBar
81 self.__stackedUrlBar = StackedUrlBar(self)
82 self.__tabBar.tabMoved.connect(self.__stackedUrlBar.moveBar)
83
84 self.__tabContextMenuIndex = -1
85 self.currentChanged[int].connect(self.__currentChanged)
86 self.setTabContextMenuPolicy(Qt.CustomContextMenu)
87 self.customTabContextMenuRequested.connect(self.__showContextMenu)
88
89 self.__rightCornerWidget = QWidget(self)
90 self.__rightCornerWidgetLayout = QHBoxLayout(self.__rightCornerWidget)
91 self.__rightCornerWidgetLayout.setContentsMargins(0, 0, 0, 0)
92 self.__rightCornerWidgetLayout.setSpacing(0)
93
94 self.__navigationMenu = QMenu(self)
95 self.__navigationMenu.aboutToShow.connect(self.__showNavigationMenu)
96 self.__navigationMenu.triggered.connect(self.__navigationMenuTriggered)
97
98 self.__navigationButton = QToolButton(self)
99 self.__navigationButton.setIcon(
100 UI.PixmapCache.getIcon("1downarrow.png"))
101 self.__navigationButton.setToolTip(
102 self.tr("Show a navigation menu"))
103 self.__navigationButton.setPopupMode(QToolButton.InstantPopup)
104 self.__navigationButton.setMenu(self.__navigationMenu)
105 self.__navigationButton.setEnabled(False)
106 self.__rightCornerWidgetLayout.addWidget(self.__navigationButton)
107
108 # TODO: re-enable once Closed Tabs Manager is done
109 ## self.__closedTabsMenu = QMenu(self)
110 ## self.__closedTabsMenu.aboutToShow.connect(
111 ## self.__aboutToShowClosedTabsMenu)
112 ##
113 ## self.__closedTabsButton = QToolButton(self)
114 ## self.__closedTabsButton.setIcon(UI.PixmapCache.getIcon("trash.png"))
115 ## self.__closedTabsButton.setToolTip(
116 ## self.tr("Show a navigation menu for closed tabs"))
117 ## self.__closedTabsButton.setPopupMode(QToolButton.InstantPopup)
118 ## self.__closedTabsButton.setMenu(self.__closedTabsMenu)
119 ## self.__closedTabsButton.setEnabled(False)
120 ## self.__rightCornerWidgetLayout.addWidget(self.__closedTabsButton)
121 ##
122 self.__closeButton = QToolButton(self)
123 self.__closeButton.setIcon(UI.PixmapCache.getIcon("close.png"))
124 self.__closeButton.setToolTip(
125 self.tr("Close the current web browser"))
126 self.__closeButton.setEnabled(False)
127 self.__closeButton.clicked.connect(self.closeBrowser)
128 self.__rightCornerWidgetLayout.addWidget(self.__closeButton)
129 if Preferences.getUI("SingleCloseButton") or \
130 not hasattr(self, 'setTabsClosable'):
131 self.__closeButton.show()
132 else:
133 self.setTabsClosable(True)
134 self.tabCloseRequested.connect(self.closeBrowserAt)
135 self.__closeButton.hide()
136
137 self.setCornerWidget(self.__rightCornerWidget, Qt.TopRightCorner)
138
139 self.__newTabButton = QToolButton(self)
140 self.__newTabButton.setIcon(UI.PixmapCache.getIcon("plus.png"))
141 self.__newTabButton.setToolTip(
142 self.tr("Open a new web browser tab"))
143 self.setCornerWidget(self.__newTabButton, Qt.TopLeftCorner)
144 self.__newTabButton.clicked.connect(self.__newBrowser)
145
146 self.__initTabContextMenu()
147
148 self.__historyCompleter = None
149
150 def __initTabContextMenu(self):
151 """
152 Private method to create the tab context menu.
153 """
154 self.__tabContextMenu = QMenu(self)
155 self.tabContextNewAct = self.__tabContextMenu.addAction(
156 UI.PixmapCache.getIcon("tabNew.png"),
157 self.tr('New Tab'), self.newBrowser)
158 self.__tabContextMenu.addSeparator()
159 self.leftMenuAct = self.__tabContextMenu.addAction(
160 UI.PixmapCache.getIcon("1leftarrow.png"),
161 self.tr('Move Left'), self.__tabContextMenuMoveLeft)
162 self.rightMenuAct = self.__tabContextMenu.addAction(
163 UI.PixmapCache.getIcon("1rightarrow.png"),
164 self.tr('Move Right'), self.__tabContextMenuMoveRight)
165 self.__tabContextMenu.addSeparator()
166 self.tabContextCloneAct = self.__tabContextMenu.addAction(
167 self.tr("Duplicate Page"), self.__tabContextMenuClone)
168 self.__tabContextMenu.addSeparator()
169 self.tabContextCloseAct = self.__tabContextMenu.addAction(
170 UI.PixmapCache.getIcon("tabClose.png"),
171 self.tr('Close'), self.__tabContextMenuClose)
172 self.tabContextCloseOthersAct = self.__tabContextMenu.addAction(
173 UI.PixmapCache.getIcon("tabCloseOther.png"),
174 self.tr("Close Others"), self.__tabContextMenuCloseOthers)
175 self.__tabContextMenu.addAction(
176 self.tr('Close All'), self.closeAllBrowsers)
177 ## self.__tabContextMenu.addSeparator()
178 ## self.__tabContextMenu.addAction(
179 ## UI.PixmapCache.getIcon("printPreview.png"),
180 ## self.tr('Print Preview'), self.__tabContextMenuPrintPreview)
181 ## self.__tabContextMenu.addAction(
182 ## UI.PixmapCache.getIcon("print.png"),
183 ## self.tr('Print'), self.__tabContextMenuPrint)
184 ## self.__tabContextMenu.addAction(
185 ## UI.PixmapCache.getIcon("printPdf.png"),
186 ## self.tr('Print as PDF'), self.__tabContextMenuPrintPdf)
187 self.__tabContextMenu.addSeparator()
188 self.__tabContextMenu.addAction(
189 UI.PixmapCache.getIcon("reload.png"),
190 self.tr('Reload All'), self.reloadAllBrowsers)
191 ## self.__tabContextMenu.addSeparator()
192 ## self.__tabContextMenu.addAction(
193 ## UI.PixmapCache.getIcon("addBookmark.png"),
194 ## self.tr('Bookmark All Tabs'), self.__mainWindow.bookmarkAll)
195
196 self.__tabBackContextMenu = QMenu(self)
197 self.__tabBackContextMenu.addAction(
198 self.tr('Close All'), self.closeAllBrowsers)
199 self.__tabBackContextMenu.addAction(
200 UI.PixmapCache.getIcon("reload.png"),
201 self.tr('Reload All'), self.reloadAllBrowsers)
202 ## self.__tabBackContextMenu.addAction(
203 ## UI.PixmapCache.getIcon("addBookmark.png"),
204 ## self.tr('Bookmark All Tabs'), self.__mainWindow.bookmarkAll)
205 ## self.__tabBackContextMenu.addSeparator()
206 ## self.__restoreClosedTabAct = self.__tabBackContextMenu.addAction(
207 ## UI.PixmapCache.getIcon("trash.png"),
208 ## self.tr('Restore Closed Tab'), self.restoreClosedTab)
209 ## self.__restoreClosedTabAct.setEnabled(False)
210 ## self.__restoreClosedTabAct.setData(0)
211
212 def __showContextMenu(self, coord, index):
213 """
214 Private slot to show the tab context menu.
215
216 @param coord the position of the mouse pointer (QPoint)
217 @param index index of the tab the menu is requested for (integer)
218 """
219 coord = self.mapToGlobal(coord)
220 if index == -1:
221 self.__tabBackContextMenu.popup(coord)
222 else:
223 self.__tabContextMenuIndex = index
224 self.leftMenuAct.setEnabled(index > 0)
225 self.rightMenuAct.setEnabled(index < self.count() - 1)
226
227 self.tabContextCloseOthersAct.setEnabled(self.count() > 1)
228
229 self.__tabContextMenu.popup(coord)
230
231 def __tabContextMenuMoveLeft(self):
232 """
233 Private method to move a tab one position to the left.
234 """
235 self.moveTab(self.__tabContextMenuIndex,
236 self.__tabContextMenuIndex - 1)
237
238 def __tabContextMenuMoveRight(self):
239 """
240 Private method to move a tab one position to the right.
241 """
242 self.moveTab(self.__tabContextMenuIndex,
243 self.__tabContextMenuIndex + 1)
244
245 def __tabContextMenuClone(self):
246 """
247 Private method to clone the selected tab.
248 """
249 idx = self.__tabContextMenuIndex
250 if idx < 0:
251 idx = self.currentIndex()
252 if idx < 0 or idx > self.count():
253 return
254
255 ## req = QNetworkRequest(self.widget(idx).url())
256 ## req.setRawHeader(b"X-Eric6-UserLoadAction", b"1")
257 ## self.newBrowser(None, (req, QNetworkAccessManager.GetOperation, b""))
258 url = self.widget(idx).url()
259 self.newBrowser(url)
260
261 def __tabContextMenuClose(self):
262 """
263 Private method to close the selected tab.
264 """
265 self.closeBrowserAt(self.__tabContextMenuIndex)
266
267 def __tabContextMenuCloseOthers(self):
268 """
269 Private slot to close all other tabs.
270 """
271 index = self.__tabContextMenuIndex
272 for i in list(range(self.count() - 1, index, -1)) + \
273 list(range(index - 1, -1, -1)):
274 self.closeBrowserAt(i)
275
276 ## def __tabContextMenuPrint(self):
277 ## """
278 ## Private method to print the selected tab.
279 ## """
280 ## browser = self.widget(self.__tabContextMenuIndex)
281 ## self.printBrowser(browser)
282 ##
283 ## def __tabContextMenuPrintPdf(self):
284 ## """
285 ## Private method to print the selected tab as PDF.
286 ## """
287 ## browser = self.widget(self.__tabContextMenuIndex)
288 ## self.printBrowserPdf(browser)
289 ##
290 ## def __tabContextMenuPrintPreview(self):
291 ## """
292 ## Private method to show a print preview of the selected tab.
293 ## """
294 ## browser = self.widget(self.__tabContextMenuIndex)
295 ## self.printPreviewBrowser(browser)
296 ##
297 @pyqtSlot()
298 def __newBrowser(self):
299 """
300 Private slot to open a new browser tab.
301 """
302 self.newBrowser()
303
304 # TODO: remove requestData from signature
305 def newBrowser(self, link=None, requestData=None, position=-1):
306 """
307 Public method to create a new web browser tab.
308
309 @param link link to be shown (string or QUrl)
310 @param requestData tuple containing the request data (QNetworkRequest,
311 QNetworkAccessManager.Operation, QByteArray)
312 @keyparam position position to create the new tab at or -1 to add it
313 to the end (integer)
314 """
315 if link is None:
316 linkName = ""
317 elif isinstance(link, QUrl):
318 linkName = link.toString()
319 else:
320 linkName = link
321
322 from .UrlBar.UrlBar import UrlBar
323 urlbar = UrlBar(self.__mainWindow, self)
324 ## if self.__historyCompleter is None:
325 ## import Helpviewer.HelpWindow
326 ## from .History.HistoryCompleter import HistoryCompletionModel, \
327 ## HistoryCompleter
328 ## self.__historyCompletionModel = HistoryCompletionModel(self)
329 ## self.__historyCompletionModel.setSourceModel(
330 ## Helpviewer.HelpWindow.HelpWindow.historyManager()
331 ## .historyFilterModel())
332 ## self.__historyCompleter = HistoryCompleter(
333 ## self.__historyCompletionModel, self)
334 ## self.__historyCompleter.activated[str].connect(self.__pathSelected)
335 ## urlbar.setCompleter(self.__historyCompleter)
336 urlbar.returnPressed.connect(self.__lineEditReturnPressed)
337 if position == -1:
338 self.__stackedUrlBar.addWidget(urlbar)
339 else:
340 self.__stackedUrlBar.insertWidget(position, urlbar)
341
342 browser = WebBrowserView(self.__mainWindow, self)
343 urlbar.setBrowser(browser)
344
345 browser.sourceChanged.connect(self.__sourceChanged)
346 browser.titleChanged.connect(self.__titleChanged)
347 browser.highlighted.connect(self.showMessage)
348 browser.backwardAvailable.connect(
349 self.__mainWindow.setBackwardAvailable)
350 browser.forwardAvailable.connect(self.__mainWindow.setForwardAvailable)
351 browser.loadStarted.connect(self.__loadStarted)
352 browser.loadFinished.connect(self.__loadFinished)
353 browser.iconUrlChanged.connect(self.__iconUrlChanged)
354 browser.search.connect(self.newBrowser)
355 browser.page().windowCloseRequested.connect(
356 self.__windowCloseRequested)
357 ## browser.page().printRequested.connect(self.__printRequested)
358 browser.zoomValueChanged.connect(self.browserZoomValueChanged)
359
360 if position == -1:
361 index = self.addTab(browser, self.tr("..."))
362 else:
363 index = self.insertTab(position, browser, self.tr("..."))
364 self.setCurrentIndex(index)
365
366 self.__mainWindow.closeAct.setEnabled(True)
367 self.__mainWindow.closeAllAct.setEnabled(True)
368 self.__closeButton.setEnabled(True)
369 self.__navigationButton.setEnabled(True)
370
371 ## if not linkName and not requestData:
372 if not linkName:
373 if Preferences.getWebBrowser("StartupBehavior") == 0:
374 linkName = Preferences.getWebBrowser("HomePage")
375 elif Preferences.getWebBrowser("StartupBehavior") == 1:
376 linkName = "eric:speeddial"
377
378 if linkName:
379 browser.setSource(QUrl(linkName))
380 if not browser.documentTitle():
381 self.setTabText(index, self.__elide(linkName, Qt.ElideMiddle))
382 self.setTabToolTip(index, linkName)
383 else:
384 self.setTabText(
385 index,
386 self.__elide(browser.documentTitle().replace("&", "&&")))
387 self.setTabToolTip(index, browser.documentTitle())
388 ## elif requestData:
389 ## browser.load(*requestData)
390
391 # TODO: remove requestData from signature
392 def newBrowserAfter(self, browser, link=None, requestData=None):
393 """
394 Public method to create a new web browser tab after a given one.
395
396 @param browser reference to the browser to add after (WebBrowserView)
397 @param link link to be shown (string or QUrl)
398 @param requestData tuple containing the request data (QNetworkRequest,
399 QNetworkAccessManager.Operation, QByteArray)
400 """
401 if browser:
402 position = self.indexOf(browser) + 1
403 else:
404 position = -1
405 self.newBrowser(link, requestData, position)
406
407 def __showNavigationMenu(self):
408 """
409 Private slot to show the navigation button menu.
410 """
411 self.__navigationMenu.clear()
412 for index in range(self.count()):
413 act = self.__navigationMenu.addAction(
414 self.tabIcon(index), self.tabText(index))
415 act.setData(index)
416
417 def __navigationMenuTriggered(self, act):
418 """
419 Private slot called to handle the navigation button menu selection.
420
421 @param act reference to the selected action (QAction)
422 """
423 index = act.data()
424 if index is not None:
425 self.setCurrentIndex(index)
426
427 def __windowCloseRequested(self):
428 """
429 Private slot to handle the windowCloseRequested signal of a browser.
430 """
431 page = self.sender()
432 if page is None:
433 return
434
435 browser = page.view()
436 if browser is None:
437 return
438
439 index = self.indexOf(browser)
440 self.closeBrowserAt(index)
441
442 def reloadAllBrowsers(self):
443 """
444 Public slot to reload all browsers.
445 """
446 for index in range(self.count()):
447 browser = self.widget(index)
448 browser and browser.reload()
449
450 @pyqtSlot()
451 def closeBrowser(self):
452 """
453 Public slot called to handle the close action.
454 """
455 self.closeBrowserAt(self.currentIndex())
456
457 def closeAllBrowsers(self):
458 """
459 Public slot called to handle the close all action.
460 """
461 for index in range(self.count() - 1, -1, -1):
462 self.closeBrowserAt(index)
463
464 def closeBrowserAt(self, index):
465 """
466 Public slot to close a browser based on its index.
467
468 @param index index of browser to close (integer)
469 """
470 browser = self.widget(index)
471 if browser is None:
472 return
473
474 ## if browser.isModified():
475 ## ok = E5MessageBox.yesNo(
476 ## self,
477 ## self.tr("Do you really want to close this page?"),
478 ## self.tr("""You have modified this page and when closing it"""
479 ## """ you would lose the modification.\nDo you really"""
480 ## """ want to close this page?"""))
481 ## if not ok:
482 ## return
483 ##
484 urlbar = self.__stackedUrlBar.widget(index)
485 self.__stackedUrlBar.removeWidget(urlbar)
486 urlbar.deleteLater()
487 del urlbar
488
489 ## self.__closedTabsManager.recordBrowser(browser, index)
490 ##
491 ## browser.closeWebInspector()
492 browser.home()
493 self.removeTab(index)
494 self.browserClosed.emit(browser)
495 browser.deleteLater()
496 del browser
497
498 if self.count() == 0:
499 self.newBrowser()
500 else:
501 self.currentChanged[int].emit(self.currentIndex())
502
503 def currentBrowser(self):
504 """
505 Public method to get a reference to the current browser.
506
507 @return reference to the current browser (WebBrowserView)
508 """
509 return self.currentWidget()
510
511 def browserAt(self, index):
512 """
513 Public method to get a reference to the browser with the given index.
514
515 @param index index of the browser to get (integer)
516 @return reference to the indexed browser (WebBrowserView)
517 """
518 return self.widget(index)
519
520 def browsers(self):
521 """
522 Public method to get a list of references to all browsers.
523
524 @return list of references to browsers (list of WebBrowserView)
525 """
526 li = []
527 for index in range(self.count()):
528 li.append(self.widget(index))
529 return li
530
531 ## @pyqtSlot()
532 ## def printBrowser(self, browser=None):
533 ## """
534 ## Public slot called to print the displayed page.
535 ##
536 ## @param browser reference to the browser to be printed (WebBrowserView)
537 ## """
538 ## if browser is None:
539 ## browser = self.currentBrowser()
540 ##
541 ## self.__printRequested(browser.page().mainFrame())
542 ##
543 ## def __printRequested(self, frame):
544 ## """
545 ## Private slot to handle a print request.
546 ##
547 ## @param frame reference to the frame to be printed (QWebFrame)
548 ## """
549 ## printer = QPrinter(mode=QPrinter.HighResolution)
550 ## if Preferences.getPrinter("ColorMode"):
551 ## printer.setColorMode(QPrinter.Color)
552 ## else:
553 ## printer.setColorMode(QPrinter.GrayScale)
554 ## if Preferences.getPrinter("FirstPageFirst"):
555 ## printer.setPageOrder(QPrinter.FirstPageFirst)
556 ## else:
557 ## printer.setPageOrder(QPrinter.LastPageFirst)
558 ## printer.setPageMargins(
559 ## Preferences.getPrinter("LeftMargin") * 10,
560 ## Preferences.getPrinter("TopMargin") * 10,
561 ## Preferences.getPrinter("RightMargin") * 10,
562 ## Preferences.getPrinter("BottomMargin") * 10,
563 ## QPrinter.Millimeter
564 ## )
565 ## printerName = Preferences.getPrinter("PrinterName")
566 ## if printerName:
567 ## printer.setPrinterName(printerName)
568 ##
569 ## printDialog = QPrintDialog(printer, self)
570 ## if printDialog.exec_() == QDialog.Accepted:
571 ## try:
572 ## frame.print_(printer)
573 ## except AttributeError:
574 ## E5MessageBox.critical(
575 ## self,
576 ## self.tr("eric6 Web Browser"),
577 ## self.tr(
578 ## """<p>Printing is not available due to a bug in"""
579 ## """ PyQt5. Please upgrade.</p>"""))
580 ## return
581 ##
582 ## @pyqtSlot()
583 ## def printBrowserPdf(self, browser=None):
584 ## """
585 ## Public slot called to print the displayed page to PDF.
586 ##
587 ## @param browser reference to the browser to be printed (HelpBrowser)
588 ## """
589 ## if browser is None:
590 ## browser = self.currentBrowser()
591 ##
592 ## self.__printPdfRequested(browser.page().mainFrame())
593 ##
594 ## def __printPdfRequested(self, frame):
595 ## """
596 ## Private slot to handle a print to PDF request.
597 ##
598 ## @param frame reference to the frame to be printed (QWebFrame)
599 ## """
600 ## printer = QPrinter(mode=QPrinter.HighResolution)
601 ## if Preferences.getPrinter("ColorMode"):
602 ## printer.setColorMode(QPrinter.Color)
603 ## else:
604 ## printer.setColorMode(QPrinter.GrayScale)
605 ## printerName = Preferences.getPrinter("PrinterName")
606 ## if printerName:
607 ## printer.setPrinterName(printerName)
608 ## printer.setOutputFormat(QPrinter.PdfFormat)
609 ## name = frame.url().path().rsplit('/', 1)[-1]
610 ## if name:
611 ## name = name.rsplit('.', 1)[0]
612 ## name += '.pdf'
613 ## printer.setOutputFileName(name)
614 ##
615 ## printDialog = QPrintDialog(printer, self)
616 ## if printDialog.exec_() == QDialog.Accepted:
617 ## try:
618 ## frame.print_(printer)
619 ## except AttributeError:
620 ## E5MessageBox.critical(
621 ## self,
622 ## self.tr("eric6 Web Browser"),
623 ## self.tr(
624 ## """<p>Printing is not available due to a bug in"""
625 ## """ PyQt5. Please upgrade.</p>"""))
626 ## return
627 ##
628 ## @pyqtSlot()
629 ## def printPreviewBrowser(self, browser=None):
630 ## """
631 ## Public slot called to show a print preview of the displayed file.
632 ##
633 ## @param browser reference to the browser to be printed (HelpBrowserWV)
634 ## """
635 ## from PyQt5.QtPrintSupport import QPrintPreviewDialog
636 ##
637 ## if browser is None:
638 ## browser = self.currentBrowser()
639 ##
640 ## printer = QPrinter(mode=QPrinter.HighResolution)
641 ## if Preferences.getPrinter("ColorMode"):
642 ## printer.setColorMode(QPrinter.Color)
643 ## else:
644 ## printer.setColorMode(QPrinter.GrayScale)
645 ## if Preferences.getPrinter("FirstPageFirst"):
646 ## printer.setPageOrder(QPrinter.FirstPageFirst)
647 ## else:
648 ## printer.setPageOrder(QPrinter.LastPageFirst)
649 ## printer.setPageMargins(
650 ## Preferences.getPrinter("LeftMargin") * 10,
651 ## Preferences.getPrinter("TopMargin") * 10,
652 ## Preferences.getPrinter("RightMargin") * 10,
653 ## Preferences.getPrinter("BottomMargin") * 10,
654 ## QPrinter.Millimeter
655 ## )
656 ## printerName = Preferences.getPrinter("PrinterName")
657 ## if printerName:
658 ## printer.setPrinterName(printerName)
659 ##
660 ## self.__printPreviewBrowser = browser
661 ## preview = QPrintPreviewDialog(printer, self)
662 ## preview.paintRequested.connect(self.__printPreview)
663 ## preview.exec_()
664 ##
665 ## def __printPreview(self, printer):
666 ## """
667 ## Private slot to generate a print preview.
668 ##
669 ## @param printer reference to the printer object (QPrinter)
670 ## """
671 ## try:
672 ## self.__printPreviewBrowser.print_(printer)
673 ## except AttributeError:
674 ## E5MessageBox.critical(
675 ## self,
676 ## self.tr("eric6 Web Browser"),
677 ## self.tr(
678 ## """<p>Printing is not available due to a bug in PyQt5."""
679 ## """Please upgrade.</p>"""))
680 ## return
681 ##
682 def __sourceChanged(self, url):
683 """
684 Private slot to handle a change of a browsers source.
685
686 @param url URL of the new site (QUrl)
687 """
688 browser = self.sender()
689
690 if browser is not None:
691 self.sourceChanged.emit(browser, url)
692
693 def __titleChanged(self, title):
694 """
695 Private slot to handle a change of a browsers title.
696
697 @param title new title (string)
698 """
699 browser = self.sender()
700
701 if browser is not None and isinstance(browser, QWidget):
702 index = self.indexOf(browser)
703 if title == "":
704 title = browser.url().toString()
705
706 self.setTabText(index, self.__elide(title.replace("&", "&&")))
707 self.setTabToolTip(index, title)
708
709 self.titleChanged.emit(browser, title)
710
711 def __elide(self, txt, mode=Qt.ElideRight, length=40):
712 """
713 Private method to elide some text.
714
715 @param txt text to be elided (string)
716 @keyparam mode elide mode (Qt.TextElideMode)
717 @keyparam length amount of characters to be used (integer)
718 @return the elided text (string)
719 """
720 if mode == Qt.ElideNone or len(txt) < length:
721 return txt
722 elif mode == Qt.ElideLeft:
723 return "...{0}".format(txt[-length:])
724 elif mode == Qt.ElideMiddle:
725 return "{0}...{1}".format(txt[:length // 2], txt[-(length // 2):])
726 elif mode == Qt.ElideRight:
727 return "{0}...".format(txt[:length])
728 else:
729 # just in case
730 return txt
731
732 def preferencesChanged(self):
733 """
734 Public slot to handle a change of preferences.
735 """
736 for browser in self.browsers():
737 browser.preferencesChanged()
738
739 for urlbar in self.__stackedUrlBar.urlBars():
740 urlbar.preferencesChanged()
741
742 if Preferences.getUI("SingleCloseButton"):
743 self.setTabsClosable(False)
744 try:
745 self.tabCloseRequested.disconnect(self.closeBrowserAt)
746 except TypeError:
747 pass
748 self.__closeButton.show()
749 else:
750 self.setTabsClosable(True)
751 self.tabCloseRequested.connect(self.closeBrowserAt)
752 self.__closeButton.hide()
753
754 def __loadStarted(self):
755 """
756 Private method to handle the loadStarted signal.
757 """
758 browser = self.sender()
759
760 if browser is not None:
761 index = self.indexOf(browser)
762 anim = self.animationLabel(
763 index, os.path.join(getConfig("ericPixDir"), "loading.gif"),
764 100)
765 if not anim:
766 loading = QIcon(os.path.join(getConfig("ericPixDir"),
767 "loading.gif"))
768 self.setTabIcon(index, loading)
769 else:
770 self.setTabIcon(index, QIcon())
771 self.setTabText(index, self.tr("Loading..."))
772 self.setTabToolTip(index, self.tr("Loading..."))
773 self.showMessage.emit(self.tr("Loading..."))
774
775 self.__mainWindow.setLoadingActions(True)
776
777 def __loadFinished(self, ok):
778 """
779 Private method to handle the loadFinished signal.
780
781 @param ok flag indicating the result (boolean)
782 """
783 browser = self.sender()
784 if not isinstance(browser, WebBrowserView):
785 return
786
787 if browser is not None:
788 import WebBrowser.WebBrowserWindow
789 index = self.indexOf(browser)
790 self.resetAnimation(index)
791 self.setTabIcon(
792 index, WebBrowser.WebBrowserWindow.WebBrowserWindow.icon(
793 browser.url()))
794 if ok:
795 self.showMessage.emit(self.tr("Finished loading"))
796 else:
797 self.showMessage.emit(self.tr("Failed to load"))
798
799 self.__mainWindow.setLoadingActions(False)
800
801 def __iconUrlChanged(self, url):
802 """
803 Private slot to handle a change of the icon URL.
804
805 @param url URL of the icon
806 @type QUrl
807 """
808 browser = self.sender()
809
810 if browser is not None and isinstance(browser, QWidget):
811 import WebBrowser.WebBrowserWindow
812 self.setTabIcon(
813 self.indexOf(browser),
814 WebBrowser.WebBrowserWindow.WebBrowserWindow.icon(url))
815 WebBrowser.WebBrowserWindow.WebBrowserWindow.bookmarksManager()\
816 .iconChanged(url)
817
818 def getSourceFileList(self):
819 """
820 Public method to get a list of all opened Qt help files.
821
822 @return dictionary with tab id as key and host/namespace as value
823 """
824 sourceList = {}
825 for i in range(self.count()):
826 browser = self.widget(i)
827 if browser is not None and \
828 browser.source().isValid():
829 sourceList[i] = browser.source().host()
830
831 return sourceList
832
833 def shallShutDown(self):
834 """
835 Public method to check, if the application should be shut down.
836
837 @return flag indicating a shut down (boolean)
838 """
839 if self.count() > 1 and Preferences.getHelp("WarnOnMultipleClose"):
840 mb = E5MessageBox.E5MessageBox(
841 E5MessageBox.Information,
842 self.tr("Are you sure you want to close the window?"),
843 self.tr("""Are you sure you want to close the window?\n"""
844 """You have %n tab(s) open.""", "", self.count()),
845 modal=True,
846 parent=self)
847 if self.__mainWindow.fromEric:
848 quitButton = mb.addButton(
849 self.tr("&Close"), E5MessageBox.AcceptRole)
850 quitButton.setIcon(UI.PixmapCache.getIcon("close.png"))
851 else:
852 quitButton = mb.addButton(
853 self.tr("&Quit"), E5MessageBox.AcceptRole)
854 quitButton.setIcon(UI.PixmapCache.getIcon("exit.png"))
855 closeTabButton = mb.addButton(
856 self.tr("C&lose Current Tab"), E5MessageBox.AcceptRole)
857 closeTabButton.setIcon(UI.PixmapCache.getIcon("tabClose.png"))
858 mb.addButton(E5MessageBox.Cancel)
859 mb.exec_()
860 if mb.clickedButton() == quitButton:
861 return True
862 else:
863 if mb.clickedButton() == closeTabButton:
864 self.closeBrowser()
865 return False
866
867 return True
868
869 def stackedUrlBar(self):
870 """
871 Public method to get a reference to the stacked url bar.
872
873 @return reference to the stacked url bar (StackedUrlBar)
874 """
875 return self.__stackedUrlBar
876
877 def currentUrlBar(self):
878 """
879 Public method to get a reference to the current url bar.
880
881 @return reference to the current url bar (UrlBar)
882 """
883 return self.__stackedUrlBar.currentWidget()
884
885 def __lineEditReturnPressed(self):
886 """
887 Private slot to handle the entering of an URL.
888 """
889 edit = self.sender()
890 url = self.__guessUrlFromPath(edit.text())
891 ## request = QNetworkRequest(url)
892 ## request.setRawHeader(b"X-Eric6-UserLoadAction", b"1")
893 if e5App().keyboardModifiers() == Qt.AltModifier:
894 self.newBrowser(url)
895 ## self.newBrowser(
896 ## None, (request, QNetworkAccessManager.GetOperation, b""))
897 else:
898 self.currentBrowser().setSource(url)
899 ## self.currentBrowser().setSource(
900 ## None, (request, QNetworkAccessManager.GetOperation, b""))
901 self.currentBrowser().setFocus()
902
903 ## def __pathSelected(self, path):
904 ## """
905 ## Private slot called when a URL is selected from the completer.
906 ##
907 ## @param path path to be shown (string)
908 ## """
909 ## url = self.__guessUrlFromPath(path)
910 ## self.currentBrowser().setSource(url)
911
912 def __guessUrlFromPath(self, path):
913 """
914 Private method to guess an URL given a path string.
915
916 @param path path string to guess an URL for (string)
917 @return guessed URL (QUrl)
918 """
919 # TODO: re-enable once Open Search is done
920 ## manager = self.__mainWindow.openSearchManager()
921 ## path = Utilities.fromNativeSeparators(path)
922 ## url = manager.convertKeywordSearchToUrl(path)
923 ## if url.isValid():
924 ## return url
925
926 try:
927 url = QUrl.fromUserInput(path)
928 except AttributeError:
929 url = QUrl(path)
930
931 if url.scheme() == "about" and \
932 url.path() == "home":
933 url = QUrl("eric:home")
934
935 # TODO: extend this logic to about:config (open config dialog)
936
937 ## if url.scheme() in ["s", "search"]:
938 ## url = manager.currentEngine().searchUrl(url.path().strip())
939
940 if url.scheme() != "" and \
941 (url.host() != "" or url.path() != ""):
942 return url
943
944 urlString = Preferences.getWebBrowser("DefaultScheme") + path.strip()
945 url = QUrl.fromEncoded(urlString.encode("utf-8"), QUrl.TolerantMode)
946
947 return url
948
949 def __currentChanged(self, index):
950 """
951 Private slot to handle an index change.
952
953 @param index new index (integer)
954 """
955 self.__stackedUrlBar.setCurrentIndex(index)
956
957 browser = self.browserAt(index)
958 if browser is not None:
959 if browser.url() == "" and browser.hasFocus():
960 self.__stackedUrlBar.currentWidget.setFocus()
961 elif browser.url() != "":
962 browser.setFocus()
963
964 # TODO: re-enable once Closed Tabs Manager is done
965 ## def restoreClosedTab(self):
966 ## """
967 ## Public slot to restore the most recently closed tab.
968 ## """
969 ## if not self.canRestoreClosedTab():
970 ## return
971 ##
972 ## act = self.sender()
973 ## tab = self.__closedTabsManager.getClosedTabAt(act.data())
974 ##
975 ## self.newBrowser(tab.url.toString(), position=tab.position)
976 ##
977 ## def canRestoreClosedTab(self):
978 ## """
979 ## Public method to check, if closed tabs can be restored.
980 ##
981 ## @return flag indicating that closed tabs can be restored (boolean)
982 ## """
983 ## return self.__closedTabsManager.isClosedTabAvailable()
984 ##
985 ## def restoreAllClosedTabs(self):
986 ## """
987 ## Public slot to restore all closed tabs.
988 ## """
989 ## if not self.canRestoreClosedTab():
990 ## return
991 ##
992 ## for tab in self.__closedTabsManager.allClosedTabs():
993 ## self.newBrowser(tab.url.toString(), position=tab.position)
994 ## self.__closedTabsManager.clearList()
995 ##
996 ## def clearClosedTabsList(self):
997 ## """
998 ## Public slot to clear the list of closed tabs.
999 ## """
1000 ## self.__closedTabsManager.clearList()
1001 ##
1002 ## def __aboutToShowClosedTabsMenu(self):
1003 ## """
1004 ## Private slot to populate the closed tabs menu.
1005 ## """
1006 ## fm = self.__closedTabsMenu.fontMetrics()
1007 ## maxWidth = fm.width('m') * 40
1008 ##
1009 ## self.__closedTabsMenu.clear()
1010 ## index = 0
1011 ## for tab in self.__closedTabsManager.allClosedTabs():
1012 ## title = fm.elidedText(tab.title, Qt.ElideRight, maxWidth)
1013 ## self.__closedTabsMenu.addAction(
1014 ## self.__mainWindow.icon(tab.url), title,
1015 ## self.restoreClosedTab).setData(index)
1016 ## index += 1
1017 ## self.__closedTabsMenu.addSeparator()
1018 ## self.__closedTabsMenu.addAction(
1019 ## self.tr("Restore All Closed Tabs"), self.restoreAllClosedTabs)
1020 ## self.__closedTabsMenu.addAction(
1021 ## self.tr("Clear List"), self.clearClosedTabsList)
1022 ##
1023 ## def closedTabsManager(self):
1024 ## """
1025 ## Public slot to get a reference to the closed tabs manager.
1026 ##
1027 ## @return reference to the closed tabs manager (ClosedTabsManager)
1028 ## """
1029 ## return self.__closedTabsManager
1030 ##
1031 ## def __closedTabAvailable(self, avail):
1032 ## """
1033 ## Private slot to handle changes of the availability of closed tabs.
1034 ##
1035 ## @param avail flag indicating the availability of closed tabs (boolean)
1036 ## """
1037 ## self.__closedTabsButton.setEnabled(avail)
1038 ## self.__restoreClosedTabAct.setEnabled(avail)

eric ide

mercurial