mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #9
This commit is contained in:
parent
4b2afac719
commit
f9e3b0a422
@ -117,6 +117,12 @@ class LibraryDatabase(object):
|
||||
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):
|
||||
"""
|
||||
If data for format ext already exists, it is replaced
|
||||
|
@ -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_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())
|
||||
|
||||
|
||||
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)
|
||||
|
@ -209,12 +209,41 @@ 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):
|
||||
|
@ -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():
|
||||
|
Loading…
x
Reference in New Issue
Block a user