WebBrowser/AutoScroll/AutoScroller.py

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

eric ide

mercurial