Wire up the split in preview button (not yet implemented)

This commit is contained in:
Kovid Goyal 2013-11-20 17:02:18 +05:30
parent cf3d54c2d2
commit 9415af8e1e
4 changed files with 120 additions and 11 deletions

View File

@ -17,6 +17,21 @@ is_hidden = (elem) ->
elem = elem.parentNode
return false
previous_sibling = (node) ->
node = node.previousSibling
while node and node.nodeType != Node.ELEMENT_NODE
node = node.previousSibling
return node
is_block = (elem) ->
style = window.getComputedStyle(elem)
return style.display in ['block', 'flex-box', 'box']
find_containing_block = (elem) ->
while elem and elem.getAttribute('data-is-block') != '1'
elem = elem.parentNode
return elem
class PreviewIntegration
###
@ -27,18 +42,20 @@ class PreviewIntegration
constructor: () ->
if not this instanceof arguments.callee
throw new Error('PreviewIntegration constructor called as function')
this.blocks_found = false
this.in_split_mode = false
go_to_line: (lnum) ->
go_to_line: (lnum) =>
for node in document.querySelectorAll('[data-lnum="' + lnum + '"]')
if is_hidden(node)
continue
top = window.calibre_utils.abstop(node) - (window.innerHeight / 2)
if (top < 0)
if top < 0
top = 0
window.scrollTo(0, top)
return
line_numbers: () ->
line_numbers: () =>
found_body = false
ans = []
for node in document.getElementsByTagName('*')
@ -49,18 +66,43 @@ class PreviewIntegration
return ans
find_blocks: () =>
if this.blocks_found
return
for elem in document.body.getElementsByTagName('*')
style = window.getComputedStyle(elem)
if style.display in ['block', 'flex-box', 'box']
if is_block(elem)
elem.setAttribute('data-is-block', '1')
elem.onclick = this.onclick
this.blocks_found = true
onload: () ->
window.document.body.addEventListener('click', window.calibre_preview_integration.onclick, true)
split_mode: (enabled) =>
this.in_split_mode = enabled
document.body.setAttribute('data-in-split-mode', if enabled then '1' else '0')
if enabled
this.find_blocks()
onclick: (event) ->
report_split: (node) =>
loc = []
parent = find_containing_block(node)
while parent and parent.tagName.toLowerCase() != 'body'
num = 0
sibling = previous_sibling(parent)
while sibling
num += 1
sibling = previous_sibling(sibling)
loc.push(num)
parent = parent.parentNode
loc.reverse()
window.py_bridge.request_split(loc)
onload: () =>
window.document.body.addEventListener('click', this.onclick, true)
onclick: (event) =>
event.preventDefault()
window.py_bridge.request_sync(event.target.getAttribute("data-lnum"))
if this.in_split_mode
this.report_split(event.target)
else
window.py_bridge.request_sync(event.target.getAttribute("data-lnum"))
return false
window.calibre_preview_integration = new PreviewIntegration()
window.onload = window.calibre_preview_integration.onload

View File

@ -57,6 +57,7 @@ class Boss(QObject):
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)
self.gui.preview.split_start_requested.connect(self.split_start_requested)
def mkdtemp(self, prefix=''):
self.container_count += 1
@ -502,6 +503,11 @@ class Boss(QObject):
if ok:
ed.current_line = num
def split_start_requested(self):
if not self.check_dirtied():
return self.gui.preview.stop_split()
self.gui.preview.do_start_split()
def sync_editor_to_preview(self, name, lnum):
editor = self.edit_file(name, 'html')
self.ignore_preview_to_editor_sync = True

View File

