mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Clicking on the preview panel moves the cursor to corresponding location in the editor
This commit is contained in:
parent
b1652a2316
commit
5abe588d71
@ -55,6 +55,7 @@ class Boss(QObject):
|
|||||||
self.gui.central.current_editor_changed.connect(self.apply_current_editor_state)
|
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.close_requested.connect(self.editor_close_requested)
|
||||||
self.gui.central.search_panel.search_triggered.connect(self.search)
|
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=''):
|
def mkdtemp(self, prefix=''):
|
||||||
self.container_count += 1
|
self.container_count += 1
|
||||||
@ -492,6 +493,10 @@ class Boss(QObject):
|
|||||||
_('Saving of the book failed. Click "Show Details"'
|
_('Saving of the book failed. Click "Show Details"'
|
||||||
' for more information.'), det_msg=tb, show=True)
|
' 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):
|
def init_editor(self, name, editor, data=None, use_template=False):
|
||||||
editor.undo_redo_state_changed.connect(self.editor_undo_redo_state_changed)
|
editor.undo_redo_state_changed.connect(self.editor_undo_redo_state_changed)
|
||||||
editor.data_changed.connect(self.editor_data_changed)
|
editor.data_changed.connect(self.editor_data_changed)
|
||||||
@ -514,6 +519,7 @@ class Boss(QObject):
|
|||||||
data = use_template
|
data = use_template
|
||||||
self.init_editor(name, editor, data, use_template=bool(use_template))
|
self.init_editor(name, editor, data, use_template=bool(use_template))
|
||||||
self.show_editor(name)
|
self.show_editor(name)
|
||||||
|
return editor
|
||||||
|
|
||||||
def show_editor(self, name):
|
def show_editor(self, name):
|
||||||
self.gui.central.show_editor(editors[name])
|
self.gui.central.show_editor(editors[name])
|
||||||
|
@ -136,6 +136,22 @@ class TextEdit(QPlainTextEdit):
|
|||||||
self.setTextCursor(c)
|
self.setTextCursor(c)
|
||||||
self.ensureCursorVisible()
|
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):
|
def update_extra_selections(self):
|
||||||
sel = []
|
sel = []
|
||||||
if self.current_cursor_line is not None:
|
if self.current_cursor_line is not None:
|
||||||
|
@ -51,6 +51,9 @@ class Editor(QMainWindow):
|
|||||||
def init_from_template(self, template):
|
def init_from_template(self, template):
|
||||||
self.editor.load_text(template, syntax=self.syntax, process_template=True)
|
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):
|
def get_raw_data(self):
|
||||||
return unicode(self.editor.toPlainText())
|
return unicode(self.editor.toPlainText())
|
||||||
|
|
||||||
|
@ -12,8 +12,9 @@ from Queue import Queue, Empty
|
|||||||
|
|
||||||
from PyQt4.Qt import (
|
from PyQt4.Qt import (
|
||||||
QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon,
|
QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon,
|
||||||
QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QNetworkDiskCache, QToolBar)
|
QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QNetworkDiskCache, QToolBar,
|
||||||
from PyQt4.QtWebKit import QWebView, QWebInspector
|
pyqtSlot, pyqtSignal)
|
||||||
|
from PyQt4.QtWebKit import QWebView, QWebInspector, QWebPage
|
||||||
|
|
||||||
from calibre import prints
|
from calibre import prints
|
||||||
from calibre.constants import iswindows
|
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):
|
class WebView(QWebView):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -235,10 +271,8 @@ class WebView(QWebView):
|
|||||||
settings.setAttribute(settings.LinksIncludedInFocusChain, False)
|
settings.setAttribute(settings.LinksIncludedInFocusChain, False)
|
||||||
settings.setAttribute(settings.DeveloperExtrasEnabled, True)
|
settings.setAttribute(settings.DeveloperExtrasEnabled, True)
|
||||||
settings.setDefaultTextEncoding('utf-8')
|
settings.setDefaultTextEncoding('utf-8')
|
||||||
|
self._page = WebPage(self)
|
||||||
self.page().setNetworkAccessManager(NetworkAccessManager(self))
|
self.setPage(self._page)
|
||||||
self.page().setLinkDelegationPolicy(self.page().DelegateAllLinks)
|
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
@ -274,12 +308,15 @@ class WebView(QWebView):
|
|||||||
|
|
||||||
class Preview(QWidget):
|
class Preview(QWidget):
|
||||||
|
|
||||||
|
sync_requested = pyqtSignal(object, object)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
self.l = l = QVBoxLayout()
|
self.l = l = QVBoxLayout()
|
||||||
self.setLayout(l)
|
self.setLayout(l)
|
||||||
l.setContentsMargins(0, 0, 0, 0)
|
l.setContentsMargins(0, 0, 0, 0)
|
||||||
self.view = WebView(self)
|
self.view = WebView(self)
|
||||||
|
self.view.page().sync_requested.connect(self.request_sync)
|
||||||
self.inspector = self.view.inspector
|
self.inspector = self.view.inspector
|
||||||
self.inspector.setPage(self.view.page())
|
self.inspector.setPage(self.view.page())
|
||||||
l.addWidget(self.view)
|
l.addWidget(self.view)
|
||||||
@ -305,6 +342,10 @@ class Preview(QWidget):
|
|||||||
self.refresh_timer.timeout.connect(self.refresh)
|
self.refresh_timer.timeout.connect(self.refresh)
|
||||||
parse_worker.start()
|
parse_worker.start()
|
||||||
|
|
||||||
|
def request_sync(self, lnum):
|
||||||
|
if self.current_name:
|
||||||
|
self.sync_requested.emit(self.current_name, lnum)
|
||||||
|
|
||||||
def show(self, name):
|
def show(self, name):
|
||||||
if name != self.current_name:
|
if name != self.current_name:
|
||||||
self.refresh_timer.stop()
|
self.refresh_timer.stop()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user