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:
Kovid Goyal 2013-04-24 09:14:58 +05:30
commit 3bb7e0c23f
2 changed files with 51 additions and 26 deletions

View File

@ -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):

View File

@ -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()