23 | 23 |
import os.path
|
24 | 24 |
import math
|
25 | 25 |
import shutil
|
26 | |
import BeautifulSoup
|
27 | |
|
28 | |
from epub import _Epub
|
|
26 |
|
29 | 27 |
from jobs import _JobPaginator as _Paginator
|
30 | 28 |
|
31 | 29 |
LOADING_HTML = '''
|
|
39 | 37 |
|
40 | 38 |
__gproperties__ = {
|
41 | 39 |
'scale': (GObject.TYPE_FLOAT, 'the zoom level',
|
42 | |
'the zoom level of the widget',
|
43 | |
0.5, 4.0, 1.0, GObject.PARAM_READWRITE),
|
|
40 |
'the zoom level of the widget',
|
|
41 |
0.5, 4.0, 1.0, GObject.PARAM_READWRITE),
|
44 | 42 |
}
|
45 | 43 |
__gsignals__ = {
|
46 | 44 |
'page-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,
|
47 | |
([int, int])),
|
|
45 |
([int, int])),
|
48 | 46 |
'selection-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,
|
49 | 47 |
([])),
|
50 | 48 |
}
|
|
59 | 57 |
self._paginator = None
|
60 | 58 |
self._loaded_page = -1
|
61 | 59 |
self._file_loaded = True
|
62 | |
#self._old_scrollval = -1
|
|
60 |
# self._old_scrollval = -1
|
63 | 61 |
self._loaded_filename = None
|
64 | 62 |
self._pagecount = -1
|
65 | 63 |
self.__going_fwd = True
|
|
85 | 83 |
self._view.connect('scroll-event', self._view_scroll_event_cb)
|
86 | 84 |
self._view.connect('key-press-event', self._view_keypress_event_cb)
|
87 | 85 |
self._view.connect('selection-changed',
|
88 | |
self._view_selection_changed_cb)
|
|
86 |
self._view_selection_changed_cb)
|
89 | 87 |
self._view.connect_after('populate-popup',
|
90 | |
self._view_populate_popup_cb)
|
|
88 |
self._view_populate_popup_cb)
|
91 | 89 |
self._view.connect('touch-change-page', self.__touch_page_changed_cb)
|
92 | 90 |
|
93 | 91 |
self._sw.add(self._view)
|
94 | 92 |
self._v_vscrollbar = self._sw.get_vscrollbar()
|
95 | |
self._v_scrollbar_value_changed_cb_id = \
|
96 | |
self._v_vscrollbar.connect('value-changed', \
|
97 | |
self._v_scrollbar_value_changed_cb)
|
|
93 |
self._v_scrollbar_value_changed_cb_id = self._v_vscrollbar.connect(
|
|
94 |
'value-changed', self._v_scrollbar_value_changed_cb)
|
98 | 95 |
self._scrollbar = Gtk.VScrollbar()
|
99 | |
self._scrollbar_change_value_cb_id = \
|
100 | |
self._scrollbar.connect('change-value', \
|
101 | |
self._scrollbar_change_value_cb)
|
|
96 |
self._scrollbar_change_value_cb_id = self._scrollbar.connect(
|
|
97 |
'change-value', self._scrollbar_change_value_cb)
|
102 | 98 |
|
103 | 99 |
overlay = Gtk.Overlay()
|
104 | 100 |
hbox = Gtk.HBox()
|
|
237 | 233 |
'''
|
238 | 234 |
Returns the currently loaded XML file
|
239 | 235 |
'''
|
240 | |
#return self._loaded_filename
|
|
236 |
# return self._loaded_filename
|
241 | 237 |
if self._paginator:
|
242 | 238 |
return self._paginator.get_file_for_pageno(self._loaded_page)
|
243 | 239 |
else:
|
|
339 | 335 |
self._view.grab_focus()
|
340 | 336 |
|
341 | 337 |
if self._view.search_text(self._findjob.get_search_text(),
|
342 | |
self._findjob.get_case_sensitive(),
|
343 | |
True, False):
|
|
338 |
self._findjob.get_case_sensitive(),
|
|
339 |
True, False):
|
344 | 340 |
return
|
345 | 341 |
else:
|
346 | 342 |
path = os.path.join(self._epub.get_basedir(),
|
347 | |
self._findjob.get_next_file())
|
|
343 |
self._findjob.get_next_file())
|
348 | 344 |
self.__in_search = True
|
349 | 345 |
self.__search_fwd = True
|
350 | 346 |
self._load_file(path)
|
|
356 | 352 |
self._view.grab_focus()
|
357 | 353 |
|
358 | 354 |
if self._view.search_text(self._findjob.get_search_text(),
|
359 | |
self._findjob.get_case_sensitive(),
|
360 | |
False, False):
|
|
355 |
self._findjob.get_case_sensitive(),
|
|
356 |
False, False):
|
361 | 357 |
return
|
362 | 358 |
else:
|
363 | 359 |
path = os.path.join(self._epub.get_basedir(),
|
364 | |
self._findjob.get_prev_file())
|
|
360 |
self._findjob.get_prev_file())
|
365 | 361 |
self.__in_search = True
|
366 | 362 |
self.__search_fwd = False
|
367 | 363 |
self._load_file(path)
|
|
374 | 370 |
|
375 | 371 |
def _mark_found_text(self):
|
376 | 372 |
self._view.unmark_text_matches()
|
377 | |
self._view.mark_text_matches(self._findjob.get_search_text(),
|
378 | |
case_sensitive=self._findjob.get_case_sensitive(), limit=0)
|
|
373 |
self._view.mark_text_matches(
|
|
374 |
self._findjob.get_search_text(),
|
|
375 |
case_sensitive=self._findjob.get_case_sensitive(), limit=0)
|
379 | 376 |
self._view.set_highlight_text_matches(True)
|
380 | 377 |
|
381 | 378 |
def __set_zoom(self, value):
|
|
435 | 432 |
|
436 | 433 |
filename = filename.split('#')[0] # Get rid of anchors
|
437 | 434 |
|
438 | |
if self._loaded_page < 1 or filename == None:
|
|
435 |
if self._loaded_page < 1 or filename is None:
|
439 | 436 |
return False
|
440 | 437 |
|
441 | 438 |
self._loaded_filename = filename
|
442 | 439 |
|
443 | 440 |
remfactor = self._paginator.get_remfactor_for_file(filename)
|
444 | 441 |
pages = self._paginator.get_pagecount_for_file(filename)
|
445 | |
extra = int(math.ceil(remfactor *
|
446 | |
self._view.get_page_height() / (pages - remfactor)))
|
|
442 |
extra = int(math.ceil(
|
|
443 |
remfactor * self._view.get_page_height() / (pages - remfactor)))
|
447 | 444 |
if extra > 0:
|
448 | 445 |
self._view.add_bottom_padding(extra)
|
449 | 446 |
|
450 | 447 |
if self.__in_search:
|
451 | 448 |
self._mark_found_text()
|
452 | |
self._view.search_text(self._findjob.get_search_text(), \
|
453 | |
self._findjob.get_case_sensitive(), \
|
454 | |
self.__search_fwd, False)
|
|
449 |
self._view.search_text(self._findjob.get_search_text(),
|
|
450 |
self._findjob.get_case_sensitive(),
|
|
451 |
self.__search_fwd, False)
|
455 | 452 |
self.__in_search = False
|
456 | 453 |
else:
|
457 | 454 |
if self.__going_back:
|
|
460 | 457 |
else:
|
461 | 458 |
self._scroll_page()
|
462 | 459 |
|
463 | |
process_file = True
|
|
460 |
# process_file = True
|
464 | 461 |
if self._internal_link is not None:
|
465 | 462 |
self._view.go_to_link(self._internal_link)
|
466 | 463 |
vertical_pos = \
|
467 | 464 |
self._view.get_vertical_position_element(self._internal_link)
|
468 | 465 |
# set the page number based in the vertical position
|
469 | 466 |
initial_page = self._paginator.get_base_pageno_for_file(filename)
|
470 | |
self._loaded_page = initial_page + int(vertical_pos /
|
471 | |
self._paginator.get_single_page_height())
|
|
467 |
self._loaded_page = initial_page + int(
|
|
468 |
vertical_pos / self._paginator.get_single_page_height())
|
472 | 469 |
|
473 | 470 |
# There are epub files, created with Calibre,
|
474 | 471 |
# where the link in the index points to the end of the previos
|
|
483 | 480 |
logging.error('load next file %s', next_file)
|
484 | 481 |
self.__in_search = False
|
485 | 482 |
self.__going_back = False
|
486 | |
process_file = False
|
|
483 |
# process_file = False
|
487 | 484 |
GObject.idle_add(self._load_file, next_file)
|
488 | 485 |
|
489 | 486 |
# if process_file:
|
|
501 | 498 |
word_begin = 0
|
502 | 499 |
word_end = 0
|
503 | 500 |
ignore_chars = [' ', '\n', u'\r', '_', '[', '{', ']', '}', '|',
|
504 | |
'<', '>', '*', '+', '/', '\\']
|
|
501 |
'<', '>', '*', '+', '/', '\\']
|
505 | 502 |
ignore_set = set(ignore_chars)
|
506 | 503 |
self.word_tuples = []
|
507 | 504 |
len_page_text = len(page_text)
|
|
509 | 506 |
if page_text[i] not in ignore_set:
|
510 | 507 |
word_begin = i
|
511 | 508 |
j = i
|
512 | |
while j < len_page_text and page_text[j] not in ignore_set:
|
|
509 |
while j < len_page_text and page_text[j] not in ignore_set:
|
513 | 510 |
j = j + 1
|
514 | 511 |
word_end = j
|
515 | 512 |
i = j
|
516 | 513 |
word_tuple = (word_begin, word_end,
|
517 | |
page_text[word_begin: word_end])
|
|
514 |
page_text[word_begin: word_end])
|
518 | 515 |
if word_tuple[2] != u'\r':
|
519 | 516 |
self.word_tuples.append(word_tuple)
|
520 | 517 |
i = i + 1
|
521 | 518 |
|
522 | 519 |
def _scroll_page_end(self):
|
523 | 520 |
v_upper = self._v_vscrollbar.props.adjustment.props.upper
|
524 | |
v_page_size = self._v_vscrollbar.props.adjustment.props.page_size
|
|
521 |
# v_page_size = self._v_vscrollbar.props.adjustment.props.page_size
|
525 | 522 |
self._v_vscrollbar.set_value(v_upper)
|
526 | 523 |
|
527 | 524 |
def _scroll_page(self):
|
|
561 | 558 |
scroll_upper = self._v_vscrollbar.props.adjustment.props.upper
|
562 | 559 |
scroll_page_size = self._v_vscrollbar.props.adjustment.props.page_size
|
563 | 560 |
|
564 | |
if self.__going_fwd == True and \
|
565 | |
not self._loaded_page == self._pagecount:
|
|
561 |
if self.__going_fwd and not self._loaded_page == self._pagecount:
|
566 | 562 |
if self._paginator.get_file_for_pageno(self._loaded_page) != \
|
567 | |
self._paginator.get_file_for_pageno(self._loaded_page + 1):
|
|
563 |
self._paginator.get_file_for_pageno(self._loaded_page + 1):
|
568 | 564 |
# We don't need this if the next page is in another file
|
569 | 565 |
return
|
570 | 566 |
|
571 | 567 |
scrollfactor_next = \
|
572 | |
self._paginator.get_scrollfactor_pos_for_pageno(
|
|
568 |
self._paginator.get_scrollfactor_pos_for_pageno(
|
573 | 569 |
self._loaded_page + 1)
|
574 | 570 |
if scrollval > 0:
|
575 | 571 |
scrollfactor = scrollval / (scroll_upper - scroll_page_size)
|
|
577 | 573 |
scrollfactor = 0
|
578 | 574 |
if scrollfactor >= scrollfactor_next:
|
579 | 575 |
self._on_page_changed(self._loaded_page, self._loaded_page + 1)
|
580 | |
elif self.__going_back == True and self._loaded_page > 1:
|
|
576 |
elif self.__going_back and self._loaded_page > 1:
|
581 | 577 |
if self._paginator.get_file_for_pageno(self._loaded_page) != \
|
582 | |
self._paginator.get_file_for_pageno(
|
583 | |
self._loaded_page - 1):
|
|
578 |
self._paginator.get_file_for_pageno(self._loaded_page - 1):
|
584 | 579 |
return
|
585 | 580 |
|
586 | 581 |
scrollfactor_cur = \
|
587 | |
self._paginator.get_scrollfactor_pos_for_pageno(
|
|
582 |
self._paginator.get_scrollfactor_pos_for_pageno(
|
588 | 583 |
self._loaded_page)
|
589 | 584 |
if scrollval > 0:
|
590 | 585 |
scrollfactor = scrollval / (scroll_upper - scroll_page_size)
|
|
607 | 602 |
|
608 | 603 |
def _load_page(self, pageno):
|
609 | 604 |
if pageno > self._pagecount or pageno < 1:
|
610 | |
#TODO: Cause an exception
|
|
605 |
# TODO: Cause an exception
|
611 | 606 |
return
|
612 | 607 |
if self._loaded_page == pageno:
|
613 | 608 |
return
|
|
630 | 625 |
shutil.copy('./epubview/highlight_words.js', destpath)
|
631 | 626 |
self._insert_js_reference(filename.replace('file://', ''),
|
632 | 627 |
destpath)
|
|
628 |
IMPORTANT: Find a way to do this without modify the files
|
|
629 |
now text highlight is implemented and the epub file is saved
|
633 | 630 |
"""
|
634 | 631 |
|
635 | 632 |
if filename.endswith('xml'):
|
|
646 | 643 |
|
647 | 644 |
def _insert_js_reference(self, file_name, path):
|
648 | 645 |
js_reference = '<script type="text/javascript" ' + \
|
649 | |
'src="./highlight_words.js"></script>'
|
|
646 |
'src="./highlight_words.js"></script>'
|
650 | 647 |
o = open(file_name + '.tmp', 'a')
|
651 | 648 |
for line in open(file_name):
|
652 | 649 |
line = line.replace('</head>', js_reference + '</head>')
|
|
665 | 662 |
self._view.load_uri('file://' + filepath)
|
666 | 663 |
oldpage = self._loaded_page
|
667 | 664 |
self._loaded_page = \
|
668 | |
self._paginator.get_base_pageno_for_file(filepath)
|
|
665 |
self._paginator.get_base_pageno_for_file(filepath)
|
669 | 666 |
self._scroll_page()
|
670 | 667 |
self._on_page_changed(oldpage, self._loaded_page)
|
671 | 668 |
break
|
|
690 | 687 |
self._load_page(round(value))
|
691 | 688 |
else:
|
692 | 689 |
print 'Warning: unknown scrolltype %s with value %f' \
|
693 | |
% (str(scrolltype), value)
|
694 | |
|
695 | |
#FIXME: This should not be needed here
|
|
690 |
% (str(scrolltype), value)
|
|
691 |
|
|
692 |
# FIXME: This should not be needed here
|
696 | 693 |
self._scrollbar.set_value(self._loaded_page)
|
697 | 694 |
|
698 | |
if self.__page_changed == True:
|
|
695 |
if self.__page_changed:
|
699 | 696 |
self.__page_changed = False
|
700 | 697 |
return False
|
701 | 698 |
else:
|