23 |
23 |
24 class AutoScroller(QObject): |
24 class AutoScroller(QObject): |
25 """ |
25 """ |
26 Class implementing the automatic scroller. |
26 Class implementing the automatic scroller. |
27 """ |
27 """ |
|
28 |
28 def __init__(self, parent=None): |
29 def __init__(self, parent=None): |
29 """ |
30 """ |
30 Constructor |
31 Constructor |
31 |
32 |
32 @param parent reference to the parent object |
33 @param parent reference to the parent object |
33 @type QObject |
34 @type QObject |
34 """ |
35 """ |
35 super().__init__(parent) |
36 super().__init__(parent) |
36 |
37 |
37 self.__view = None |
38 self.__view = None |
38 |
39 |
39 self.__indicator = QLabel() |
40 self.__indicator = QLabel() |
40 self.__indicator.resize(32, 32) |
41 self.__indicator.resize(32, 32) |
41 self.__indicator.setContentsMargins(0, 0, 0, 0) |
42 self.__indicator.setContentsMargins(0, 0, 0, 0) |
42 self.__indicator.installEventFilter(self) |
43 self.__indicator.installEventFilter(self) |
43 |
44 |
44 self.__scroller = FrameScroller(self) |
45 self.__scroller = FrameScroller(self) |
45 self.__scroller.setScrollDivider( |
46 self.__scroller.setScrollDivider(Preferences.getWebBrowser("AutoScrollDivider")) |
46 Preferences.getWebBrowser("AutoScrollDivider")) |
47 |
47 |
|
48 self.__enabled = Preferences.getWebBrowser("AutoScrollEnabled") |
48 self.__enabled = Preferences.getWebBrowser("AutoScrollEnabled") |
49 |
49 |
50 def isEnabled(self): |
50 def isEnabled(self): |
51 """ |
51 """ |
52 Public method to get the enabled state. |
52 Public method to get the enabled state. |
53 |
53 |
54 @return enabled state |
54 @return enabled state |
55 @rtype bool |
55 @rtype bool |
56 """ |
56 """ |
57 return self.__enabled |
57 return self.__enabled |
58 |
58 |
59 def mouseMove(self, evt): |
59 def mouseMove(self, evt): |
60 """ |
60 """ |
61 Public method to handle mouse move events. |
61 Public method to handle mouse move events. |
62 |
62 |
63 @param evt reference to the mouse move event |
63 @param evt reference to the mouse move event |
64 @type QMouseEvent |
64 @type QMouseEvent |
65 @return flag indicating, that the event was handled |
65 @return flag indicating, that the event was handled |
66 @rtype bool |
66 @rtype bool |
67 """ |
67 """ |
68 if self.__enabled and self.__indicator.isVisible(): |
68 if self.__enabled and self.__indicator.isVisible(): |
69 rect = self.__indicatorGlobalRect() |
69 rect = self.__indicatorGlobalRect() |
70 xlen = 0 |
70 xlen = 0 |
71 ylen = 0 |
71 ylen = 0 |
72 egp = evt.globalPosition().toPoint() |
72 egp = evt.globalPosition().toPoint() |
73 |
73 |
74 if rect.left() > egp.x(): |
74 if rect.left() > egp.x(): |
75 xlen = egp.x() - rect.left() |
75 xlen = egp.x() - rect.left() |
76 elif rect.right() < egp.x(): |
76 elif rect.right() < egp.x(): |
77 xlen = egp.x() - rect.right() |
77 xlen = egp.x() - rect.right() |
78 |
78 |
79 if rect.top() > egp.y(): |
79 if rect.top() > egp.y(): |
80 ylen = egp.y() - rect.top() |
80 ylen = egp.y() - rect.top() |
81 elif rect.bottom() < egp.y(): |
81 elif rect.bottom() < egp.y(): |
82 ylen = egp.y() - rect.bottom() |
82 ylen = egp.y() - rect.bottom() |
83 |
83 |
84 self.__scroller.startScrolling(xlen, ylen) |
84 self.__scroller.startScrolling(xlen, ylen) |
85 |
85 |
86 return False |
86 return False |
87 |
87 |
88 def mousePress(self, view, evt): |
88 def mousePress(self, view, evt): |
89 """ |
89 """ |
90 Public method to handle mouse button presses. |
90 Public method to handle mouse button presses. |
91 |
91 |
92 @param view reference to the web view the button was pressed on |
92 @param view reference to the web view the button was pressed on |
93 @type WebBrowserView |
93 @type WebBrowserView |
94 @param evt reference to the mouse button press event |
94 @param evt reference to the mouse button press event |
95 @type QMouseEvent |
95 @type QMouseEvent |
96 @return flag indicating, that the event was handled |
96 @return flag indicating, that the event was handled |
97 @rtype bool |
97 @rtype bool |
98 """ |
98 """ |
99 if self.__enabled: |
99 if self.__enabled: |
100 middleButton = evt.buttons() == Qt.MouseButton.MiddleButton |
100 middleButton = evt.buttons() == Qt.MouseButton.MiddleButton |
101 |
101 |
102 if view: |
102 if view: |
103 # test for start |
103 # test for start |
104 if ( |
104 if middleButton and ( |
105 middleButton and |
105 self.__view != view or not self.__indicator.isVisible() |
106 (self.__view != view or not self.__indicator.isVisible()) |
|
107 ): |
106 ): |
108 return self.__showIndicator(view, evt.position().toPoint()) |
107 return self.__showIndicator(view, evt.position().toPoint()) |
109 |
108 |
110 # test for stop |
109 # test for stop |
111 if self.__indicator.isVisible(): |
110 if self.__indicator.isVisible(): |
112 self.__stopScrolling() |
111 self.__stopScrolling() |
113 return True |
112 return True |
114 |
113 |
115 return False |
114 return False |
116 |
115 |
117 def mouseRelease(self, evt): |
116 def mouseRelease(self, evt): |
118 """ |
117 """ |
119 Public method to handle mouse button releases. |
118 Public method to handle mouse button releases. |
120 |
119 |
121 @param evt reference to the mouse button release event |
120 @param evt reference to the mouse button release event |
122 @type QMouseEvent |
121 @type QMouseEvent |
123 @return flag indicating, that the event was handled |
122 @return flag indicating, that the event was handled |
124 @rtype bool |
123 @rtype bool |
125 """ |
124 """ |
126 if self.__enabled and self.__indicator.isVisible(): |
125 if self.__enabled and self.__indicator.isVisible(): |
127 if not self.__indicatorGlobalRect().contains( |
126 if not self.__indicatorGlobalRect().contains( |
128 evt.globalPosition().toPoint()): |
127 evt.globalPosition().toPoint() |
|
128 ): |
129 self.__stopScrolling() |
129 self.__stopScrolling() |
130 return True |
130 return True |
131 |
131 |
132 return False |
132 return False |
133 |
133 |
134 def wheel(self): |
134 def wheel(self): |
135 """ |
135 """ |
136 Public method to handle a mouse wheel event. |
136 Public method to handle a mouse wheel event. |
137 |
137 |
138 @return flag indicating, that the event was handled |
138 @return flag indicating, that the event was handled |
139 @rtype bool |
139 @rtype bool |
140 """ |
140 """ |
141 if self.__enabled and self.__indicator.isVisible(): |
141 if self.__enabled and self.__indicator.isVisible(): |
142 self.__stopScrolling() |
142 self.__stopScrolling() |
143 return True |
143 return True |
144 |
144 |
145 return False |
145 return False |
146 |
146 |
147 def preferencesChanged(self): |
147 def preferencesChanged(self): |
148 """ |
148 """ |
149 Public method to handle a change of the settings. |
149 Public method to handle a change of the settings. |
150 """ |
150 """ |
151 enabled = Preferences.getWebBrowser("AutoScrollEnabled") |
151 enabled = Preferences.getWebBrowser("AutoScrollEnabled") |
152 if enabled != self.__enabled: |
152 if enabled != self.__enabled: |
153 if self.__indicator.isVisible(): |
153 if self.__indicator.isVisible(): |
154 self.__stopScrolling() |
154 self.__stopScrolling() |
155 self.__enabled = enabled |
155 self.__enabled = enabled |
156 |
156 |
157 self.__scroller.setScrollDivider( |
157 self.__scroller.setScrollDivider(Preferences.getWebBrowser("AutoScrollDivider")) |
158 Preferences.getWebBrowser("AutoScrollDivider")) |
158 |
159 |
|
160 def eventFilter(self, obj, evt): |
159 def eventFilter(self, obj, evt): |
161 """ |
160 """ |
162 Public method to handle event for an object. |
161 Public method to handle event for an object. |
163 |
162 |
164 @param obj refernce to the object sending the event |
163 @param obj refernce to the object sending the event |
165 @type QObject |
164 @type QObject |
166 @param evt reference to the event to be handled |
165 @param evt reference to the event to be handled |
167 @type QEvent |
166 @type QEvent |
168 @return flag indicating, that the event was handled |
167 @return flag indicating, that the event was handled |
169 @rtype bool |
168 @rtype bool |
170 """ |
169 """ |
171 if obj == self.__indicator: |
170 if obj == self.__indicator: |
172 if evt.type() == QEvent.Type.Enter: |
171 if evt.type() == QEvent.Type.Enter: |
173 self.__scroller.stopScrolling() |
172 self.__scroller.stopScrolling() |
174 elif evt.type() in [QEvent.Type.Wheel, QEvent.Type.Hide, |
173 elif evt.type() in [ |
175 QEvent.Type.MouseButtonPress]: |
174 QEvent.Type.Wheel, |
|
175 QEvent.Type.Hide, |
|
176 QEvent.Type.MouseButtonPress, |
|
177 ]: |
176 self.__stopScrolling() |
178 self.__stopScrolling() |
177 |
179 |
178 return False |
180 return False |
179 |
181 |
180 def __showIndicator(self, view, pos): |
182 def __showIndicator(self, view, pos): |
181 """ |
183 """ |
182 Private method to show the auto scroll indicator. |
184 Private method to show the auto scroll indicator. |
183 |
185 |
184 @param view reference to the view to show the indicator on |
186 @param view reference to the view to show the indicator on |
185 @type WebBrowserView |
187 @type WebBrowserView |
186 @param pos position to show the indicator at |
188 @param pos position to show the indicator at |
187 @type QPoint |
189 @type QPoint |
188 @return flag indicating, that the indicator is shown |
190 @return flag indicating, that the indicator is shown |
189 @rtype bool |
191 @rtype bool |
190 """ |
192 """ |
191 hit = view.page().hitTestContent(pos) |
193 hit = view.page().hitTestContent(pos) |
192 |
194 |
193 if hit.isContentEditable() or not hit.linkUrl().isEmpty(): |
195 if hit.isContentEditable() or not hit.linkUrl().isEmpty(): |
194 return False |
196 return False |
195 |
197 |
196 jsSource = """ |
198 jsSource = """ |
197 var out = { |
199 var out = { |
198 vertical: |
200 vertical: |
199 window.innerWidth > document.documentElement.clientWidth, |
201 window.innerWidth > document.documentElement.clientWidth, |
200 horizontal: |
202 horizontal: |
201 window.innerHeight > document.documentElement.clientHeight |
203 window.innerHeight > document.documentElement.clientHeight |
202 }; |
204 }; |
203 out;""" |
205 out;""" |
204 |
206 |
205 res = view.page().execJavaScript(jsSource) |
207 res = view.page().execJavaScript(jsSource) |
206 if res is None: |
208 if res is None: |
207 return False |
209 return False |
208 |
210 |
209 vertical = res["vertical"] |
211 vertical = res["vertical"] |
210 horizontal = res["horizontal"] |
212 horizontal = res["horizontal"] |
211 if not vertical and not horizontal: |
213 if not vertical and not horizontal: |
212 return False |
214 return False |
213 |
215 |
214 if vertical and horizontal: |
216 if vertical and horizontal: |
215 self.__indicator.setPixmap( |
217 self.__indicator.setPixmap(UI.PixmapCache.getPixmap("scrollAll")) |
216 UI.PixmapCache.getPixmap("scrollAll")) |
|
217 elif vertical: |
218 elif vertical: |
218 self.__indicator.setPixmap( |
219 self.__indicator.setPixmap(UI.PixmapCache.getPixmap("scrollVertical")) |
219 UI.PixmapCache.getPixmap("scrollVertical")) |
|
220 else: |
220 else: |
221 self.__indicator.setPixmap( |
221 self.__indicator.setPixmap(UI.PixmapCache.getPixmap("scrollHorizontal")) |
222 UI.PixmapCache.getPixmap("scrollHorizontal")) |
222 |
223 |
|
224 self.__view = view |
223 self.__view = view |
225 p = QPoint( |
224 p = QPoint( |
226 pos.x() - self.__indicator.pixmap().width() // 2, |
225 pos.x() - self.__indicator.pixmap().width() // 2, |
227 pos.y() - self.__indicator.pixmap().height() // 2 |
226 pos.y() - self.__indicator.pixmap().height() // 2, |
228 ) |
227 ) |
229 |
228 |
230 self.__indicator.setParent(self.__view) |
229 self.__indicator.setParent(self.__view) |
231 self.__indicator.move(p) |
230 self.__indicator.move(p) |
232 self.__indicator.show() |
231 self.__indicator.show() |
233 |
232 |
234 self.__scroller.setPage(view.page()) |
233 self.__scroller.setPage(view.page()) |
235 |
234 |
236 self.__view.inputWidget().grabMouse() |
235 self.__view.inputWidget().grabMouse() |
237 QApplication.setOverrideCursor(Qt.CursorShape.ArrowCursor) |
236 QApplication.setOverrideCursor(Qt.CursorShape.ArrowCursor) |
238 |
237 |
239 return True |
238 return True |
240 |
239 |
241 def __stopScrolling(self): |
240 def __stopScrolling(self): |
242 """ |
241 """ |
243 Private method to stop scrolling. |
242 Private method to stop scrolling. |
244 """ |
243 """ |
245 self.__view.inputWidget().releaseMouse() |
244 self.__view.inputWidget().releaseMouse() |
246 QApplication.restoreOverrideCursor() |
245 QApplication.restoreOverrideCursor() |
247 |
246 |
248 self.__indicator.hide() |
247 self.__indicator.hide() |
249 self.__indicator.setParent(None) |
248 self.__indicator.setParent(None) |
250 self.__scroller.stopScrolling() |
249 self.__scroller.stopScrolling() |
251 |
250 |
252 def __indicatorGlobalRect(self): |
251 def __indicatorGlobalRect(self): |
253 """ |
252 """ |
254 Private method to calculate the global indicator parameters. |
253 Private method to calculate the global indicator parameters. |
255 |
254 |
256 @return global indicator parameters |
255 @return global indicator parameters |
257 @rtype QRect |
256 @rtype QRect |
258 """ |
257 """ |
259 pos = self.__indicator.parentWidget().mapToGlobal( |
258 pos = self.__indicator.parentWidget().mapToGlobal( |
260 self.__indicator.geometry().topLeft()) |
259 self.__indicator.geometry().topLeft() |
261 return QRect(pos.x(), pos.y(), |
260 ) |
262 self.__indicator.width(), self.__indicator.height()) |
261 return QRect( |
|
262 pos.x(), pos.y(), self.__indicator.width(), self.__indicator.height() |
|
263 ) |