@ -6,8 +6,9 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
import time
import time, textwrap
from bisect import bisect_right
from base64 import b64encode
from future_builtins import map
from threading import Thread
from Queue import Queue, Empty
@ -23,6 +24,7 @@ from calibre.constants import iswindows, DEBUG
from calibre.ebooks.oeb.polish.parsing import parse
from calibre.ebooks.oeb.base import serialize, OEB_DOCS
from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book import current_container, editors, tprefs, actions
from calibre.gui2.viewer.documentview import apply_settings
from calibre.gui2.viewer.config import config
@ -237,6 +239,7 @@ def find_le(a, x):
class WebPage(QWebPage):
sync_requested = pyqtSignal(object)
split_requested = pyqtSignal(object)
def __init__(self, parent):
QWebPage.__init__(self, parent)
@ -251,6 +254,10 @@ class WebPage(QWebPage):
settings.setAttribute(settings.LinksIncludedInFocusChain, False)
settings.setAttribute(settings.DeveloperExtrasEnabled, True)
settings.setDefaultTextEncoding('utf-8')
data = 'data:text/css;charset=utf-8;base64,'
css = '[data-in-split-mode="1"] [data-is-block="1"]:hover { cursor: pointer !important; border-top: solid 5px green !important }'
data += b64encode(css.encode('utf-8'))
settings.setUserStyleSheetUrl(QUrl(data))
self.setNetworkAccessManager(NetworkAccessManager(self))
self.setLinkDelegationPolicy(self.DelegateAllLinks)
@ -277,6 +284,14 @@ class WebPage(QWebPage):
except (TypeError, ValueError, OverflowError, AttributeError):
pass
@pyqtSlot('QList<int>')
def request_split(self, loc):
actions['split-in-preview'].setChecked(False)
if not loc:
return error_dialog(self.view(), _('Invalid location'),
_('Cannot split on the body tag'), show=True)
self.split_requested.emit(loc)
@property
def line_numbers(self):
if self._line_numbers is None:
@ -297,6 +312,12 @@ class WebPage(QWebPage):
self.mainFrame().evaluateJavaScript(
'window.calibre_preview_integration.go_to_line(%d)' % lnum)
def split_mode(self, enabled):
self.mainFrame().evaluateJavaScript(
'window.calibre_preview_integration.split_mode(%s)' % (
'true' if enabled else 'false'))
class WebView(QWebView):
def __init__(self, parent=None):
@ -343,6 +364,8 @@ class WebView(QWebView):
class Preview(QWidget):
sync_requested = pyqtSignal(object, object)
split_requested = pyqtSignal(object, object)
split_start_requested = pyqtSignal()
def __init__(self, parent=None):
QWidget.__init__(self, parent)
@ -351,6 +374,8 @@ class Preview(QWidget):
l.setContentsMargins(0, 0, 0, 0)
self.view = WebView(self)
self.view.page().sync_requested.connect(self.request_sync)
self.view.page().split_requested.connect(self.request_split)
self.view.page().loadFinished.connect(self.load_finished)
self.inspector = self.view.inspector
self.inspector.setPage(self.view.page())
l.addWidget(self.view)
@ -373,6 +398,13 @@ class Preview(QWidget):
self.bar.addSeparator()
ac = actions['split-in-preview']
ac.setCheckable(True)
ac.setChecked(False)
ac.toggled.connect(self.split_toggled)
self.split_toggled(ac.isChecked())
self.bar.addAction(ac)
ac = actions['reload-preview']
ac.triggered.connect(self.refresh)
self.bar.addAction(ac)
@ -390,6 +422,10 @@ class Preview(QWidget):
if self.current_name:
self.sync_requested.emit(self.current_name, lnum)
def request_split(self, loc):
if self.current_name:
self.split_requested.emit(self.current_name, loc)
def sync_to_editor(self, name, lnum):
self.current_sync_request = (name, lnum)
QTimer.singleShot(100, self._sync_to_editor)
@ -455,3 +491,26 @@ class Preview(QWidget):
if is_visible:
self.refresh()
def split_toggled(self, checked):
actions['split-in-preview'].setToolTip(textwrap.fill(_(
'Abort file split') if checked else _(
'Split this file at a specified location.\n\nAfter clicking this button, click'
' inside the preview panel above at the location you want the file to be split.')))
if checked:
self.split_start_requested.emit()
else:
self.view.page().split_mode(False)
def do_start_split(self):
self.view.page().split_mode(True)
def stop_split(self):
actions['split-in-preview'].setChecked(False)
def load_finished(self, ok):
if actions['split-in-preview'].isChecked():
if ok:
self.do_start_split()
else:
self.stop_split()

View File

@ -223,6 +223,8 @@ class Main(MainWindow):
self.action_auto_sync_preview = reg('sync-right.png', _('Sync preview position to editor position'), None, 'sync-preview-to-editor', (), _(
'Sync preview position to editor position'))
self.action_reload_preview = reg('view-refresh.png', _('Refresh preview'), None, 'reload-preview', ('F5',), _('Refresh preview'))
self.action_split_in_preview = reg('auto_author_sort.png', _('Split this file'), None, 'split-in-preview', (), _(
'Split file in the preview panel'))
# Search actions
group = _('Search')