0 | 0 |
# Copyright 2009 One Laptop Per Child
|
1 | 1 |
# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
|
|
2 |
# WebKit2 port Copyright (C) 2018 Lubomir Rintel <lkundrak@v3.sk>
|
2 | 3 |
#
|
3 | 4 |
# This program is free software; you can redistribute it and/or modify
|
4 | 5 |
# it under the terms of the GNU General Public License as published by
|
|
14 | 15 |
# along with this program; if not, write to the Free Software
|
15 | 16 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
16 | 17 |
|
|
18 |
import gi
|
|
19 |
gi.require_version('WebKit2', '4.0')
|
|
20 |
|
17 | 21 |
from gi.repository import Gtk
|
18 | 22 |
from gi.repository import GObject
|
19 | 23 |
from gi.repository import Gdk
|
|
24 |
from gi.repository import WebKit2
|
20 | 25 |
import widgets
|
21 | 26 |
|
22 | 27 |
import logging
|
|
27 | 32 |
from jobs import _JobPaginator as _Paginator
|
28 | 33 |
|
29 | 34 |
LOADING_HTML = '''
|
30 | |
<div style="width:100%;height:100%;text-align:center;padding-top:50%;">
|
31 | |
<h1>Loading...</h1>
|
32 | |
</div>
|
|
35 |
<html style="height: 100%; margin: 0; padding: 0; width: 100%;">
|
|
36 |
<body style="display: table; height: 100%; margin: 0; padding: 0; width: 100%;">
|
|
37 |
<div style="display: table-cell; text-align: center; vertical-align: middle;">
|
|
38 |
<h1>Loading...</h1>
|
|
39 |
</div>
|
|
40 |
</body>
|
|
41 |
</html>
|
33 | 42 |
'''
|
34 | |
|
35 | 43 |
|
36 | 44 |
class _View(Gtk.HBox):
|
37 | 45 |
|
|
56 | 64 |
self._ready = False
|
57 | 65 |
self._paginator = None
|
58 | 66 |
self._loaded_page = -1
|
59 | |
self._file_loaded = True
|
60 | 67 |
# self._old_scrollval = -1
|
61 | 68 |
self._loaded_filename = None
|
62 | 69 |
self._pagecount = -1
|
63 | |
self.__going_fwd = True
|
64 | |
self.__going_back = False
|
|
70 |
self.__scroll_to_end = False
|
65 | 71 |
self.__page_changed = False
|
66 | 72 |
self._has_selection = False
|
|
73 |
self._scrollval = 0.0
|
67 | 74 |
self.scale = 1.0
|
68 | 75 |
self._epub = None
|
69 | 76 |
self._findjob = None
|
|
72 | 79 |
self._filelist = None
|
73 | 80 |
self._internal_link = None
|
74 | 81 |
|
75 | |
self._sw = Gtk.ScrolledWindow()
|
76 | 82 |
self._view = widgets._WebView()
|
77 | |
self._view.load_string(LOADING_HTML, 'text/html', 'utf-8', '/')
|
|
83 |
self._view.load_html(LOADING_HTML, '/')
|
78 | 84 |
settings = self._view.get_settings()
|
79 | 85 |
settings.props.default_font_family = 'DejaVu LGC Serif'
|
80 | 86 |
settings.props.enable_plugins = False
|
81 | |
settings.props.default_encoding = 'utf-8'
|
82 | |
self._view.connect('load-finished', self._view_load_finished_cb)
|
83 | |
self._view.connect('scroll-event', self._view_scroll_event_cb)
|
84 | |
self._view.connect('key-press-event', self._view_keypress_event_cb)
|
85 | |
self._view.connect('selection-changed',
|
86 | |
self._view_selection_changed_cb)
|
87 | |
self._view.connect_after('populate-popup',
|
88 | |
self._view_populate_popup_cb)
|
89 | |
self._view.connect('touch-change-page', self.__touch_page_changed_cb)
|
90 | |
|
91 | |
self._sw.add(self._view)
|
92 | |
self._v_vscrollbar = self._sw.get_vscrollbar()
|
93 | |
self._v_scrollbar_value_changed_cb_id = self._v_vscrollbar.connect(
|
94 | |
'value-changed', self._v_scrollbar_value_changed_cb)
|
|
87 |
settings.props.default_charset = 'utf-8'
|
|
88 |
self._view.connect('load-changed', self._view_load_changed_cb)
|
|
89 |
self._view.connect('scrolled', self._view_scrolled_cb)
|
|
90 |
self._view.connect('scrolled-top', self._view_scrolled_top_cb)
|
|
91 |
self._view.connect('scrolled-bottom', self._view_scrolled_bottom_cb)
|
|
92 |
self._view.connect('selection-changed', self._view_selection_changed_cb)
|
|
93 |
|
|
94 |
find = self._view.get_find_controller()
|
|
95 |
find.connect('failed-to-find-text', self._find_failed_cb)
|
|
96 |
|
|
97 |
self._eventbox = Gtk.EventBox()
|
|
98 |
self._eventbox.connect('scroll-event', self._eventbox_scroll_event_cb)
|
|
99 |
self._eventbox.add_events(Gdk.EventMask.SCROLL_MASK)
|
|
100 |
self._eventbox.add(self._view)
|
|
101 |
|
95 | 102 |
self._scrollbar = Gtk.VScrollbar()
|
96 | 103 |
self._scrollbar_change_value_cb_id = self._scrollbar.connect(
|
97 | 104 |
'change-value', self._scrollbar_change_value_cb)
|
98 | 105 |
|
99 | |
overlay = Gtk.Overlay()
|
100 | 106 |
hbox = Gtk.HBox()
|
101 | |
overlay.add(hbox)
|
102 | |
hbox.add(self._sw)
|
103 | |
|
104 | |
self._scrollbar.props.halign = Gtk.Align.END
|
105 | |
self._scrollbar.props.valign = Gtk.Align.FILL
|
106 | |
overlay.add_overlay(self._scrollbar)
|
107 | |
|
108 | |
self.pack_start(overlay, True, True, 0)
|
109 | |
|
|
107 |
hbox.pack_start(self._eventbox, True, True, 0)
|
|
108 |
hbox.pack_end(self._scrollbar, False, True, 0)
|
|
109 |
|
|
110 |
self.pack_start(hbox, True, True, 0)
|
110 | 111 |
self._view.set_can_default(True)
|
111 | 112 |
self._view.set_can_focus(True)
|
112 | 113 |
|
|
141 | 142 |
'''
|
142 | 143 |
Returns True if any part of the content is selected
|
143 | 144 |
'''
|
144 | |
return self._view.can_copy_clipboard()
|
|
145 |
return self._has_selection
|
145 | 146 |
|
146 | 147 |
def get_zoom(self):
|
147 | 148 |
'''
|
|
197 | 198 |
"""
|
198 | 199 |
Used to save the scrolled position and restore when needed
|
199 | 200 |
"""
|
200 | |
return self._v_vscrollbar.get_adjustment().get_value()
|
|
201 |
return self._scrollval
|
201 | 202 |
|
202 | 203 |
def set_vertical_pos(self, position):
|
203 | 204 |
"""
|
204 | 205 |
Used to save the scrolled position and restore when needed
|
205 | 206 |
"""
|
206 | |
self._v_vscrollbar.get_adjustment().set_value(position)
|
|
207 |
self._view.scroll_to(position)
|
207 | 208 |
|
208 | 209 |
def can_zoom_in(self):
|
209 | 210 |
'''
|
|
281 | 282 |
Valid scrolltypes are:
|
282 | 283 |
Gtk.ScrollType.PAGE_BACKWARD, Gtk.ScrollType.PAGE_FORWARD,
|
283 | 284 |
Gtk.ScrollType.STEP_BACKWARD, Gtk.ScrollType.STEP_FORWARD
|
284 | |
Gtk.ScrollType.STEP_START and Gtk.ScrollType.STEP_STOP
|
|
285 |
Gtk.ScrollType.STEP_START and Gtk.ScrollType.STEP_END
|
285 | 286 |
'''
|
286 | 287 |
if scrolltype == Gtk.ScrollType.PAGE_BACKWARD:
|
287 | |
self.__going_back = True
|
288 | |
self.__going_fwd = False
|
289 | |
if not self._do_page_transition():
|
290 | |
self._view.move_cursor(Gtk.MovementStep.PAGES, -1)
|
|
288 |
pages = self._paginator.get_pagecount_for_file(self._loaded_filename)
|
|
289 |
self._view.scroll_by(self._page_height / pages * -1)
|
291 | 290 |
elif scrolltype == Gtk.ScrollType.PAGE_FORWARD:
|
292 | |
self.__going_back = False
|
293 | |
self.__going_fwd = True
|
294 | |
if not self._do_page_transition():
|
295 | |
self._view.move_cursor(Gtk.MovementStep.PAGES, 1)
|
|
291 |
pages = self._paginator.get_pagecount_for_file(self._loaded_filename)
|
|
292 |
self._view.scroll_by(self._page_height / pages * 1)
|
296 | 293 |
elif scrolltype == Gtk.ScrollType.STEP_BACKWARD:
|
297 | |
self.__going_fwd = False
|
298 | |
self.__going_back = True
|
299 | |
if not self._do_page_transition():
|
300 | |
self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, -1)
|
|
294 |
self._view.scroll_by(self._view.get_settings().get_default_font_size() * -3)
|
301 | 295 |
elif scrolltype == Gtk.ScrollType.STEP_FORWARD:
|
302 | |
self.__going_fwd = True
|
303 | |
self.__going_back = False
|
304 | |
if not self._do_page_transition():
|
305 | |
self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, 1)
|
|
296 |
self._view.scroll_by(self._view.get_settings().get_default_font_size() * 3)
|
306 | 297 |
elif scrolltype == Gtk.ScrollType.START:
|
307 | |
self.__going_back = True
|
308 | |
self.__going_fwd = False
|
309 | |
if not self._do_page_transition():
|
310 | |
self.set_current_page(1)
|
|
298 |
self.set_current_page(0)
|
311 | 299 |
elif scrolltype == Gtk.ScrollType.END:
|
312 | |
self.__going_back = False
|
313 | |
self.__going_fwd = True
|
314 | |
if not self._do_page_transition():
|
315 | |
self.set_current_page(self._pagecount - 1)
|
316 | |
else:
|
317 | |
print ('Got unsupported scrolltype %s' % str(scrolltype))
|
|
300 |
self.__scroll_to_end = True
|
|
301 |
self.set_current_page(self._pagecount - 1)
|
|
302 |
else:
|
|
303 |
print('Got unsupported scrolltype %s' % str(scrolltype))
|
318 | 304 |
|
319 | 305 |
def __touch_page_changed_cb(self, widget, forward):
|
320 | 306 |
if forward:
|
|
326 | 312 |
'''
|
327 | 313 |
Copies the current selection to clipboard.
|
328 | 314 |
'''
|
329 | |
self._view.copy_clipboard()
|
|
315 |
self._view.run_javascript('document.execCommand("copy")')
|
330 | 316 |
|
331 | 317 |
def find_next(self):
|
332 | 318 |
'''
|
333 | 319 |
Highlights the next matching item for current search
|
334 | 320 |
'''
|
335 | 321 |
self._view.grab_focus()
|
336 | |
|
337 | |
if self._view.search_text(self._findjob.get_search_text(),
|
338 | |
self._findjob.get_case_sensitive(),
|
339 | |
True, False):
|
340 | |
return
|
341 | |
else:
|
342 | |
path = os.path.join(self._epub.get_basedir(),
|
343 | |
self._findjob.get_next_file())
|
|
322 |
self.__search_fwd = True
|
|
323 |
self._view.get_find_controller().search_next()
|
|
324 |
|
|
325 |
def find_previous(self):
|
|
326 |
'''
|
|
327 |
Highlights the previous matching item for current search
|
|
328 |
'''
|
|
329 |
self._view.grab_focus()
|
|
330 |
self.__search_fwd = False
|
|
331 |
self._view.get_find_controller().search_previous()
|
|
332 |
|
|
333 |
def _find_failed_cb(self, find_controller):
|
|
334 |
try:
|
|
335 |
if self.__search_fwd:
|
|
336 |
path = os.path.join(self._epub.get_basedir(),
|
|
337 |
self._findjob.get_next_file())
|
|
338 |
else:
|
|
339 |
path = os.path.join(self._epub.get_basedir(),
|
|
340 |
self._findjob.get_prev_file())
|
344 | 341 |
self.__in_search = True
|
345 | |
self.__search_fwd = True
|
346 | 342 |
self._load_file(path)
|
347 | |
|
348 | |
def find_previous(self):
|
349 | |
'''
|
350 | |
Highlights the previous matching item for current search
|
351 | |
'''
|
352 | |
self._view.grab_focus()
|
353 | |
|
354 | |
if self._view.search_text(self._findjob.get_search_text(),
|
355 | |
self._findjob.get_case_sensitive(),
|
356 | |
False, False):
|
357 | |
return
|
358 | |
else:
|
359 | |
path = os.path.join(self._epub.get_basedir(),
|
360 | |
self._findjob.get_prev_file())
|
361 | |
self.__in_search = True
|
362 | |
self.__search_fwd = False
|
363 | |
self._load_file(path)
|
|
343 |
except IndexError:
|
|
344 |
# No match anywhere, no other file to pick
|
|
345 |
pass
|
364 | 346 |
|
365 | 347 |
def _find_changed(self, job):
|
366 | 348 |
self._view.grab_focus()
|
367 | 349 |
self._findjob = job
|
368 | |
self._mark_found_text()
|
369 | |
self.find_next()
|
370 | |
|
371 | |
def _mark_found_text(self):
|
372 | |
self._view.unmark_text_matches()
|
373 | |
self._view.mark_text_matches(
|
374 | |
self._findjob.get_search_text(),
|
375 | |
case_sensitive=self._findjob.get_case_sensitive(), limit=0)
|
376 | |
self._view.set_highlight_text_matches(True)
|
|
350 |
find = self._view.get_find_controller()
|
|
351 |
find.search (self._findjob.get_search_text(),
|
|
352 |
self._findjob.get_flags(),
|
|
353 |
GObject.G_MAXUINT)
|
377 | 354 |
|
378 | 355 |
def __set_zoom(self, value):
|
379 | 356 |
self._view.set_zoom_level(value)
|
380 | 357 |
self.scale = value
|
381 | 358 |
|
382 | |
def _view_populate_popup_cb(self, view, menu):
|
383 | |
menu.destroy() # HACK
|
384 | |
return
|
385 | |
|
386 | |
def _view_selection_changed_cb(self, view):
|
|
359 |
def _view_scrolled_cb(self, view, scrollval):
|
|
360 |
if self._loaded_page < 1:
|
|
361 |
return
|
|
362 |
|
|
363 |
self._scrollval = scrollval
|
|
364 |
scroll_upper = self._page_height
|
|
365 |
scroll_page_size = self._view.get_allocated_height()
|
|
366 |
|
|
367 |
if scrollval > 0:
|
|
368 |
scrollfactor = scrollval / (scroll_upper - scroll_page_size)
|
|
369 |
else:
|
|
370 |
scrollfactor = 0
|
|
371 |
|
|
372 |
if not self._loaded_page == self._pagecount and \
|
|
373 |
not self._paginator.get_file_for_pageno(self._loaded_page) != \
|
|
374 |
self._paginator.get_file_for_pageno(self._loaded_page + 1):
|
|
375 |
|
|
376 |
scrollfactor_next = \
|
|
377 |
self._paginator.get_scrollfactor_pos_for_pageno(
|
|
378 |
self._loaded_page + 1)
|
|
379 |
if scrollfactor >= scrollfactor_next:
|
|
380 |
self._on_page_changed(self._loaded_page, self._loaded_page + 1)
|
|
381 |
return
|
|
382 |
|
|
383 |
if self._loaded_page > 1 and \
|
|
384 |
not self._paginator.get_file_for_pageno(self._loaded_page) != \
|
|
385 |
self._paginator.get_file_for_pageno(self._loaded_page - 1):
|
|
386 |
|
|
387 |
scrollfactor_cur = \
|
|
388 |
self._paginator.get_scrollfactor_pos_for_pageno(
|
|
389 |
self._loaded_page)
|
|
390 |
if scrollfactor <= scrollfactor_cur:
|
|
391 |
self._on_page_changed(self._loaded_page, self._loaded_page - 1)
|
|
392 |
return
|
|
393 |
|
|
394 |
def _view_scrolled_top_cb(self, view):
|
|
395 |
if self._loaded_page > 1:
|
|
396 |
self.__scroll_to_end = True
|
|
397 |
self._load_prev_page()
|
|
398 |
|
|
399 |
def _view_scrolled_bottom_cb(self, view):
|
|
400 |
if self._loaded_page < self._pagecount:
|
|
401 |
self._load_next_page()
|
|
402 |
|
|
403 |
def _view_selection_changed_cb(self, view, has_selection):
|
|
404 |
self._has_selection = has_selection
|
387 | 405 |
self.emit('selection-changed')
|
388 | 406 |
|
389 | |
def _view_keypress_event_cb(self, view, event):
|
390 | |
name = Gdk.keyval_name(event.keyval)
|
391 | |
if name == 'Page_Down' or name == 'Down':
|
392 | |
self.__going_back = False
|
393 | |
self.__going_fwd = True
|
394 | |
elif name == 'Page_Up' or name == 'Up':
|
395 | |
self.__going_back = True
|
396 | |
self.__going_fwd = False
|
397 | |
|
398 | |
self._do_page_transition()
|
399 | |
|
400 | |
def _view_scroll_event_cb(self, view, event):
|
|
407 |
def _eventbox_scroll_event_cb(self, view, event):
|
401 | 408 |
if event.direction == Gdk.ScrollDirection.DOWN:
|
402 | |
self.__going_back = False
|
403 | |
self.__going_fwd = True
|
|
409 |
self.scroll(Gtk.ScrollType.STEP_FORWARD, False)
|
404 | 410 |
elif event.direction == Gdk.ScrollDirection.UP:
|
405 | |
self.__going_back = True
|
406 | |
self.__going_fwd = False
|
407 | |
|
408 | |
self._do_page_transition()
|
409 | |
|
410 | |
def _do_page_transition(self):
|
411 | |
if self.__going_fwd:
|
412 | |
if self._v_vscrollbar.get_value() >= \
|
413 | |
self._v_vscrollbar.props.adjustment.props.upper - \
|
414 | |
self._v_vscrollbar.props.adjustment.props.page_size:
|
415 | |
self._load_page(self._loaded_page + 1)
|
416 | |
return True
|
417 | |
elif self.__going_back:
|
418 | |
if self._v_vscrollbar.get_value() == \
|
419 | |
self._v_vscrollbar.props.adjustment.props.lower:
|
420 | |
self._load_page(self._loaded_page - 1)
|
421 | |
return True
|
422 | |
|
423 | |
return False
|
424 | |
|
425 | |
def _view_load_finished_cb(self, v, frame):
|
426 | |
|
427 | |
self._file_loaded = True
|
|
411 |
self.scroll(Gtk.ScrollType.STEP_BACKWARD, False)
|
|
412 |
|
|
413 |
def _view_load_changed_cb(self, v, load_event):
|
|
414 |
if load_event != WebKit2.LoadEvent.FINISHED:
|
|
415 |
return True
|
|
416 |
|
428 | 417 |
filename = self._view.props.uri.replace('file://', '')
|
429 | 418 |
if os.path.exists(filename.replace('xhtml', 'xml')):
|
430 | 419 |
# Hack for making javascript work
|
|
443 | 432 |
remfactor * self._view.get_page_height() / (pages - remfactor)))
|
444 | 433 |
if extra > 0:
|
445 | 434 |
self._view.add_bottom_padding(extra)
|
|
435 |
self._page_height = self._view.get_page_height()
|
446 | 436 |
|
447 | 437 |
if self.__in_search:
|
448 | |
self._mark_found_text()
|
449 | |
self._view.search_text(self._findjob.get_search_text(),
|
450 | |
self._findjob.get_case_sensitive(),
|
451 | |
self.__search_fwd, False)
|
452 | 438 |
self.__in_search = False
|
453 | |
else:
|
454 | |
if self.__going_back:
|
455 | |
# We need to scroll to the last page
|
456 | |
self._scroll_page_end()
|
457 | |
else:
|
458 | |
self._scroll_page()
|
|
439 |
find = self._view.get_find_controller()
|
|
440 |
find.search (self._findjob.get_search_text(),
|
|
441 |
self._findjob.get_flags(self.__search_fwd),
|
|
442 |
GObject.G_MAXUINT)
|
|
443 |
else:
|
|
444 |
self._scroll_page()
|
459 | 445 |
|
460 | 446 |
# process_file = True
|
461 | 447 |
if self._internal_link is not None:
|
|
473 | 459 |
# if the link is at the bottom of the page, we open the next file
|
474 | 460 |
one_page_height = self._paginator.get_single_page_height()
|
475 | 461 |
self._internal_link = None
|
476 | |
if vertical_pos > self._view.get_page_height() - one_page_height:
|
|
462 |
if vertical_pos > self._page_height - one_page_height:
|
477 | 463 |
logging.error('bottom page link, go to next file')
|
478 | 464 |
next_file = self._paginator.get_next_filename(filename)
|
479 | 465 |
if next_file is not None:
|
480 | 466 |
logging.error('load next file %s', next_file)
|
481 | 467 |
self.__in_search = False
|
482 | |
self.__going_back = False
|
|
468 |
self.__scroll_to_end = False
|
483 | 469 |
# process_file = False
|
484 | 470 |
GObject.idle_add(self._load_file, next_file)
|
485 | 471 |
|
|
516 | 502 |
self.word_tuples.append(word_tuple)
|
517 | 503 |
i = i + 1
|
518 | 504 |
|
519 | |
def _scroll_page_end(self):
|
520 | |
v_upper = self._v_vscrollbar.props.adjustment.props.upper
|
521 | |
# v_page_size = self._v_vscrollbar.props.adjustment.props.page_size
|
522 | |
self._v_vscrollbar.set_value(v_upper)
|
523 | |
|
524 | 505 |
def _scroll_page(self):
|
525 | |
pageno = self._loaded_page
|
526 | |
|
527 | |
v_upper = self._v_vscrollbar.props.adjustment.props.upper
|
528 | |
v_page_size = self._v_vscrollbar.props.adjustment.props.page_size
|
529 | |
|
530 | |
scrollfactor = self._paginator.get_scrollfactor_pos_for_pageno(pageno)
|
531 | |
self._v_vscrollbar.set_value((v_upper - v_page_size) * scrollfactor)
|
|
506 |
v_upper = self._page_height
|
|
507 |
if self.__scroll_to_end:
|
|
508 |
# We need to scroll to the last page
|
|
509 |
scrollval = v_upper
|
|
510 |
self.__scroll_to_end = False
|
|
511 |
else:
|
|
512 |
pageno = self._loaded_page
|
|
513 |
scrollfactor = self._paginator.get_scrollfactor_pos_for_pageno(pageno)
|
|
514 |
scrollval = math.ceil(v_upper * scrollfactor)
|
|
515 |
self._view.scroll_to(scrollval)
|
532 | 516 |
|
533 | 517 |
def _paginate(self):
|
534 | 518 |
filelist = []
|
|
550 | 534 |
|
551 | 535 |
def _load_prev_page(self):
|
552 | 536 |
self._load_page(self._loaded_page - 1)
|
553 | |
|
554 | |
def _v_scrollbar_value_changed_cb(self, scrollbar):
|
555 | |
if self._loaded_page < 1:
|
556 | |
return
|
557 | |
scrollval = scrollbar.get_value()
|
558 | |
scroll_upper = self._v_vscrollbar.props.adjustment.props.upper
|
559 | |
scroll_page_size = self._v_vscrollbar.props.adjustment.props.page_size
|
560 | |
|
561 | |
if self.__going_fwd and not self._loaded_page == self._pagecount:
|
562 | |
if self._paginator.get_file_for_pageno(self._loaded_page) != \
|
563 | |
self._paginator.get_file_for_pageno(self._loaded_page + 1):
|
564 | |
# We don't need this if the next page is in another file
|
565 | |
return
|
566 | |
|
567 | |
scrollfactor_next = \
|
568 | |
self._paginator.get_scrollfactor_pos_for_pageno(
|
569 | |
self._loaded_page + 1)
|
570 | |
if scrollval > 0:
|
571 | |
scrollfactor = scrollval / (scroll_upper - scroll_page_size)
|
572 | |
else:
|
573 | |
scrollfactor = 0
|
574 | |
if scrollfactor >= scrollfactor_next:
|
575 | |
self._on_page_changed(self._loaded_page, self._loaded_page + 1)
|
576 | |
elif self.__going_back and self._loaded_page > 1:
|
577 | |
if self._paginator.get_file_for_pageno(self._loaded_page) != \
|
578 | |
self._paginator.get_file_for_pageno(self._loaded_page - 1):
|
579 | |
return
|
580 | |
|
581 | |
scrollfactor_cur = \
|
582 | |
self._paginator.get_scrollfactor_pos_for_pageno(
|
583 | |
self._loaded_page)
|
584 | |
if scrollval > 0:
|
585 | |
scrollfactor = scrollval / (scroll_upper - scroll_page_size)
|
586 | |
else:
|
587 | |
scrollfactor = 0
|
588 | |
|
589 | |
if scrollfactor <= scrollfactor_cur:
|
590 | |
self._on_page_changed(self._loaded_page, self._loaded_page - 1)
|
591 | 537 |
|
592 | 538 |
def _on_page_changed(self, oldpage, pageno):
|
593 | 539 |
if oldpage == pageno:
|
|
607 | 553 |
if self._loaded_page == pageno:
|
608 | 554 |
return
|
609 | 555 |
|
|
556 |
oldpage = self._loaded_page
|
|
557 |
|
610 | 558 |
filename = self._paginator.get_file_for_pageno(pageno)
|
611 | 559 |
filename = filename.replace('file://', '')
|
612 | 560 |
|
613 | 561 |
if filename != self._loaded_filename:
|
614 | 562 |
self._loaded_filename = filename
|
615 | |
if not self._file_loaded:
|
616 | |
# wait until the file is loaded
|
617 | |
return
|
618 | |
self._file_loaded = False
|
619 | 563 |
|
620 | 564 |
"""
|
621 | 565 |
TODO: disabled because javascript can't be executed
|
|
629 | 573 |
now text highlight is implemented and the epub file is saved
|
630 | 574 |
"""
|
631 | 575 |
|
|
576 |
self._view.stop_loading()
|
632 | 577 |
if filename.endswith('xml'):
|
633 | 578 |
dest = filename.replace('xml', 'xhtml')
|
634 | 579 |
if not os.path.exists(dest):
|
|
639 | 584 |
else:
|
640 | 585 |
self._loaded_page = pageno
|
641 | 586 |
self._scroll_page()
|
642 | |
self._on_page_changed(self._loaded_page, pageno)
|
|
587 |
self._on_page_changed(oldpage, pageno)
|
643 | 588 |
|
644 | 589 |
def _insert_js_reference(self, file_name, path):
|
645 | 590 |
js_reference = '<script type="text/javascript" ' + \
|
|
668 | 613 |
break
|
669 | 614 |
|
670 | 615 |
def _scrollbar_change_value_cb(self, range, scrolltype, value):
|
671 | |
if scrolltype == Gtk.ScrollType.STEP_FORWARD:
|
672 | |
self.__going_fwd = True
|
673 | |
self.__going_back = False
|
674 | |
if not self._do_page_transition():
|
675 | |
self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, 1)
|
676 | |
elif scrolltype == Gtk.ScrollType.STEP_BACKWARD:
|
677 | |
self.__going_fwd = False
|
678 | |
self.__going_back = True
|
679 | |
if not self._do_page_transition():
|
680 | |
self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, -1)
|
|
616 |
if scrolltype == Gtk.ScrollType.STEP_FORWARD or \
|
|
617 |
scrolltype == Gtk.ScrollType.STEP_BACKWARD:
|
|
618 |
self.scroll(scrolltype, False)
|
681 | 619 |
elif scrolltype == Gtk.ScrollType.JUMP or \
|
682 | |
scrolltype == Gtk.ScrollType.PAGE_FORWARD or \
|
|
620 |
scrolltype == Gtk.ScrollType.PAGE_FORWARD or \
|
683 | 621 |
scrolltype == Gtk.ScrollType.PAGE_BACKWARD:
|
684 | 622 |
if value > self._scrollbar.props.adjustment.props.upper:
|
685 | 623 |
self._load_page(self._pagecount)
|
686 | 624 |
else:
|
687 | |
self._load_page(round(value))
|
|
625 |
self._load_page(int(value))
|
688 | 626 |
else:
|
689 | 627 |
print 'Warning: unknown scrolltype %s with value %f' \
|
690 | 628 |
% (str(scrolltype), value)
|
|
702 | 640 |
self._ready = True
|
703 | 641 |
|
704 | 642 |
self._pagecount = self._paginator.get_total_pagecount()
|
705 | |
self._scrollbar.set_range(1.0, self._pagecount - 1.0)
|
|
643 |
self._scrollbar.set_range(1.0, self._pagecount)
|
706 | 644 |
self._scrollbar.set_increments(1.0, 1.0)
|
707 | 645 |
self._view.grab_focus()
|
708 | 646 |
self._view.grab_default()
|