Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/epubview/jobs.py
diff options
context:
space:
mode:
Diffstat (limited to 'epubview/jobs.py')
-rw-r--r--epubview/jobs.py248
1 files changed, 248 insertions, 0 deletions
diff --git a/epubview/jobs.py b/epubview/jobs.py
new file mode 100644
index 0000000..de276b3
--- /dev/null
+++ b/epubview/jobs.py
@@ -0,0 +1,248 @@
+# Copyright 2009 One Laptop Per Child
+# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+import gobject
+import gtk
+import widgets
+import cairo
+
+import math
+import os.path
+import BeautifulSoup
+
+import epub
+
+import threading
+
+PAGE_WIDTH = 135
+PAGE_HEIGHT = 216
+
+def _pixel_to_mm(pixel, dpi):
+ inches = pixel/dpi
+ return int(inches/0.03937)
+
+def _mm_to_pixel(mm, dpi):
+ inches = mm * 0.03937
+ return int(inches * dpi)
+
+
+
+class SearchThread(threading.Thread):
+ def __init__(self, obj):
+ threading.Thread.__init__ (self)
+ self.obj = obj
+ self.stopthread = threading.Event()
+
+ def _start_search(self):
+ for entry in self.obj.flattoc:
+ if self.stopthread.isSet():
+ break
+ name, file = entry
+ filepath = os.path.join(self.obj._document.get_basedir(), file)
+ f = open(filepath)
+ if self._searchfile(f):
+ self.obj._matchfilelist.append(file)
+ f.close()
+
+ gtk.gdk.threads_enter()
+ self.obj._finished = True
+ self.obj.emit('updated')
+ gtk.gdk.threads_leave()
+
+ return False
+
+ def _searchfile(self, fileobj):
+ soup = BeautifulSoup.BeautifulSoup(fileobj)
+ body = soup.find('body')
+ tags = body.findChildren(True)
+ for tag in tags:
+ if not tag.string is None:
+ if tag.string.find(self.obj._text) > -1:
+ return True
+
+ return False
+
+ def run (self):
+ self._start_search()
+
+ def stop(self):
+ self.stopthread.set()
+
+
+
+class _JobPaginator(gobject.GObject):
+ __gsignals__ = {
+ 'paginated': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([]))
+ }
+ def __init__(self, filelist):
+ gobject.GObject.__init__(self)
+
+ self._filelist = filelist
+ self._filedict = {}
+ self._pagemap = {}
+
+ self._bookheight = 0
+ self._count = 0
+ self._pagecount = 0
+
+ self._screen = gtk.gdk.screen_get_default()
+ self._old_fontoptions = self._screen.get_font_options()
+ options = cairo.FontOptions()
+ options.set_hint_style(cairo.HINT_STYLE_MEDIUM)
+ options.set_antialias(cairo.ANTIALIAS_GRAY)
+ options.set_subpixel_order(cairo.SUBPIXEL_ORDER_DEFAULT)
+ options.set_hint_metrics(cairo.HINT_METRICS_DEFAULT)
+ self._screen.set_font_options(options)
+
+ self._temp_win = gtk.Window()
+ self._temp_view = widgets._WebView()
+
+ settings = self._temp_view.get_settings()
+ settings.props.default_font_family = 'DejaVu LGC Serif'
+ settings.props.sans_serif_font_family = 'DejaVu LGC Sans'
+ settings.props.serif_font_family = 'DejaVu LGC Serif'
+ settings.props.monospace_font_family = 'DejaVu LGC Sans Mono'
+ settings.props.enforce_96_dpi = True
+ #settings.props.auto_shrink_images = False #FIXME: This does not seem to work
+ settings.props.enable_plugins = False
+ settings.props.default_font_size = 12
+ settings.props.default_monospace_font_size = 10
+ settings.props.default_encoding = 'utf-8'
+
+ sw = gtk.ScrolledWindow()
+ sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
+ self._dpi = 96
+ sw.set_size_request(_mm_to_pixel(PAGE_WIDTH, self._dpi), _mm_to_pixel(PAGE_HEIGHT, self._dpi))
+ sw.add(self._temp_view)
+ self._temp_win.add(sw)
+ self._temp_view.connect('load-finished', self._page_load_finished_cb)
+
+ self._temp_win.show_all()
+ self._temp_win.unrealize()
+
+ self._temp_view.open(self._filelist[self._count])
+
+ def _page_load_finished_cb(self, v, frame):
+ f = v.get_main_frame()
+ pageheight = v.get_page_height()
+
+ if pageheight <= _mm_to_pixel(PAGE_HEIGHT, self._dpi):
+ pages = 1
+ else:
+ pages = pageheight/float(_mm_to_pixel(PAGE_HEIGHT, self._dpi))
+ for i in range(1, int(math.ceil(pages) + 1)):
+ if pages - i < 0:
+ pagelen = (pages - math.floor(pages))/pages
+ else:
+ pagelen = 1/pages
+ self._pagemap[float(self._pagecount + i)] = (f.props.uri, (i-1)/math.ceil(pages), pagelen)
+
+ self._pagecount += math.ceil(pages)
+ self._filedict[f.props.uri.replace('file://', '')] = (math.ceil(pages), math.ceil(pages) - pages)
+ self._bookheight += pageheight
+
+ if self._count+1 >= len(self._filelist):
+ self._temp_win.destroy()
+ self._screen.set_font_options(self._old_fontoptions)
+ self.emit('paginated')
+ else:
+ self._count += 1
+ self._temp_view.open(self._filelist[self._count])
+
+
+ def get_file_for_pageno(self, pageno):
+ return self._pagemap[pageno][0]
+
+ def get_scrollfactor_pos_for_pageno(self, pageno):
+ return self._pagemap[pageno][1]
+
+ def get_scrollfactor_len_for_pageno(self, pageno):
+ return self._pagemap[pageno][2]
+
+ def get_pagecount_for_file(self, file):
+ return self._filedict[file][0]
+
+ def get_remfactor_for_file(self, file):
+ return self._filedict[file][1]
+
+ def get_total_pagecount(self):
+ return self._pagecount
+
+ def get_total_height(self):
+ return self._bookheight
+
+
+class _JobFind(gobject.GObject):
+ __gsignals__ = {
+ 'updated': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([]))
+ }
+ def __init__(self, document, start_page, n_pages, text, case_sensitive=False):
+ gobject.GObject.__init__(self)
+ gtk.threads_init()
+
+ self._finished = False
+ self._document = document
+ self._start_page = start_page
+ self._n_pages = n_pages
+ self._text = text
+ self._case_sensitive = case_sensitive
+ self.flattoc = self._document.get_flattoc()
+ self._matchfilelist = []
+ self._current_file_index = 0
+ self.threads = []
+
+ s_thread = SearchThread(self)
+ self.threads.append(s_thread)
+ s_thread.start()
+
+ def cancel(self):
+ for s_thread in self.threads:
+ s_thread.stop()
+
+ def is_finished(self):
+ return self._finished
+
+ def get_next_file(self):
+ self._current_file_index += 1
+ try:
+ path = self._matchfilelist[self._current_file_index]
+ except IndexError:
+ self._current_file_index = 0
+ path = self._matchfilelist[self._current_file_index]
+
+ return path
+
+ def get_prev_file(self):
+ self._current_file_index -= 1
+ try:
+ path = self._matchfilelist[self._current_file_index]
+ except IndexError:
+ self._current_file_index = -1
+ path = self._matchfilelist[self._current_file_index]
+
+ return path
+
+ def get_search_text(self):
+ return self._text
+
+ def get_case_sensitive(self):
+ return self._case_sensitive