mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow comparing the ORIGINAL_EPUB version of a book to the EPUB version by right clicking on the ORIGINAL_EPUB format in the book details panel.
This commit is contained in:
parent
4fadc7dacc
commit
0d5cf9d78c
@ -671,8 +671,9 @@ class Cache(object):
|
||||
'''
|
||||
Return absolute path to the ebook file of format `format`
|
||||
|
||||
Currently used only in calibredb list, the viewer, edit book and the
|
||||
catalogs (via get_data_as_dict()).
|
||||
Currently used only in calibredb list, the viewer, edit book,
|
||||
compare_format to original format and the catalogs (via
|
||||
get_data_as_dict()).
|
||||
|
||||
Apart from the viewer, I don't believe any of the others do any file
|
||||
I/O with the results of this call.
|
||||
|
@ -413,6 +413,7 @@ class BookInfo(QWebView):
|
||||
remove_format = pyqtSignal(int, object)
|
||||
save_format = pyqtSignal(int, object)
|
||||
restore_format = pyqtSignal(int, object)
|
||||
compare_format = pyqtSignal(int, object)
|
||||
copy_link = pyqtSignal(object)
|
||||
manage_author = pyqtSignal(object)
|
||||
|
||||
@ -433,7 +434,7 @@ class BookInfo(QWebView):
|
||||
for x, icon in [
|
||||
('remove_format', 'trash.png'), ('save_format', 'save.png'),
|
||||
('restore_format', 'edit-undo.png'), ('copy_link','edit-copy.png'),
|
||||
('manage_author', 'user_profile.png')]:
|
||||
('manage_author', 'user_profile.png'), ('compare_format', 'diff.png')]:
|
||||
ac = QAction(QIcon(I(icon)), '', self)
|
||||
ac.current_fmt = None
|
||||
ac.current_url = None
|
||||
@ -458,6 +459,9 @@ class BookInfo(QWebView):
|
||||
def restore_format_triggerred(self):
|
||||
self.context_action_triggered('restore_format')
|
||||
|
||||
def compare_format_triggerred(self):
|
||||
self.context_action_triggered('compare_format')
|
||||
|
||||
def copy_link_triggerred(self):
|
||||
self.context_action_triggered('copy_link')
|
||||
|
||||
@ -517,20 +521,31 @@ class BookInfo(QWebView):
|
||||
if url.startswith('format:'):
|
||||
parts = url.split(':')
|
||||
try:
|
||||
book_id, fmt = int(parts[1]), parts[2]
|
||||
book_id, fmt = int(parts[1]), parts[2].upper()
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
else:
|
||||
from calibre.gui2.ui import get_gui
|
||||
db = get_gui().current_db.new_api
|
||||
ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt
|
||||
fmts = {x.upper() for x in db.formats(book_id)}
|
||||
for a, t in [('remove', _('Delete the %s format')),
|
||||
('save', _('Save the %s format to disk')),
|
||||
('restore', _('Restore the %s format')),
|
||||
('compare', ''),
|
||||
]:
|
||||
if a == 'restore' and not fmt.upper().startswith('ORIGINAL_'):
|
||||
if a == 'restore' and not fmt.startswith('ORIGINAL_'):
|
||||
continue
|
||||
if a == 'compare':
|
||||
if ofmt not in fmts:
|
||||
continue
|
||||
t = _('Compare to the %s format') % (fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt)
|
||||
else:
|
||||
t = t % fmt
|
||||
ac = getattr(self, '%s_format_action'%a)
|
||||
ac.current_fmt = (book_id, fmt)
|
||||
ac.setText(t%parts[2])
|
||||
ac.setText(t)
|
||||
menu.addAction(ac)
|
||||
if len(menu.actions()) > 0:
|
||||
menu.exec_(ev.globalPos())
|
||||
@ -635,6 +650,7 @@ class BookDetails(QWidget): # {{{
|
||||
remove_specific_format = pyqtSignal(int, object)
|
||||
save_specific_format = pyqtSignal(int, object)
|
||||
restore_specific_format = pyqtSignal(int, object)
|
||||
compare_specific_format = pyqtSignal(int, object)
|
||||
copy_link = pyqtSignal(object)
|
||||
remote_file_dropped = pyqtSignal(object, object)
|
||||
files_dropped = pyqtSignal(object, object)
|
||||
@ -706,6 +722,7 @@ class BookDetails(QWidget): # {{{
|
||||
self.book_info.remove_format.connect(self.remove_specific_format)
|
||||
self.book_info.save_format.connect(self.save_specific_format)
|
||||
self.book_info.restore_format.connect(self.restore_specific_format)
|
||||
self.book_info.compare_format.connect(self.compare_specific_format)
|
||||
self.book_info.copy_link.connect(self.copy_link)
|
||||
self.book_info.manage_author.connect(self.manage_author)
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
|
@ -449,6 +449,7 @@ class LayoutMixin(object): # {{{
|
||||
self.book_details.view_device_book.connect(
|
||||
self.iactions['View'].view_device_book)
|
||||
self.book_details.manage_author.connect(lambda author:self.do_author_sort_edit(self, author, select_sort=False, select_link=False))
|
||||
self.book_details.compare_specific_format.connect(self.compare_format)
|
||||
|
||||
m = self.library_view.model()
|
||||
if m.rowCount(None) > 0:
|
||||
@ -475,6 +476,18 @@ class LayoutMixin(object): # {{{
|
||||
if url:
|
||||
QApplication.clipboard().setText(url)
|
||||
|
||||
def compare_format(self, book_id, fmt):
|
||||
db = self.current_db.new_api
|
||||
ofmt = fmt
|
||||
if fmt.startswith('ORIGINAL_'):
|
||||
fmt = fmt.partition('_')[-1]
|
||||
else:
|
||||
ofmt = 'ORIGINAL_' + fmt
|
||||
path1, path2 = db.format_abspath(book_id, ofmt), db.format_abspath(book_id, fmt)
|
||||
from calibre.gui2.tweak_book.diff.main import compare_books
|
||||
compare_books(path1, path2, parent=self, revert_msg=_('Restore %s') % ofmt, revert_callback=partial(
|
||||
self.iactions['Remove Books'].restore_format, book_id, ofmt))
|
||||
|
||||
def save_layout_state(self):
|
||||
for x in ('library', 'memory', 'card_a', 'card_b'):
|
||||
getattr(self, x+'_view').save_state()
|
||||
|
@ -11,7 +11,7 @@ from functools import partial
|
||||
from PyQt4.Qt import (
|
||||
QGridLayout, QToolButton, QIcon, QRadioButton, QMenu, QApplication, Qt,
|
||||
QSize, QWidget, QLabel, QStackedLayout, QPainter, QRect, QVBoxLayout,
|
||||
QCursor, QEventLoop, QKeySequence, pyqtSignal)
|
||||
QCursor, QEventLoop, QKeySequence, pyqtSignal, QTimer)
|
||||
|
||||
from calibre.ebooks.oeb.polish.container import Container
|
||||
from calibre.gui2 import info_dialog
|
||||
@ -107,8 +107,8 @@ def container_diff(left, right):
|
||||
left_names -= samefile_names
|
||||
right_names -= samefile_names
|
||||
|
||||
cache, changed_names, renamed_names, removed_names, added_names = changed_files(
|
||||
left_names, right_names, left.raw_data, right.raw_data)
|
||||
cache, changed_names, renamed_names, removed_names, added_names = changed_files(
|
||||
left_names, right_names, left.raw_data, right.raw_data)
|
||||
|
||||
def syntax(container, name):
|
||||
mt = container.mime_map[name]
|
||||
@ -141,6 +141,7 @@ class Diff(Dialog):
|
||||
return QSize(int(0.9 * geom.width()), int(0.8 * geom.height()))
|
||||
|
||||
def setup_ui(self):
|
||||
self.setWindowIcon(QIcon(I('diff.png')))
|
||||
self.stacks = st = QStackedLayout(self)
|
||||
self.busy = BusyWidget(self)
|
||||
self.w = QWidget(self)
|
||||
@ -300,6 +301,18 @@ class Diff(Dialog):
|
||||
return
|
||||
return Dialog.keyPressEvent(self, ev)
|
||||
|
||||
def compare_books(path1, path2, revert_msg=None, revert_callback=None, parent=None):
|
||||
d = Diff(parent=parent, revert_button_msg=revert_msg)
|
||||
if revert_msg is not None:
|
||||
d.revert_requested.connect(revert_callback)
|
||||
QTimer.singleShot(0, partial(d.ebook_diff, path1, path2))
|
||||
d.exec_()
|
||||
try:
|
||||
d.revert_requested.disconnect()
|
||||
except:
|
||||
pass
|
||||
d.break_cycles()
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
app = QApplication([])
|
||||
|
Loading…
x
Reference in New Issue
Block a user