From f9e3b0a422b62e027eafdb20499dd4a7d99e89a3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 22 Dec 2006 20:27:02 +0000 Subject: [PATCH] Fix #9 --- libprs500/gui/database.py | 6 ++ libprs500/gui/editbook.py | 170 ++++++++++++++++++++++---------------- libprs500/gui/main.py | 31 ++++++- libprs500/gui/widgets.py | 6 ++ 4 files changed, 142 insertions(+), 71 deletions(-) diff --git a/libprs500/gui/database.py b/libprs500/gui/database.py index b7c7bf02c6..1098a93dc9 100644 --- a/libprs500/gui/database.py +++ b/libprs500/gui/database.py @@ -116,6 +116,12 @@ class LibraryDatabase(object): pass else: return decompress(str(data["data"])) + + def remove_format(self, _id, ext): + """ Remove format C{ext} from book C{_id} """ + self.con.execute("delete from books_data where id=? and extension=?", \ + (_id, ext)) + self.con.commit() def add_format(self, _id, ext, data): """ diff --git a/libprs500/gui/editbook.py b/libprs500/gui/editbook.py index 0aa6c418b5..1d39beecae 100644 --- a/libprs500/gui/editbook.py +++ b/libprs500/gui/editbook.py @@ -12,117 +12,142 @@ ## 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. -import sys, os, StringIO -from PyQt4 import uic +""" +The dialog used to edit meta information for a book as well as +add/remove formats +""" +import os + from PyQt4.QtCore import Qt, SIGNAL -from PyQt4.Qt import QObject, QDialog, QPixmap, QListWidgetItem -from libprs500.lrf.meta import LRFMetaFile -from libprs500.gui import import_ui +from PyQt4.Qt import QObject, QPixmap, QListWidgetItem, QErrorMessage, \ + QVariant, QSettings, QFileDialog + +from libprs500.gui import import_ui, extension class Format(QListWidgetItem): - def __init__(self, parent, ext, data): - self.data = data + def __init__(self, parent, ext, path=None): + self.path = path self.ext = ext - QListWidgetItem.__init__(self, ext.upper(), parent, QListWidgetItem.UserType) + QListWidgetItem.__init__(self, ext.upper(), parent, \ + QListWidgetItem.UserType) Ui_BookEditDialog = import_ui("editbook.ui") class EditBookDialog(Ui_BookEditDialog): def select_cover(self, checked): settings = QSettings() - dir = settings.value("change cover dir", QVariant(os.path.expanduser("~"))).toString() - file = QFileDialog.getOpenFileName(self.window, "Choose cover for " + str(self.title.text()), dir, "Images (*.png *.gif *.jpeg *.jpg);;All files (*)") - if len(str(file)): - file = os.path.abspath(file) - settings.setValue("change cover dir", QVariant(os.path.dirname(file))) - if not os.access(file, os.R_OK): - QErrorMessage(self.parent).showMessage("You do not have permission to read the file: " + file) + _dir = settings.value("change cover dir", \ + QVariant(os.path.expanduser("~"))).toString() + _file = str(QFileDialog.getOpenFileName(self.parent, \ + "Choose cover for " + str(self.title.text()), _dir, \ + "Images (*.png *.gif *.jpeg *.jpg);;All files (*)")) + if len(_file): + _file = os.path.abspath(_file) + settings.setValue("change cover dir", \ + QVariant(os.path.dirname(_file))) + if not os.access(_file, os.R_OK): + QErrorMessage(self.parent).showMessage("You do not have "+\ + "permission to read the file: " + _file) return cf, cover = None, None try: - cf = open(file, "rb") + cf = open(_file, "rb") cover = cf.read() - except IOError, e: QErrorMessage(self.parent).showMessage("There was an error reading from file: " + file + "\n"+str(e)) + except IOError, e: + QErrorMessage(self.parent).showMessage("There was an error"+\ + " reading from file: " + _file + "\n"+str(e)) if cover: pix = QPixmap() pix.loadFromData(cover, "", Qt.AutoColor) - if pix.isNull(): QErrorMessage(self.parent).showMessage(file + " is not a valid picture") + if pix.isNull(): + QErrorMessage(self.parent).showMessage(_file + \ + " is not a valid picture") else: - self.cover_path.setText(file) - self.cover.setPixmap(pix) - self.cover_data = cover - - - def write_data(self): - title = str(self.title.text()).strip() - authors = str(self.authors.text()).strip() - rating = self.rating.value() - tags = str(self.tags.text()).strip() - publisher = str(self.publisher.text()).strip() - comments = str(self.comments.toPlainText()).strip() - self.db.set_metadata(self.id, title=title, authors=authors, rating=rating, tags=tags, publisher=publisher, comments=comments, cover=self.cover_data) - if self.formats_changed: - for r in range(self.formats.count()): - format = self.formats.item(r) - self.db.add_format(self.id, format.ext, format.data) - lrf = self.db.get_format(self.id, "lrf") - if lrf: - lrf = StringIO.StringIO(lrf) - lf = LRFMetaFile(lrf) - if title: lf.title = title - if authors: lf.title = authors - if publisher: lf.publisher = publisher - if self.cover_data: lf.thumbnail = self.cover_data - self.db.add_format(self.id, "lrf", lrf.getvalue()) + self.cover_path.setText(_file) + self.cover.setPixmap(pix) def add_format(self, x): - dir = settings.value("add formats dialog dir", QVariant(os.path.expanduser("~"))).toString() - files = QFileDialog.getOpenFileNames(self.window, "Choose formats for " + str(self.title.text()), dir, "Books (*.lrf *.lrx *.rtf *.txt *.html *.xhtml *.htm *.rar);;All files (*)") + settings = QSettings() + _dir = settings.value("add formats dialog dir", \ + QVariant(os.path.expanduser("~"))).toString() + files = QFileDialog.getOpenFileNames(self.parent, \ + "Choose formats for " + str(self.title.text()), _dir, \ + "Books (*.lrf *.lrx *.rtf *.txt *.html *.xhtml *.htm *.rar);;"+\ + "All files (*)") if not files.isEmpty(): x = str(files[0]) - settings.setValue("add formats dialog dir", QVariant(os.path.dirname(x))) + settings.setValue("add formats dialog dir", \ + QVariant(os.path.dirname(x))) files = str(files.join("|||")).split("|||") - for file in files: - file = os.path.abspath(file) - if not os.access(file, os.R_OK): - QErrorMessage(self.parent).showMessage("You do not have permission to read the file: " + file) + for _file in files: + _file = os.path.abspath(_file) + if not os.access(_file, os.R_OK): + QErrorMessage(self.parent).showMessage("You do not have "+\ + "permission to read the file: " + _file) continue - f, data = None, None - try: - f = open(file, "rb") - data = f.read() - except IOError, e: QErrorMessage(self.parent).showMessage("There was an error reading from file: " + file + "\n"+str(e)) - if data: - ext = file[file.rfind(".")+1:].lower() if file.find(".") > -1 else None - Format(self.formats, ext, data) - self.formats_changed = True + ext = extension(_file) + for row in range(self.formats.count()): + fmt = self.formats.item(row) + if fmt.ext == ext: + self.formats.takeItem(fmt) + break + Format(self.formats, ext, path=_file) + self.formats_changed = True def remove_format(self, x): rows = self.formats.selectionModel().selectedRows(0) for row in rows: - item = self.formats.takeItem(row.row()) + self.formats.takeItem(row.row()) self.formats_changed = True - def __init__(self, dialog, id, db): + def sync_formats(self): + old_extensions, new_extensions, paths = set(), set(), {} + for row in range(self.formats.count()): + fmt = self.formats.item(row) + ext, path = fmt.ext, fmt.path + if "unknown" in ext.lower(): + ext = None + if path: + new_extensions.add(ext) + paths[ext] = path + else: + old_extensions.add(ext) + for ext in new_extensions: + self.db.add_format(self.id, ext, file(paths[ext], "rb")) + db_extensions = self.db.get_extensions(self.id) + extensions = new_extensions.union(old_extensions) + for ext in db_extensions: + if ext not in extensions: + self.db.remove_format(self.id, ext) + self.db.update_max_size(self.id) + + def __init__(self, dialog, _id, db): Ui_BookEditDialog.__init__(self) self.parent = dialog self.setupUi(dialog) - self.splitter.setStretchFactor(100,1) + self.splitter.setStretchFactor(100, 1) self.db = db - self.id = id + self.id = _id self.cover_data = None self.formats_changed = False - QObject.connect(self.cover_button, SIGNAL("clicked(bool)"), self.select_cover) - QObject.connect(self.button_box, SIGNAL("accepted()"), self.write_data) - QObject.connect(self.add_format_button, SIGNAL("clicked(bool)"), self.add_format) - QObject.connect(self.remove_format_button, SIGNAL("clicked(bool)"), self.remove_format) - data = self.db.get_row_by_id(self.id, ["title","authors","rating","publisher","tags","comments"]) + QObject.connect(self.cover_button, SIGNAL("clicked(bool)"), \ + self.select_cover) + QObject.connect(self.add_format_button, SIGNAL("clicked(bool)"), \ + self.add_format) + QObject.connect(self.remove_format_button, SIGNAL("clicked(bool)"), \ + self.remove_format) + QObject.connect(self.button_box, SIGNAL("accepted()"), \ + self.sync_formats) + + data = self.db.get_row_by_id(self.id, \ + ["title","authors","rating","publisher","tags","comments"]) self.title.setText(data["title"]) self.authors.setText(data["authors"] if data["authors"] else "") self.publisher.setText(data["publisher"] if data["publisher"] else "") self.tags.setText(data["tags"] if data["tags"] else "") - if data["rating"] > 0: self.rating.setValue(data["rating"]) + if data["rating"] > 0: + self.rating.setValue(data["rating"]) self.comments.setPlainText(data["comments"] if data["comments"] else "") cover = self.db.get_cover(self.id) if cover: @@ -131,3 +156,8 @@ class EditBookDialog(Ui_BookEditDialog): self.cover.setPixmap(pm) else: self.cover.setPixmap(QPixmap(":/default_cover")) + exts = self.db.get_extensions(self.id) + for ext in exts: + if not ext: + ext = "Unknown" + Format(self.formats, ext) diff --git a/libprs500/gui/main.py b/libprs500/gui/main.py index 621ee934fb..8f6e5441b7 100644 --- a/libprs500/gui/main.py +++ b/libprs500/gui/main.py @@ -209,14 +209,43 @@ class Main(QObject, Ui_MainWindow): def edit(self, action): if self.library_view.isVisible(): rows = self.library_view.selectionModel().selectedRows() + accepted = False for row in rows: _id = self.library_model.id_from_index(row) dialog = QDialog(self.window) - EditBookDialog(dialog, _id, self.library_model.db) + ebd = EditBookDialog(dialog, _id, self.library_model.db) if dialog.exec_() == QDialog.Accepted: + accepted = True + title = str(ebd.title.text()).strip() + authors = str(ebd.authors.text()).strip() + rating = ebd.rating.value() + tags = str(ebd.tags.text()).strip() + publisher = str(ebd.publisher.text()).strip() + comments = str(ebd.comments.toPlainText()).strip() + pix = ebd.cover.pixmap() + if not pix.isNull(): + self.update_cover(pix) + model = self.library_view.model() + if title: + index = model.index(row.row(), 0) + model.setData(index, QVariant(title), Qt.EditRole) + if authors: + index = model.index(row.row(), 1) + model.setData(index, QVariant(authors), Qt.EditRole) + if publisher: + index = model.index(row.row(), 5) + model.setData(index, QVariant(publisher), Qt.EditRole) + index = model.index(row.row(), 4) + model.setData(index, QVariant(rating), Qt.EditRole) + self.update_tags_and_comments(row, tags, comments) self.library_model.refresh_row(row.row()) + self.show_book(self.current_view.currentIndex(), QModelIndex()) + def update_tags_and_comments(self, index, tags, comments): + self.library_model.update_tags_and_comments(index, tags, comments) + + def update_cover(self, pix): if not pix.isNull(): try: diff --git a/libprs500/gui/widgets.py b/libprs500/gui/widgets.py index 84a4637b5d..bfc3a1df6d 100644 --- a/libprs500/gui/widgets.py +++ b/libprs500/gui/widgets.py @@ -482,6 +482,12 @@ class LibraryBooksModel(QAbstractTableModel): done = True return done + def update_tags_and_comments(self, index, tags, comments): + _id = self.id_from_index(index) + self.db.set_metadata_item(_id, "tags", tags) + self.db.set_metadata_item(_id, "comments", comments) + self.refresh_row(index.row()) + def flags(self, index): flags = QAbstractTableModel.flags(self, index) if index.isValid():