Create subclass InterfaceActionWithLibraryDrop (DRY)

All actual implementation of `accepts_drops` for built-in InterfaceAction
are a "from_library" drag-and-drop. Create a subclass that implement the
relatives methods.
This commit is contained in:
un-pogaz 2024-02-18 20:43:07 +01:00
parent 49e7bf5c97
commit 37d4946e97
10 changed files with 67 additions and 210 deletions

View File

@ -8,8 +8,9 @@ __docformat__ = 'restructuredtext en'
from functools import partial
from zipfile import ZipFile
from qt.core import (QToolButton, QAction, QIcon, QObject, QMenu, QPoint,
QKeySequence)
from qt.core import (
QAction, QIcon, QKeySequence, QMenu, QObject, QPoint, QTimer, QToolButton,
)
from calibre import prints
from calibre.constants import ismacos
@ -438,3 +439,35 @@ class InterfaceAction(QObject):
long periods of time.
'''
pass
class InterfaceActionWithLibraryDrop(InterfaceAction):
'''
Subclass of InterfaceAction that implemente methods to execute the default action
by drop some books from the library.
Inside the do_drop() method, the ids of the droped books are provided
by the attribute self.dropped_ids
'''
accepts_drops = True
mime = 'application/calibre+from_library'
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat(self.mime):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat(self.mime):
return True
return False
def drop_event(self, event, mime_data):
if mime_data.hasFormat(self.mime):
self.dropped_ids = tuple(map(int, mime_data.data(self.mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
raise NotImplementedError()

View File

@ -7,17 +7,17 @@ __docformat__ = 'restructuredtext en'
import os
from functools import partial
from qt.core import QModelIndex, QTimer
from qt.core import QModelIndex
from calibre.customize.ui import plugin_for_input_format, run_plugins_on_postconvert
from calibre.gui2 import Dispatcher, error_dialog, gprefs
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.gui2.tools import convert_bulk_ebook, convert_single_ebook
from calibre.utils.config import prefs, tweaks
from calibre.utils.localization import ngettext
class ConvertAction(InterfaceAction):
class ConvertAction(InterfaceActionWithLibraryDrop):
name = 'Convert Books'
action_spec = (_('Convert books'), 'convert.png', _('Convert books between different e-book formats'), _('C'))
@ -25,26 +25,6 @@ class ConvertAction(InterfaceAction):
action_type = 'current'
action_add_menu = True
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids

View File

@ -11,7 +11,7 @@ from qt.core import QDialog, QModelIndex, QObject, QTimer
from calibre.constants import ismacos
from calibre.gui2 import Aborted, error_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.confirm_delete_location import confirm_location
from calibre.gui2.dialogs.delete_matching_from_device import (
@ -77,7 +77,7 @@ class MultiDeleter(QObject): # {{{
# }}}
class DeleteAction(InterfaceAction):
class DeleteAction(InterfaceActionWithLibraryDrop):
name = 'Remove Books'
action_spec = (_('Remove books'), 'remove_books.png', _('Delete books'), 'Backspace' if ismacos else 'Del')
@ -85,26 +85,6 @@ class DeleteAction(InterfaceAction):
action_add_menu = True
action_menu_clone_qaction = _('Remove selected books')
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids

View File

@ -21,7 +21,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
from calibre.ebooks.metadata.sources.prefs import msprefs
from calibre.gui2 import Dispatcher, error_dialog, gprefs, question_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.device_category_editor import DeviceCategoryEditor
@ -35,33 +35,13 @@ from polyglot.builtins import iteritems
DATA_FILES_ICON_NAME = 'unpack-book.png'
class EditMetadataAction(InterfaceAction):
class EditMetadataAction(InterfaceActionWithLibraryDrop):
name = 'Edit Metadata'
action_spec = (_('Edit metadata'), 'edit_input.png', _('Change the title/author/cover etc. of books'), _('E'))
action_type = 'current'
action_add_menu = True
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids

View File

@ -9,11 +9,11 @@ from qt.core import QProgressDialog, Qt, QTimer
from calibre import force_unicode
from calibre.gui2 import gprefs
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.utils.localization import ngettext
class EmbedAction(InterfaceAction):
class EmbedAction(InterfaceActionWithLibraryDrop):
name = 'Embed Metadata'
action_spec = (_('Embed metadata'), 'modified.png', _('Embed metadata into book files'), None)
@ -21,26 +21,6 @@ class EmbedAction(InterfaceAction):
action_add_menu = True
action_menu_clone_qaction = _('Embed metadata into book files')
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids

View File

@ -7,11 +7,11 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
from functools import partial
from qt.core import (
QApplication, QDialog, QDialogButtonBox, QEvent, QGridLayout, QIcon, QLabel, QMenu,
QPushButton, Qt, QTimer,
QPushButton, Qt,
)
from calibre.gui2 import error_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.gui2.widgets2 import HistoryComboBox
from calibre.startup import connect_lambda
from calibre.utils.icu import sort_key
@ -81,7 +81,7 @@ class MarkWithTextDialog(QDialog):
mark_books_with_text = None
class MarkBooksAction(InterfaceAction):
class MarkBooksAction(InterfaceActionWithLibraryDrop):
name = 'Mark Books'
action_spec = (_('Mark books'), 'marked.png', _('Temporarily mark books for easy access'), 'Ctrl+M')
@ -91,26 +91,6 @@ class MarkBooksAction(InterfaceAction):
'context-menu-device', 'menubar-device', 'context-menu-cover-browser'])
action_menu_clone_qaction = _('Toggle mark for selected books')
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids

View File

@ -18,7 +18,7 @@ from qt.core import (
)
from calibre.gui2 import Dispatcher, error_dialog, gprefs, question_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.gui2.convert.metadata import create_opf_file
from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.ptempfile import PersistentTemporaryDirectory
@ -409,32 +409,13 @@ class Report(QDialog): # {{{
# }}}
class PolishAction(InterfaceAction):
class PolishAction(InterfaceActionWithLibraryDrop):
name = 'Polish Books'
action_spec = (_('Polish books'), 'polish.png',
_('Apply the shine of perfection to your books'), _('P'))
dont_add_to = frozenset(['context-menu-device'])
action_type = 'current'
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_id_map = self.get_supported_books(self.dropped_ids)

View File

@ -13,7 +13,7 @@ from qt.core import (
)
from calibre.gui2 import error_dialog, gprefs, question_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.startup import connect_lambda
from calibre.utils.monotonic import monotonic
from polyglot.builtins import iteritems
@ -68,32 +68,13 @@ class ChooseFormat(QDialog): # {{{
# }}}
class ToCEditAction(InterfaceAction):
class ToCEditAction(InterfaceActionWithLibraryDrop):
name = 'Edit ToC'
action_spec = (_('Edit ToC'), 'toc.png',
_('Edit the Table of Contents in your books'), _('K'))
dont_add_to = frozenset(['context-menu-device'])
action_type = 'current'
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_id_map = self.get_supported_books(self.dropped_ids)

View File

@ -7,11 +7,11 @@ __docformat__ = 'restructuredtext en'
import time
from qt.core import (
QCheckBox, QDialog, QDialogButtonBox, QLabel, Qt, QTimer, QVBoxLayout,
QCheckBox, QDialog, QDialogButtonBox, QLabel, Qt, QVBoxLayout,
)
from calibre.gui2 import error_dialog, question_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.startup import connect_lambda
@ -54,33 +54,13 @@ class Choose(QDialog):
QDialog.accept(self)
class TweakEpubAction(InterfaceAction):
class TweakEpubAction(InterfaceActionWithLibraryDrop):
name = 'Tweak ePub'
action_spec = (_('Edit book'), 'edit_book.png', _('Edit books in the EPUB or AZW formats'), _('T'))
dont_add_to = frozenset(('context-menu-device',))
action_type = 'current'
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids

View File

@ -5,17 +5,19 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os, weakref, shutil
from qt.core import (QDialog, QVBoxLayout, QHBoxLayout, QRadioButton, QFrame,
QPushButton, QLabel, QGroupBox, QGridLayout, QIcon, QSize, QTimer)
import os
import shutil
import weakref
from qt.core import (
QDialog, QFrame, QGridLayout, QGroupBox, QHBoxLayout, QIcon, QLabel, QPushButton,
QRadioButton, QSize, QTimer, QVBoxLayout,
)
from calibre import as_unicode
from calibre.constants import ismacos
from calibre.gui2 import error_dialog, question_dialog, open_local_file, gprefs
from calibre.gui2.actions import InterfaceAction
from calibre.ptempfile import (PersistentTemporaryDirectory,
PersistentTemporaryFile)
from calibre.gui2 import error_dialog, gprefs, open_local_file, question_dialog
from calibre.gui2.actions import InterfaceActionWithLibraryDrop
from calibre.ptempfile import PersistentTemporaryDirectory, PersistentTemporaryFile
from calibre.utils.config import prefs, tweaks
@ -163,7 +165,7 @@ class UnpackBook(QDialog):
return question_dialog(self, _('Are you sure?'), msg)
def do_explode(self):
from calibre.ebooks.tweak import get_tools, Error, WorkerError
from calibre.ebooks.tweak import Error, WorkerError, get_tools
tdir = PersistentTemporaryDirectory('_tweak_explode')
self._cleanup_dirs.append(tdir)
det_msg = None
@ -201,7 +203,7 @@ class UnpackBook(QDialog):
open_local_file(tdir)
def rebuild_it(self):
from calibre.ebooks.tweak import get_tools, WorkerError
from calibre.ebooks.tweak import WorkerError, get_tools
src_dir = self._exploded
det_msg = None
of = PersistentTemporaryFile('_tweak_rebuild.'+self.current_format.lower())
@ -284,7 +286,7 @@ class UnpackBook(QDialog):
return str(b.text())
class UnpackBookAction(InterfaceAction):
class UnpackBookAction(InterfaceActionWithLibraryDrop):
name = 'Unpack Book'
action_spec = (_('Unpack book'), 'unpack-book.png',
@ -292,26 +294,6 @@ class UnpackBookAction(InterfaceAction):
dont_add_to = frozenset(['context-menu-device'])
action_type = 'current'
accepts_drops = True
def accept_enter_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def accept_drag_move_event(self, event, mime_data):
if mime_data.hasFormat("application/calibre+from_library"):
return True
return False
def drop_event(self, event, mime_data):
mime = 'application/calibre+from_library'
if mime_data.hasFormat(mime):
self.dropped_ids = tuple(map(int, mime_data.data(mime).data().split()))
QTimer.singleShot(1, self.do_drop)
return True
return False
def do_drop(self):
book_ids = self.dropped_ids
del self.dropped_ids