mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow drag and drop of books onto formats in the Tag Browser to convert them. Fixes #1945890 [[Enhancement] Drag book to format in the Tag browser to convert it to that format](https://bugs.launchpad.net/calibre/+bug/1945890)
This commit is contained in:
parent
afe7d69681
commit
200b62d25c
@ -160,7 +160,15 @@ class ConvertAction(InterfaceAction):
|
|||||||
return
|
return
|
||||||
self.do_convert(book_ids, bulk=bulk)
|
self.do_convert(book_ids, bulk=bulk)
|
||||||
|
|
||||||
def do_convert(self, book_ids, bulk=None):
|
def convert_ebooks_to_format(self, book_ids, to_fmt):
|
||||||
|
from calibre.customize.ui import available_output_formats
|
||||||
|
to_fmt = to_fmt.upper()
|
||||||
|
if to_fmt.lower() not in available_output_formats():
|
||||||
|
return error_dialog(self.gui, _('Cannot convert'), _(
|
||||||
|
'Conversion to the {} format is not supported').format(to_fmt), show=True)
|
||||||
|
self.do_convert(book_ids, output_fmt=to_fmt, auto_conversion=True)
|
||||||
|
|
||||||
|
def do_convert(self, book_ids, bulk=None, auto_conversion=False, output_fmt=None):
|
||||||
previous = self.gui.library_view.currentIndex()
|
previous = self.gui.library_view.currentIndex()
|
||||||
rows = [x.row() for x in
|
rows = [x.row() for x in
|
||||||
self.gui.library_view.selectionModel().selectedRows()]
|
self.gui.library_view.selectionModel().selectedRows()]
|
||||||
@ -168,14 +176,14 @@ class ConvertAction(InterfaceAction):
|
|||||||
if bulk or (bulk is None and len(book_ids) > 1):
|
if bulk or (bulk is None and len(book_ids) > 1):
|
||||||
self.__bulk_queue = convert_bulk_ebook(self.gui, self.queue_convert_jobs,
|
self.__bulk_queue = convert_bulk_ebook(self.gui, self.queue_convert_jobs,
|
||||||
self.gui.library_view.model().db, book_ids,
|
self.gui.library_view.model().db, book_ids,
|
||||||
out_format=prefs['output_format'], args=(rows, previous,
|
out_format=output_fmt or prefs['output_format'], args=(rows, previous,
|
||||||
self.book_converted))
|
self.book_converted))
|
||||||
if self.__bulk_queue is None:
|
if self.__bulk_queue is None:
|
||||||
return
|
return
|
||||||
num = len(self.__bulk_queue.book_ids)
|
num = len(self.__bulk_queue.book_ids)
|
||||||
else:
|
else:
|
||||||
jobs, changed, bad = convert_single_ebook(self.gui,
|
jobs, changed, bad = convert_single_ebook(self.gui,
|
||||||
self.gui.library_view.model().db, book_ids, out_format=prefs['output_format'])
|
self.gui.library_view.model().db, book_ids, out_format=output_fmt or prefs['output_format'], auto_conversion=auto_conversion)
|
||||||
self.queue_convert_jobs(jobs, changed, bad, rows, previous,
|
self.queue_convert_jobs(jobs, changed, bad, rows, previous,
|
||||||
self.book_converted)
|
self.book_converted)
|
||||||
num = len(jobs)
|
num = len(jobs)
|
||||||
|
@ -317,6 +317,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
user_categories_edited = pyqtSignal(object, object)
|
user_categories_edited = pyqtSignal(object, object)
|
||||||
user_category_added = pyqtSignal()
|
user_category_added = pyqtSignal()
|
||||||
show_error_after_event_loop_tick_signal = pyqtSignal(object, object, object)
|
show_error_after_event_loop_tick_signal = pyqtSignal(object, object, object)
|
||||||
|
convert_requested = pyqtSignal(object, object)
|
||||||
|
|
||||||
def __init__(self, parent, prefs=gprefs):
|
def __init__(self, parent, prefs=gprefs):
|
||||||
QAbstractItemModel.__init__(self, parent)
|
QAbstractItemModel.__init__(self, parent)
|
||||||
@ -977,7 +978,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
if node.type == TagTreeItem.TAG:
|
if node.type == TagTreeItem.TAG:
|
||||||
fm = self.db.metadata_for_field(node.tag.category)
|
fm = self.db.metadata_for_field(node.tag.category)
|
||||||
if node.tag.category in \
|
if node.tag.category in \
|
||||||
('tags', 'series', 'authors', 'rating', 'publisher', 'languages') or \
|
('tags', 'series', 'authors', 'rating', 'publisher', 'languages', 'formats') or \
|
||||||
(fm['is_custom'] and (
|
(fm['is_custom'] and (
|
||||||
fm['datatype'] in ['text', 'rating', 'series',
|
fm['datatype'] in ['text', 'rating', 'series',
|
||||||
'enumeration'] or (
|
'enumeration'] or (
|
||||||
@ -1038,9 +1039,15 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
self.refresh_required.emit()
|
self.refresh_required.emit()
|
||||||
self.user_category_added.emit()
|
self.user_category_added.emit()
|
||||||
|
|
||||||
|
def handle_drop_on_format(self, fmt, book_ids):
|
||||||
|
self.convert_requested.emit(book_ids, fmt)
|
||||||
|
|
||||||
def handle_drop(self, on_node, ids):
|
def handle_drop(self, on_node, ids):
|
||||||
# print 'Dropped ids:', ids, on_node.tag
|
# print 'Dropped ids:', ids, on_node.tag
|
||||||
key = on_node.tag.category
|
key = on_node.tag.category
|
||||||
|
if key == 'formats':
|
||||||
|
self.handle_drop_on_format(on_node.tag.name, ids)
|
||||||
|
return
|
||||||
if (key == 'authors' and len(ids) >= 5):
|
if (key == 'authors' and len(ids) >= 5):
|
||||||
if not confirm('<p>'+_('Changing the authors for several books can '
|
if not confirm('<p>'+_('Changing the authors for several books can '
|
||||||
'take a while. Are you sure?') +
|
'take a while. Are you sure?') +
|
||||||
@ -1393,12 +1400,13 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
ans |= Qt.ItemFlag.ItemIsDragEnabled
|
ans |= Qt.ItemFlag.ItemIsDragEnabled
|
||||||
fm = self.db.metadata_for_field(category)
|
fm = self.db.metadata_for_field(category)
|
||||||
if category in \
|
if category in \
|
||||||
('tags', 'series', 'authors', 'rating', 'publisher', 'languages') or \
|
('tags', 'series', 'authors', 'rating', 'publisher', 'languages', 'formats') or \
|
||||||
(fm['is_custom'] and
|
(fm['is_custom'] and
|
||||||
fm['datatype'] in ['text', 'rating', 'series', 'enumeration']):
|
fm['datatype'] in ['text', 'rating', 'series', 'enumeration']):
|
||||||
ans |= Qt.ItemFlag.ItemIsDropEnabled
|
ans |= Qt.ItemFlag.ItemIsDropEnabled
|
||||||
else:
|
else:
|
||||||
ans |= Qt.ItemFlag.ItemIsDropEnabled
|
if node.type != TagTreeItem.CATEGORY or node.category_key != 'formats':
|
||||||
|
ans |= Qt.ItemFlag.ItemIsDropEnabled
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def supportedDropActions(self):
|
def supportedDropActions(self):
|
||||||
|
@ -216,9 +216,14 @@ class TagsView(QTreeView): # {{{
|
|||||||
self._model.user_categories_edited.connect(self.user_categories_edited,
|
self._model.user_categories_edited.connect(self.user_categories_edited,
|
||||||
type=Qt.ConnectionType.QueuedConnection)
|
type=Qt.ConnectionType.QueuedConnection)
|
||||||
self._model.drag_drop_finished.connect(self.drag_drop_finished)
|
self._model.drag_drop_finished.connect(self.drag_drop_finished)
|
||||||
|
self._model.convert_requested.connect(self.convert_requested)
|
||||||
self.set_look_and_feel(first=True)
|
self.set_look_and_feel(first=True)
|
||||||
QApplication.instance().palette_changed.connect(self.set_style_sheet, type=Qt.ConnectionType.QueuedConnection)
|
QApplication.instance().palette_changed.connect(self.set_style_sheet, type=Qt.ConnectionType.QueuedConnection)
|
||||||
|
|
||||||
|
def convert_requested(self, book_ids, to_fmt):
|
||||||
|
from calibre.gui2.ui import get_gui
|
||||||
|
get_gui().iactions['Convert Books'].convert_ebooks_to_format(book_ids, to_fmt)
|
||||||
|
|
||||||
def set_style_sheet(self):
|
def set_style_sheet(self):
|
||||||
stylish_tb = '''
|
stylish_tb = '''
|
||||||
QTreeView {
|
QTreeView {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user