Clicking on the preview panel moves the cursor to corresponding location in the editor

This commit is contained in:
Kovid Goyal 2013-11-18 10:12:30 +05:30
parent b1652a2316
commit 5abe588d71
4 changed files with 72 additions and 6 deletions

View File

@ -55,6 +55,7 @@ class Boss(QObject):
self.gui.central.current_editor_changed.connect(self.apply_current_editor_state)
self.gui.central.close_requested.connect(self.editor_close_requested)
self.gui.central.search_panel.search_triggered.connect(self.search)
self.gui.preview.sync_requested.connect(self.sync_editor_to_preview)
def mkdtemp(self, prefix=''):
self.container_count += 1
@ -492,6 +493,10 @@ class Boss(QObject):
_('Saving of the book failed. Click "Show Details"'
' for more information.'), det_msg=tb, show=True)
def sync_editor_to_preview(self, name, lnum):
editor = self.edit_file(name, 'html')
editor.go_to_line(lnum)
def init_editor(self, name, editor, data=None, use_template=False):
editor.undo_redo_state_changed.connect(self.editor_undo_redo_state_changed)
editor.data_changed.connect(self.editor_data_changed)
@ -514,6 +519,7 @@ class Boss(QObject):
data = use_template
self.init_editor(name, editor, data, use_template=bool(use_template))
self.show_editor(name)
return editor
def show_editor(self, name):
self.gui.central.show_editor(editors[name])

View File

@ -136,6 +136,22 @@ class TextEdit(QPlainTextEdit):
self.setTextCursor(c)
self.ensureCursorVisible()
def go_to_line(self, lnum):
lnum = max(1, min(self.blockCount(), lnum))
c = self.textCursor()
c.clearSelection()
c.movePosition(c.Start)
c.movePosition(c.NextBlock, n=lnum - 1)
c.movePosition(c.StartOfLine)
c.movePosition(c.EndOfLine, c.KeepAnchor)
text = unicode(c.selectedText())
c.movePosition(c.StartOfLine)
lt = text.lstrip()
if text and lt and lt != text:
c.movePosition(c.NextWord)
self.setTextCursor(c)
self.ensureCursorVisible()
def update_extra_selections(self):
sel = []
if self.current_cursor_line is not None:

View File

@ -51,6 +51,9 @@ class Editor(QMainWindow):
def init_from_template(self, template):
self.editor.load_text(template, syntax=self.syntax, process_template=True)
def go_to_line(self, lnum):
self.editor.go_to_line(lnum)
def get_raw_data(self):
return unicode(self.editor.toPlainText())

View File

@ -12,8 +12,9 @@ from Queue import Queue, Empty
from PyQt4.Qt import (
QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon,
QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QNetworkDiskCache, QToolBar)
from PyQt4.QtWebKit import QWebView, QWebInspector
QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QNetworkDiskCache, QToolBar,
pyqtSlot, pyqtSignal)
from PyQt4.QtWebKit import QWebView, QWebInspector, QWebPage
from calibre import prints
from calibre.constants import iswindows
@ -217,6 +218,41 @@ class NetworkAccessManager(QNetworkAccessManager):
# }}}
class WebPage(QWebPage):
sync_requested = pyqtSignal(object)
def __init__(self, parent):
QWebPage.__init__(self, parent)
self.setNetworkAccessManager(NetworkAccessManager(self))
self.setLinkDelegationPolicy(self.DelegateAllLinks)
self.mainFrame().javaScriptWindowObjectCleared.connect(self.init_javascript)
self.init_javascript()
def javaScriptConsoleMessage(self, msg, lineno, source_id):
prints('preview js:%s:%s:'%(unicode(source_id), lineno), unicode(msg))
def init_javascript(self):
mf = self.mainFrame()
mf.addToJavaScriptWindowObject("py_bridge", self)
mf.evaluateJavaScript(
'''
function handle_click(event) {
event.preventDefault();
window.py_bridge.request_sync(event.target.getAttribute("lnum"));
}
window.onload = function() {
document.body.addEventListener('click', handle_click, true);
}
''')
@pyqtSlot(str)
def request_sync(self, lnum):
try:
self.sync_requested.emit(int(lnum))
except (TypeError, ValueError, OverflowError, AttributeError):
pass
class WebView(QWebView):
def __init__(self, parent=None):
@ -235,10 +271,8 @@ class WebView(QWebView):
settings.setAttribute(settings.LinksIncludedInFocusChain, False)
settings.setAttribute(settings.DeveloperExtrasEnabled, True)
settings.setDefaultTextEncoding('utf-8')
self.page().setNetworkAccessManager(NetworkAccessManager(self))
self.page().setLinkDelegationPolicy(self.page().DelegateAllLinks)
self._page = WebPage(self)
self.setPage(self._page)
self.clear()
def sizeHint(self):
@ -274,12 +308,15 @@ class WebView(QWebView):
class Preview(QWidget):
sync_requested = pyqtSignal(object, object)
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.l = l = QVBoxLayout()
self.setLayout(l)
l.setContentsMargins(0, 0, 0, 0)
self.view = WebView(self)
self.view.page().sync_requested.connect(self.request_sync)
self.inspector = self.view.inspector
self.inspector.setPage(self.view.page())
l.addWidget(self.view)
@ -305,6 +342,10 @@ class Preview(QWidget):
self.refresh_timer.timeout.connect(self.refresh)
parse_worker.start()
def request_sync(self, lnum):
if self.current_name:
self.sync_requested.emit(self.current_name, lnum)
def show(self, name):
if name != self.current_name:
self.refresh_timer.stop()