mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Start work on saving
This commit is contained in:
parent
8cc9440847
commit
f4d132b823
@ -16,14 +16,16 @@ from calibre.ebooks.oeb.polish.main import SUPPORTED
|
|||||||
from calibre.ebooks.oeb.polish.container import get_container, clone_container
|
from calibre.ebooks.oeb.polish.container import get_container, clone_container
|
||||||
from calibre.gui2.tweak_book import set_current_container, current_container, tprefs
|
from calibre.gui2.tweak_book import set_current_container, current_container, tprefs
|
||||||
from calibre.gui2.tweak_book.undo import GlobalUndoHistory
|
from calibre.gui2.tweak_book.undo import GlobalUndoHistory
|
||||||
|
from calibre.gui2.tweak_book.save import SaveManager
|
||||||
|
|
||||||
class Boss(QObject):
|
class Boss(QObject):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent):
|
||||||
QObject.__init__(self, parent)
|
QObject.__init__(self, parent)
|
||||||
self.global_undo = GlobalUndoHistory()
|
self.global_undo = GlobalUndoHistory()
|
||||||
self.container_count = 0
|
self.container_count = 0
|
||||||
self.tdir = None
|
self.tdir = None
|
||||||
|
self.save_manager = SaveManager(parent)
|
||||||
|
|
||||||
def __call__(self, gui):
|
def __call__(self, gui):
|
||||||
self.gui = gui
|
self.gui = gui
|
||||||
@ -40,6 +42,7 @@ class Boss(QObject):
|
|||||||
def open_book(self, path=None):
|
def open_book(self, path=None):
|
||||||
if not self.check_dirtied():
|
if not self.check_dirtied():
|
||||||
return
|
return
|
||||||
|
# TODO: Check if a save is in progress and abort if it is
|
||||||
|
|
||||||
if not hasattr(path, 'rpartition'):
|
if not hasattr(path, 'rpartition'):
|
||||||
path = choose_files(self.gui, 'open-book-for-tweaking', _('Choose book'),
|
path = choose_files(self.gui, 'open-book-for-tweaking', _('Choose book'),
|
||||||
@ -119,7 +122,10 @@ class Boss(QObject):
|
|||||||
# TODO: Update other GUI elements
|
# TODO: Update other GUI elements
|
||||||
|
|
||||||
def save_book(self):
|
def save_book(self):
|
||||||
pass
|
self.gui.action_save.setEnabled(False)
|
||||||
|
tdir = tempfile.mkdtemp(prefix='save-%05d-' % self.container_count, dir=self.tdir)
|
||||||
|
container = clone_container(current_container(), tdir)
|
||||||
|
self.save_manager.schedule(tdir, container)
|
||||||
|
|
||||||
def quit(self):
|
def quit(self):
|
||||||
if not self.confirm_quit():
|
if not self.confirm_quit():
|
||||||
|
125
src/calibre/gui2/tweak_book/save.py
Normal file
125
src/calibre/gui2/tweak_book/save.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
|
print_function)
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
from threading import Thread
|
||||||
|
from Queue import LifoQueue, Empty
|
||||||
|
|
||||||
|
from PyQt4.Qt import (QObject, pyqtSignal, QLabel, QWidget, QHBoxLayout, Qt)
|
||||||
|
|
||||||
|
from calibre.utils import join_with_timeout
|
||||||
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
|
|
||||||
|
class SaveWidget(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.l = l = QHBoxLayout(self)
|
||||||
|
self.setLayout(l)
|
||||||
|
self.label = QLabel('')
|
||||||
|
self.pi = ProgressIndicator(self, 24)
|
||||||
|
l.addWidget(self.label)
|
||||||
|
l.addWidget(self.pi)
|
||||||
|
l.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.pi.setVisible(False)
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.pi.setVisible(True)
|
||||||
|
self.pi.startAnimation()
|
||||||
|
self.label.setText(_('Saving...'))
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.pi.setVisible(False)
|
||||||
|
self.pi.stopAnimation()
|
||||||
|
self.label.setText(_('Saved'))
|
||||||
|
|
||||||
|
class SaveManager(QObject):
|
||||||
|
|
||||||
|
start_save = pyqtSignal()
|
||||||
|
report_error = pyqtSignal(object)
|
||||||
|
save_done = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
QObject.__init__(self, parent)
|
||||||
|
self.count = 0
|
||||||
|
self.last_saved = -1
|
||||||
|
self.requests = LifoQueue()
|
||||||
|
t = Thread(name='save-thread', target=self.run)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
self.status_widget = w = SaveWidget(parent)
|
||||||
|
self.start_save.connect(w.start, type=Qt.QueuedConnection)
|
||||||
|
self.save_done.connect(w.stop, type=Qt.QueuedConnection)
|
||||||
|
|
||||||
|
def schedule(self, tdir, container):
|
||||||
|
self.count += 1
|
||||||
|
self.requests.put((self.count, tdir, container))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
x = self.requests.get()
|
||||||
|
if x is None:
|
||||||
|
self.requests.task_done()
|
||||||
|
self.__empty_queue()
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
count, tdir, container = x
|
||||||
|
self.process_save(count, tdir, container)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
self.requests.task_done()
|
||||||
|
|
||||||
|
def __empty_queue(self):
|
||||||
|
' Only to be used during shutdown '
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
self.requests.get_nowait()
|
||||||
|
except Empty:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.requests.task_done()
|
||||||
|
|
||||||
|
def process_save(self, count, tdir, container):
|
||||||
|
if count <= self.last_saved:
|
||||||
|
shutil.rmtree(tdir, ignore_errors=True)
|
||||||
|
return
|
||||||
|
self.last_saved = count
|
||||||
|
self.start_save.emit()
|
||||||
|
try:
|
||||||
|
self.do_save(tdir, container)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
self.report_error.emit(traceback.format_exc())
|
||||||
|
self.save_done.emit()
|
||||||
|
|
||||||
|
def do_save(self, tdir, container):
|
||||||
|
try:
|
||||||
|
import time
|
||||||
|
time.sleep(10)
|
||||||
|
finally:
|
||||||
|
shutil.rmtree(tdir, ignore_errors=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_tasks(self):
|
||||||
|
return bool(self.requests.unfinished_tasks)
|
||||||
|
|
||||||
|
def wait(self, timeout=30):
|
||||||
|
if timeout is None:
|
||||||
|
self.requests.join()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
join_with_timeout(self.requests, timeout)
|
||||||
|
except RuntimeError:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
self.requests.put(None)
|
@ -8,6 +8,7 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
from PyQt4.Qt import QDockWidget, Qt, QLabel, QIcon, QAction, QApplication
|
from PyQt4.Qt import QDockWidget, Qt, QLabel, QIcon, QAction, QApplication
|
||||||
|
|
||||||
|
from calibre.constants import __appname__, get_version
|
||||||
from calibre.gui2.main_window import MainWindow
|
from calibre.gui2.main_window import MainWindow
|
||||||
from calibre.gui2.tweak_book import current_container, tprefs
|
from calibre.gui2.tweak_book import current_container, tprefs
|
||||||
from calibre.gui2.tweak_book.file_list import FileListWidget
|
from calibre.gui2.tweak_book.file_list import FileListWidget
|
||||||
@ -39,6 +40,11 @@ class Main(MainWindow):
|
|||||||
|
|
||||||
self.status_bar = self.statusBar()
|
self.status_bar = self.statusBar()
|
||||||
self.l = QLabel('Placeholder')
|
self.l = QLabel('Placeholder')
|
||||||
|
self.status_bar.addPermanentWidget(self.boss.save_manager.status_widget)
|
||||||
|
self.status_bar.addWidget(QLabel(_('%s %s created by %s') % (__appname__, get_version(), 'Kovid Goyal')))
|
||||||
|
f = self.status_bar.font()
|
||||||
|
f.setBold(True)
|
||||||
|
self.status_bar.setFont(f)
|
||||||
|
|
||||||
self.setCentralWidget(self.l)
|
self.setCentralWidget(self.l)
|
||||||
self.boss(self)
|
self.boss(self)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user