diff --git a/src/calibre/gui2/viewer/bookmarkmanager.py b/src/calibre/gui2/viewer/bookmarkmanager.py index 073087f1e3..acd00c3a6f 100644 --- a/src/calibre/gui2/viewer/bookmarkmanager.py +++ b/src/calibre/gui2/viewer/bookmarkmanager.py @@ -1,15 +1,17 @@ -from __future__ import with_statement +#!/usr/bin/env python +# vim:fileencoding=utf-8 +from __future__ import (unicode_literals, division, absolute_import, + print_function) -__license__ = 'GPL v3' -__copyright__ = '2009, John Schember ' +__license__ = 'GPL v3' +__copyright__ = '2013, Kovid Goyal ' import cPickle, os -from PyQt4.Qt import (Qt, QDialog, QAbstractListModel, QVariant, - QModelIndex, QInputDialog, QLineEdit, QFileDialog, QItemSelectionModel) +from PyQt4.Qt import ( + Qt, QDialog, QListWidgetItem, QFileDialog, QItemSelectionModel) from calibre.gui2.viewer.bookmarkmanager_ui import Ui_BookmarkManager -from calibre.gui2 import NONE class BookmarkManager(QDialog, Ui_BookmarkManager): def __init__(self, parent, bookmarks): @@ -17,7 +19,7 @@ class BookmarkManager(QDialog, Ui_BookmarkManager): self.setupUi(self) - self.bookmarks = bookmarks[:] + self.original_bookmarks = bookmarks self.set_bookmarks() self.button_revert.clicked.connect(lambda :self.set_bookmarks()) @@ -26,46 +28,68 @@ class BookmarkManager(QDialog, Ui_BookmarkManager): self.button_export.clicked.connect(self.export_bookmarks) self.button_import.clicked.connect(self.import_bookmarks) self.bookmarks_list.setStyleSheet('QListView::item { padding: 0.5ex }') + self.bookmarks_list.viewport().setAcceptDrops(True) + self.bookmarks_list.setDropIndicatorShown(True) + self.bookmarks_list.itemChanged.connect(self.item_changed) self.resize(600, 500) + self.bookmarks_list.setFocus(Qt.OtherFocusReason) def set_bookmarks(self, bookmarks=None): if bookmarks is None: - bookmarks = self.bookmarks[:] - self._model = BookmarkListModel(self, bookmarks) - self.bookmarks_list.setModel(self._model) - if self._model.rowCount(QModelIndex()) > 0: - self.bookmarks_list.selectionModel().select(self._model.index(0), QItemSelectionModel.SelectCurrent) + bookmarks = self.original_bookmarks + self.bookmarks_list.clear() + for bm in bookmarks: + i = QListWidgetItem(bm['title']) + i.setData(Qt.UserRole, self.bm_to_item(bm)) + i.setFlags(i.flags() | Qt.ItemIsEditable) + self.bookmarks_list.addItem(i) + if len(bookmarks) > 0: + self.bookmarks_list.setCurrentItem(self.bookmarks_list.item(0), QItemSelectionModel.ClearAndSelect) + + def item_changed(self, item): + self.bookmarks_list.blockSignals(True) + title = unicode(item.data(Qt.DisplayRole).toString()) + if not title: + title = _('Unknown') + item.setData(Qt.DisplayRole, title) + bm = self.item_to_bm(item) + bm['title'] = title + item.setData(Qt.UserRole, self.bm_to_item(bm)) + self.bookmarks_list.blockSignals(False) def delete_bookmark(self): - indexes = list(self.bookmarks_list.selectionModel().selectedIndexes()) - if indexes: - self._model.remove_row(indexes[0].row()) + row = self.bookmarks_list.currentRow() + if row > -1: + self.bookmarks_list.takeItem(row) def edit_bookmark(self): - indexes = list(self.bookmarks_list.selectionModel().selectedIndexes()) - if indexes: - title, ok = QInputDialog.getText(self, _('Edit bookmark'), _( - 'New title for bookmark:'), QLineEdit.Normal, self._model.data(indexes[0], Qt.DisplayRole).toString()) - title = QVariant(unicode(title).strip()) - if ok and title: - self._model.setData(indexes[0], title, Qt.EditRole) + item = self.bookmarks_list.currentItem() + if item is not None: + self.bookmarks_list.editItem(item) + + def bm_to_item(self, bm): + return bytearray(cPickle.dumps(bm, -1)) + + def item_to_bm(self, item): + return cPickle.loads(bytes(item.data(Qt.UserRole).toPyObject())) def get_bookmarks(self): - return self._model.bookmarks + l = self.bookmarks_list + return [self.item_to_bm(l.item(i)) for i in xrange(l.count())] def export_bookmarks(self): filename = QFileDialog.getSaveFileName(self, _("Export Bookmarks"), '%s%suntitled.pickle' % (os.getcwdu(), os.sep), _("Saved Bookmarks (*.pickle)")) - if filename == '': + if not filename: return with open(filename, 'w') as fileobj: - cPickle.dump(self._model.bookmarks, fileobj) + cPickle.dump(self.get_bookmarks(), fileobj) def import_bookmarks(self): filename = QFileDialog.getOpenFileName(self, _("Import Bookmarks"), '%s' % os.getcwdu(), _("Pickled Bookmarks (*.pickle)")) - if filename == '': + if not filename: return imported = None @@ -83,61 +107,18 @@ class BookmarkManager(QDialog, Ui_BookmarkManager): pass if not bad: - bookmarks = self._model.bookmarks[:] + bookmarks = self.get_bookmarks() for bm in imported: if bm not in bookmarks and bm['title'] != 'calibre_current_page_bookmark': bookmarks.append(bm) self.set_bookmarks(bookmarks) - -class BookmarkListModel(QAbstractListModel): - - def __init__(self, parent, bookmarks): - QAbstractListModel.__init__(self, parent) - - self.bookmarks = bookmarks[:] - - def rowCount(self, parent): - if parent and parent.isValid(): - return 0 - return len(self.bookmarks) - - def data(self, index, role): - if role in (Qt.DisplayRole, Qt.EditRole): - ans = self.bookmarks[index.row()]['title'] - return NONE if ans is None else QVariant(ans) - return NONE - - def setData(self, index, value, role): - if role == Qt.EditRole: - bm = self.bookmarks[index.row()] - bm['title'] = unicode(value.toString()).strip() - self.dataChanged.emit(index, index) - return True - return False - - def flags(self, index): - flags = QAbstractListModel.flags(self, index) - flags |= Qt.ItemIsEditable - return flags - - def headerData(self, section, orientation, role): - if role != Qt.DisplayRole: - return NONE - if orientation == Qt.Horizontal: - return QVariant(self.headers[section]) - else: - return QVariant(section+1) - - def remove_row(self, row): - self.beginRemoveRows(QModelIndex(), row, row) - del self.bookmarks[row] - self.endRemoveRows() - if __name__ == '__main__': from PyQt4.Qt import QApplication app = QApplication([]) - d = BookmarkManager(None, [{'title':'Bookmark #%d' % i} for i in range(1, 50)]) + d = BookmarkManager(None, [{'title':'Bookmark #%d' % i, 'data':b'xxxxx'} for i in range(1, 5)]) d.exec_() + import pprint + pprint.pprint(d.get_bookmarks()) diff --git a/src/calibre/gui2/viewer/bookmarkmanager.ui b/src/calibre/gui2/viewer/bookmarkmanager.ui index 44c746038c..5d7f6a67d7 100644 --- a/src/calibre/gui2/viewer/bookmarkmanager.ui +++ b/src/calibre/gui2/viewer/bookmarkmanager.ui @@ -14,13 +14,6 @@ Bookmark Manager - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - @@ -85,8 +78,24 @@ + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + - + + + true + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + true