mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix deletion bug in device books model and store column widths in jobs view
This commit is contained in:
parent
976cf43e42
commit
709dd81a08
@ -16,7 +16,8 @@
|
|||||||
import sys, os, re, StringIO, traceback
|
import sys, os, re, StringIO, traceback
|
||||||
from PyQt4.QtCore import QVariant, QSettings, QFileInfo, QObject, SIGNAL, QBuffer, \
|
from PyQt4.QtCore import QVariant, QSettings, QFileInfo, QObject, SIGNAL, QBuffer, \
|
||||||
QByteArray
|
QByteArray
|
||||||
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, QIcon
|
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
|
||||||
|
QIcon, QTableView
|
||||||
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
|
||||||
@ -58,6 +59,32 @@ def human_readable(size):
|
|||||||
return size + " " + suffix
|
return size + " " + suffix
|
||||||
|
|
||||||
|
|
||||||
|
class TableView(QTableView):
|
||||||
|
def __init__(self, parent):
|
||||||
|
QTableView.__init__(self, parent)
|
||||||
|
self.read_settings()
|
||||||
|
|
||||||
|
|
||||||
|
def read_settings(self):
|
||||||
|
self.cw = str(QSettings().value(self.__class__.__name__ + ' column widths', QVariant('')).toString())
|
||||||
|
try:
|
||||||
|
self.cw = tuple(int(i) for i in self.cw.split(','))
|
||||||
|
except ValueError:
|
||||||
|
self.cw = None
|
||||||
|
|
||||||
|
def write_settings(self):
|
||||||
|
settings = QSettings()
|
||||||
|
settings.setValue(self.__class__.__name__ + ' column widths',
|
||||||
|
QVariant(','.join(str(self.columnWidth(i))
|
||||||
|
for i in range(self.model().columnCount(None)))))
|
||||||
|
|
||||||
|
def restore_column_widths(self):
|
||||||
|
if self.cw and len(self.cw):
|
||||||
|
for i in range(len(self.cw)):
|
||||||
|
self.setColumnWidth(i, self.cw[i])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class FileIconProvider(QFileIconProvider):
|
class FileIconProvider(QFileIconProvider):
|
||||||
|
|
||||||
ICONS = {
|
ICONS = {
|
||||||
|
@ -23,5 +23,9 @@ class Dialog(QObject):
|
|||||||
self.dialog = QDialog(window)
|
self.dialog = QDialog(window)
|
||||||
self.accept = self.dialog.accept
|
self.accept = self.dialog.accept
|
||||||
self.reject = self.dialog.reject
|
self.reject = self.dialog.reject
|
||||||
|
self.dialog.closeEvent = self.close_event
|
||||||
self.window = window
|
self.window = window
|
||||||
self.isVisible = self.dialog.isVisible
|
self.isVisible = self.dialog.isVisible
|
||||||
|
|
||||||
|
def close_event(self, e):
|
||||||
|
e.accept()
|
||||||
|
@ -38,3 +38,7 @@ class JobsDialog(Ui_JobsDialog, Dialog):
|
|||||||
|
|
||||||
def hide(self):
|
def hide(self):
|
||||||
self.dialog.hide()
|
self.dialog.hide()
|
||||||
|
|
||||||
|
def close_event(self, e):
|
||||||
|
self.jobs_view.write_settings()
|
||||||
|
e.accept()
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" >
|
<layout class="QVBoxLayout" >
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableView" name="jobs_view" >
|
<widget class="JobsView" name="jobs_view" >
|
||||||
<property name="contextMenuPolicy" >
|
<property name="contextMenuPolicy" >
|
||||||
<enum>Qt::NoContextMenu</enum>
|
<enum>Qt::NoContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -43,6 +43,13 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>JobsView</class>
|
||||||
|
<extends>QTableView</extends>
|
||||||
|
<header>widgets.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc" />
|
<include location="../images.qrc" />
|
||||||
</resources>
|
</resources>
|
||||||
|
4
src/libprs500/gui2/dialogs/widgets.py
Normal file
4
src/libprs500/gui2/dialogs/widgets.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from libprs500.gui2 import TableView
|
||||||
|
|
||||||
|
class JobsView(TableView):
|
||||||
|
pass
|
@ -105,7 +105,6 @@ class JobManager(QAbstractTableModel):
|
|||||||
self.cleanup = {}
|
self.cleanup = {}
|
||||||
self.device_job_icon = QVariant(QIcon(':/images/reader.svg'))
|
self.device_job_icon = QVariant(QIcon(':/images/reader.svg'))
|
||||||
self.job_icon = QVariant(QIcon(':/images/jobs.svg'))
|
self.job_icon = QVariant(QIcon(':/images/jobs.svg'))
|
||||||
self.wrapper = textwrap.TextWrapper(width=40)
|
|
||||||
|
|
||||||
def terminate_device_jobs(self):
|
def terminate_device_jobs(self):
|
||||||
changed = False
|
changed = False
|
||||||
@ -235,7 +234,7 @@ class JobManager(QAbstractTableModel):
|
|||||||
job = self.jobs[keys[row]]
|
job = self.jobs[keys[row]]
|
||||||
if role == Qt.DisplayRole:
|
if role == Qt.DisplayRole:
|
||||||
if col == 0:
|
if col == 0:
|
||||||
return QVariant('\n'.join(self.wrapper.wrap(job.description)))
|
return QVariant(job.description)
|
||||||
if col == 1:
|
if col == 1:
|
||||||
status = 'Waiting'
|
status = 'Waiting'
|
||||||
if job.isRunning():
|
if job.isRunning():
|
||||||
@ -260,4 +259,9 @@ class JobManager(QAbstractTableModel):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def closeEvent(self, e):
|
||||||
|
self.jobs_view.write_settings()
|
||||||
|
e.accept()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,12 +22,11 @@ from PyQt4.QtGui import QTableView, QProgressDialog, QAbstractItemView, QColor,
|
|||||||
QPen, QStyle, QPainter, QLineEdit, QApplication, \
|
QPen, QStyle, QPainter, QLineEdit, QApplication, \
|
||||||
QPalette
|
QPalette
|
||||||
from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, QString, \
|
from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, QString, \
|
||||||
QCoreApplication, SIGNAL, QObject, QSize, QModelIndex, \
|
QCoreApplication, SIGNAL, QObject, QSize, QModelIndex
|
||||||
QSettings
|
|
||||||
|
|
||||||
from libprs500.ptempfile import PersistentTemporaryFile
|
from libprs500.ptempfile import PersistentTemporaryFile
|
||||||
from libprs500.library.database import LibraryDatabase
|
from libprs500.library.database import LibraryDatabase
|
||||||
from libprs500.gui2 import NONE
|
from libprs500.gui2 import NONE, TableView
|
||||||
|
|
||||||
class LibraryDelegate(QItemDelegate):
|
class LibraryDelegate(QItemDelegate):
|
||||||
COLOR = QColor("blue")
|
COLOR = QColor("blue")
|
||||||
@ -326,7 +325,7 @@ class BooksModel(QAbstractTableModel):
|
|||||||
return done
|
return done
|
||||||
|
|
||||||
|
|
||||||
class BooksView(QTableView):
|
class BooksView(TableView):
|
||||||
TIME_FMT = '%d %b %Y'
|
TIME_FMT = '%d %b %Y'
|
||||||
wrapper = textwrap.TextWrapper(width=20)
|
wrapper = textwrap.TextWrapper(width=20)
|
||||||
|
|
||||||
@ -341,7 +340,7 @@ class BooksView(QTableView):
|
|||||||
return ('%.'+str(precision)+'f') % ((size/(1024.*1024.)),)
|
return ('%.'+str(precision)+'f') % ((size/(1024.*1024.)),)
|
||||||
|
|
||||||
def __init__(self, parent, modelcls=BooksModel):
|
def __init__(self, parent, modelcls=BooksModel):
|
||||||
QTableView.__init__(self, parent)
|
TableView.__init__(self, parent)
|
||||||
self.display_parent = parent
|
self.display_parent = parent
|
||||||
self._model = modelcls(self)
|
self._model = modelcls(self)
|
||||||
self.setModel(self._model)
|
self.setModel(self._model)
|
||||||
@ -356,24 +355,7 @@ class BooksView(QTableView):
|
|||||||
QObject.connect(self.model(), SIGNAL('rowsInserted(QModelIndex, int, int)'), self.resizeRowsToContents)
|
QObject.connect(self.model(), SIGNAL('rowsInserted(QModelIndex, int, int)'), self.resizeRowsToContents)
|
||||||
# Resetting the model should resize rows (model is reset after search and sort operations)
|
# Resetting the model should resize rows (model is reset after search and sort operations)
|
||||||
QObject.connect(self.model(), SIGNAL('modelReset()'), self.resizeRowsToContents)
|
QObject.connect(self.model(), SIGNAL('modelReset()'), self.resizeRowsToContents)
|
||||||
self.cw = str(QSettings().value(self.__class__.__name__ + ' column widths', QVariant('')).toString())
|
|
||||||
try:
|
|
||||||
self.cw = tuple(int(i) for i in self.cw.split(','))
|
|
||||||
except ValueError:
|
|
||||||
self.cw = None
|
|
||||||
|
|
||||||
def write_settings(self):
|
|
||||||
settings = QSettings()
|
|
||||||
settings.setValue(self.__class__.__name__ + ' column widths',
|
|
||||||
QVariant(','.join(str(self.columnWidth(i))
|
|
||||||
for i in range(self.model().columnCount(None)))))
|
|
||||||
|
|
||||||
def restore_column_widths(self):
|
|
||||||
if self.cw and len(self.cw):
|
|
||||||
for i in range(len(self.cw)):
|
|
||||||
self.setColumnWidth(i, self.cw[i])
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def set_database(self, db):
|
def set_database(self, db):
|
||||||
self._model.set_database(db)
|
self._model.set_database(db)
|
||||||
@ -448,16 +430,10 @@ class DeviceBooksModel(BooksModel):
|
|||||||
indices = self.row_indices(self.index(row, 0))
|
indices = self.row_indices(self.index(row, 0))
|
||||||
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), indices[0], indices[-1])
|
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), indices[0], indices[-1])
|
||||||
|
|
||||||
def path_about_to_be_deleted(self, path):
|
def paths_deleted(self, paths):
|
||||||
for row in range(len(self.map)):
|
self.map = list(range(0, len(self.db)))
|
||||||
if self.db[self.map[row]].path == path:
|
self.resort(False)
|
||||||
#print row, path
|
self.research(True)
|
||||||
#print self.rowCount(None)
|
|
||||||
self.beginRemoveRows(QModelIndex(), row, row)
|
|
||||||
self.map.pop(row)
|
|
||||||
self.endRemoveRows()
|
|
||||||
#print self.rowCount(None)
|
|
||||||
return
|
|
||||||
|
|
||||||
def indices_to_be_deleted(self):
|
def indices_to_be_deleted(self):
|
||||||
ans = []
|
ans = []
|
||||||
@ -492,6 +468,7 @@ class DeviceBooksModel(BooksModel):
|
|||||||
self.map = result
|
self.map = result
|
||||||
if reset:
|
if reset:
|
||||||
self.reset()
|
self.reset()
|
||||||
|
self.last_search = text
|
||||||
|
|
||||||
def sort(self, col, order, reset=True):
|
def sort(self, col, order, reset=True):
|
||||||
if not self.db:
|
if not self.db:
|
||||||
|
@ -353,10 +353,9 @@ class Main(QObject, Ui_MainWindow):
|
|||||||
|
|
||||||
if self.delete_memory.has_key(id):
|
if self.delete_memory.has_key(id):
|
||||||
paths, model = self.delete_memory.pop(id)
|
paths, model = self.delete_memory.pop(id)
|
||||||
for path in paths:
|
self.device_manager.remove_books_from_metadata(paths, self.booklists())
|
||||||
model.path_about_to_be_deleted(path)
|
self.upload_booklists()
|
||||||
self.device_manager.remove_books_from_metadata((path,), self.booklists())
|
model.paths_deleted(paths)
|
||||||
self.upload_booklists()
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
@ -95,14 +95,18 @@ class MovieButton(QFrame):
|
|||||||
self.setCursor(Qt.PointingHandCursor)
|
self.setCursor(Qt.PointingHandCursor)
|
||||||
self.setToolTip('Click to see list of active jobs.')
|
self.setToolTip('Click to see list of active jobs.')
|
||||||
movie.start()
|
movie.start()
|
||||||
movie.setPaused(True)
|
movie.setPaused(True)
|
||||||
|
self.jobs_dialog.jobs_view.restore_column_widths()
|
||||||
|
|
||||||
|
|
||||||
def mouseReleaseEvent(self, event):
|
def mouseReleaseEvent(self, event):
|
||||||
if self.jobs_dialog.isVisible():
|
if self.jobs_dialog.isVisible():
|
||||||
|
self.jobs_dialog.jobs_view.write_settings()
|
||||||
self.jobs_dialog.hide()
|
self.jobs_dialog.hide()
|
||||||
else:
|
else:
|
||||||
|
self.jobs_dialog.jobs_view.read_settings()
|
||||||
self.jobs_dialog.show()
|
self.jobs_dialog.show()
|
||||||
|
self.jobs_dialog.jobs_view.restore_column_widths()
|
||||||
|
|
||||||
|
|
||||||
class StatusBar(QStatusBar):
|
class StatusBar(QStatusBar):
|
||||||
|
@ -98,9 +98,9 @@ class RecursiveFetcher(object):
|
|||||||
|
|
||||||
def start_fetch(self, url):
|
def start_fetch(self, url):
|
||||||
soup = BeautifulSoup('<a href="'+url+'" />')
|
soup = BeautifulSoup('<a href="'+url+'" />')
|
||||||
print 'Downloading',
|
self.logger.info('Downloading')
|
||||||
res = self.process_links(soup, url, 0, into_dir='')
|
res = self.process_links(soup, url, 0, into_dir='')
|
||||||
print '%s saved to %s'%(url, res)
|
self.logger.info('%s saved to %s', url, res)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def is_link_ok(self, url):
|
def is_link_ok(self, url):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user