X-Git-Url: http://dolda2000.com/gitweb/?p=automanga.git;a=blobdiff_plain;f=manga%2Freader.py;h=6694ecde35d5b663eb94603a646fc3ccfdb60582;hp=af272899ba32e9729acf20b3cf03dccd96f76673;hb=1aa34ec9cf4ddd9dab038465fa51a96747c8a488;hpb=32b804f27eb8039865855f6e8e5922368f62f85b diff --git a/manga/reader.py b/manga/reader.py index af27289..6694ecd 100644 --- a/manga/reader.py +++ b/manga/reader.py @@ -1,5 +1,5 @@ -import threading, gtk, gio, gobject -import lib +import threading, gtk, gobject +import lib, profile class notdone(Exception): pass @@ -23,17 +23,18 @@ class future(threading.Thread): try: val = self.value() except Exception as e: - with gtk.gdk.lock: - self._exc = e - for cb in self._notlist: - cb() - self._notlist = [] + self._exc = e + gobject.idle_add(self._callcbs, True) else: - with gtk.gdk.lock: - self._val = [val] - for cb in self._notlist: - cb() - self._notlist = [] + self._val = [val] + gobject.idle_add(self._callcbs, True) + + def _callcbs(self, final): + nls = [] + for cb in self._notlist: + if cb(): + nls.append(cb) + self._notlist = [] if final else nls # Caller must hold GDK lock def notify(self, cb): @@ -44,12 +45,7 @@ class future(threading.Thread): cb() def progcb(self): - with gtk.gdk.lock: - nls = [] - for cb in self._notlist: - if cb(): - nls.append(cb) - self._notlist = nls + gobject.idle_add(self._callcbs, False) @property def val(self): @@ -79,19 +75,22 @@ class imgload(future): self.start() def value(self): - buf = bytearray() - with self.page.open() as st: - self.p = 0 - self.st = st - while True: - read = st.read(1024) - if read == "": - break - self.p += len(read) - buf.extend(read) - self.progcb() - self.st = None - return gtk.gdk.pixbuf_new_from_stream(gio.memory_input_stream_new_from_data(str(buf))) + buf = gtk.gdk.PixbufLoader() + try: + with self.page.open() as st: + self.p = 0 + self.st = st + while True: + read = st.read(1024) + if read == "": + break + self.p += len(read) + buf.write(read) + self.progcb() + self.st = None + finally: + buf.close() + return buf.get_pixbuf() @property def prog(self): @@ -112,9 +111,17 @@ class pagecache(object): f = imgload(page) self.bk.append((idl, f)) if len(self.bk) > self.sz: - self.bk = self.bk[-sz:] + self.bk = self.bk[-self.sz:] return f + def __delitem__(self, page): + idl = page.idlist() + for i, (ol, f) in enumerate(self.bk): + if ol == idl: + del self.bk[i] + return + raise KeyError(idl) + class relpageget(future): def __init__(self, cur, prev, cache=None): super(relpageget, self).__init__() @@ -136,6 +143,15 @@ class relpageget(future): self.cache[page] return page +class idpageget(future): + def __init__(self, base, idlist): + super(idpageget, self).__init__() + self.bnode = base + self.idlist = idlist + + def value(self): + return lib.cursor(self.bnode.byidlist(self.idlist)).cur + class pageget(future): def __init__(self, fnode): super(pageget, self).__init__() @@ -185,7 +201,8 @@ class pageview(gtk.Widget): self.window.set_user_data(None) def do_size_request(self, req): - req.width, req.height = self.get_osize() + w, h = self.get_osize() + req.width, req.height = max(min(w, 4096), 0), max(min(h, 4096), 0) def fitzoom(self): w, h = self.get_osize() @@ -428,6 +445,7 @@ class sbox(gtk.ComboBox): self.set_active(0) self.set_sensitive(False) + self.set_focus_on_click(False) self.bk.append([ptnode.name]) self.loadlist = procslot(self) self.loadlist.set(loadplist(self.pnode)) @@ -435,7 +453,7 @@ class sbox(gtk.ComboBox): def setlist(self, ls): self.bk.clear() for i, ch in enumerate(ls): - self.bk.append([ch.name]) + self.bk.append(["%i/%i: %s" % (i + 1, len(ls), ch.name)]) self.set_active(self.pidx) self.set_sensitive(True) self.connect("changed", self.changed_cb) @@ -443,8 +461,24 @@ class sbox(gtk.ComboBox): def changed_cb(self, wdg, data=None): self.rd.fetchpage(pageget(self.pnode[self.get_active()])) +class profprop(object): + def __init__(self, key, default=None): + self.key = key + self.default = default + + def __get__(self, ins, cls): + return ins.profile.props.get(self.key, self.default) + + def __set__(self, ins, val): + ins.profile.props[self.key] = val + ins.profile.save() + + def __delete__(self, ins): + del ins.profile.props[self.key] + ins.profile.save() + class reader(gtk.Window): - def __init__(self, manga): + def __init__(self, manga, prof=None): super(reader, self).__init__(gtk.WINDOW_TOPLEVEL) self.connect("delete_event", lambda wdg, ev, data=None: False) self.connect("destroy", lambda wdg, data=None: self.quit()) @@ -453,6 +487,7 @@ class reader(gtk.Window): self.pagefetch = procslot(self) self.imgfetch = procslot(self) self.preload = procslot(self) + self.profile = prof if prof else profile.memmanga(None, None, manga.id) self.manga = manga self.page = None @@ -485,9 +520,15 @@ class reader(gtk.Window): self.add(vlay) vlay.show() - self.fetchpage(pageget(self.manga)) + if self.curpage is not None: + self.fetchpage(idpageget(self.manga, self.curpage)) + else: + self.fetchpage(pageget(self.manga)) self.updtitle() + zmode = profprop("zmode", "fit") + curpage = profprop("curpage") + def updpagelbl(self): if self.page is None: self.pagelbl.set_text("") @@ -517,6 +558,9 @@ class reader(gtk.Window): self.page = None if img is not None: self.page = pageview(img) + if self.zmode == "1": + self.page.set_zoom(1) + self.page.set_off((0, 0)) self.pfr.add(self.page) self.page.show() self.updpagelbl() @@ -525,6 +569,7 @@ class reader(gtk.Window): if self.point is not None: self.point = None if page is not None: + self.curpage = page.idlist() self.point = ccursor(page, self.cache) self.imgfetch.set(imgfetch(self.cache[page])) else: @@ -563,8 +608,10 @@ class reader(gtk.Window): if self.page is not None: if ev.keyval in [ord('O'), ord('o')]: self.zoom = 1.0 + self.zmode = "1" elif ev.keyval in [ord('P'), ord('p')]: self.zoom = None + self.zmode = "fit" elif ev.keyval in [ord('[')]: self.zoom = min(self.zoom * 1.25, 3) elif ev.keyval in [ord(']')]: @@ -590,6 +637,10 @@ class reader(gtk.Window): self.fetchpage(self.point.next, lambda page: self.preload.set(preload(relpageget(page, False, self.cache)))) elif ev.keyval in [65288]: self.fetchpage(self.point.prev, lambda page: self.preload.set(preload(relpageget(page, True, self.cache)))) + elif ev.keyval in [ord('R'), ord('r')]: + page = self.point.cur.cur + del self.cache[page] + self.imgfetch.set(imgfetch(self.cache[page])) def quit(self): self.hide()