Add right click menu to the formats list in the edit metadata dialog that allwos you to restore a format from its original easily

This commit is contained in:
Kovid Goyal 2011-07-15 23:25:27 -06:00
parent 7ef09c6ef5
commit 678547f545
2 changed files with 70 additions and 8 deletions

View File

@ -11,10 +11,10 @@ import textwrap, re, os
from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox, from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox,
QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication, QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication,
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDialog, QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDialog, QMenu,
QPushButton, QSpinBox, QLineEdit, QSizePolicy, QDialogButtonBox) QPushButton, QSpinBox, QLineEdit, QSizePolicy, QDialogButtonBox, QAction)
from calibre.gui2.widgets import EnLineEdit, FormatList, ImageView from calibre.gui2.widgets import EnLineEdit, FormatList as _FormatList, ImageView
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.config import tweaks, prefs from calibre.utils.config import tweaks, prefs
@ -33,6 +33,7 @@ from calibre.gui2.comments_editor import Editor
from calibre.library.comments import comments_to_html from calibre.library.comments import comments_to_html
from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.gui2.dialogs.tag_editor import TagEditor
from calibre.utils.icu import strcmp from calibre.utils.icu import strcmp
from calibre.ptempfile import PersistentTemporaryFile
def save_dialog(parent, title, msg, det_msg=''): def save_dialog(parent, title, msg, det_msg=''):
d = QMessageBox(parent) d = QMessageBox(parent)
@ -572,7 +573,9 @@ class BuddyLabel(QLabel): # {{{
self.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
# }}} # }}}
class Format(QListWidgetItem): # {{{ # Formats {{{
class Format(QListWidgetItem):
def __init__(self, parent, ext, size, path=None, timestamp=None): def __init__(self, parent, ext, size, path=None, timestamp=None):
self.path = path self.path = path
@ -588,13 +591,52 @@ class Format(QListWidgetItem): # {{{
self.setToolTip(text) self.setToolTip(text)
self.setStatusTip(text) self.setStatusTip(text)
# }}} class OrigAction(QAction):
class FormatsManager(QWidget): # {{{ restore_fmt = pyqtSignal(object)
def __init__(self, fmt, parent):
self.fmt = fmt.replace('ORIGINAL_', '')
QAction.__init__(self, _('Restore %s from the original')%self.fmt, parent)
self.triggered.connect(self._triggered)
def _triggered(self):
self.restore_fmt.emit(self.fmt)
class FormatList(_FormatList):
restore_fmt = pyqtSignal(object)
def __init__(self, parent): def __init__(self, parent):
_FormatList.__init__(self, parent)
self.setContextMenuPolicy(Qt.DefaultContextMenu)
def contextMenuEvent(self, event):
originals = [self.item(x).ext.upper() for x in range(self.count())]
originals = [x for x in originals if x.startswith('ORIGINAL_')]
if not originals:
return
self.cm = cm = QMenu(self)
for fmt in originals:
action = OrigAction(fmt, cm)
action.restore_fmt.connect(self.restore_fmt)
cm.addAction(action)
cm.popup(event.globalPos())
event.accept()
def remove_format(self, fmt):
for i in range(self.count()):
f = self.item(i)
if f.ext.upper() == fmt.upper():
self.takeItem(i)
break
class FormatsManager(QWidget):
def __init__(self, parent, copy_fmt):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.dialog = parent self.dialog = parent
self.copy_fmt = copy_fmt
self.changed = False self.changed = False
self.l = l = QGridLayout() self.l = l = QGridLayout()
@ -628,6 +670,7 @@ class FormatsManager(QWidget): # {{{
self.formats = FormatList(self) self.formats = FormatList(self)
self.formats.setAcceptDrops(True) self.formats.setAcceptDrops(True)
self.formats.formats_dropped.connect(self.formats_dropped) self.formats.formats_dropped.connect(self.formats_dropped)
self.formats.restore_fmt.connect(self.restore_fmt)
self.formats.delete_format.connect(self.remove_format) self.formats.delete_format.connect(self.remove_format)
self.formats.itemDoubleClicked.connect(self.show_format) self.formats.itemDoubleClicked.connect(self.show_format)
self.formats.setDragDropMode(self.formats.DropOnly) self.formats.setDragDropMode(self.formats.DropOnly)
@ -640,7 +683,7 @@ class FormatsManager(QWidget): # {{{
l.addWidget(self.remove_format_button, 2, 2, 1, 1) l.addWidget(self.remove_format_button, 2, 2, 1, 1)
l.addWidget(self.formats, 0, 1, 3, 1) l.addWidget(self.formats, 0, 1, 3, 1)
self.temp_files = []
def initialize(self, db, id_): def initialize(self, db, id_):
self.changed = False self.changed = False
@ -694,6 +737,16 @@ class FormatsManager(QWidget): # {{{
[(_('Books'), BOOK_EXTENSIONS)]) [(_('Books'), BOOK_EXTENSIONS)])
self._add_formats(files) self._add_formats(files)
def restore_fmt(self, fmt):
pt = PersistentTemporaryFile(suffix='_restore_fmt.'+fmt.lower())
ofmt = 'ORIGINAL_'+fmt
with pt:
self.copy_fmt(ofmt, pt)
self._add_formats((pt.name,))
self.temp_files.append(pt.name)
self.changed = True
self.formats.remove_format(ofmt)
def _add_formats(self, paths): def _add_formats(self, paths):
added = False added = False
if not paths: if not paths:
@ -774,6 +827,13 @@ class FormatsManager(QWidget): # {{{
def break_cycles(self): def break_cycles(self):
self.dialog = None self.dialog = None
self.copy_fmt = None
for name in self.temp_files:
try:
os.remove(name)
except:
pass
self.temp_files = []
# }}} # }}}
class Cover(ImageView): # {{{ class Cover(ImageView): # {{{

View File

@ -145,7 +145,7 @@ class MetadataSingleDialogBase(ResizableDialog):
self.series_index = SeriesIndexEdit(self, self.series) self.series_index = SeriesIndexEdit(self, self.series)
self.basic_metadata_widgets.extend([self.series, self.series_index]) self.basic_metadata_widgets.extend([self.series, self.series_index])
self.formats_manager = FormatsManager(self) self.formats_manager = FormatsManager(self, self.copy_fmt)
self.basic_metadata_widgets.append(self.formats_manager) self.basic_metadata_widgets.append(self.formats_manager)
self.formats_manager.metadata_from_format_button.clicked.connect( self.formats_manager.metadata_from_format_button.clicked.connect(
self.metadata_from_format) self.metadata_from_format)
@ -240,6 +240,8 @@ class MetadataSingleDialogBase(ResizableDialog):
else: else:
self.view_format.emit(self.book_id, fmt) self.view_format.emit(self.book_id, fmt)
def copy_fmt(self, fmt, f):
self.db.copy_format_to(self.book_id, fmt, f, index_is_id=True)
def do_layout(self): def do_layout(self):
raise NotImplementedError() raise NotImplementedError()