src/eric7/PdfViewer/PdfViewerWindow.py

branch
pdf_viewer
changeset 9704
6e1650b9b3b5
parent 9702
7c973954919d
child 9706
c0ff0b4d5657
equal deleted inserted replaced
9702:7c973954919d 9704:6e1650b9b3b5
10 import contextlib 10 import contextlib
11 import os 11 import os
12 import pathlib 12 import pathlib
13 13
14 from PyQt6.QtCore import Qt, pyqtSignal, QSize, pyqtSlot, QPointF 14 from PyQt6.QtCore import Qt, pyqtSignal, QSize, pyqtSlot, QPointF
15 from PyQt6.QtGui import QAction, QKeySequence, QGuiApplication, QActionGroup 15 from PyQt6.QtGui import (
16 from PyQt6.QtPdf import QPdfDocument 16 QAction, QKeySequence, QActionGroup, QGuiApplication, QClipboard
17 )
18 from PyQt6.QtPdf import QPdfDocument, QPdfLink
17 from PyQt6.QtPdfWidgets import QPdfView 19 from PyQt6.QtPdfWidgets import QPdfView
18 from PyQt6.QtWidgets import ( 20 from PyQt6.QtWidgets import (
19 QWhatsThis, QMenu, QTabWidget, QSplitter, QToolBar, QDialog 21 QWhatsThis, QMenu, QTabWidget, QSplitter, QToolBar, QDialog
20 ) 22 )
21 23
30 32
31 from .PdfPageSelector import PdfPageSelector 33 from .PdfPageSelector import PdfPageSelector
32 from .PdfZoomSelector import PdfZoomSelector 34 from .PdfZoomSelector import PdfZoomSelector
33 from .PdfToCWidget import PdfToCWidget 35 from .PdfToCWidget import PdfToCWidget
34 from .PdfInfoWidget import PdfInfoWidget 36 from .PdfInfoWidget import PdfInfoWidget
37 from .PdfSearchWidget import PdfSearchWidget
38 from .PdfView import PdfView
35 39
36 40
37 class PdfViewerWindow(EricMainWindow): 41 class PdfViewerWindow(EricMainWindow):
38 """ 42 """
39 Class implementing the PDF viewer main window. 43 Class implementing the PDF viewer main window.
65 self.setObjectName("eric7_pdf_viewer") 69 self.setObjectName("eric7_pdf_viewer")
66 70
67 self.__fromEric = fromEric 71 self.__fromEric = fromEric
68 self.setWindowIcon(EricPixmapCache.getIcon("ericPdf")) 72 self.setWindowIcon(EricPixmapCache.getIcon("ericPdf"))
69 73
70 self.__screenResolution = (
71 QGuiApplication.primaryScreen().logicalDotsPerInch() / 72.0
72 )
73
74 if not self.__fromEric: 74 if not self.__fromEric:
75 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) 75 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet"))
76 76
77 self.__pdfDocument = QPdfDocument(self) 77 self.__pdfDocument = QPdfDocument(self)
78 78
79 self.__cw = QSplitter(Qt.Orientation.Horizontal, self) 79 self.__cw = QSplitter(Qt.Orientation.Horizontal, self)
80 self.__cw.setChildrenCollapsible(False)
80 self.__info = QTabWidget(self) 81 self.__info = QTabWidget(self)
81 self.__cw.addWidget(self.__info) 82 self.__cw.addWidget(self.__info)
82 self.__view = QPdfView(self) 83 self.__view = PdfView(self)
83 self.__view.setDocument(self.__pdfDocument) 84 self.__view.setDocument(self.__pdfDocument)
84 self.__cw.addWidget(self.__view) 85 self.__cw.addWidget(self.__view)
85 self.setCentralWidget(self.__cw) 86 self.setCentralWidget(self.__cw)
86 87
87 # create the various info widgets 88 # create the various info widgets
88 self.__documentInfoWidget = PdfInfoWidget(self.__pdfDocument, self) 89 self.__documentInfoWidget = PdfInfoWidget(self.__pdfDocument, self)
89 index = self.__info.addTab( 90 index = self.__info.addTab(
90 self.__documentInfoWidget, EricPixmapCache.getIcon("documentProperties"), "" 91 self.__documentInfoWidget, EricPixmapCache.getIcon("documentProperties"), ""
91 ) 92 )
92 self.__info.setTabToolTip(index, self.tr("Document Properties")) 93 self.__info.setTabToolTip(index, self.tr("Document Properties"))
93 94
95 self.__searchWidget = PdfSearchWidget(self.__pdfDocument, self)
96 index = self.__info.addTab(
97 self.__searchWidget, EricPixmapCache.getIcon("find"), ""
98 )
99 self.__info.setTabToolTip(index, self.tr("Search"))
100
94 self.__tocWidget = PdfToCWidget(self.__pdfDocument, self) 101 self.__tocWidget = PdfToCWidget(self.__pdfDocument, self)
95 index = self.__info.addTab( 102 index = self.__info.addTab(
96 self.__tocWidget, EricPixmapCache.getIcon("listSelection"), "" 103 self.__tocWidget, EricPixmapCache.getIcon("listSelection"), ""
97 ) 104 )
98 self.__info.setTabToolTip(index, self.tr("Table of Contents")) 105 self.__info.setTabToolTip(index, self.tr("Table of Contents"))
138 self.__zoomSelector.zoomFactorChanged.connect(self.__view.setZoomFactor) 145 self.__zoomSelector.zoomFactorChanged.connect(self.__view.setZoomFactor)
139 self.__view.zoomFactorChanged.connect(self.__zoomSelector.setZoomFactor) 146 self.__view.zoomFactorChanged.connect(self.__zoomSelector.setZoomFactor)
140 self.__view.zoomModeChanged.connect(self.__zoomSelector.setZoomMode) 147 self.__view.zoomModeChanged.connect(self.__zoomSelector.setZoomMode)
141 148
142 self.__tocWidget.topicActivated.connect(self.__tocActivated) 149 self.__tocWidget.topicActivated.connect(self.__tocActivated)
150 self.__searchWidget.searchResultActivated.connect(self.__handleSearchResult)
143 151
144 PdfViewerWindow.windows.append(self) 152 PdfViewerWindow.windows.append(self)
145 153
146 self.__restoreViewerState() 154 self.__restoreViewerState()
147 155
166 self.__actions = [] 174 self.__actions = []
167 175
168 self.__initFileActions() 176 self.__initFileActions()
169 self.__initGotoActions() 177 self.__initGotoActions()
170 self.__initViewActions() 178 self.__initViewActions()
179 self.__initEditActions()
180 self.__initSettingsActions()
171 self.__initHelpActions() 181 self.__initHelpActions()
172 182
173 def __initFileActions(self): 183 def __initFileActions(self):
174 """ 184 """
175 Private method to define the file related user interface actions. 185 Private method to define the file related user interface actions.
227 ) 237 )
228 self.reloadAct.setStatusTip(self.tr("Reload the current PDF document")) 238 self.reloadAct.setStatusTip(self.tr("Reload the current PDF document"))
229 self.reloadAct.triggered.connect(self.__reload) 239 self.reloadAct.triggered.connect(self.__reload)
230 self.__actions.append(self.reloadAct) 240 self.__actions.append(self.reloadAct)
231 241
232 # TODO: maybe this will be a tab of the side widget
233 self.propertiesAct = EricAction( 242 self.propertiesAct = EricAction(
234 self.tr("Properties"), 243 self.tr("Properties"),
235 EricPixmapCache.getIcon("documentProperties"), 244 EricPixmapCache.getIcon("documentProperties"),
236 self.tr("&Properties..."), 245 self.tr("&Properties..."),
237 QKeySequence(self.tr("Alt+Return")), 246 QKeySequence(self.tr("Alt+Return")),
407 416
408 def __initViewActions(self): 417 def __initViewActions(self):
409 """ 418 """
410 Private method to define the view related user interface actions. 419 Private method to define the view related user interface actions.
411 """ 420 """
421 # TODO: add Fullscreen action
412 self.zoomInAct = EricAction( 422 self.zoomInAct = EricAction(
413 self.tr("Zoom in"), 423 self.tr("Zoom in"),
414 EricPixmapCache.getIcon("zoomIn"), 424 EricPixmapCache.getIcon("zoomIn"),
415 self.tr("Zoom &in"), 425 self.tr("Zoom &in"),
416 QKeySequence(self.tr("Ctrl++", "View|Zoom in")), 426 QKeySequence(self.tr("Ctrl++", "View|Zoom in")),
469 ) 479 )
470 self.zoomWholePageAct.triggered.connect(self.__zoomWholePage) 480 self.zoomWholePageAct.triggered.connect(self.__zoomWholePage)
471 self.zoomWholePageAct.setCheckable(True) 481 self.zoomWholePageAct.setCheckable(True)
472 self.__actions.append(self.zoomWholePageAct) 482 self.__actions.append(self.zoomWholePageAct)
473 483
474 ##self.__displayModeActGrp = QActionGroup(self) 484 def __initEditActions(self):
475 ## 485 """
476 ##self.displayModeSingleAct = EricAction( 486 Private method to create the Edit actions.
477 ##self.tr("Whole Page"), 487 """
478 ##EricPixmapCache.getIcon("zoomFitPage"), 488 self.copyAllAct = EricAction(
479 ##self.tr("Whole &Page"), 489 self.tr("Copy All Text"),
480 ##0, 490 EricPixmapCache.getIcon("editCopy"),
481 ##0, 491 self.tr("&Copy All Text"),
482 ##self, 492 QKeySequence(self.tr("Ctrl+C", "Edit|Copy All Text")),
483 ##"pdfviewer_view_zoomwholePage", 493 0,
484 ##) 494 self,
485 ##self.displayModeSingleAct.triggered.connect(self.__zoomWholePage) 495 "pdfviewer_edit_copyall",
486 ##self.displayModeSingleAct.setCheckable(True) 496 )
487 ##self.__actions.append(self.displayModeSingleAct) 497 self.copyAllAct.triggered.connect(self.__copyAllText)
498 self.__actions.append(self.copyAllAct)
499
500 self.copyAllPageAct = EricAction(
501 self.tr("Copy All Page Text"),
502 self.tr("Copy &All Page Text"),
503 QKeySequence(self.tr("Shift+Ctrl+C", "Edit|Copy All Page Text")),
504 0,
505 self,
506 "pdfviewer_edit_copyallpage",
507 )
508 self.copyAllPageAct.triggered.connect(self.__copyAllTextOfPage)
509 self.__actions.append(self.copyAllPageAct)
510
511 def __initSettingsActions(self):
512 """
513 Private method to create the Settings actions.
514 """
515 self.sidebarAct = EricAction(
516 self.tr("Show Sidebar"),
517 EricPixmapCache.getIcon("sidebarExpandLeft"),
518 self.tr("Show &Sidebar"),
519 0,
520 0,
521 self,
522 "pdfviewer_settings_sidebar",
523 )
524 self.sidebarAct.triggered.connect(self.__toggleSideBar)
525 self.sidebarAct.setCheckable(True)
526 self.__actions.append(self.sidebarAct)
527
528 self.openRecentNewAct = EricAction(
529 self.tr("Open Recent File in New Window"),
530 self.tr("Open Recent File in New Window"),
531 0,
532 0,
533 self,
534 "pdfviewer_settings_openrecent new",
535 )
536 self.openRecentNewAct.triggered.connect(self.__toggleOpenRecentNew)
537 self.openRecentNewAct.setCheckable(True)
538 self.__actions.append(self.sidebarAct)
488 539
489 def __initHelpActions(self): 540 def __initHelpActions(self):
490 """ 541 """
491 Private method to create the Help actions. 542 Private method to create the Help actions.
492 """ 543 """
574 self.zoomOutAct.setEnabled(ready) 625 self.zoomOutAct.setEnabled(ready)
575 self.zoomResetAct.setEnabled(ready) 626 self.zoomResetAct.setEnabled(ready)
576 self.zoomPageWidthAct.setEnabled(ready) 627 self.zoomPageWidthAct.setEnabled(ready)
577 self.zoomWholePageAct.setEnabled(ready) 628 self.zoomWholePageAct.setEnabled(ready)
578 self.__zoomSelector.setEnabled(ready) 629 self.__zoomSelector.setEnabled(ready)
579
580 # TODO: not yet implemented
581
582 ##def setRecentPath(self, openPath):
583 ##"""
584 ##Public method to set the last open path.
585 ##
586 ##@param openPath least recently used open path
587 ##@type str
588 ##"""
589 ##if openPath:
590 ##self.__lastOpenPath = openPath
591 630
592 def __initMenus(self): 631 def __initMenus(self):
593 """ 632 """
594 Private method to create the menus. 633 Private method to create the menus.
595 """ 634 """
633 self.__displayModeActGrp = QActionGroup(self) 672 self.__displayModeActGrp = QActionGroup(self)
634 self.__displayModeActGrp.addAction(self.__singlePageAct) 673 self.__displayModeActGrp.addAction(self.__singlePageAct)
635 self.__displayModeActGrp.addAction(self.__continuousPageAct) 674 self.__displayModeActGrp.addAction(self.__continuousPageAct)
636 modeMenu.triggered.connect(self.__displayModeSelected) 675 modeMenu.triggered.connect(self.__displayModeSelected)
637 676
677 menu = mb.addMenu(self.tr("&Edit"))
678 menu.setTearOffEnabled(True)
679 menu.addAction(self.copyAllAct)
680 menu.addSeparator()
681 menu.addAction(self.copyAllPageAct)
682
638 menu = mb.addMenu(self.tr("&Go To")) 683 menu = mb.addMenu(self.tr("&Go To"))
639 menu.setTearOffEnabled(True) 684 menu.setTearOffEnabled(True)
640 menu.addAction(self.previousPageAct) 685 menu.addAction(self.previousPageAct)
641 menu.addAction(self.nextPageAct) 686 menu.addAction(self.nextPageAct)
642 menu.addSeparator() 687 menu.addSeparator()
646 menu.addAction(self.backwardAct) 691 menu.addAction(self.backwardAct)
647 menu.addAction(self.forwardAct) 692 menu.addAction(self.forwardAct)
648 menu.addSeparator() 693 menu.addSeparator()
649 menu.addAction(self.gotoAct) 694 menu.addAction(self.gotoAct)
650 695
696 menu = mb.addMenu(self.tr("Se&ttings"))
697 menu.setTearOffEnabled(True)
698 menu.addAction(self.sidebarAct)
699 menu.addSeparator()
700 menu.addAction(self.openRecentNewAct)
701
651 mb.addSeparator() 702 mb.addSeparator()
652 703
653 menu = mb.addMenu(self.tr("&Help")) 704 menu = mb.addMenu(self.tr("&Help"))
654 menu.addAction(self.aboutAct) 705 menu.addAction(self.aboutAct)
655 menu.addAction(self.aboutQtAct) 706 menu.addAction(self.aboutQtAct)
662 """ 713 """
663 mainToolBar = QToolBar() 714 mainToolBar = QToolBar()
664 mainToolBar.setObjectName("main_toolbar") 715 mainToolBar.setObjectName("main_toolbar")
665 mainToolBar.setMovable(False) 716 mainToolBar.setMovable(False)
666 mainToolBar.setFloatable(False) 717 mainToolBar.setFloatable(False)
718
719 # 0. Sidebar action
720 mainToolBar.addAction(self.sidebarAct)
721 mainToolBar.addSeparator()
667 722
668 # 1. File actions 723 # 1. File actions
669 mainToolBar.addAction(self.newWindowAct) 724 mainToolBar.addAction(self.newWindowAct)
670 mainToolBar.addAction(self.openAct) 725 mainToolBar.addAction(self.openAct)
671 mainToolBar.addSeparator() 726 mainToolBar.addSeparator()
681 mainToolBar.addAction(self.endDocumentAct) 736 mainToolBar.addAction(self.endDocumentAct)
682 mainToolBar.addWidget(EricStretchableSpacer()) 737 mainToolBar.addWidget(EricStretchableSpacer())
683 mainToolBar.addSeparator() 738 mainToolBar.addSeparator()
684 739
685 # 3. View actions 740 # 3. View actions
686 # TODO: not yet implemented
687 mainToolBar.addAction(self.zoomOutAct) 741 mainToolBar.addAction(self.zoomOutAct)
688 mainToolBar.addWidget(self.__zoomSelector) 742 mainToolBar.addWidget(self.__zoomSelector)
689 mainToolBar.addAction(self.zoomInAct) 743 mainToolBar.addAction(self.zoomInAct)
690 mainToolBar.addAction(self.zoomResetAct) 744 mainToolBar.addAction(self.zoomResetAct)
691 mainToolBar.addAction(self.zoomPageWidthAct) 745 mainToolBar.addAction(self.zoomPageWidthAct)
725 779
726 def __saveViewerState(self): 780 def __saveViewerState(self):
727 """ 781 """
728 Private method to save the PDF Viewer state data. 782 Private method to save the PDF Viewer state data.
729 """ 783 """
730 # TODO: save current zoom factor and mode + page mode
731 state = self.saveState() 784 state = self.saveState()
732 Preferences.setPdfViewer("PdfViewerState", state) 785 Preferences.setPdfViewer("PdfViewerState", state)
733 splitterState = self.__cw.saveState() 786 splitterState = self.__cw.saveState()
734 Preferences.setPdfViewer("PdfViewerSplitterState", splitterState) 787 Preferences.setPdfViewer("PdfViewerSplitterState", splitterState)
788 Preferences.setPdfViewer("PdfViewerSidebarVisible", self.sidebarAct.isChecked())
789 Preferences.setPdfViewer("PdfViewerZoomFactor", self.__view.zoomFactor())
790 Preferences.setPdfViewer("PdfViewerZoomMode", self.__view.zoomMode())
791 Preferences.setPdfViewer(
792 "PdfViewerOpenRecentInNewWindow", self.openRecentNewAct.isChecked()
793 )
735 794
736 if not self.__fromEric: 795 if not self.__fromEric:
737 Preferences.syncPreferences() 796 Preferences.syncPreferences()
738 797
739 def __restoreViewerState(self): 798 def __restoreViewerState(self):
740 """ 799 """
741 Private method to restore the PDF Viewer state data. 800 Private method to restore the PDF Viewer state data.
742 """ 801 """
743 # TODO: restore zoom factor and mode + page mode
744 state = Preferences.getPdfViewer("PdfViewerState") 802 state = Preferences.getPdfViewer("PdfViewerState")
745 self.restoreState(state) 803 self.restoreState(state)
746 splitterState = Preferences.getPdfViewer("PdfViewerSplitterState") 804 splitterState = Preferences.getPdfViewer("PdfViewerSplitterState")
747 self.__cw.restoreState(splitterState) 805 self.__cw.restoreState(splitterState)
806 self.__toggleSideBar(Preferences.getPdfViewer("PdfViewerSidebarVisible"))
807 self.__view.setZoomFactor(Preferences.getPdfViewer("PdfViewerZoomFactor"))
808 self.__view.setZoomMode(Preferences.getPdfViewer("PdfViewerZoomMode"))
809 self.openRecentNewAct.setChecked(
810 Preferences.getPdfViewer("PdfViewerOpenRecentInNewWindow")
811 )
748 812
749 def __setViewerTitle(self, title): 813 def __setViewerTitle(self, title):
750 """ 814 """
751 Private method to set the viewer title. 815 Private method to set the viewer title.
752 816
847 ) 911 )
848 if fileName: 912 if fileName:
849 self.__loadPdfFile(fileName) 913 self.__loadPdfFile(fileName)
850 914
851 @pyqtSlot() 915 @pyqtSlot()
852 def __openPdfFileNewWindow(self): 916 def __openPdfFileNewWindow(self, fileName=""):
853 """ 917 """
854 Private slot called to open a PDF file in new viewer window. 918 Private slot called to open a PDF file in new viewer window.
919
920 @param fileName name of the file to open (defaults to "")
921 @type str (optional)
855 """ 922 """
856 if ( 923 if (
857 not self.__lastOpenPath 924 not self.__lastOpenPath
858 and self.__project is not None 925 and self.__project is not None
859 and self.__project.isOpen() 926 and self.__project.isOpen()
860 ): 927 ):
861 self.__lastOpenPath = self.__project.getProjectPath() 928 self.__lastOpenPath = self.__project.getProjectPath()
862 929
863 fileName = EricFileDialog.getOpenFileName( 930 if not fileName:
864 self, 931 fileName = EricFileDialog.getOpenFileName(
865 self.tr("Open PDF File"), 932 self,
866 self.__lastOpenPath, 933 self.tr("Open PDF File"),
867 self.tr("PDF Files (*.pdf);;All Files (*)"), 934 self.__lastOpenPath,
868 ) 935 self.tr("PDF Files (*.pdf);;All Files (*)"),
936 )
869 if fileName: 937 if fileName:
870 viewer = PdfViewerWindow( 938 viewer = PdfViewerWindow(
871 fileName=fileName, 939 fileName=fileName,
872 parent=self.parent(), 940 parent=self.parent(),
873 fromEric=self.__fromEric, 941 fromEric=self.__fromEric,
915 @param zoomFactor zoom factor 983 @param zoomFactor zoom factor
916 @type float 984 @type float
917 """ 985 """
918 nav = self.__view.pageNavigator() 986 nav = self.__view.pageNavigator()
919 nav.jump(page, QPointF(), zoomFactor) 987 nav.jump(page, QPointF(), zoomFactor)
988
989 @pyqtSlot(QPdfLink)
990 def __handleSearchResult(self, link):
991 """
992 Private slot to handle the selection of a search result.
993
994 @param link PDF link to navigate to
995 @type QPdfLink
996 """
997 self.__view.pageNavigator().jump(link)
920 998
921 def __setCurrentFile(self, fileName): 999 def __setCurrentFile(self, fileName):
922 """ 1000 """
923 Private method to register the file name of the current file. 1001 Private method to register the file name of the current file.
924 1002
1006 Private method to open a file from the list of recently opened files. 1084 Private method to open a file from the list of recently opened files.
1007 1085
1008 @param act reference to the action that triggered 1086 @param act reference to the action that triggered
1009 @type QAction 1087 @type QAction
1010 """ 1088 """
1011 # TODO: add config option to open recent files in new viewer or the same one
1012 fileName = act.data() 1089 fileName = act.data()
1013 self.__loadPdfFile(fileName) 1090 if Preferences.getPdfViewer("PdfViewerOpenRecentInNewWindow"):
1091 self.__openPdfFileNewWindow(fileName)
1092 else:
1093 self.__loadPdfFile(fileName)
1014 1094
1015 @pyqtSlot() 1095 @pyqtSlot()
1016 def __clearRecent(self): 1096 def __clearRecent(self):
1017 """ 1097 """
1018 Private method to clear the list of recently opened files. 1098 Private method to clear the list of recently opened files.
1057 @pyqtSlot() 1137 @pyqtSlot()
1058 def __showDocumentProperties(self): 1138 def __showDocumentProperties(self):
1059 """ 1139 """
1060 Private slot to open a dialog showing the document properties. 1140 Private slot to open a dialog showing the document properties.
1061 """ 1141 """
1062 # TODO: not yet implemented 1142 self.__toggleSideBar(True)
1143 self.__info.setCurrentWidget(self.__documentInfoWidget)
1063 1144
1064 @pyqtSlot() 1145 @pyqtSlot()
1065 def __gotoPage(self): 1146 def __gotoPage(self):
1066 """ 1147 """
1067 Private slot to show a dialog to select a page to jump to. 1148 Private slot to show a dialog to select a page to jump to.
1068 """ 1149 """
1069 # TODO: not yet implemented
1070 from .PdfGoToDialog import PdfGoToDialog 1150 from .PdfGoToDialog import PdfGoToDialog
1071 1151
1072 dlg = PdfGoToDialog( 1152 dlg = PdfGoToDialog(
1073 self.__view.pageNavigator().currentPage(), 1153 self.__view.pageNavigator().currentPage(),
1074 self.__pdfDocument.pageCount(), 1154 self.__pdfDocument.pageCount(),
1122 """ 1202 """
1123 Private slot to go forward in the view history. 1203 Private slot to go forward in the view history.
1124 """ 1204 """
1125 self.__view.pageNavigator().forward() 1205 self.__view.pageNavigator().forward()
1126 1206
1127 def __zoomInOut(self, zoomIn):
1128 """
1129 Private method to zoom into or out of the view.
1130
1131 @param zoomIn flag indicating to zoom into the view
1132 @type bool
1133 """
1134 zoomFactor = self.__zoomFactorForMode(self.__view.zoomMode())
1135
1136 factors = list(PdfZoomSelector.ZoomValues)
1137 factors.append(self.__zoomFactorForMode(QPdfView.ZoomMode.FitInView))
1138 factors.append(self.__zoomFactorForMode(QPdfView.ZoomMode.FitToWidth))
1139 if zoomIn:
1140 factors.sort()
1141 if zoomFactor >= factors[-1]:
1142 return
1143 newIndex = next(x for x, val in enumerate(factors) if val > zoomFactor)
1144 else:
1145 factors.sort(reverse=True)
1146 if zoomFactor <= factors[-1]:
1147 return
1148 newIndex = next(x for x, val in enumerate(factors) if val < zoomFactor)
1149 newFactor = factors[newIndex]
1150 if newFactor == self.__zoomFactorForMode(QPdfView.ZoomMode.FitInView):
1151 self.__zoomWholePage(True)
1152 elif newFactor == self.__zoomFactorForMode(QPdfView.ZoomMode.FitToWidth):
1153 self.__zoomPageWidth(True)
1154 else:
1155 self.__view.setZoomFactor(newFactor)
1156 self.__zoomSelector.setZoomFactor(newFactor)
1157 self.__zoomModeChanged(QPdfView.ZoomMode.Custom)
1158
1159 @pyqtSlot() 1207 @pyqtSlot()
1160 def __zoomIn(self): 1208 def __zoomIn(self):
1161 """ 1209 """
1162 Private slot to zoom into the view. 1210 Private slot to zoom into the view.
1163 """ 1211 """
1164 self.__zoomInOut(True) 1212 self.__view.zoomIn()
1165 1213
1166 @pyqtSlot() 1214 @pyqtSlot()
1167 def __zoomOut(self): 1215 def __zoomOut(self):
1168 """ 1216 """
1169 Private slot to zoom out of the view. 1217 Private slot to zoom out of the view.
1170 """ 1218 """
1171 self.__zoomInOut(False) 1219 self.__view.zoomOut()
1172 1220
1173 @pyqtSlot() 1221 @pyqtSlot()
1174 def __zoomReset(self): 1222 def __zoomReset(self):
1175 """ 1223 """
1176 Private slot to reset the zoom factor of the view. 1224 Private slot to reset the zoom factor of the view.
1177 """ 1225 """
1178 self.__view.setZoomFactor(1.0) 1226 self.__view.zoomReset()
1179 self.__zoomSelector.setZoomFactor(1.0)
1180 self.__zoomModeChanged(QPdfView.ZoomMode.Custom)
1181 1227
1182 @pyqtSlot(bool) 1228 @pyqtSlot(bool)
1183 def __zoomPageWidth(self, checked): 1229 def __zoomPageWidth(self, checked):
1184 """ 1230 """
1185 Private slot to fit the page width. 1231 Private slot to fit the page width.
1211 @param zoomMode new zoom mode 1257 @param zoomMode new zoom mode
1212 @type QPdfView.ZoomMode 1258 @type QPdfView.ZoomMode
1213 """ 1259 """
1214 self.zoomWholePageAct.setChecked(zoomMode == QPdfView.ZoomMode.FitInView) 1260 self.zoomWholePageAct.setChecked(zoomMode == QPdfView.ZoomMode.FitInView)
1215 self.zoomPageWidthAct.setChecked(zoomMode == QPdfView.ZoomMode.FitToWidth) 1261 self.zoomPageWidthAct.setChecked(zoomMode == QPdfView.ZoomMode.FitToWidth)
1216
1217 def __zoomFactorForMode(self, zoomMode):
1218 """
1219 Private method to calculate the zoom factor iaw. the current zoom mode.
1220
1221 @param zoomMode zoom mode to get the zoom factor for
1222 @type QPdfView.ZoomMode
1223 @return zoom factor
1224 @rtype float
1225 """
1226 if zoomMode == QPdfView.ZoomMode.Custom:
1227 return self.__view.zoomFactor()
1228 else:
1229 viewport = self.__view.viewport()
1230 curPage = self.__view.pageNavigator().currentPage()
1231 margins = self.__view.documentMargins()
1232 if zoomMode == QPdfView.ZoomMode.FitToWidth:
1233 pageSize = (
1234 self.__pdfDocument.pagePointSize(curPage) * self.__screenResolution
1235 ).toSize()
1236 factor = (
1237 viewport.width() - margins.left() - margins.right()
1238 ) / pageSize.width()
1239 pageSize *= factor
1240 else:
1241 # QPdfView.ZoomMode.FitInView
1242 viewportSize = viewport.size() + QSize(
1243 -margins.left() - margins.right(), -self.__view.pageSpacing()
1244 )
1245 pageSize = (
1246 self.__pdfDocument.pagePointSize(curPage) * self.__screenResolution
1247 ).toSize()
1248 pageSize = pageSize.scaled(
1249 viewportSize, Qt.AspectRatioMode.KeepAspectRatio
1250 )
1251 zoomFactor = pageSize.width() / (
1252 self.__pdfDocument.pagePointSize(curPage) * self.__screenResolution
1253 ).width()
1254 return zoomFactor
1255
1256 @pyqtSlot()
1257 def __setFocusToView(self):
1258 """
1259 Private slot to set the focus to the PDF document view.
1260 """
1261 self.__view.setFocus(Qt.FocusReason.OtherFocusReason)
1262 1262
1263 @pyqtSlot(QAction) 1263 @pyqtSlot(QAction)
1264 def __displayModeSelected(self, act): 1264 def __displayModeSelected(self, act):
1265 """ 1265 """
1266 Private slot to handle the selection of a display mode. 1266 Private slot to handle the selection of a display mode.
1283 self.__singlePageAct.setChecked(True) 1283 self.__singlePageAct.setChecked(True)
1284 else: 1284 else:
1285 self.__view.setPageMode(QPdfView.PageMode.MultiPage) 1285 self.__view.setPageMode(QPdfView.PageMode.MultiPage)
1286 self.__continuousPageAct.setChecked(True) 1286 self.__continuousPageAct.setChecked(True)
1287 return 1287 return
1288
1289 @pyqtSlot(bool)
1290 def __toggleSideBar(self, visible):
1291 """
1292 Private slot to togle the sidebar (info) widget.
1293
1294 @param visible desired state of the sidebar
1295 @type bool
1296 """
1297 self.sidebarAct.setChecked(visible)
1298 self.__info.setVisible(visible)
1299 Preferences.setPdfViewer("PdfViewerSidebarVisible", visible)
1300
1301 @pyqtSlot(bool)
1302 def __toggleOpenRecentNew(self, on):
1303 """
1304 Private slot to toggle the 'Open Recent File in New Window' action.
1305
1306 @param on desired state of the action
1307 @type bool
1308 """
1309 Preferences.setPdfViewer("PdfViewerOpenRecentInNewWindow", on)
1310
1311 @pyqtSlot()
1312 def __copyAllTextOfPage(self):
1313 """
1314 Private slot to copy all text of the current page to the system clipboard.
1315 """
1316 selection = self.__pdfDocument.getAllText(
1317 self.__view.pageNavigator().currentPage()
1318 )
1319 selection.copyToClipboard()
1320
1321 @pyqtSlot()
1322 def __copyAllText(self):
1323 """
1324 Private slot to copy all text of the document to the system clipboard.
1325 """
1326 textPages = []
1327 for page in range(self.__pdfDocument.pageCount()):
1328 textPages.append(self.__pdfDocument.getAllText(page).text())
1329 QGuiApplication.clipboard().setText(
1330 "\r\n".join(textPages), QClipboard.Mode.Clipboard
1331 )

eric ide

mercurial