Use a scrollbar to navigate the entire book in txt books.
Mimic the behaviour of epub and pdf files.
This patch also solves a error in search in txt files,
introduced in the port to gtk3
Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org>
Gonzalo Odiard
11 years ago
27 | 27 | |
28 | 28 | def setup(self, activity): |
29 | 29 | self._activity = activity |
30 | activity._scrolled = Gtk.ScrolledWindow() | |
31 | activity._scrolled.set_policy(Gtk.PolicyType.NEVER, | |
32 | Gtk.PolicyType.AUTOMATIC) | |
33 | activity._scrolled.props.shadow_type = Gtk.ShadowType.NONE | |
34 | ||
35 | self._scrolled = activity._scrolled | |
30 | ||
31 | self.__going_fwd = False | |
32 | self.__going_back = True | |
36 | 33 | |
37 | 34 | self.textview = Gtk.TextView() |
38 | 35 | self.textview.set_editable(False) |
49 | 46 | Gdk.EventMask.TOUCH_MASK) |
50 | 47 | self.textview.connect('event', self.__touch_event_cb) |
51 | 48 | |
52 | activity._scrolled.add(self.textview) | |
53 | self.textview.show() | |
54 | activity._scrolled.show() | |
55 | activity._hbox.pack_start(activity._scrolled, True, True, 0) | |
49 | self._sw = Gtk.ScrolledWindow() | |
50 | self._sw.add(self.textview) | |
51 | self._v_vscrollbar = self._sw.get_vscrollbar() | |
52 | self._v_scrollbar_value_changed_cb_id = \ | |
53 | self._v_vscrollbar.connect('value-changed', \ | |
54 | self._v_scrollbar_value_changed_cb) | |
55 | self._scrollbar = Gtk.VScrollbar() | |
56 | self._scrollbar_change_value_cb_id = \ | |
57 | self._scrollbar.connect('change-value', \ | |
58 | self._scrollbar_change_value_cb) | |
59 | ||
60 | overlay = Gtk.Overlay() | |
61 | hbox = Gtk.HBox() | |
62 | overlay.add(hbox) | |
63 | hbox.add(self._sw) | |
64 | ||
65 | self._scrollbar.props.halign = Gtk.Align.END | |
66 | self._scrollbar.props.valign = Gtk.Align.FILL | |
67 | overlay.add_overlay(self._scrollbar) | |
68 | overlay.show_all() | |
69 | ||
70 | activity._hbox.pack_start(overlay, True, True, 0) | |
56 | 71 | |
57 | 72 | self._font_size = style.zoom(10) |
58 | 73 | self.font_desc = Pango.FontDescription("sans %d" % self._font_size) |
108 | 123 | pagecount = pagecount + 1 |
109 | 124 | self._pagecount = pagecount + 1 |
110 | 125 | self.set_current_page(0) |
126 | self._scrollbar.set_range(1.0, self._pagecount - 1.0) | |
127 | self._scrollbar.set_increments(1.0, 1.0) | |
111 | 128 | |
112 | 129 | speech.highlight_cb = self.highlight_next_word |
113 | 130 | speech.reset_cb = self.reset_text_to_speech |
129 | 146 | label_text = label_text + '\n\n\n' |
130 | 147 | textbuffer.set_text(label_text) |
131 | 148 | self._prepare_text_to_speech(label_text) |
149 | ||
150 | def _v_scrollbar_value_changed_cb(self, scrollbar): | |
151 | """ | |
152 | This is the real scrollbar containing the text view | |
153 | """ | |
154 | if self._current_page < 1: | |
155 | return | |
156 | scrollval = scrollbar.get_value() | |
157 | scroll_upper = self._v_vscrollbar.props.adjustment.props.upper | |
158 | scroll_page_size = self._v_vscrollbar.props.adjustment.props.page_size | |
159 | ||
160 | if self.__going_fwd == True and \ | |
161 | not self._current_page == self._pagecount: | |
162 | ||
163 | if scrollval == scroll_upper: | |
164 | self.set_current_page(self._current_page + 1) | |
165 | elif self.__going_back == True and self._current_page > 1: | |
166 | if scrollval == 0.0: | |
167 | self.set_current_page(self._current_page - 1) | |
168 | ||
169 | def _scrollbar_change_value_cb(self, range, scrolltype, value): | |
170 | """ | |
171 | This is the fake scrollbar visible, used to show the lenght of the book | |
172 | """ | |
173 | old_page = self._current_page | |
174 | if scrolltype == Gtk.ScrollType.STEP_FORWARD: | |
175 | self.__going_fwd = True | |
176 | self.__going_back = False | |
177 | elif scrolltype == Gtk.ScrollType.STEP_BACKWARD: | |
178 | self.__going_fwd = False | |
179 | self.__going_back = True | |
180 | elif scrolltype == Gtk.ScrollType.JUMP or \ | |
181 | scrolltype == Gtk.ScrollType.PAGE_FORWARD or \ | |
182 | scrolltype == Gtk.ScrollType.PAGE_BACKWARD: | |
183 | if value > self._scrollbar.props.adjustment.props.upper: | |
184 | value = self._pagecount | |
185 | self._show_page(int(value)) | |
186 | self._current_page = int(value) | |
187 | self.emit('page-changed', old_page, self._current_page) | |
188 | else: | |
189 | print 'Warning: unknown scrolltype %s with value %f' \ | |
190 | % (str(scrolltype), value) | |
191 | ||
192 | #FIXME: This should not be needed here | |
193 | self._scrollbar.set_value(self._current_page) | |
132 | 194 | |
133 | 195 | def __touch_event_cb(self, widget, event): |
134 | 196 | if event.type == Gdk.EventType.TOUCH_BEGIN: |
217 | 279 | bounds = textbuffer.get_bounds() |
218 | 280 | textbuffer.apply_tag(self.normal_tag, bounds[0], iterStart) |
219 | 281 | textbuffer.apply_tag(self.spoken_word_tag, iterStart, iterEnd) |
220 | v_adjustment = self._scrolled.get_vadjustment() | |
282 | v_adjustment = self._sw.get_vadjustment() | |
221 | 283 | max_pos = v_adjustment.get_upper() - v_adjustment.get_page_size() |
222 | 284 | max_pos = max_pos * word_count |
223 | 285 | max_pos = max_pos / len(self.word_tuples) |
243 | 305 | old_page = self._current_page |
244 | 306 | self._current_page = page |
245 | 307 | self._show_page(self._current_page) |
308 | self._scrollbar.handler_block(self._scrollbar_change_value_cb_id) | |
309 | self._scrollbar.set_value(self._current_page) | |
310 | self._scrollbar.handler_unblock(self._scrollbar_change_value_cb_id) | |
246 | 311 | self.emit('page-changed', old_page, self._current_page) |
247 | 312 | |
248 | 313 | def scroll(self, scrolltype, horizontal): |
249 | v_adjustment = self._scrolled.get_vadjustment() | |
314 | v_adjustment = self._sw.get_vadjustment() | |
250 | 315 | v_value = v_adjustment.get_value() |
251 | 316 | if scrolltype in (Gtk.ScrollType.PAGE_BACKWARD, |
252 | 317 | Gtk.ScrollType.PAGE_FORWARD): |
256 | 321 | |
257 | 322 | if scrolltype in (Gtk.ScrollType.PAGE_BACKWARD, |
258 | 323 | Gtk.ScrollType.STEP_BACKWARD): |
324 | self.__going_fwd = False | |
325 | self.__going_back = True | |
259 | 326 | if v_value <= v_adjustment.get_lower(): |
260 | 327 | self.previous_page() |
261 | 328 | v_adjustment.set_value(v_adjustment.get_upper() - \ |
268 | 335 | v_adjustment.set_value(new_value) |
269 | 336 | elif scrolltype in (Gtk.ScrollType.PAGE_FORWARD, |
270 | 337 | Gtk.ScrollType.STEP_FORWARD): |
338 | self.__going_fwd = True | |
339 | self.__going_back = False | |
340 | ||
271 | 341 | if v_value >= v_adjustment.get_upper() - \ |
272 | 342 | v_adjustment.get_page_size(): |
273 | 343 | self.next_page() |
286 | 356 | self.set_current_page(self._pagecount - 1) |
287 | 357 | |
288 | 358 | def previous_page(self): |
289 | v_adjustment = self._scrolled.get_vadjustment() | |
359 | v_adjustment = self._sw.get_vadjustment() | |
290 | 360 | v_adjustment.set_value(v_adjustment.get_upper() - |
291 | 361 | v_adjustment.get_page_size()) |
292 | 362 | self.set_current_page(self.get_current_page() - 1) |
293 | 363 | |
294 | 364 | def next_page(self): |
295 | v_adjustment = self._scrolled.get_vadjustment() | |
365 | v_adjustment = self._sw.get_vadjustment() | |
296 | 366 | v_adjustment.set_value(v_adjustment.get_lower()) |
297 | 367 | self.set_current_page(self.get_current_page() + 1) |
298 | 368 | |
313 | 383 | |
314 | 384 | def copy(self): |
315 | 385 | self.textview.get_buffer().copy_clipboard(Gtk.Clipboard()) |
316 | ||
317 | def update_view_size(self, _scrolled): | |
318 | pass | |
319 | 386 | |
320 | 387 | def _view_buttonrelease_event_cb(self, view, event): |
321 | 388 | self._has_selection = \ |
411 | 478 | def __init__(self, text_file, start_page, n_pages, text, \ |
412 | 479 | case_sensitive=False): |
413 | 480 | GObject.GObject.__init__(self) |
414 | Gtk.gdk.threads_init() | |
481 | Gdk.threads_init() | |
415 | 482 | |
416 | 483 | self._finished = False |
417 | 484 | self._text_file = text_file |
501 | 568 | self._found_records[self._current_found_item] |
502 | 569 | self._page = self.current_found_tuple[0] |
503 | 570 | |
504 | Gtk.gdk.threads_enter() | |
571 | Gdk.threads_enter() | |
505 | 572 | self.obj._finished = True |
506 | 573 | self.obj.emit('updated') |
507 | Gtk.gdk.threads_leave() | |
574 | Gdk.threads_leave() | |
508 | 575 | |
509 | 576 | return False |
510 | 577 |