Show progress information in jobs dialog while downloading feeds

This commit is contained in:
Kovid Goyal 2008-06-05 15:43:17 -07:00
parent 36484b906d
commit 77d65631a9
7 changed files with 83 additions and 23 deletions

View File

@ -10,7 +10,7 @@ Module to implement the Cover Flow feature
import sys, os import sys, os
from PyQt4.QtGui import QImage, QSizePolicy from PyQt4.QtGui import QImage, QSizePolicy
from PyQt4.QtCore import Qt, QSize, SIGNAL from PyQt4.QtCore import Qt, QSize, SIGNAL, QObject
from calibre import pictureflow from calibre import pictureflow
@ -49,7 +49,7 @@ if pictureflow is not None:
def __init__(self, model, buffer=20): def __init__(self, model, buffer=20):
pictureflow.FlowImages.__init__(self) pictureflow.FlowImages.__init__(self)
self.model = model self.model = model
self.connect(self.model, SIGNAL('modelReset()'), self.reset) QObject.connect(self.model, SIGNAL('modelReset()'), self.reset)
def count(self): def count(self):
return self.model.count() return self.model.count()
@ -76,9 +76,9 @@ if pictureflow is not None:
def wheelEvent(self, ev): def wheelEvent(self, ev):
ev.accept() ev.accept()
if ev.delta() > 0: if ev.delta() < 0:
self.showNext() self.showNext()
elif ev.delta() < 0: elif ev.delta() > 0:
self.showPrevious() self.showPrevious()

View File

@ -2,12 +2,31 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
'''Display active jobs''' '''Display active jobs'''
from PyQt4.QtCore import Qt, QObject, SIGNAL from PyQt4.QtCore import Qt, QObject, SIGNAL, QSize, QString
from PyQt4.QtGui import QDialog from PyQt4.QtGui import QDialog, QAbstractItemDelegate, QStyleOptionProgressBarV2, \
QApplication, QStyle
from calibre.gui2.dialogs.jobs_ui import Ui_JobsDialog from calibre.gui2.dialogs.jobs_ui import Ui_JobsDialog
from calibre import __appname__ from calibre import __appname__
class ProgressBarDelegate(QAbstractItemDelegate):
def sizeHint(self, option, index):
return QSize(120, 30)
def paint(self, painter, option, index):
opts = QStyleOptionProgressBarV2()
opts.rect = option.rect
opts.minimum = 1
opts.maximum = 100
opts.textVisible = True
percent, ok = index.model().data(index, Qt.DisplayRole).toInt()
if not ok:
percent = 0
opts.progress = percent
opts.text = QString(_('Unavailable') if percent == 0 else '%d%%'%percent)
QApplication.style().drawControl(QStyle.CE_ProgressBar, opts, painter)
class JobsDialog(QDialog, Ui_JobsDialog): class JobsDialog(QDialog, Ui_JobsDialog):
def __init__(self, window, model): def __init__(self, window, model):
QDialog.__init__(self, window) QDialog.__init__(self, window)
@ -23,6 +42,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
self.kill_job) self.kill_job)
QObject.connect(self, SIGNAL('kill_job(int, PyQt_PyObject)'), QObject.connect(self, SIGNAL('kill_job(int, PyQt_PyObject)'),
self.jobs_view.model().kill_job) self.jobs_view.model().kill_job)
self.pb_delegate = ProgressBarDelegate(self)
self.jobs_view.setItemDelegateForColumn(2, self.pb_delegate)
def kill_job(self): def kill_job(self):
for index in self.jobs_view.selectedIndexes(): for index in self.jobs_view.selectedIndexes():

View File

@ -224,6 +224,18 @@ class JobManager(QAbstractTableModel):
if isinstance(job, ConversionJob): if isinstance(job, ConversionJob):
yield job yield job
def update_progress(self, id, percent):
row = -1
for collection in (self.running_jobs, self.waiting_jobs, self.finished_jobs):
for job in collection:
row += 1
if job.id == id:
job.percent_done = percent
index = self.index(row, 2)
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), index, index)
return
def create_job(self, job_class, description, slot, priority, *args, **kwargs): def create_job(self, job_class, description, slot, priority, *args, **kwargs):
self.next_id += 1 self.next_id += 1
id = self.next_id id = self.next_id
@ -312,8 +324,7 @@ class JobManager(QAbstractTableModel):
st = [_('Working'), _('Waiting')][status] st = [_('Working'), _('Waiting')][status]
return QVariant(st) return QVariant(st)
if col == 2: if col == 2:
p = str(job.percent_done) + r'%' if job.percent_done > 0 else _('Unavailable') return QVariant(int(100*job.percent_done))
return QVariant(p)
if col == 3: if col == 3:
if job.start_time is None: if job.start_time is None:
return NONE return NONE

