mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use the highlighted matching tags for Live CSS as a performance optimization
This commit is contained in:
parent
df15f6120a
commit
6a1f82320d
@ -1134,14 +1134,6 @@ class Boss(QObject):
|
||||
if name is not None and getattr(ed, 'syntax', None) == 'html':
|
||||
self.gui.preview.sync_to_editor(name, ed.current_tag())
|
||||
|
||||
def sync_live_css_to_editor(self):
|
||||
' Sync the Live CSS panel to the current cursor position in the current editor '
|
||||
ed = self.gui.central.current_editor
|
||||
if ed is not None:
|
||||
name = editor_name(ed)
|
||||
if name is not None and getattr(ed, 'syntax', None) == 'html':
|
||||
self.gui.live_css.sync_to_editor(name)
|
||||
|
||||
def goto_style_declaration(self, data):
|
||||
name = data['name']
|
||||
editor = self.edit_file(name, syntax=data['syntax'])
|
||||
@ -1152,12 +1144,13 @@ class Boss(QObject):
|
||||
editor.data_changed.connect(self.editor_data_changed)
|
||||
editor.copy_available_state_changed.connect(self.editor_copy_available_state_changed)
|
||||
editor.cursor_position_changed.connect(self.sync_preview_to_editor)
|
||||
editor.cursor_position_changed.connect(self.sync_live_css_to_editor)
|
||||
editor.cursor_position_changed.connect(self.update_cursor_position)
|
||||
if hasattr(editor, 'word_ignored'):
|
||||
editor.word_ignored.connect(self.word_ignored)
|
||||
if hasattr(editor, 'link_clicked'):
|
||||
editor.link_clicked.connect(self.editor_link_clicked)
|
||||
if getattr(editor, 'syntax', None) == 'html':
|
||||
editor.smart_highlighting_updated.connect(self.gui.live_css.sync_to_editor)
|
||||
if data is not None:
|
||||
if use_template:
|
||||
editor.init_from_template(data)
|
||||
@ -1284,7 +1277,6 @@ class Boss(QObject):
|
||||
# focused. This is not inefficient since multiple requests
|
||||
# to sync are de-bounced with a 100 msec wait.
|
||||
self.sync_preview_to_editor()
|
||||
self.sync_live_css_to_editor()
|
||||
if name is not None:
|
||||
self.gui.file_list.mark_name_as_current(name)
|
||||
if ed.has_line_numbers:
|
||||
|
@ -20,7 +20,7 @@ class NullSmarts(object):
|
||||
def verify_for_spellcheck(self, cursor, highlighter):
|
||||
return False
|
||||
|
||||
def cursor_position_with_sourceline(self, cursor):
|
||||
def cursor_position_with_sourceline(self, cursor, for_position_sync=True):
|
||||
return None, None
|
||||
|
||||
def goto_sourceline(self, editor, sourceline, tags, attribute=None):
|
||||
|
@ -270,6 +270,10 @@ def set_style_property(tag, property_name, value, editor):
|
||||
|
||||
class HTMLSmarts(NullSmarts):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
NullSmarts.__init__(self, *args, **kwargs)
|
||||
self.last_matched_tag = None
|
||||
|
||||
def get_extra_selections(self, editor):
|
||||
ans = []
|
||||
|
||||
@ -288,7 +292,7 @@ class HTMLSmarts(NullSmarts):
|
||||
|
||||
c = editor.textCursor()
|
||||
block, offset = c.block(), c.positionInBlock()
|
||||
tag = find_closest_containing_tag(block, offset, max_tags=2000)
|
||||
tag = self.last_matched_tag = find_closest_containing_tag(block, offset, max_tags=2000)
|
||||
if tag is not None:
|
||||
add_tag(tag)
|
||||
tag = find_closing_tag(tag, max_tags=4000)
|
||||
@ -391,13 +395,14 @@ class HTMLSmarts(NullSmarts):
|
||||
|
||||
return False
|
||||
|
||||
def cursor_position_with_sourceline(self, cursor, for_position_sync=True):
|
||||
def cursor_position_with_sourceline(self, cursor, for_position_sync=True, use_matched_tag=True):
|
||||
''' Return the tag just before the current cursor as a source line
|
||||
number and a list of tags defined on that line upto and including the
|
||||
containing tag. If ``for_position_sync`` is False then the tag
|
||||
*containing* the cursor is returned instead of the tag just before the
|
||||
cursor. Note that finding the containing tag is relative expensive, so
|
||||
use with care.'''
|
||||
cursor. Note that finding the containing tag is expensive, so
|
||||
use with care. As an optimization, the last tag matched by
|
||||
get_extra_selections is used, unless use_matched_tag is False. '''
|
||||
block, offset = cursor.block(), cursor.positionInBlock()
|
||||
if for_position_sync:
|
||||
nblock, boundary = next_tag_boundary(block, offset, forward=False)
|
||||
@ -417,7 +422,11 @@ class HTMLSmarts(NullSmarts):
|
||||
break
|
||||
block, offset = block.previous(), sys.maxint
|
||||
else:
|
||||
tag = find_closest_containing_tag(block, offset, max_tags=2000)
|
||||
tag = None
|
||||
if use_matched_tag:
|
||||
tag = self.last_matched_tag
|
||||
if tag is None:
|
||||
tag = find_closest_containing_tag(block, offset, max_tags=2000)
|
||||
if tag is None:
|
||||
return None, None
|
||||
start_block, start_offset = tag.start_block, tag.start_offset
|
||||
|
@ -132,6 +132,7 @@ class PlainTextEdit(QPlainTextEdit):
|
||||
class TextEdit(PlainTextEdit):
|
||||
|
||||
link_clicked = pyqtSignal(object)
|
||||
smart_highlighting_updated = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None, expected_geometry=(100, 50)):
|
||||
PlainTextEdit.__init__(self, parent)
|
||||
@ -274,6 +275,7 @@ class TextEdit(PlainTextEdit):
|
||||
sel.append(self.current_search_mark)
|
||||
if instant and not self.highlighter.has_requests:
|
||||
sel.extend(self.smarts.get_extra_selections(self))
|
||||
self.smart_highlighting_updated.emit()
|
||||
else:
|
||||
self.smarts_highlight_timer.start()
|
||||
self.setExtraSelections(sel)
|
||||
|
@ -107,6 +107,7 @@ class Editor(QMainWindow):
|
||||
cursor_position_changed = pyqtSignal()
|
||||
word_ignored = pyqtSignal(object, object)
|
||||
link_clicked = pyqtSignal(object)
|
||||
smart_highlighting_updated = pyqtSignal()
|
||||
|
||||
def __init__(self, syntax, parent=None):
|
||||
QMainWindow.__init__(self, parent)
|
||||
@ -129,6 +130,7 @@ class Editor(QMainWindow):
|
||||
self.editor.copyAvailable.connect(self._copy_available)
|
||||
self.editor.cursorPositionChanged.connect(self._cursor_position_changed)
|
||||
self.editor.link_clicked.connect(self.link_clicked)
|
||||
self.editor.smart_highlighting_updated.connect(self.smart_highlighting_updated)
|
||||
|
||||
@dynamic_property
|
||||
def current_line(self):
|
||||
@ -328,7 +330,7 @@ class Editor(QMainWindow):
|
||||
self.restore_state()
|
||||
|
||||
def break_cycles(self):
|
||||
for x in ('modification_state_changed', 'word_ignored', 'link_clicked'):
|
||||
for x in ('modification_state_changed', 'word_ignored', 'link_clicked', 'smart_highlighting_updated'):
|
||||
try:
|
||||
getattr(self, x).disconnect()
|
||||
except TypeError:
|
||||
@ -344,6 +346,7 @@ class Editor(QMainWindow):
|
||||
self.editor.copyAvailable.disconnect()
|
||||
self.editor.cursorPositionChanged.disconnect()
|
||||
self.editor.link_clicked.disconnect()
|
||||
self.editor.smart_highlighting_updated.disconnect()
|
||||
self.editor.setPlainText('')
|
||||
self.editor.smarts = None
|
||||
|
||||
|
@ -470,8 +470,8 @@ class LiveCSS(QWidget):
|
||||
actions['auto-reload-preview'].setEnabled(True)
|
||||
return QWidget.showEvent(self, ev)
|
||||
|
||||
def sync_to_editor(self, name):
|
||||
self.start_update_timer()
|
||||
def sync_to_editor(self):
|
||||
self.update_data()
|
||||
|
||||
def update_data(self):
|
||||
if not self.is_visible or self.preview_is_refreshing:
|
||||
|
Loading…
x
Reference in New Issue
Block a user