mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement clicking on links in the preview panel
Clicking links in the preview panel now opens the linked to document in an editor at the location pointed to by the link
This commit is contained in:
parent
4491fad3d7
commit
b8c52790bc
Binary file not shown.
@ -105,9 +105,26 @@ class PreviewIntegration
|
||||
if this.in_split_mode
|
||||
this.report_split(event.target)
|
||||
else
|
||||
window.py_bridge.request_sync(event.target.getAttribute("data-lnum"))
|
||||
e = event.target
|
||||
# Find the closest containing link, if any
|
||||
lnum = e.getAttribute('data-lnum')
|
||||
href = tn = ''
|
||||
while e and e != document.body and e != document and (tn != 'a' or not href)
|
||||
tn = e.tagName?.toLowerCase()
|
||||
href = e.getAttribute('href')
|
||||
e = e.parentNode
|
||||
window.py_bridge.request_sync(tn, href, lnum)
|
||||
return false
|
||||
|
||||
go_to_anchor: (anchor, lnum) =>
|
||||
elem = document.getElementById(anchor)
|
||||
if not elem
|
||||
elem = document.querySelector('[name="' + anchor + '"]')
|
||||
if elem
|
||||
elem.scrollIntoView()
|
||||
lnum = elem.getAttribute('data-lnum')
|
||||
window.py_bridge.request_sync('', '', lnum)
|
||||
|
||||
window.calibre_preview_integration = new PreviewIntegration()
|
||||
window.onload = window.calibre_preview_integration.onload
|
||||
|
||||
|
@ -91,6 +91,7 @@ class Boss(QObject):
|
||||
self.gui.preview.sync_requested.connect(self.sync_editor_to_preview)
|
||||
self.gui.preview.split_start_requested.connect(self.split_start_requested)
|
||||
self.gui.preview.split_requested.connect(self.split_requested)
|
||||
self.gui.preview.link_clicked.connect(self.link_clicked)
|
||||
|
||||
def preferences(self):
|
||||
p = Preferences(self.gui)
|
||||
@ -668,6 +669,17 @@ class Boss(QObject):
|
||||
self.apply_container_update_to_gui()
|
||||
self.edit_file(bottom_name, 'html')
|
||||
|
||||
@in_thread_job
|
||||
def link_clicked(self, name, anchor):
|
||||
if name in editors:
|
||||
editor = editors[name]
|
||||
self.gui.central.show_editor(editor)
|
||||
else:
|
||||
syntax = syntax_from_mime(name, current_container().mime_map[name])
|
||||
editor = self.edit_file(name, syntax)
|
||||
if anchor:
|
||||
editor.go_to_anchor(anchor)
|
||||
|
||||
@in_thread_job
|
||||
def merge_requested(self, category, names, master):
|
||||
self.commit_all_editors_to_container()
|
||||
|
@ -287,6 +287,20 @@ class TextEdit(QPlainTextEdit):
|
||||
text = m.expand(template)
|
||||
c.insertText(text)
|
||||
return True
|
||||
|
||||
def go_to_anchor(self, anchor):
|
||||
base = r'''%%s\s*=\s*['"]{0,1}%s''' % regex.escape(anchor)
|
||||
raw = unicode(self.toPlainText())
|
||||
m = regex.search(base % 'id', raw)
|
||||
if m is None:
|
||||
m = regex.search(base % 'name', raw)
|
||||
if m is not None:
|
||||
c = self.textCursor()
|
||||
c.setPosition(m.start())
|
||||
self.setTextCursor(c)
|
||||
return True
|
||||
return False
|
||||
|
||||
# }}}
|
||||
|
||||
# Line numbers and cursor line {{{
|
||||
|
@ -108,6 +108,9 @@ class Editor(QMainWindow):
|
||||
|
||||
def all_in_marked(self, *args, **kwargs):
|
||||
return self.editor.all_in_marked(*args, **kwargs)
|
||||
|
||||
def go_to_anchor(self, *args, **kwargs):
|
||||
return self.editor.go_to_anchor(*args, **kwargs)
|
||||
# }}}
|
||||
|
||||
@property
|
||||
|
@ -14,6 +14,7 @@ from threading import Thread
|
||||
from Queue import Queue, Empty
|
||||
from collections import namedtuple
|
||||
from functools import partial
|
||||
from urlparse import urlparse
|
||||
|
||||
from PyQt4.Qt import (
|
||||
QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon,
|
||||
@ -273,7 +274,7 @@ def find_le(a, x):
|
||||
|
||||
class WebPage(QWebPage):
|
||||
|
||||
sync_requested = pyqtSignal(object)
|
||||
sync_requested = pyqtSignal(object, object, object)
|
||||
split_requested = pyqtSignal(object)
|
||||
|
||||
def __init__(self, parent):
|
||||
@ -312,13 +313,17 @@ class WebPage(QWebPage):
|
||||
mf.addToJavaScriptWindowObject("py_bridge", self)
|
||||
mf.evaluateJavaScript(self.js)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def request_sync(self, lnum):
|
||||
@pyqtSlot(str, str, str)
|
||||
def request_sync(self, tag_name, href, lnum):
|
||||
try:
|
||||
self.sync_requested.emit(int(lnum))
|
||||
self.sync_requested.emit(unicode(tag_name), unicode(href), int(unicode(lnum)))
|
||||
except (TypeError, ValueError, OverflowError, AttributeError):
|
||||
pass
|
||||
|
||||
def go_to_anchor(self, anchor, lnum):
|
||||
self.mainFrame().evaluateJavaScript('window.calibre_preview_integration.go_to_anchor(%s, %s)' % (
|
||||
json.dumps(anchor), json.dumps(str(lnum))))
|
||||
|
||||
@pyqtSlot(str)
|
||||
def request_split(self, loc):
|
||||
actions['split-in-preview'].setChecked(False)
|
||||
@ -414,6 +419,7 @@ class Preview(QWidget):
|
||||
sync_requested = pyqtSignal(object, object)
|
||||
split_requested = pyqtSignal(object, object)
|
||||
split_start_requested = pyqtSignal()
|
||||
link_clicked = pyqtSignal(object, object)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
@ -482,8 +488,18 @@ class Preview(QWidget):
|
||||
self.view.findText(text, QWebPage.FindWrapsAroundDocument | (
|
||||
QWebPage.FindBackward if direction == 'prev' else QWebPage.FindFlags(0)))
|
||||
|
||||
def request_sync(self, lnum):
|
||||
def request_sync(self, tagname, href, lnum):
|
||||
if self.current_name:
|
||||
c = current_container()
|
||||
if tagname == 'a' and href:
|
||||
if href and href.startswith('#'):
|
||||
name = self.current_name
|
||||
else:
|
||||
name = c.href_to_name(href, self.current_name) if href else None
|
||||
if name == self.current_name:
|
||||
return self.view.page().go_to_anchor(urlparse(href).fragment, lnum)
|
||||
if name and c.exists(name) and c.mime_map[name] in OEB_DOCS:
|
||||
return self.link_clicked.emit(name, urlparse(href).fragment)
|
||||
self.sync_requested.emit(self.current_name, lnum)
|
||||
|
||||
def request_split(self, loc):
|
||||
|
Loading…
x
Reference in New Issue
Block a user