mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Added Drag'nDrop support to library book list
This commit is contained in:
parent
1fba894a89
commit
8e4010e0f3
@ -89,6 +89,9 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
self.book_cover.show()
|
self.book_cover.show()
|
||||||
self.book_info.show()
|
self.book_info.show()
|
||||||
|
|
||||||
|
def formats_added(self, index):
|
||||||
|
if index == self.library_view.currentIndex():
|
||||||
|
self.show_book(index, index)
|
||||||
|
|
||||||
def delete(self, action):
|
def delete(self, action):
|
||||||
count = str(len(self.current_view.selectionModel().selectedRows()))
|
count = str(len(self.current_view.selectionModel().selectedRows()))
|
||||||
@ -162,15 +165,18 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
x = str(files[0])
|
x = str(files[0])
|
||||||
settings.setValue("add books dialog dir", QVariant(os.path.dirname(x)))
|
settings.setValue("add books dialog dir", QVariant(os.path.dirname(x)))
|
||||||
files = str(files.join("|||")).split("|||")
|
files = str(files.join("|||")).split("|||")
|
||||||
for file in files:
|
self.add_books(files)
|
||||||
file = os.path.abspath(file)
|
|
||||||
self.library_view.model().add_book(file)
|
def add_books(self, files):
|
||||||
self.search.clear()
|
for file in files:
|
||||||
hv = self.library_view.horizontalHeader()
|
file = os.path.abspath(file)
|
||||||
col = hv.sortIndicatorSection()
|
self.library_view.model().add_book(file)
|
||||||
order = hv.sortIndicatorOrder()
|
self.search.clear()
|
||||||
self.library_view.model().sort(col, order)
|
hv = self.library_view.horizontalHeader()
|
||||||
|
col = hv.sortIndicatorSection()
|
||||||
|
order = hv.sortIndicatorOrder()
|
||||||
|
self.library_view.model().sort(col, order)
|
||||||
|
|
||||||
|
|
||||||
def edit(self, action):
|
def edit(self, action):
|
||||||
if self.library_view.isVisible():
|
if self.library_view.isVisible():
|
||||||
@ -217,6 +223,8 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
QObject.connect(self.library_model, SIGNAL("searched()"), self.model_modified)
|
QObject.connect(self.library_model, SIGNAL("searched()"), self.model_modified)
|
||||||
QObject.connect(self.library_model, SIGNAL("deleted()"), self.model_modified)
|
QObject.connect(self.library_model, SIGNAL("deleted()"), self.model_modified)
|
||||||
QObject.connect(self.library_model, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.resize_columns)
|
QObject.connect(self.library_model, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.resize_columns)
|
||||||
|
QObject.connect(self.library_view, SIGNAL('books_dropped'), self.add_books)
|
||||||
|
QObject.connect(self.library_model, SIGNAL('formats_added'), self.formats_added)
|
||||||
self.library_view.resizeColumnsToContents()
|
self.library_view.resizeColumnsToContents()
|
||||||
|
|
||||||
# Create Device tree
|
# Create Device tree
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
from PyQt4.QtCore import Qt, SIGNAL
|
from PyQt4.QtCore import Qt, SIGNAL
|
||||||
from PyQt4.Qt import QApplication, QString, QFont, QStandardItemModel, QStandardItem, QVariant, QAbstractTableModel, QTableView, QTreeView, QLabel,\
|
from PyQt4.Qt import QApplication, QString, QFont, QStandardItemModel, QStandardItem, QVariant, QAbstractTableModel, QTableView, QTreeView, QLabel,\
|
||||||
QAbstractItemView, QPixmap, QIcon, QSize, QMessageBox, QSettings, QFileDialog, QErrorMessage, QDialog, QSpinBox, QPoint, QTemporaryFile, QDir,\
|
QAbstractItemView, QPixmap, QIcon, QSize, QMessageBox, QSettings, QFileDialog, QErrorMessage, QDialog, QSpinBox, QPoint, QTemporaryFile, QDir, QFile, QIODevice,\
|
||||||
QPainterPath, QItemDelegate, QPainter, QPen, QColor, QLinearGradient, QBrush, QStyle,\
|
QPainterPath, QItemDelegate, QPainter, QPen, QColor, QLinearGradient, QBrush, QStyle,\
|
||||||
QStringList, QByteArray, QBuffer, QMimeData, QTextStream, QIODevice, QDrag,\
|
QStringList, QByteArray, QBuffer, QMimeData, QTextStream, QIODevice, QDrag, QRect
|
||||||
qDebug, qFatal, qWarning, qCritical
|
import re, os, string, textwrap, time, traceback, sys
|
||||||
import re, os, string, textwrap, time, traceback
|
|
||||||
|
|
||||||
from operator import itemgetter, attrgetter
|
from operator import itemgetter, attrgetter
|
||||||
from socket import gethostname
|
from socket import gethostname
|
||||||
@ -48,25 +47,11 @@ def human_readable(size):
|
|||||||
def wrap(s, width=20):
|
def wrap(s, width=20):
|
||||||
return textwrap.fill(str(s), width)
|
return textwrap.fill(str(s), width)
|
||||||
|
|
||||||
def get_r_ok_files(event):
|
|
||||||
""" @type event: QDropEvent """
|
|
||||||
files = []
|
|
||||||
md = event.mimeData()
|
|
||||||
if md.hasFormat("text/uri-list"):
|
|
||||||
candidates = bytes_to_string(md.data("text/uri-list")).split("\n")
|
|
||||||
print candidates
|
|
||||||
for path in candidates:
|
|
||||||
path = os.path.abspath(re.sub(r"^file://", "", path))
|
|
||||||
if os.path.isfile(path) and os.access(path, os.R_OK): files.append(path)
|
|
||||||
return files
|
|
||||||
|
|
||||||
|
|
||||||
def bytes_to_string(qba):
|
|
||||||
""" @type qba: QByteArray """
|
|
||||||
return unicode(QString.fromUtf8(qba.data())).strip()
|
|
||||||
|
|
||||||
class FileDragAndDrop(object):
|
class FileDragAndDrop(object):
|
||||||
_drag_start_position = QPoint()
|
_drag_start_position = QPoint()
|
||||||
|
_dragged_files = []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _bytes_to_string(cls, qba):
|
def _bytes_to_string(cls, qba):
|
||||||
@ -80,13 +65,13 @@ class FileDragAndDrop(object):
|
|||||||
if md.hasFormat("text/uri-list"):
|
if md.hasFormat("text/uri-list"):
|
||||||
candidates = cls._bytes_to_string(md.data("text/uri-list")).split()
|
candidates = cls._bytes_to_string(md.data("text/uri-list")).split()
|
||||||
for url in candidates:
|
for url in candidates:
|
||||||
o = urlparse(url)
|
o = urlparse(url)
|
||||||
if o.scheme != 'file':
|
if o.scheme and o.scheme != 'file':
|
||||||
qWarning(o.scheme + " not supported in drop events")
|
print >>sys.stderr, o.scheme, " not supported in drop events"
|
||||||
continue
|
continue
|
||||||
path = unquote(o.path)
|
path = unquote(o.path)
|
||||||
if not os.access(path, os.R_OK):
|
if not os.access(path, os.R_OK):
|
||||||
qWarning("You do not have read permission for: " + path)
|
print >>sys.stderr, "You do not have read permission for: " + path
|
||||||
continue
|
continue
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
root, dirs, files2 = os.walk(path)
|
root, dirs, files2 = os.walk(path)
|
||||||
@ -95,16 +80,23 @@ class FileDragAndDrop(object):
|
|||||||
if os.access(path, os.R_OK): files.append(path)
|
if os.access(path, os.R_OK): files.append(path)
|
||||||
else: files.append(path)
|
else: files.append(path)
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
def __init__(self, QtBaseClass):
|
||||||
|
self.QtBaseClass = QtBaseClass
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
|
self.QtBaseClass.mousePressEvent(self, event)
|
||||||
if event.button == Qt.LeftButton:
|
if event.button == Qt.LeftButton:
|
||||||
self._drag_start_position = event.pos()
|
self._drag_start_position = event.pos()
|
||||||
|
|
||||||
|
|
||||||
def mouseMoveEvent(self, event):
|
def mouseMoveEvent(self, event):
|
||||||
|
self.QtBaseClass.mousePressEvent(self, event)
|
||||||
if event.buttons() & Qt.LeftButton != Qt.LeftButton: return
|
if event.buttons() & Qt.LeftButton != Qt.LeftButton: return
|
||||||
if (event.pos() - self._drag_start_position).manhattanLength() < QApplication.startDragDistance(): return
|
if (event.pos() - self._drag_start_position).manhattanLength() < QApplication.startDragDistance(): return
|
||||||
self.start_drag(self._drag_start_position)
|
self.start_drag(self._drag_start_position)
|
||||||
|
|
||||||
|
|
||||||
def start_drag(self, pos): pass
|
def start_drag(self, pos): pass
|
||||||
|
|
||||||
def dragEnterEvent(self, event):
|
def dragEnterEvent(self, event):
|
||||||
@ -116,38 +108,83 @@ class FileDragAndDrop(object):
|
|||||||
def dropEvent(self, event):
|
def dropEvent(self, event):
|
||||||
files = self._get_r_ok_files(event)
|
files = self._get_r_ok_files(event)
|
||||||
if files:
|
if files:
|
||||||
if self.files_dropped(files): event.acceptProposedAction()
|
if self.files_dropped(files, event): event.acceptProposedAction()
|
||||||
|
|
||||||
def files_dropped(self, files): return False
|
def files_dropped(self, files): return False
|
||||||
|
|
||||||
def drag_object(self, extensions):
|
def drag_object_from_files(self, files):
|
||||||
if extensions:
|
if files:
|
||||||
drag = QDrag(self)
|
drag = QDrag(self)
|
||||||
mime_data = QMimeData()
|
mime_data = QMimeData()
|
||||||
self._dragged_files, urls = [], []
|
self._dragged_files, urls = [], []
|
||||||
for ext in extensions:
|
for file in files:
|
||||||
f = TemporaryFile(ext=ext)
|
urls.append(urlunparse(('file', quote(gethostname()), quote(str(file.name)), '','','')))
|
||||||
f.open()
|
self._dragged_files.append(file)
|
||||||
urls.append(urlunparse(('file', quote(gethostname()), quote(str(f.fileName())), '','','')))
|
|
||||||
self._dragged_files.append(f)
|
|
||||||
mime_data.setData("text/uri-list", QByteArray("\n".join(urls)))
|
mime_data.setData("text/uri-list", QByteArray("\n".join(urls)))
|
||||||
user = None
|
user = None
|
||||||
try: user = os.environ['USER']
|
try: user = os.environ['USER']
|
||||||
except: pass
|
except: pass
|
||||||
if user: mime_data.setData("text/x-xdnd-username", QByteArray(user))
|
if user: mime_data.setData("text/x-xdnd-username", QByteArray(user))
|
||||||
drag.setMimeData(mime_data)
|
drag.setMimeData(mime_data)
|
||||||
return drag, self._dragged_files
|
return drag
|
||||||
|
|
||||||
|
def drag_object(self, extensions):
|
||||||
|
if extensions:
|
||||||
|
files = []
|
||||||
|
for ext in extensions:
|
||||||
|
f = TemporaryFile(ext=ext)
|
||||||
|
f.open()
|
||||||
|
files.append(f)
|
||||||
|
return self.drag_object_from_files(files), self._dragged_files
|
||||||
|
|
||||||
|
|
||||||
|
class TableView(QTableView):
|
||||||
|
def renderToPixmap(self, indices):
|
||||||
|
rect = self.visualRect(indices[0])
|
||||||
|
rects = []
|
||||||
|
for i in range(len(indices)):
|
||||||
|
rects.append(self.visualRect(indices[i]))
|
||||||
|
rect |= rects[i]
|
||||||
|
rect = rect.intersected(self.viewport().rect())
|
||||||
|
pixmap = QPixmap(rect.size())
|
||||||
|
pixmap.fill(self.palette().base().color())
|
||||||
|
painter = QPainter(pixmap)
|
||||||
|
option = self.viewOptions()
|
||||||
|
option.state |= QStyle.State_Selected
|
||||||
|
for j in range(len(indices)):
|
||||||
|
option.rect = QRect(rects[j].topLeft() - rect.topLeft(), rects[j].size())
|
||||||
|
self.itemDelegate(indices[j]).paint(painter, option, indices[j])
|
||||||
|
painter.end()
|
||||||
|
return pixmap
|
||||||
|
|
||||||
class TemporaryFile(QTemporaryFile):
|
class TemporaryFile(QTemporaryFile):
|
||||||
|
_file_name = ""
|
||||||
def __init__(self, ext=""):
|
def __init__(self, ext=""):
|
||||||
if ext: ext = "." + ext
|
if ext: ext = "." + ext
|
||||||
path = QDir.tempPath() + "/" + TFT + "_XXXXXX"+ext
|
path = QDir.tempPath() + "/" + TFT + "_XXXXXX"+ext
|
||||||
QTemporaryFile.__init__(self, path)
|
QTemporaryFile.__init__(self, path)
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
ok = QFile.open(self, QIODevice.ReadWrite)
|
||||||
|
self._file_name = os.path.normpath(os.path.abspath(str(QTemporaryFile.fileName(self))))
|
||||||
|
return ok
|
||||||
|
|
||||||
|
@apply
|
||||||
|
def name():
|
||||||
|
def fget(self):
|
||||||
|
return self._file_name
|
||||||
|
return property(**locals())
|
||||||
|
|
||||||
|
class NamedTemporaryFile(TemporaryFile):
|
||||||
|
def __init__(self, name):
|
||||||
|
path = QDir.tempPath() + "/" + "XXXXXX"+name
|
||||||
|
QTemporaryFile.__init__(self, path)
|
||||||
|
|
||||||
class CoverDisplay(FileDragAndDrop, QLabel):
|
class CoverDisplay(FileDragAndDrop, QLabel):
|
||||||
def files_dropped(self, files):
|
def __init__(self, parent):
|
||||||
|
FileDragAndDrop.__init__(self, QLabel)
|
||||||
|
QLabel.__init__(self, parent)
|
||||||
|
def files_dropped(self, files, event):
|
||||||
pix = QPixmap()
|
pix = QPixmap()
|
||||||
for file in files:
|
for file in files:
|
||||||
pix = QPixmap(file)
|
pix = QPixmap(file)
|
||||||
@ -177,34 +214,45 @@ class DeviceView(QTreeView):
|
|||||||
def hide_card(self, x):
|
def hide_card(self, x):
|
||||||
self.setRowHidden(4, self.model().indexFromItem(self.model().invisibleRootItem()), x)
|
self.setRowHidden(4, self.model().indexFromItem(self.model().invisibleRootItem()), x)
|
||||||
|
|
||||||
class DeviceBooksView(QTableView):
|
class DeviceBooksView(TableView):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QTableView.__init__(self, parent)
|
QTableView.__init__(self, parent)
|
||||||
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
self.setSortingEnabled(True)
|
self.setSortingEnabled(True)
|
||||||
|
|
||||||
class LibraryBooksView(QTableView):
|
class LibraryBooksView(FileDragAndDrop, TableView):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
|
FileDragAndDrop.__init__(self, QTableView)
|
||||||
QTableView.__init__(self, parent)
|
QTableView.__init__(self, parent)
|
||||||
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
self.setSortingEnabled(True)
|
self.setSortingEnabled(True)
|
||||||
self.setItemDelegate(LibraryDelegate(self))
|
self.setItemDelegate(LibraryDelegate(self))
|
||||||
|
|
||||||
def get_verified_path(self, mime_data):
|
|
||||||
if mime_data.hasFormat("text/plain"):
|
|
||||||
text = unicode(mime_data.text())
|
|
||||||
text = re.sub(r"^file://", "", text)
|
|
||||||
if os.access(os.path.abspath(text), os.R_OK): return text
|
|
||||||
return None
|
|
||||||
def dragEnterEvent(self, event):
|
def dragEnterEvent(self, event):
|
||||||
if self.get_verified_path(event.mimeData()): event.acceptProposedAction()
|
if not event.mimeData().hasFormat("application/x-libprs500-id"):
|
||||||
|
FileDragAndDrop.dragEnterEvent(self, event)
|
||||||
def dragMoveEvent(self, event): event.acceptProposedAction()
|
|
||||||
|
|
||||||
|
def start_drag(self, pos):
|
||||||
|
index = self.indexAt(pos)
|
||||||
|
if index.isValid():
|
||||||
|
indexes = self.selectedIndexes()
|
||||||
|
files = self.model().extract_formats(indexes)
|
||||||
|
drag = self.drag_object_from_files(files)
|
||||||
|
if drag:
|
||||||
|
ids = [ str(self.model().id_from_index(index)) for index in indexes ]
|
||||||
|
drag.mimeData().setData("application/x-libprs500-id", QByteArray("\n".join(ids)))
|
||||||
|
drag.setPixmap(self.renderToPixmap(indexes))
|
||||||
|
drag.start()
|
||||||
|
|
||||||
|
|
||||||
|
def files_dropped(self, files, event):
|
||||||
|
if not files: return
|
||||||
|
index = self.indexAt(event.pos())
|
||||||
|
if index.isValid():
|
||||||
|
self.model().add_formats(files, index)
|
||||||
|
else: self.emit(SIGNAL('books_dropped'), files)
|
||||||
|
|
||||||
def dropEvent(self, event):
|
|
||||||
path = self.get_verified_path(event.mimeData())
|
|
||||||
if path:
|
|
||||||
if self.model().handle_drop(path, self.indexAt(event.pos())): event.acceptProposedAction()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -304,6 +352,28 @@ class LibraryBooksModel(QAbstractTableModel):
|
|||||||
self._orig_data = None
|
self._orig_data = None
|
||||||
self.image_file = None
|
self.image_file = None
|
||||||
|
|
||||||
|
def extract_formats(self, indices):
|
||||||
|
files, rows = [], []
|
||||||
|
for index in indices:
|
||||||
|
row = index.row()
|
||||||
|
if row in rows: continue
|
||||||
|
else: rows.append(row)
|
||||||
|
id = self.id_from_index(index)
|
||||||
|
basename = re.sub("\n", "", self._data[row]["title"]+" by "+ self._data[row]["authors"])
|
||||||
|
exts = self.db.get_extensions(id)
|
||||||
|
for ext in exts:
|
||||||
|
fmt = self.db.get_format(id, ext)
|
||||||
|
if not ext: ext =""
|
||||||
|
else: ext = "."+ext
|
||||||
|
name = basename+ext
|
||||||
|
file = NamedTemporaryFile(name)
|
||||||
|
file.open()
|
||||||
|
if not fmt: continue
|
||||||
|
file.write(QByteArray(fmt))
|
||||||
|
file.close()
|
||||||
|
files.append(file)
|
||||||
|
return files
|
||||||
|
|
||||||
def update_cover(self, index, pix):
|
def update_cover(self, index, pix):
|
||||||
id = self.id_from_index(index)
|
id = self.id_from_index(index)
|
||||||
qb = QBuffer()
|
qb = QBuffer()
|
||||||
@ -313,17 +383,14 @@ class LibraryBooksModel(QAbstractTableModel):
|
|||||||
qb.close()
|
qb.close()
|
||||||
self.db.update_cover(id, data)
|
self.db.update_cover(id, data)
|
||||||
|
|
||||||
def handle_drop(self, path, index):
|
def add_formats(self, paths, index):
|
||||||
print "249", path, index.row()
|
for path in paths:
|
||||||
if index.isValid():
|
|
||||||
f = open(path, "rb")
|
f = open(path, "rb")
|
||||||
title = os.path.basename(path)
|
title = os.path.basename(path)
|
||||||
ext = title[title.rfind(".")+1:].lower() if "." in title > -1 else None
|
ext = title[title.rfind(".")+1:].lower() if "." in title > -1 else None
|
||||||
self.db.add_format(self.id_from_index(index), ext, f)
|
self.db.add_format(self.id_from_index(index), ext, f)
|
||||||
f.close()
|
f.close()
|
||||||
else:
|
self.emit(SIGNAL('formats_added'), index)
|
||||||
pass # TODO: emit book add signal
|
|
||||||
return True
|
|
||||||
|
|
||||||
def rowCount(self, parent): return len(self._data)
|
def rowCount(self, parent): return len(self._data)
|
||||||
def columnCount(self, parent): return len(self.FIELDS)-2
|
def columnCount(self, parent): return len(self.FIELDS)-2
|
||||||
@ -357,10 +424,8 @@ class LibraryBooksModel(QAbstractTableModel):
|
|||||||
|
|
||||||
def flags(self, index):
|
def flags(self, index):
|
||||||
flags = QAbstractTableModel.flags(self, index)
|
flags = QAbstractTableModel.flags(self, index)
|
||||||
if index.isValid():
|
if index.isValid():
|
||||||
flags |= Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled
|
if index.column() not in [2,3]: flags |= Qt.ItemIsEditable
|
||||||
if index.column() not in [2,3]: flags |= Qt.ItemIsEditable
|
|
||||||
else: flags |= Qt.ItemIsDropEnabled
|
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
def set_data(self, db):
|
def set_data(self, db):
|
||||||
@ -428,7 +493,7 @@ class LibraryBooksModel(QAbstractTableModel):
|
|||||||
if text == None: text = "Unknown"
|
if text == None: text = "Unknown"
|
||||||
return QVariant(text)
|
return QVariant(text)
|
||||||
elif role == Qt.TextAlignmentRole and index.column() in [2,3,4]:
|
elif role == Qt.TextAlignmentRole and index.column() in [2,3,4]:
|
||||||
return QVariant(Qt.AlignRight)
|
return QVariant(Qt.AlignRight | Qt.AlignVCenter)
|
||||||
return NONE
|
return NONE
|
||||||
|
|
||||||
def sort(self, col, order):
|
def sort(self, col, order):
|
||||||
@ -483,35 +548,10 @@ class LibraryBooksModel(QAbstractTableModel):
|
|||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
|
||||||
def add_book(self, path):
|
def add_book(self, path):
|
||||||
""" Must call search and sort after this """
|
""" Must call search and sort on this models view after this """
|
||||||
id = self.db.add_book(path)
|
id = self.db.add_book(path)
|
||||||
self._orig_data.append(self.db.get_row_by_id(id, self.FIELDS))
|
self._orig_data.append(self.db.get_row_by_id(id, self.FIELDS))
|
||||||
|
|
||||||
def mimeTypes(self):
|
|
||||||
s = QStringList()
|
|
||||||
s << "application/vnd.text.list" # Title, authors
|
|
||||||
s << "image/jpeg" # 60x80 thumbnail
|
|
||||||
s << "application/x-sony-bbeb"
|
|
||||||
s << "application/pdf"
|
|
||||||
s << "text/rtf"
|
|
||||||
s << "text/plain"
|
|
||||||
return s
|
|
||||||
|
|
||||||
def mimeData(self, indices):
|
|
||||||
mime_data = QMimeData()
|
|
||||||
encoded_data = QByteArray()
|
|
||||||
rows = []
|
|
||||||
for index in indices:
|
|
||||||
if index.isValid():
|
|
||||||
row = index.row()
|
|
||||||
if row in rows: continue
|
|
||||||
title, authors, size, exts, cover = self.info(row)
|
|
||||||
encoded_data.append(title)
|
|
||||||
encoded_data.append(authors)
|
|
||||||
rows.append(row)
|
|
||||||
mime_data.setData("application/vnd.text.list", encoded_data)
|
|
||||||
return mime_data
|
|
||||||
|
|
||||||
class DeviceBooksModel(QAbstractTableModel):
|
class DeviceBooksModel(QAbstractTableModel):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QAbstractTableModel.__init__(self, parent)
|
QAbstractTableModel.__init__(self, parent)
|
||||||
@ -538,7 +578,7 @@ class DeviceBooksModel(QAbstractTableModel):
|
|||||||
return QVariant(self.trUtf8(text))
|
return QVariant(self.trUtf8(text))
|
||||||
else: return QVariant(str(1+section))
|
else: return QVariant(str(1+section))
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role == Qt.DisplayRole:
|
if role == Qt.DisplayRole:
|
||||||
row, col = index.row(), index.column()
|
row, col = index.row(), index.column()
|
||||||
book = self._data[row]
|
book = self._data[row]
|
||||||
@ -548,7 +588,7 @@ class DeviceBooksModel(QAbstractTableModel):
|
|||||||
elif col == 3: text = time.strftime(TIME_WRITE_FMT, book.datetime)
|
elif col == 3: text = time.strftime(TIME_WRITE_FMT, book.datetime)
|
||||||
return QVariant(text)
|
return QVariant(text)
|
||||||
elif role == Qt.TextAlignmentRole and index.column() in [2,3]:
|
elif role == Qt.TextAlignmentRole and index.column() in [2,3]:
|
||||||
return QVariant(Qt.AlignRight)
|
return QVariant(Qt.AlignRight | Qt.AlignVCenter)
|
||||||
return NONE
|
return NONE
|
||||||
|
|
||||||
def info(self, row):
|
def info(self, row):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user