All the more obvious bugs have been ironed out of gui2

This commit is contained in:
Kovid Goyal 2007-08-05 22:36:55 +00:00
parent 65681cf015
commit 3b6141f135
9 changed files with 82 additions and 30 deletions

View File

@ -13,7 +13,7 @@
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
''' E-book management software'''
__version__ = "0.3.86"
__version__ = "0.3.87"
__docformat__ = "epytext"
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
__appname__ = 'libprs500'

View File

@ -905,7 +905,7 @@ class PRS500(Device):
space = self.free_space(end_session=False)
mspace = space[0]
cspace = space[1] if space[1] >= space[2] else space[2]
if oncard and size > cspace - 1024*1024:
if oncard and size > cspace - 1024*1024:
raise FreeSpaceError("There is insufficient free space "+\
"on the storage card")
if not oncard and size > mspace - 1024*1024:

View File

@ -12,9 +12,16 @@
## 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.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
import sys
from PyQt4.QtCore import QThread, SIGNAL, QObject
from libprs500.devices.prs500.driver import PRS500
_libusb_available = False
try:
from libprs500.devices.prs500.driver import PRS500
_libusb_available = True
except OSError, err: #libusb not availabe
print >>sys.stderr, err
class DeviceDetector(QThread):
'''
@ -27,14 +34,20 @@ class DeviceDetector(QThread):
@param sleep_time: Time to sleep between device probes in millisecs
@type sleep_time: integer
'''
self.devices = ([PRS500, False],)
self.devices = []
if _libusb_available:
for dclass in (PRS500,):
self.devices.append([dclass, False])
self.sleep_time = sleep_time
QThread.__init__(self)
def run(self):
while True:
for device in self.devices:
connected = device[0].is_connected()
try:
connected = device[0].is_connected()
except:
connected = False
if connected and not device[1]:
self.emit(SIGNAL('connected(PyQt_PyObject, PyQt_PyObject)'), device[0], True)
device[1] ^= True

View File

@ -222,7 +222,11 @@ class JobManager(QAbstractTableModel):
def status_update(self, id, progress):
keys = self.jobs.keys()
keys.sort()
row = keys.index(id)
index = self.index(row, 2)
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), index, index)
try:
row = keys.index(id)
index = self.index(row, 2)
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), index, index)
except ValueError:
pass

View File

@ -12,8 +12,7 @@
## 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.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from libprs500.ptempfile import PersistentTemporaryFile
import os, textwrap, traceback, time, re
import os, textwrap, traceback, time, re, sre_constants
from datetime import timedelta, datetime
from operator import attrgetter
from math import cos, sin, pi
@ -24,6 +23,7 @@ from PyQt4.QtGui import QTableView, QProgressDialog, QAbstractItemView, QColor,
from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, QString, \
QCoreApplication, SIGNAL, QObject, QSize, QModelIndex
from libprs500.ptempfile import PersistentTemporaryFile
from libprs500.library.database import LibraryDatabase
from libprs500.gui2 import NONE
@ -118,7 +118,15 @@ class BooksModel(QAbstractTableModel):
text = text.replace('"'+quot.group(1)+'"', '')
quot = re.search('"(.*?)"', text)
tokens += text.split(' ')
return [re.compile(i, re.IGNORECASE) for i in tokens]
ans = []
for i in tokens:
try:
ans.append(re.compile(i, re.IGNORECASE))
except sre_constants.error:
continue
return ans
def search(self, text, refinement):
tokens = self.search_tokens(text)

View File

