src/eric7/PdfViewer/PdfView.py

branch
pdf_viewer
changeset 9704
6e1650b9b3b5
child 9707
717f95e35ca8
equal deleted inserted replaced
9702:7c973954919d 9704:6e1650b9b3b5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a specialized PDF view class.
8 """
9
10 from PyQt6.QtCore import QSize, Qt, pyqtSlot, QEvent
11 from PyQt6.QtGui import QGuiApplication
12 from PyQt6.QtPdfWidgets import QPdfView
13
14 from .PdfZoomSelector import PdfZoomSelector
15
16
17 class PdfView(QPdfView):
18 """
19 Class implementing a specialized PDF view.
20 """
21
22 def __init__(self, parent):
23 """
24 Constructor
25
26 @param parent reference to the parent widget
27 @type QWidget
28 """
29 super().__init__(parent)
30
31 self.__screenResolution = (
32 QGuiApplication.primaryScreen().logicalDotsPerInch() / 72.0
33 )
34
35 self.grabGesture(Qt.GestureType.PinchGesture)
36
37 def __zoomInOut(self, zoomIn):
38 """
39 Private method to zoom into or out of the view.
40
41 @param zoomIn flag indicating to zoom into the view
42 @type bool
43 """
44 zoomFactor = self.__zoomFactorForMode(self.zoomMode())
45
46 factors = list(PdfZoomSelector.ZoomValues)
47 factors.append(self.__zoomFactorForMode(QPdfView.ZoomMode.FitInView))
48 factors.append(self.__zoomFactorForMode(QPdfView.ZoomMode.FitToWidth))
49 if zoomIn:
50 factors.sort()
51 if zoomFactor >= factors[-1]:
52 return
53 newIndex = next(x for x, val in enumerate(factors) if val > zoomFactor)
54 else:
55 factors.sort(reverse=True)
56 if zoomFactor <= factors[-1]:
57 return
58 newIndex = next(x for x, val in enumerate(factors) if val < zoomFactor)
59 newFactor = factors[newIndex]
60 if newFactor == self.__zoomFactorForMode(QPdfView.ZoomMode.FitInView):
61 self.setZoomMode(QPdfView.ZoomMode.FitInView)
62 self.zoomModeChanged.emit(QPdfView.ZoomMode.FitInView)
63 elif newFactor == self.__zoomFactorForMode(QPdfView.ZoomMode.FitToWidth):
64 self.setZoomMode(QPdfView.ZoomMode.FitToWidth)
65 self.zoomModeChanged.emit(QPdfView.ZoomMode.FitToWidth)
66 else:
67 self.setZoomFactor(newFactor)
68 self.zoomFactorChanged.emit(newFactor)
69 self.setZoomMode(QPdfView.ZoomMode.Custom)
70 self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
71
72 def __zoomFactorForMode(self, zoomMode):
73 """
74 Private method to calculate the zoom factor iaw. the current zoom mode.
75
76 @param zoomMode zoom mode to get the zoom factor for
77 @type QPdfView.ZoomMode
78 @return zoom factor
79 @rtype float
80 """
81 if zoomMode == QPdfView.ZoomMode.Custom:
82 return self.zoomFactor()
83 else:
84 viewport = self.viewport()
85 curPage = self.pageNavigator().currentPage()
86 margins = self.documentMargins()
87 if zoomMode == QPdfView.ZoomMode.FitToWidth:
88 pageSize = (
89 self.document().pagePointSize(curPage) * self.__screenResolution
90 ).toSize()
91 factor = (
92 viewport.width() - margins.left() - margins.right()
93 ) / pageSize.width()
94 pageSize *= factor
95 else:
96 # QPdfView.ZoomMode.FitInView
97 viewportSize = viewport.size() + QSize(
98 -margins.left() - margins.right(), -self.pageSpacing()
99 )
100 pageSize = (
101 self.document().pagePointSize(curPage) * self.__screenResolution
102 ).toSize()
103 pageSize = pageSize.scaled(
104 viewportSize, Qt.AspectRatioMode.KeepAspectRatio
105 )
106 zoomFactor = pageSize.width() / (
107 self.document().pagePointSize(curPage) * self.__screenResolution
108 ).width()
109 return zoomFactor
110
111 @pyqtSlot()
112 def zoomIn(self):
113 """
114 Public slot to zoom into the view.
115 """
116 self.__zoomInOut(True)
117
118 @pyqtSlot()
119 def zoomOut(self):
120 """
121 Public slot to zoom out of the view.
122 """
123 self.__zoomInOut(False)
124
125 @pyqtSlot()
126 def zoomReset(self):
127 """
128 Public slot to reset the zoom factor of the view.
129 """
130 if self.zoomMode() != QPdfView.ZoomMode.Custom or self.zoomFactor() != 1.0:
131 self.setZoomFactor(1.0)
132 self.zoomFactorChanged.emit(1.0)
133 self.setZoomMode(QPdfView.ZoomMode.Custom)
134 self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
135
136 def wheelEvent(self, evt):
137 """
138 Protected method to handle wheel events.
139
140 @param evt reference to the wheel event
141 @type QWheelEvent
142 """
143 delta = evt.angleDelta().y()
144 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier:
145 if delta < 0:
146 self.zoomOut()
147 elif delta > 0:
148 self.zoomIn()
149 evt.accept()
150 return
151
152 elif evt.modifiers() & Qt.KeyboardModifier.ShiftModifier:
153 if delta < 0:
154 self.pageNavigator().back()
155 elif delta > 0:
156 self.pageNavigator().forward()
157 evt.accept()
158 return
159
160 super().wheelEvent(evt)
161
162 def event(self, evt):
163 """
164 Public method handling events.
165
166 @param evt reference to the event
167 @type QEvent
168 @return flag indicating, if the event was handled
169 @rtype bool
170 """
171 if evt.type() == QEvent.Type.Gesture:
172 self.gestureEvent(evt)
173 return True
174
175 return super().event(evt)
176
177 def gestureEvent(self, evt):
178 """
179 Protected method handling gesture events.
180
181 @param evt reference to the gesture event
182 @type QGestureEvent
183 """
184 pinch = evt.gesture(Qt.GestureType.PinchGesture)
185 if pinch:
186 if pinch.state() == Qt.GestureState.GestureStarted:
187 pinch.setTotalScaleFactor(self.__zoomFactorForMode(self.zoomMode()))
188 elif pinch.state() == Qt.GestureState.GestureUpdated:
189 if self.zoomMode() != QPdfView.ZoomMode.Custom:
190 self.setZoomMode(QPdfView.ZoomMode.Custom)
191 self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
192 zoomFactor = pinch.totalScaleFactor()
193 self.setZoomFactor(zoomFactor)
194 self.zoomFactorChanged.emit(zoomFactor)
195 evt.accept()

eric ide

mercurial