Busy cursor during preparation stage of sending books to device

This commit is contained in:
Kovid Goyal 2013-12-10 09:07:09 +05:30
parent 97ce7bf539
commit aba91c645b

View File

@ -6,9 +6,9 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os, traceback, Queue, time, cStringIO, re, sys, weakref import os, traceback, Queue, time, cStringIO, re, sys, weakref
from threading import Thread, Event from threading import Thread, Event
from PyQt4.Qt import (QMenu, QAction, QActionGroup, QIcon, SIGNAL, from PyQt4.Qt import (
Qt, pyqtSignal, QDialog, QObject, QVBoxLayout, QMenu, QAction, QActionGroup, QIcon, SIGNAL, Qt, pyqtSignal, QDialog,
QDialogButtonBox) QObject, QVBoxLayout, QDialogButtonBox, QCursor)
from calibre.customize.ui import (available_input_formats, available_output_formats, from calibre.customize.ui import (available_input_formats, available_output_formats,
device_plugins, disabled_device_plugins) device_plugins, disabled_device_plugins)
@ -119,6 +119,17 @@ def device_name_for_plugboards(device_class):
return device_class.DEVICE_PLUGBOARD_NAME return device_class.DEVICE_PLUGBOARD_NAME
return device_class.__class__.__name__ return device_class.__class__.__name__
class BusyCursor(object):
def __enter__(self):
from PyQt4.Qt import QApplication
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
def __exit__(self, *args):
from PyQt4.Qt import QApplication
QApplication.restoreOverrideCursor()
class DeviceManager(Thread): # {{{ class DeviceManager(Thread): # {{{
def __init__(self, connected_slot, job_manager, open_feedback_slot, def __init__(self, connected_slot, job_manager, open_feedback_slot,
@ -695,7 +706,6 @@ class DeviceMenu(QMenu): # {{{
self.set_default_menu = QMenu(_('Set default send to device action')) self.set_default_menu = QMenu(_('Set default send to device action'))
self.set_default_menu.setIcon(QIcon(I('config.png'))) self.set_default_menu.setIcon(QIcon(I('config.png')))
basic_actions = [ basic_actions = [
('main:', False, False, I('reader.png'), ('main:', False, False, I('reader.png'),
_('Send to main memory')), _('Send to main memory')),
@ -816,12 +826,12 @@ class DeviceMenu(QMenu): # {{{
if action.dest == 'main:': if action.dest == 'main:':
action.setEnabled(True) action.setEnabled(True)
elif action.dest == 'carda:0': elif action.dest == 'carda:0':
if card_prefix and card_prefix[0] != None: if card_prefix and card_prefix[0] is not None:
action.setEnabled(True) action.setEnabled(True)
else: else:
action.setEnabled(False) action.setEnabled(False)
elif action.dest == 'cardb:0': elif action.dest == 'cardb:0':
if card_prefix and card_prefix[1] != None: if card_prefix and card_prefix[1] is not None:
action.setEnabled(True) action.setEnabled(True)
else: else:
action.setEnabled(False) action.setEnabled(False)
@ -926,7 +936,8 @@ class DeviceMixin(object): # {{{
self.device_manager.umount_device() self.device_manager.umount_device()
def configure_connected_device(self): def configure_connected_device(self):
if not self.device_manager.is_device_connected: return if not self.device_manager.is_device_connected:
return
if self.job_manager.has_device_jobs(queued_also=True): if self.job_manager.has_device_jobs(queued_also=True):
return error_dialog(self, _('Running jobs'), return error_dialog(self, _('Running jobs'),
_('Cannot configure the device while there are running' _('Cannot configure the device while there are running'
@ -1039,12 +1050,12 @@ class DeviceMixin(object): # {{{
self.set_device_menu_items_state(connected) self.set_device_menu_items_state(connected)
if connected: if connected:
self.device_connected = device_kind self.device_connected = device_kind
self.device_manager.get_device_information(\ self.device_manager.get_device_information(
FunctionDispatcher(self.info_read)) FunctionDispatcher(self.info_read))
self.set_default_thumbnail(\ self.set_default_thumbnail(
self.device_manager.device.THUMBNAIL_HEIGHT) self.device_manager.device.THUMBNAIL_HEIGHT)
self.status_bar.show_message(_('Device: ')+\ self.status_bar.show_message(_('Device: ')+
self.device_manager.device.get_gui_name()+\ self.device_manager.device.get_gui_name()+
_(' detected.'), 3000) _(' detected.'), 3000)
self.library_view.set_device_connected(self.device_connected) self.library_view.set_device_connected(self.device_connected)
self.refresh_ondevice(reset_only=True) self.refresh_ondevice(reset_only=True)
@ -1247,6 +1258,7 @@ class DeviceMixin(object): # {{{
settings = self.device_manager.device.settings() settings = self.device_manager.device.settings()
ids = list(dynamic.get('catalogs_to_be_synced', set([]))) if send_ids is None else send_ids ids = list(dynamic.get('catalogs_to_be_synced', set([]))) if send_ids is None else send_ids
ids = [id for id in ids if self.library_view.model().db.has_id(id)] ids = [id for id in ids if self.library_view.model().db.has_id(id)]
with BusyCursor():
files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids( files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(
ids, settings.format_map, ids, settings.format_map,
exclude_auto=do_auto_convert) exclude_auto=do_auto_convert)
@ -1297,7 +1309,6 @@ class DeviceMixin(object): # {{{
memory=[files, remove]) memory=[files, remove])
self.status_bar.show_message(_('Sending catalogs to device.'), 5000) self.status_bar.show_message(_('Sending catalogs to device.'), 5000)
@dynamic_property @dynamic_property
def news_to_be_synced(self): def news_to_be_synced(self):
doc = 'Set of ids to be sent to device' doc = 'Set of ids to be sent to device'
@ -1321,13 +1332,13 @@ class DeviceMixin(object): # {{{
return property(fget=fget, fset=fset, doc=doc) return property(fget=fget, fset=fset, doc=doc)
def sync_news(self, send_ids=None, do_auto_convert=True): def sync_news(self, send_ids=None, do_auto_convert=True):
if self.device_connected: if self.device_connected:
del_on_upload = config['delete_news_from_library_on_upload'] del_on_upload = config['delete_news_from_library_on_upload']
settings = self.device_manager.device.settings() settings = self.device_manager.device.settings()
ids = list(self.news_to_be_synced) if send_ids is None else send_ids ids = list(self.news_to_be_synced) if send_ids is None else send_ids
ids = [id for id in ids if self.library_view.model().db.has_id(id)] ids = [id for id in ids if self.library_view.model().db.has_id(id)]
with BusyCursor():
files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids( files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(
ids, settings.format_map, ids, settings.format_map,
exclude_auto=do_auto_convert) exclude_auto=do_auto_convert)
@ -1394,10 +1405,9 @@ class DeviceMixin(object): # {{{
memory=[files, remove]) memory=[files, remove])
self.status_bar.show_message(_('Sending news to device.'), 5000) self.status_bar.show_message(_('Sending news to device.'), 5000)
def sync_to_device(self, on_card, delete_from_library, def sync_to_device(self, on_card, delete_from_library,
specific_format=None, send_ids=None, do_auto_convert=True): specific_format=None, send_ids=None, do_auto_convert=True):
ids = [self.library_view.model().id(r) \ ids = [self.library_view.model().id(r)
for r in self.library_view.selectionModel().selectedRows()] \ for r in self.library_view.selectionModel().selectedRows()] \
if send_ids is None else send_ids if send_ids is None else send_ids
if not self.device_manager or not ids or len(ids) == 0 or \ if not self.device_manager or not ids or len(ids) == 0 or \
@ -1406,6 +1416,7 @@ class DeviceMixin(object): # {{{
settings = self.device_manager.device.settings() settings = self.device_manager.device.settings()
with BusyCursor():
_files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(ids, _files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(ids,
settings.format_map, settings.format_map,
specific_format=specific_format, specific_format=specific_format,
@ -1450,11 +1461,12 @@ class DeviceMixin(object): # {{{
auto = [] auto = []
if _auto_ids != []: if _auto_ids != []:
for id in _auto_ids: for id in _auto_ids:
if specific_format == None: if specific_format is None:
formats = self.library_view.model().db.formats(id, index_is_id=True) formats = self.library_view.model().db.formats(id, index_is_id=True)
formats = formats.split(',') if formats is not None else [] formats = formats.split(',') if formats is not None else []
formats = [f.lower().strip() for f in formats] formats = [f.lower().strip() for f in formats]
if list(set(formats).intersection(available_input_formats())) != [] and list(set(settings.format_map).intersection(available_output_formats())) != []: if (list(set(formats).intersection(available_input_formats())) != [] and
list(set(settings.format_map).intersection(available_output_formats())) != []):
auto.append(id) auto.append(id)
else: else:
bad.append(self.library_view.model().db.title(id, index_is_id=True)) bad.append(self.library_view.model().db.title(id, index_is_id=True))
@ -1556,7 +1568,7 @@ class DeviceMixin(object): # {{{
if isinstance(job.exception, FreeSpaceError): if isinstance(job.exception, FreeSpaceError):
where = 'in main memory.' if 'memory' in str(job.exception) \ where = 'in main memory.' if 'memory' in str(job.exception) \
else 'on the storage card.' else 'on the storage card.'
titles = '\n'.join(['<li>'+mi.title+'</li>' \ titles = '\n'.join(['<li>'+mi.title+'</li>'
for mi in metadata]) for mi in metadata])
d = error_dialog(self, _('No space on device'), d = error_dialog(self, _('No space on device'),
_('<p>Cannot upload books to device there ' _('<p>Cannot upload books to device there '
@ -1666,7 +1678,6 @@ class DeviceMixin(object): # {{{
else: else:
book.thumbnail = self.default_thumbnail book.thumbnail = self.default_thumbnail
def set_books_in_library(self, booklists, reset=False, add_as_step_to_job=None, def set_books_in_library(self, booklists, reset=False, add_as_step_to_job=None,
force_send=False): force_send=False):
''' '''