View File

@ -266,6 +266,16 @@ class Main(MainWindow, Ui_MainWindow):
elif msg.startswith('refreshdb:'): elif msg.startswith('refreshdb:'):
self.library_view.model().resort() self.library_view.model().resort()
self.library_view.model().research() self.library_view.model().research()
elif msg.startswith('progress:'):
try:
fields = msg.split(':')
job_id, percent = fields[1:3]
job_id, percent = int(job_id), float(percent)
self.job_manager.update_progress(job_id, percent)
except:
pass
else:
print msg
def current_view(self): def current_view(self):

View File

@ -12,12 +12,25 @@ from calibre.ebooks.lrf.web.convert_from import main as web2lrf
from calibre.ebooks.lrf.feeds.convert_from import main as feeds2lrf from calibre.ebooks.lrf.feeds.convert_from import main as feeds2lrf
from calibre.gui2.lrf_renderer.main import main as lrfviewer from calibre.gui2.lrf_renderer.main import main as lrfviewer
from calibre import iswindows, __appname__ from calibre import iswindows, __appname__
try:
from calibre.utils.single_qt_application import SingleApplication
except:
SingleApplication = None
sa = None
job_id = None
def report_progress(percent, msg=''):
if sa is not None and job_id is not None:
msg = 'progress:%s:%f:%s'%(job_id, percent, msg)
sa.send_message(msg)
PARALLEL_FUNCS = { PARALLEL_FUNCS = {
'any2lrf' : partial(any2lrf, gui_mode=True), 'any2lrf' : partial(any2lrf, gui_mode=True),
'web2lrf' : web2lrf, 'web2lrf' : web2lrf,
'lrfviewer' : lrfviewer, 'lrfviewer' : lrfviewer,
'feeds2lrf' : feeds2lrf, 'feeds2lrf' : partial(feeds2lrf, notification=report_progress),
} }
python = sys.executable python = sys.executable
@ -90,7 +103,7 @@ class Server(object):
os.mkdir(job_dir) os.mkdir(job_dir)
job_data = os.path.join(job_dir, 'job_data.pickle') job_data = os.path.join(job_dir, 'job_data.pickle')
cPickle.dump((func, args, kwdargs), open(job_data, 'wb'), -1) cPickle.dump((job_id, func, args, kwdargs), open(job_data, 'wb'), -1)
prefix = '' prefix = ''
if hasattr(sys, 'frameworks_dir'): if hasattr(sys, 'frameworks_dir'):
fd = getattr(sys, 'frameworks_dir') fd = getattr(sys, 'frameworks_dir')
@ -129,10 +142,13 @@ class Server(object):
def run_job(job_data): def run_job(job_data):
global sa, job_id
if SingleApplication is not None:
sa = SingleApplication('calibre GUI')
job_data = binascii.unhexlify(job_data) job_data = binascii.unhexlify(job_data)
base = os.path.dirname(job_data) base = os.path.dirname(job_data)
job_result = os.path.join(base, 'job_result.pickle') job_result = os.path.join(base, 'job_result.pickle')
func, args, kwdargs = cPickle.load(open(job_data, 'rb')) job_id, func, args, kwdargs = cPickle.load(open(job_data, 'rb'))
func = PARALLEL_FUNCS[func] func = PARALLEL_FUNCS[func]
exception, tb = None, None exception, tb = None, None
try: try:
@ -154,3 +170,5 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())
from calibre.utils.single_qt_application import SingleApplication

View File

@ -9,7 +9,7 @@ applications using a local socket.
''' '''
import atexit import atexit
from PyQt4.QtCore import QByteArray, QDataStream, QIODevice, SIGNAL, QObject, Qt from PyQt4.QtCore import QByteArray, QDataStream, QIODevice, SIGNAL, QObject, Qt, QString
from PyQt4.QtNetwork import QLocalSocket, QLocalServer from PyQt4.QtNetwork import QLocalSocket, QLocalServer
timeout_read = 5000 timeout_read = 5000
@ -20,7 +20,7 @@ def write_message(socket, message, timeout = 5000):
out = QDataStream(block, QIODevice.WriteOnly) out = QDataStream(block, QIODevice.WriteOnly)
out.writeInt32(0) out.writeInt32(0)
out.writeString(message) out.writeString(QString(message))
out.device().seek(0) out.device().seek(0)
out.writeInt32(len(message)) out.writeInt32(len(message))