mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-07 09:01:38 -04:00
gui2 gets nice error dialogs.
This commit is contained in:
parent
0daf6d3588
commit
79391a5f57
@ -111,6 +111,9 @@ class Device(object):
|
|||||||
'''
|
'''
|
||||||
Upload a list of books to the device. If a file already
|
Upload a list of books to the device. If a file already
|
||||||
exists on the device, it should be replaced.
|
exists on the device, it should be replaced.
|
||||||
|
This method should raise a L{FreeSpaceError} if there is not enough
|
||||||
|
free space on the device. The text of the FreeSpaceError must contain the
|
||||||
|
word "card" if C{on_card} is True otherwise it must contain the word "memory".
|
||||||
@param files: A list of paths and/or file-like objects.
|
@param files: A list of paths and/or file-like objects.
|
||||||
@param names: A list of file names that the books should have
|
@param names: A list of file names that the books should have
|
||||||
once uploaded to the device. len(names) == len(files)
|
once uploaded to the device. len(names) == len(files)
|
||||||
|
@ -830,23 +830,24 @@ class PRS500(Device):
|
|||||||
def upload_books(self, files, names, on_card=False, end_session=True):
|
def upload_books(self, files, names, on_card=False, end_session=True):
|
||||||
card = self.card(end_session=False)
|
card = self.card(end_session=False)
|
||||||
prefix = card + '/' if on_card else '/Data/media/books/'
|
prefix = card + '/' if on_card else '/Data/media/books/'
|
||||||
paths, ctimes, sizes = [], [], []
|
paths, ctimes = [], []
|
||||||
names = iter(names)
|
names = iter(names)
|
||||||
for file in files:
|
infiles = [file if hasattr(file, 'read') else open(file, 'rb') for file in files]
|
||||||
infile = file if hasattr(file, 'read') else open(file, 'rb')
|
for f in infiles: f.seek(0, 2)
|
||||||
infile.seek(0, 2)
|
sizes = [f.tell() for f in infiles]
|
||||||
size = infile.tell()
|
size = sum(sizes)
|
||||||
sizes.append(size)
|
space = self.free_space(end_session=False)
|
||||||
|
mspace = space[0]
|
||||||
|
cspace = space[1] if space[1] >= space[2] else space[2]
|
||||||
|
if on_card and size > cspace - 1024*1024:
|
||||||
|
raise FreeSpaceError("There is insufficient free space "+\
|
||||||
|
"on the storage card")
|
||||||
|
if not on_card and size > mspace - 2*1024*1024:
|
||||||
|
raise FreeSpaceError("There is insufficient free space " +\
|
||||||
|
"in main memory")
|
||||||
|
|
||||||
|
for infile in infiles:
|
||||||
infile.seek(0)
|
infile.seek(0)
|
||||||
space = self.free_space(end_session=False)
|
|
||||||
mspace = space[0]
|
|
||||||
cspace = space[1] if space[1] >= space[2] else space[2]
|
|
||||||
if on_card and size > cspace - 1024*1024:
|
|
||||||
raise FreeSpaceError("There is insufficient free space "+\
|
|
||||||
"on the storage card")
|
|
||||||
if not on_card and size > mspace - 1024*1024:
|
|
||||||
raise FreeSpaceError("There is insufficient free space " +\
|
|
||||||
"in main memory")
|
|
||||||
name = names.next()
|
name = names.next()
|
||||||
paths.append(prefix+name)
|
paths.append(prefix+name)
|
||||||
self.put_file(infile, paths[-1], replace_file=True, end_session=False)
|
self.put_file(infile, paths[-1], replace_file=True, end_session=False)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
""" The GUI for libprs500. """
|
""" The GUI for libprs500. """
|
||||||
import sys, os, re, StringIO, traceback
|
import sys, os, re, StringIO, traceback
|
||||||
from PyQt4.QtCore import QVariant, QSettings
|
from PyQt4.QtCore import QVariant, QSettings
|
||||||
from PyQt4.QtGui import QFileDialog
|
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap
|
||||||
from libprs500 import __appname__ as APP_TITLE
|
from libprs500 import __appname__ as APP_TITLE
|
||||||
from libprs500 import __author__
|
from libprs500 import __author__
|
||||||
NONE = QVariant() #: Null value to return from the data function of item models
|
NONE = QVariant() #: Null value to return from the data function of item models
|
||||||
@ -25,28 +25,18 @@ error_dialog = None
|
|||||||
def extension(path):
|
def extension(path):
|
||||||
return os.path.splitext(path)[1][1:].lower()
|
return os.path.splitext(path)[1][1:].lower()
|
||||||
|
|
||||||
def installErrorHandler(dialog):
|
def warning_dialog(parent, title, msg):
|
||||||
''' Create the error dialog for unhandled exceptions'''
|
d = QMessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok,
|
||||||
global error_dialog
|
parent)
|
||||||
error_dialog = dialog
|
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg'))
|
||||||
error_dialog.resize(600, 400)
|
return d
|
||||||
error_dialog.setWindowTitle(APP_TITLE + " - Error")
|
|
||||||
error_dialog.setModal(True)
|
|
||||||
|
|
||||||
|
def error_dialog(parent, title, msg):
|
||||||
|
d = QMessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok,
|
||||||
|
parent)
|
||||||
|
d.setIconPixmap(QPixmap(':/images/dialog_error.svg'))
|
||||||
|
return d
|
||||||
|
|
||||||
def _Warning(msg, e):
|
|
||||||
print >> sys.stderr, msg
|
|
||||||
if e:
|
|
||||||
traceback.print_exc(e)
|
|
||||||
|
|
||||||
def Error(msg, e):
|
|
||||||
if error_dialog:
|
|
||||||
if e:
|
|
||||||
msg += "<br>" + traceback.format_exc(e)
|
|
||||||
msg = re.sub("Traceback", "<b>Traceback</b>", msg)
|
|
||||||
msg = re.sub(r"\n", "<br>", msg)
|
|
||||||
error_dialog.showMessage(msg)
|
|
||||||
error_dialog.show()
|
|
||||||
|
|
||||||
def human_readable(size):
|
def human_readable(size):
|
||||||
""" Convert a size in bytes into a human readable form """
|
""" Convert a size in bytes into a human readable form """
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<qresource prefix="/" >
|
<qresource prefix="/" >
|
||||||
<file>images/book.svg</file>
|
<file>images/book.svg</file>
|
||||||
<file>images/clear_left.svg</file>
|
<file>images/clear_left.svg</file>
|
||||||
|
<file>images/dialog_error.svg</file>
|
||||||
|
<file>images/dialog_warning.svg</file>
|
||||||
<file>images/edit_input.svg</file>
|
<file>images/edit_input.svg</file>
|
||||||
<file>images/jobs-animated.mng</file>
|
<file>images/jobs-animated.mng</file>
|
||||||
<file>images/jobs.svg</file>
|
<file>images/jobs.svg</file>
|
||||||
|
@ -12,18 +12,18 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## 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.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
|
||||||
from libprs500.devices.interface import Device
|
|
||||||
from libprs500 import __appname__
|
|
||||||
import os, tempfile, sys
|
import os, tempfile, sys
|
||||||
|
|
||||||
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \
|
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \
|
||||||
QSettings, QVariant, QSize, QThread, QBuffer, QByteArray
|
QSettings, QVariant, QSize, QThread, QBuffer, QByteArray
|
||||||
from PyQt4.QtGui import QErrorMessage, QPixmap, QColor, QPainter, QMenu, QIcon
|
from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon
|
||||||
from PyQt4.QtSvg import QSvgRenderer
|
from PyQt4.QtSvg import QSvgRenderer
|
||||||
|
|
||||||
from libprs500 import __version__ as VERSION
|
from libprs500 import __version__, __appname__
|
||||||
from libprs500.ebooks.metadata.meta import get_metadata
|
from libprs500.ebooks.metadata.meta import get_metadata
|
||||||
from libprs500.gui2 import APP_TITLE, installErrorHandler, choose_files
|
from libprs500.devices.errors import FreeSpaceError
|
||||||
|
from libprs500.devices.interface import Device
|
||||||
|
from libprs500.gui2 import APP_TITLE, warning_dialog, choose_files, error_dialog
|
||||||
from libprs500.gui2.main_ui import Ui_MainWindow
|
from libprs500.gui2.main_ui import Ui_MainWindow
|
||||||
from libprs500.gui2.device import DeviceDetector, DeviceManager
|
from libprs500.gui2.device import DeviceDetector, DeviceManager
|
||||||
from libprs500.gui2.status import StatusBar
|
from libprs500.gui2.status import StatusBar
|
||||||
@ -60,7 +60,7 @@ class Main(QObject, Ui_MainWindow):
|
|||||||
self.location_selected)
|
self.location_selected)
|
||||||
|
|
||||||
####################### Vanity ########################
|
####################### Vanity ########################
|
||||||
self.vanity_template = self.vanity.text().arg(VERSION)
|
self.vanity_template = self.vanity.text().arg(__version__)
|
||||||
self.vanity.setText(self.vanity_template.arg(' '))
|
self.vanity.setText(self.vanity_template.arg(' '))
|
||||||
|
|
||||||
####################### Status Bar #####################
|
####################### Status Bar #####################
|
||||||
@ -238,7 +238,15 @@ class Main(QObject, Ui_MainWindow):
|
|||||||
'''
|
'''
|
||||||
metadata = self.upload_memory.pop(id)
|
metadata = self.upload_memory.pop(id)
|
||||||
if exception:
|
if exception:
|
||||||
self.job_exception(id, exception, formatted_traceback)
|
if isinstance(exception, FreeSpaceError):
|
||||||
|
where = 'in main memory.' if 'memory' in str(exception) else 'on the storage card.'
|
||||||
|
titles = '\n'.join(['<li>'+mi['title']+'</li>' for mi in metadata])
|
||||||
|
d = error_dialog(self.window, 'No space on device',
|
||||||
|
'<p>Cannot upload books to device there is no more free space available '+where+
|
||||||
|
'</p><ul>%s</ul>'%(titles,))
|
||||||
|
d.exec_()
|
||||||
|
else:
|
||||||
|
self.job_exception(id, exception, formatted_traceback)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.device_manager.add_books_to_metadata(result, metadata, self.booklists())
|
self.device_manager.add_books_to_metadata(result, metadata, self.booklists())
|
||||||
@ -343,15 +351,17 @@ class Main(QObject, Ui_MainWindow):
|
|||||||
mi = metadata.next()
|
mi = metadata.next()
|
||||||
id = ids.next()
|
id = ids.next()
|
||||||
if f is None:
|
if f is None:
|
||||||
bad.append(mi)
|
bad.append(mi['title'])
|
||||||
else:
|
else:
|
||||||
good.append(mi)
|
good.append(mi)
|
||||||
gf.append(f)
|
gf.append(f)
|
||||||
names.append('%s_%d%s'%(__appname__, id, os.path.splitext(f.name)[1]))
|
names.append('%s_%d%s'%(__appname__, id, os.path.splitext(f.name)[1]))
|
||||||
self.upload_books(gf, names, good, on_card)
|
self.upload_books(gf, names, good, on_card)
|
||||||
|
|
||||||
raise Exception, str(bad)
|
if bad:
|
||||||
|
bad = '\n'.join('<li>%s</li>'%(i,) for i in bad)
|
||||||
|
d = warning_dialog(self.window, 'No suitable formats', 'Could not upload the following books to the device, as no suitable formats were found:<br><ul>%s</ul>'%(bad,))
|
||||||
|
d.exec_()
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
@ -411,7 +421,6 @@ def main():
|
|||||||
#return 0
|
#return 0
|
||||||
window = QMainWindow()
|
window = QMainWindow()
|
||||||
window.setWindowTitle(APP_TITLE)
|
window.setWindowTitle(APP_TITLE)
|
||||||
installErrorHandler(QErrorMessage(window))
|
|
||||||
QCoreApplication.setOrganizationName("KovidsBrain")
|
QCoreApplication.setOrganizationName("KovidsBrain")
|
||||||
QCoreApplication.setApplicationName(APP_TITLE)
|
QCoreApplication.setApplicationName(APP_TITLE)
|
||||||
main = Main(window)
|
main = Main(window)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user