16 from PyQt6.QtCore import ( |
16 from PyQt6.QtCore import ( |
17 QByteArray, |
17 QByteArray, |
18 QDataStream, |
18 QDataStream, |
19 QDateTime, |
19 QDateTime, |
20 QEvent, |
20 QEvent, |
|
21 QEventLoop, |
21 QIODevice, |
22 QIODevice, |
|
23 QMarginsF, |
22 QPoint, |
24 QPoint, |
23 QPointF, |
25 QPointF, |
24 QStandardPaths, |
26 QStandardPaths, |
25 Qt, |
27 Qt, |
26 QTimer, |
28 QTimer, |
27 QUrl, |
29 QUrl, |
28 pyqtSignal, |
30 pyqtSignal, |
29 pyqtSlot, |
31 pyqtSlot, |
30 ) |
32 ) |
31 from PyQt6.QtGui import QClipboard, QCursor, QDesktopServices, QIcon, QPixmap |
33 from PyQt6.QtGui import ( |
|
34 QClipboard, |
|
35 QCursor, |
|
36 QDesktopServices, |
|
37 QIcon, |
|
38 QPageLayout, |
|
39 QPixmap, |
|
40 ) |
|
41 from PyQt6.QtPrintSupport import ( |
|
42 QAbstractPrintDialog, |
|
43 QPrintDialog, |
|
44 QPrinter, |
|
45 QPrintPreviewDialog, |
|
46 ) |
32 from PyQt6.QtWebEngineCore import QWebEngineDownloadRequest, QWebEnginePage |
47 from PyQt6.QtWebEngineCore import QWebEngineDownloadRequest, QWebEnginePage |
33 from PyQt6.QtWebEngineWidgets import QWebEngineView |
48 from PyQt6.QtWebEngineWidgets import QWebEngineView |
34 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QStyle |
49 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QStyle |
35 |
50 |
36 from eric7 import Preferences |
51 from eric7 import Preferences |
37 from eric7.EricGui import EricPixmapCache |
52 from eric7.EricGui import EricPixmapCache |
38 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
53 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
39 from eric7.EricWidgets.EricApplication import ericApp |
54 from eric7.EricWidgets.EricApplication import ericApp |
40 from eric7.SystemUtilities import FileSystemUtilities, OSUtilities |
55 from eric7.SystemUtilities import FileSystemUtilities, OSUtilities |
|
56 from eric7.UI.Info import Homepage, VersionOnly |
41 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow |
57 from eric7.WebBrowser.WebBrowserWindow import WebBrowserWindow |
42 from eric7.WebBrowser.ZoomManager import ZoomManager |
58 from eric7.WebBrowser.ZoomManager import ZoomManager |
43 |
59 |
44 from . import WebInspector |
60 from . import WebInspector |
45 from .Tools import Scripts |
61 from .Tools import Scripts, WebBrowserTools |
46 from .Tools.WebBrowserTools import getHtmlPage, pixmapToDataUrl |
62 from .Tools.WebBrowserTools import getHtmlPage, pixmapToDataUrl |
47 from .Tools.WebIconLoader import WebIconLoader |
63 from .Tools.WebIconLoader import WebIconLoader |
48 from .WebBrowserPage import WebBrowserPage |
64 from .WebBrowserPage import WebBrowserPage |
|
65 |
|
66 |
|
67 def isCupsAvailable(): |
|
68 """ |
|
69 Static method to test the availability of CUPS. |
|
70 |
|
71 @return flag indicating the availability of CUPS |
|
72 @rtype bool |
|
73 """ |
|
74 if OSUtilities.isMacPlatform(): |
|
75 # OS X/MacOS always have CUPS |
|
76 return True |
|
77 elif OSUtilities.isLinuxPlatform(): |
|
78 testPrinter = QPrinter() |
|
79 return testPrinter.supportsMultipleCopies() |
|
80 else: |
|
81 return False |
49 |
82 |
50 |
83 |
51 class WebBrowserView(QWebEngineView): |
84 class WebBrowserView(QWebEngineView): |
52 """ |
85 """ |
53 Class implementing the web browser view widget. |
86 Class implementing the web browser view widget. |
2297 return self.__page.getSafeBrowsingStatus() |
2335 return self.__page.getSafeBrowsingStatus() |
2298 else: |
2336 else: |
2299 return True |
2337 return True |
2300 |
2338 |
2301 ########################################################################### |
2339 ########################################################################### |
2302 ## Methods below implement print support from the page |
2340 ## Methods below implement print support |
2303 ########################################################################### |
2341 ########################################################################### |
2304 |
2342 |
|
2343 def __setupPrinter(self, filePath=None): |
|
2344 """ |
|
2345 Private method to create and initialize a QPrinter object. |
|
2346 |
|
2347 @param filePath name of the output file for the printer (defaults to None) |
|
2348 @type str (optional) |
|
2349 @return initialized QPrinter object |
|
2350 @rtype QPrinter |
|
2351 """ |
|
2352 printer = QPrinter(mode=QPrinter.PrinterMode.HighResolution) |
|
2353 if Preferences.getPrinter("ColorMode"): |
|
2354 printer.setColorMode(QPrinter.ColorMode.Color) |
|
2355 else: |
|
2356 printer.setColorMode(QPrinter.ColorMode.GrayScale) |
|
2357 if Preferences.getPrinter("FirstPageFirst"): |
|
2358 printer.setPageOrder(QPrinter.PageOrder.FirstPageFirst) |
|
2359 else: |
|
2360 printer.setPageOrder(QPrinter.PageOrder.LastPageFirst) |
|
2361 printer.setPageMargins( |
|
2362 QMarginsF( |
|
2363 Preferences.getPrinter("LeftMargin") * 10, |
|
2364 Preferences.getPrinter("TopMargin") * 10, |
|
2365 Preferences.getPrinter("RightMargin") * 10, |
|
2366 Preferences.getPrinter("BottomMargin") * 10, |
|
2367 ), |
|
2368 QPageLayout.Unit.Millimeter, |
|
2369 ) |
|
2370 printerName = Preferences.getPrinter("PrinterName") |
|
2371 if printerName: |
|
2372 printer.setPrinterName(printerName) |
|
2373 printer.setResolution(Preferences.getPrinter("Resolution")) |
|
2374 documentName = WebBrowserTools.getFileNameFromUrl(self.url()) |
|
2375 printer.setDocName(documentName) |
|
2376 documentsPath = QStandardPaths.writableLocation( |
|
2377 QStandardPaths.StandardLocation.DocumentsLocation |
|
2378 ) |
|
2379 if filePath is None: |
|
2380 filePath = "{0}.pdf".format(documentName) |
|
2381 filePath = ( |
|
2382 os.path.join(documentsPath, filePath) |
|
2383 if documentsPath |
|
2384 else os.path.abspath(filePath) |
|
2385 ) |
|
2386 printer.setOutputFileName(filePath) |
|
2387 printer.setCreator(self.tr("eric7 {0} ({1})").format(VersionOnly, Homepage)) |
|
2388 return printer |
|
2389 |
2305 @pyqtSlot() |
2390 @pyqtSlot() |
2306 def __printPage(self): |
2391 def printPage(self): |
2307 """ |
2392 """ |
2308 Private slot to support printing from the web page. |
2393 Public slot to print the current page. |
2309 """ |
2394 """ |
2310 self.__mw.tabWidget.printBrowser(browser=self) |
2395 if self.__currentPrinter is not None: |
|
2396 EricMessageBox.warning( |
|
2397 self, |
|
2398 self.tr("Print Page"), |
|
2399 self.tr( |
|
2400 "There is already a print job in progress. Printing is temporarily" |
|
2401 " disabled until the current job is finished." |
|
2402 ), |
|
2403 ) |
|
2404 return |
|
2405 |
|
2406 printer = self.__setupPrinter() |
|
2407 |
|
2408 printDialog = QPrintDialog(printer, self) |
|
2409 printDialog.setOptions( |
|
2410 QAbstractPrintDialog.PrintDialogOption.PrintToFile |
|
2411 | QAbstractPrintDialog.PrintDialogOption.PrintShowPageSize |
|
2412 ) |
|
2413 if not OSUtilities.isWindowsPlatform(): |
|
2414 if isCupsAvailable(): |
|
2415 printDialog.setOption( |
|
2416 QAbstractPrintDialog.PrintDialogOption.PrintCollateCopies |
|
2417 ) |
|
2418 printDialog.setOption(QAbstractPrintDialog.PrintDialogOption.PrintPageRange) |
|
2419 if printDialog.exec() == QDialog.DialogCode.Accepted: |
|
2420 if printer.outputFormat() == QPrinter.OutputFormat.PdfFormat: |
|
2421 self.printToPdf( |
|
2422 printer.outputFileName(), printer.pageLayout(), printer.pageRanges() |
|
2423 ) |
|
2424 else: |
|
2425 self.__currentPrinter = printer |
|
2426 self.print(printer) |
|
2427 |
|
2428 @pyqtSlot() |
|
2429 def printPageToPdf(self): |
|
2430 """ |
|
2431 Public slot to save the current page as a PDF file. |
|
2432 """ |
|
2433 from .Tools.PrintToPdfDialog import PrintToPdfDialog |
|
2434 |
|
2435 name = WebBrowserTools.getFileNameFromUrl(self.url()) |
|
2436 name = name.rsplit(".", 1)[0] + ".pdf" if name else "printout.pdf" |
|
2437 dlg = PrintToPdfDialog(self.__setupPrinter(filePath=name), self) |
|
2438 if dlg.exec() == QDialog.DialogCode.Accepted: |
|
2439 filePath, pageLayout = dlg.getData() |
|
2440 if filePath: |
|
2441 if os.path.exists(filePath): |
|
2442 res = EricMessageBox.warning( |
|
2443 self, |
|
2444 self.tr("Print to PDF"), |
|
2445 self.tr( |
|
2446 """<p>The file <b>{0}</b> exists""" |
|
2447 """ already. Shall it be""" |
|
2448 """ overwritten?</p>""" |
|
2449 ).format(filePath), |
|
2450 EricMessageBox.No | EricMessageBox.Yes, |
|
2451 EricMessageBox.No, |
|
2452 ) |
|
2453 if res == EricMessageBox.No: |
|
2454 return |
|
2455 self.printToPdf(filePath, pageLayout) |
|
2456 |
|
2457 @pyqtSlot() |
|
2458 def printPreviewPage(self): |
|
2459 """ |
|
2460 Public slot to create a print preview of the current page. |
|
2461 """ |
|
2462 printer = self.__setupPrinter() |
|
2463 preview = QPrintPreviewDialog(printer, self) |
|
2464 preview.resize(800, 750) |
|
2465 preview.paintRequested.connect(self.__printPreviewRequested) |
|
2466 preview.exec() |
|
2467 |
|
2468 @pyqtSlot(QPrinter) |
|
2469 def __printPreviewRequested(self, printer): |
|
2470 """ |
|
2471 Private slot to generate the print preview. |
|
2472 |
|
2473 @param printer reference to the printer object |
|
2474 @type QPrinter |
|
2475 """ |
|
2476 # This needs to run its own event loop to prevent a premature return from |
|
2477 # the method. |
|
2478 self.__printPreviewLoop = QEventLoop() |
|
2479 |
|
2480 self.print(printer) |
|
2481 |
|
2482 self.__printPreviewLoop.exec() |
|
2483 self.__printPreviewLoop = None |
|
2484 |
|
2485 @pyqtSlot(bool) |
|
2486 def __printPageFinished(self, success): |
|
2487 """ |
|
2488 Private slot to handle the finishing of a print job. |
|
2489 |
|
2490 @param success flag indicating success (not used) |
|
2491 @type bool |
|
2492 """ |
|
2493 if self.__printPreviewLoop is not None: |
|
2494 # The print preview was created, now stop the print preview loop. |
|
2495 self.__printPreviewLoop.quit() |
|
2496 return |
|
2497 |
|
2498 # we printed to a real printer |
|
2499 self.__currentPrinter = None |
|
2500 |
|
2501 @pyqtSlot(str, bool) |
|
2502 def __printPageToPdfFinished(self, filepath, success): |
|
2503 """ |
|
2504 Private slot to handle the finishing of a PDF print job. |
|
2505 |
|
2506 @param filepath path of the output PDF file |
|
2507 @type str |
|
2508 @param success flag indicating success |
|
2509 @type bool |
|
2510 """ |
|
2511 if not success: |
|
2512 EricMessageBox.critical( |
|
2513 self, |
|
2514 self.tr("Print to PDF"), |
|
2515 self.tr( |
|
2516 """<p>The PDF file <b>{0}</b> could not be generated.</p>""" |
|
2517 ).format(filepath), |
|
2518 ) |
2311 |
2519 |
2312 ########################################################################### |
2520 ########################################################################### |
2313 ## Methods below implement slots for Qt 6.0 to 6.4 |
2521 ## Methods below implement slots for Qt 6.0 to 6.4 |
2314 ########################################################################### |
2522 ########################################################################### |
2315 |
2523 |