mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Wire up the split in preview button (not yet implemented)
This commit is contained in:
parent
cf3d54c2d2
commit
9415af8e1e
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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')
|
||||
|
Loading…
x
Reference in New Issue
Block a user