@ -12,15 +12,14 @@
## 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.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
from libprs500.ptempfile import PersistentTemporaryFile
import os, tempfile, sys, traceback
import os, sys, traceback, StringIO, textwrap
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \
QSettings, QVariant, QSize, QThread
from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon, QMessageBox
from PyQt4.QtSvg import QSvgRenderer
from libprs500 import __version__, __appname__
from libprs500 import __version__, __appname__, iswindows, isosx
from libprs500.ebooks.metadata.meta import get_metadata
from libprs500.devices.errors import FreeSpaceError
from libprs500.devices.interface import Device
@ -30,7 +29,7 @@ from libprs500.gui2 import APP_TITLE, warning_dialog, choose_files, error_dialog
from libprs500.gui2.main_ui import Ui_MainWindow
from libprs500.gui2.device import DeviceDetector, DeviceManager
from libprs500.gui2.status import StatusBar
from libprs500.gui2.jobs import JobManager, JobException
from libprs500.gui2.jobs import JobManager
from libprs500.gui2.dialogs.metadata_single import MetadataSingleDialog
from libprs500.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from libprs500.gui2.dialogs.jobs import JobsDialog
@ -61,6 +60,7 @@ class Main(QObject, Ui_MainWindow):
self.default_thumbnail = None
self.device_error_dialog = error_dialog(self.window, 'Error communicating with device', ' ')
self.device_error_dialog.setModal(Qt.NonModal)
self.tb_wrapper = textwrap.TextWrapper(width=40)
####################### Location View ########################
QObject.connect(self.location_view, SIGNAL('location_selected(PyQt_PyObject)'),
self.location_selected)
@ -436,6 +436,12 @@ class Main(QObject, Ui_MainWindow):
self.current_view().setCurrentIndex(self.current_view().model().index(0, 0))
def wrap_traceback(self, tb):
tb = unicode(tb, 'utf8', 'replace')
if iswindows or isosx:
tb = '\n'.join(self.tb_wrapper.wrap(tb))
return tb
def device_job_exception(self, id, description, exception, formatted_traceback):
'''
Handle exceptions in threaded jobs.
@ -444,10 +450,11 @@ class Main(QObject, Ui_MainWindow):
print >>sys.stderr, exception
print >>sys.stderr, formatted_traceback
if not self.device_error_dialog.isVisible():
msg = '<p><b>%s</b>: '%(exception.__class__.__name__,) + str(exception) + '</p>'
msg += '<p>Failed to perform <b>job</b>: '+description
msg += '<p>Further device related error messages will not be shown while this message is visible.'
msg += '<p>Detailed <b>traceback</b>:<pre>'+formatted_traceback+'</pre>'
msg = u'<p><b>%s</b>: '%(exception.__class__.__name__,) + unicode(str(exception), 'utf8', 'replace') + u'</p>'
msg += u'<p>Failed to perform <b>job</b>: '+description
msg += u'<p>Further device related error messages will not be shown while this message is visible.'
msg += u'<p>Detailed <b>traceback</b>:<pre>'
msg += self.wrap_traceback(formatted_traceback)
self.device_error_dialog.setText(msg)
self.device_error_dialog.show()
@ -456,10 +463,10 @@ class Main(QObject, Ui_MainWindow):
def read_settings(self):
settings = QSettings()
settings.beginGroup("MainWindow")
self.window.resize(settings.value("size", QVariant(QSize(1000, 700))).toSize())
self.window.resize(settings.value("size", QVariant(QSize(800, 600))).toSize())
settings.endGroup()
self.database_path = settings.value("database path", QVariant(os.path\
.expanduser("~/library1.db"))).toString()
self.database_path = settings.value("database path",
QVariant(os.path.join(os.path.expanduser('~'),'library1.db'))).toString()
def write_settings(self):
settings = QSettings()
@ -485,13 +492,15 @@ class Main(QObject, Ui_MainWindow):
e.ignore()
def unhandled_exception(self, type, value, tb):
traceback.print_exception(type, value, tb, file=sys.stderr)
sio = StringIO.StringIO()
traceback.print_exception(type, value, tb, file=sio)
fe = sio.getvalue()
print >>sys.stderr, fe
if type == KeyboardInterrupt:
self.window.close()
self.window.thread().exit(0)
fe = '\n'.join(traceback.format_exception(type, value, tb))
msg = '<p><b>' + str(value) + '</b></p>'
msg += '<p>Detailed <b>traceback</b>:<pre>'+fe+'</pre>'
msg = '<p><b>' + unicode(str(value), 'utf8', 'replace') + '</b></p>'
msg += '<p>Detailed <b>traceback</b>:<pre>'+self.wrap_traceback(fe)+'</pre>'
d = error_dialog(self.window, 'ERROR: Unhandled exception', msg)
d.exec_()
@ -502,6 +511,7 @@ def main():
window.setWindowTitle(APP_TITLE)
QCoreApplication.setOrganizationName("KovidsBrain")
QCoreApplication.setApplicationName(APP_TITLE)
initialize_file_icon_provider()
main = Main(window)
sys.excepthook = main.unhandled_exception

View File

@ -90,7 +90,10 @@ class LibraryDatabase(object):
obj = conn.execute('INSERT INTO books(title, timestamp) VALUES (?,?)',
(book['title'], book['timestamp']))
id = obj.lastrowid
authors = book['authors'].split('&')
authors = book['authors']
if not authors:
authors = 'Unknown'
authors = authors.split('&')
for a in authors:
author = conn.execute('SELECT id from authors WHERE name=?', (a,)).fetchone()
if author:
@ -644,7 +647,7 @@ class LibraryDatabase(object):
'''Cover as a data string or None'''
id = self.id(index)
data = self.conn.execute('SELECT data FROM covers WHERE book=?', (id,)).fetchone()
if not data:
if not data or not data[0]:
return None
return(decompress(data[0]))

View File

@ -58,5 +58,5 @@ def PersistentTemporaryFile(suffix="", prefix="", dir=None):
prefix = ""
fd, name = tempfile.mkstemp(suffix, __appname__+"_"+ __version__+"_" + prefix,
dir=dir)
_file = os.fdopen(fd, "wb")
_file = os.fdopen(fd, 'w+b')
return _TemporaryFileWrapper(_file, name)

View File

@ -355,7 +355,8 @@ r'''<?xml version='1.0' encoding='windows-1252'?>
class BuildEXE(build_exe):
manifest_resource_id = 0
manifest_resource_id = 0
QT_PREFIX = r'C:\\Qt\\4.3.0'
MANIFEST_TEMPLATE = '''
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
@ -393,7 +394,20 @@ class BuildEXE(build_exe):
print 'Adding', qtxmldll
shutil.copyfile(qtxmldll,
os.path.join(self.dist_dir, os.path.basename(qtxmldll)))
print 'Adding plugins...',
qt_prefix = self.QT_PREFIX
if qtsvgdll:
qt_prefix = os.path.dirname(os.path.dirname(qtsvgdll))
plugdir = os.path.join(qt_prefix, 'plugins')
for d in ('imageformats', 'codecs', 'iconengines'):
print d,
imfd = os.path.join(plugdir, d)
tg = os.path.join(self.dist_dir, d)
if os.path.exists(tg):
shutil.rmtree(tg)
shutil.copytree(imfd, tg)
print
print
print 'Building Installer'
installer = NSISInstaller(APPNAME, self.dist_dir, 'dist')