mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Allow copying of links in the book details panel by right clicking on them. Fixes #1171963 (Add 'Copy Link' right click menu to links in Book Details)
This commit is contained in:
commit
3bb7e0c23f
@ -406,6 +406,7 @@ class BookInfo(QWebView):
|
|||||||
remove_format = pyqtSignal(int, object)
|
remove_format = pyqtSignal(int, object)
|
||||||
save_format = pyqtSignal(int, object)
|
save_format = pyqtSignal(int, object)
|
||||||
restore_format = pyqtSignal(int, object)
|
restore_format = pyqtSignal(int, object)
|
||||||
|
copy_link = pyqtSignal(object)
|
||||||
|
|
||||||
def __init__(self, vertical, parent=None):
|
def __init__(self, vertical, parent=None):
|
||||||
QWebView.__init__(self, parent)
|
QWebView.__init__(self, parent)
|
||||||
@ -419,26 +420,33 @@ class BookInfo(QWebView):
|
|||||||
palette.setBrush(QPalette.Base, Qt.transparent)
|
palette.setBrush(QPalette.Base, Qt.transparent)
|
||||||
self.page().setPalette(palette)
|
self.page().setPalette(palette)
|
||||||
self.css = P('templates/book_details.css', data=True).decode('utf-8')
|
self.css = P('templates/book_details.css', data=True).decode('utf-8')
|
||||||
for x, icon in [('remove', 'trash.png'), ('save', 'save.png'), ('restore', 'edit-undo.png')]:
|
for x, icon in [('remove_format', 'trash.png'), ('save_format', 'save.png'), ('restore_format', 'edit-undo.png'), ('copy_link','edit-copy.png')]:
|
||||||
ac = QAction(QIcon(I(icon)), '', self)
|
ac = QAction(QIcon(I(icon)), '', self)
|
||||||
ac.current_fmt = None
|
ac.current_fmt = None
|
||||||
ac.triggered.connect(getattr(self, '%s_format_triggerred'%x))
|
ac.current_url = None
|
||||||
setattr(self, '%s_format_action'%x, ac)
|
ac.triggered.connect(getattr(self, '%s_triggerred'%x))
|
||||||
|
setattr(self, '%s_action'%x, ac)
|
||||||
|
|
||||||
def context_action_triggered(self, which):
|
def context_action_triggered(self, which):
|
||||||
f = getattr(self, '%s_format_action'%which).current_fmt
|
f = getattr(self, '%s_action'%which).current_fmt
|
||||||
if f:
|
url = getattr(self, '%s_action'%which).current_url
|
||||||
|
if f and 'format' in which:
|
||||||
book_id, fmt = f
|
book_id, fmt = f
|
||||||
getattr(self, '%s_format'%which).emit(book_id, fmt)
|
getattr(self, which).emit(book_id, fmt)
|
||||||
|
if url and 'link' in which:
|
||||||
|
getattr(self, which).emit(url)
|
||||||
|
|
||||||
def remove_format_triggerred(self):
|
def remove_format_triggerred(self):
|
||||||
self.context_action_triggered('remove')
|
self.context_action_triggered('remove_format')
|
||||||
|
|
||||||
def save_format_triggerred(self):
|
def save_format_triggerred(self):
|
||||||
self.context_action_triggered('save')
|
self.context_action_triggered('save_format')
|
||||||
|
|
||||||
def restore_format_triggerred(self):
|
def restore_format_triggerred(self):
|
||||||
self.context_action_triggered('restore')
|
self.context_action_triggered('restore_format')
|
||||||
|
|
||||||
|
def copy_link_triggerred(self):
|
||||||
|
self.context_action_triggered('copy_link')
|
||||||
|
|
||||||
def link_activated(self, link):
|
def link_activated(self, link):
|
||||||
self._link_clicked = True
|
self._link_clicked = True
|
||||||
@ -474,24 +482,33 @@ class BookInfo(QWebView):
|
|||||||
for action in list(menu.actions()):
|
for action in list(menu.actions()):
|
||||||
if action is not ca:
|
if action is not ca:
|
||||||
menu.removeAction(action)
|
menu.removeAction(action)
|
||||||
if not r.isNull() and url.startswith('format:'):
|
if not r.isNull():
|
||||||
parts = url.split(':')
|
if url.startswith('http'):
|
||||||
try:
|
for a, t in [('copy', _('&Copy Link')),
|
||||||
book_id, fmt = int(parts[1]), parts[2]
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
else:
|
|
||||||
for a, t in [('remove', _('Delete the %s format')),
|
|
||||||
('save', _('Save the %s format to disk')),
|
|
||||||
('restore', _('Restore the %s format')),
|
|
||||||
]:
|
]:
|
||||||
if a == 'restore' and not fmt.upper().startswith('ORIGINAL_'):
|
ac = getattr(self, '%s_link_action'%a)
|
||||||
continue
|
ac.current_url = url
|
||||||
ac = getattr(self, '%s_format_action'%a)
|
ac.setText(t)
|
||||||
ac.current_fmt = (book_id, fmt)
|
|
||||||
ac.setText(t%parts[2])
|
|
||||||
menu.addAction(ac)
|
menu.addAction(ac)
|
||||||
|
|
||||||
|
if url.startswith('format:'):
|
||||||
|
parts = url.split(':')
|
||||||
|
try:
|
||||||
|
book_id, fmt = int(parts[1]), parts[2]
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
else:
|
||||||
|
for a, t in [('remove', _('Delete the %s format')),
|
||||||
|
('save', _('Save the %s format to disk')),
|
||||||
|
('restore', _('Restore the %s format')),
|
||||||
|
]:
|
||||||
|
if a == 'restore' and not fmt.upper().startswith('ORIGINAL_'):
|
||||||
|
continue
|
||||||
|
ac = getattr(self, '%s_format_action'%a)
|
||||||
|
ac.current_fmt = (book_id, fmt)
|
||||||
|
ac.setText(t%parts[2])
|
||||||
|
menu.addAction(ac)
|
||||||
if len(menu.actions()) > 0:
|
if len(menu.actions()) > 0:
|
||||||
menu.exec_(ev.globalPos())
|
menu.exec_(ev.globalPos())
|
||||||
|
|
||||||
@ -594,6 +611,7 @@ class BookDetails(QWidget): # {{{
|
|||||||
remove_specific_format = pyqtSignal(int, object)
|
remove_specific_format = pyqtSignal(int, object)
|
||||||
save_specific_format = pyqtSignal(int, object)
|
save_specific_format = pyqtSignal(int, object)
|
||||||
restore_specific_format = pyqtSignal(int, object)
|
restore_specific_format = pyqtSignal(int, object)
|
||||||
|
copy_link = pyqtSignal(object)
|
||||||
remote_file_dropped = pyqtSignal(object, object)
|
remote_file_dropped = pyqtSignal(object, object)
|
||||||
files_dropped = pyqtSignal(object, object)
|
files_dropped = pyqtSignal(object, object)
|
||||||
cover_changed = pyqtSignal(object, object)
|
cover_changed = pyqtSignal(object, object)
|
||||||
@ -664,6 +682,7 @@ class BookDetails(QWidget): # {{{
|
|||||||
self.book_info.remove_format.connect(self.remove_specific_format)
|
self.book_info.remove_format.connect(self.remove_specific_format)
|
||||||
self.book_info.save_format.connect(self.save_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.restore_format.connect(self.restore_specific_format)
|
||||||
|
self.book_info.copy_link.connect(self.copy_link)
|
||||||
self.setCursor(Qt.PointingHandCursor)
|
self.setCursor(Qt.PointingHandCursor)
|
||||||
|
|
||||||
def handle_click(self, link):
|
def handle_click(self, link):
|
||||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from PyQt4.Qt import (Qt, QStackedWidget, QMenu, QTimer,
|
from PyQt4.Qt import (Qt, QApplication, QStackedWidget, QMenu, QTimer,
|
||||||
QSize, QSizePolicy, QStatusBar, QLabel, QFont)
|
QSize, QSizePolicy, QStatusBar, QLabel, QFont)
|
||||||
|
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs
|
||||||
@ -274,6 +274,8 @@ class LayoutMixin(object): # {{{
|
|||||||
self.iactions['Save To Disk'].save_library_format_by_ids)
|
self.iactions['Save To Disk'].save_library_format_by_ids)
|
||||||
self.book_details.restore_specific_format.connect(
|
self.book_details.restore_specific_format.connect(
|
||||||
self.iactions['Remove Books'].restore_format)
|
self.iactions['Remove Books'].restore_format)
|
||||||
|
self.book_details.copy_link.connect(self.bd_copy_link,
|
||||||
|
type=Qt.QueuedConnection)
|
||||||
self.book_details.view_device_book.connect(
|
self.book_details.view_device_book.connect(
|
||||||
self.iactions['View'].view_device_book)
|
self.iactions['View'].view_device_book)
|
||||||
|
|
||||||
@ -295,6 +297,10 @@ class LayoutMixin(object): # {{{
|
|||||||
if self.cover_flow:
|
if self.cover_flow:
|
||||||
self.cover_flow.dataChanged()
|
self.cover_flow.dataChanged()
|
||||||
|
|
||||||
|
def bd_copy_link(self, url):
|
||||||
|
if url:
|
||||||
|
QApplication.clipboard().setText(url)
|
||||||
|
|
||||||
def save_layout_state(self):
|
def save_layout_state(self):
|
||||||
for x in ('library', 'memory', 'card_a', 'card_b'):
|
for x in ('library', 'memory', 'card_a', 'card_b'):
|
||||||
getattr(self, x+'_view').save_state()
|
getattr(self, x+'_view').save_state()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user