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 ) |