mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Wire up the completion worker into the editor widget
This commit is contained in:
parent
dedd6c84aa
commit
8943e2883c
@ -83,7 +83,8 @@ class Boss(QObject):
|
|||||||
setup_cssutils_serialization()
|
setup_cssutils_serialization()
|
||||||
_boss = self
|
_boss = self
|
||||||
self.gui = parent
|
self.gui = parent
|
||||||
completion_worker()
|
completion_worker().result_callback = self.handle_completion_result
|
||||||
|
self.completion_request_count = 0
|
||||||
|
|
||||||
def __call__(self, gui):
|
def __call__(self, gui):
|
||||||
self.gui = gui
|
self.gui = gui
|
||||||
@ -671,6 +672,17 @@ class Boss(QObject):
|
|||||||
' Mark the book as having been modified '
|
' Mark the book as having been modified '
|
||||||
self.gui.action_save.setEnabled(True)
|
self.gui.action_save.setEnabled(True)
|
||||||
|
|
||||||
|
def request_completion(self, name, completion_type, completion_data, query=None):
|
||||||
|
request_id = (self.completion_request_count, name)
|
||||||
|
self.completion_request_count += 1
|
||||||
|
completion_worker().queue_completion(request_id, completion_type, completion_data, query)
|
||||||
|
|
||||||
|
def handle_completion_result(self, result):
|
||||||
|
name = result.request_id[1]
|
||||||
|
editor = editors.get(name)
|
||||||
|
if editor is not None:
|
||||||
|
editor.handle_completion_result(result)
|
||||||
|
|
||||||
def fix_html(self, current):
|
def fix_html(self, current):
|
||||||
if current:
|
if current:
|
||||||
ed = self.gui.central.current_editor
|
ed = self.gui.central.current_editor
|
||||||
@ -1164,6 +1176,8 @@ class Boss(QObject):
|
|||||||
editor.link_clicked.connect(self.editor_link_clicked)
|
editor.link_clicked.connect(self.editor_link_clicked)
|
||||||
if getattr(editor, 'syntax', None) == 'html':
|
if getattr(editor, 'syntax', None) == 'html':
|
||||||
editor.smart_highlighting_updated.connect(self.gui.live_css.sync_to_editor)
|
editor.smart_highlighting_updated.connect(self.gui.live_css.sync_to_editor)
|
||||||
|
if hasattr(editor, 'set_request_completion'):
|
||||||
|
editor.set_request_completion(partial(self.request_completion, name), name)
|
||||||
if data is not None:
|
if data is not None:
|
||||||
if use_template:
|
if use_template:
|
||||||
editor.init_from_template(data)
|
editor.init_from_template(data)
|
||||||
|
@ -79,7 +79,7 @@ class HandleDataRequest(QObject):
|
|||||||
|
|
||||||
# Ensure data is obtained in the GUI thread
|
# Ensure data is obtained in the GUI thread
|
||||||
|
|
||||||
call = pyqtSignal(object, object, object)
|
call = pyqtSignal(object, object)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
QObject.__init__(self)
|
QObject.__init__(self)
|
||||||
|
@ -33,3 +33,6 @@ class NullSmarts(object):
|
|||||||
|
|
||||||
def handle_key_press(self, ev, editor):
|
def handle_key_press(self, ev, editor):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_completion_data(self, editor, ev=None):
|
||||||
|
return None
|
||||||
|
@ -16,7 +16,7 @@ from calibre import prepare_string_for_xml, xml_entity_to_unicode
|
|||||||
from calibre.gui2 import error_dialog
|
from calibre.gui2 import error_dialog
|
||||||
from calibre.gui2.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END, ATTR_START, ATTR_VALUE
|
from calibre.gui2.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END, ATTR_START, ATTR_VALUE
|
||||||
from calibre.utils.icu import utf16_length
|
from calibre.utils.icu import utf16_length
|
||||||
from calibre.gui2.tweak_book import tprefs
|
from calibre.gui2.tweak_book import tprefs, current_container
|
||||||
from calibre.gui2.tweak_book.editor.smarts import NullSmarts
|
from calibre.gui2.tweak_book.editor.smarts import NullSmarts
|
||||||
from calibre.gui2.tweak_book.editor.smarts.utils import (
|
from calibre.gui2.tweak_book.editor.smarts.utils import (
|
||||||
no_modifiers, get_leading_whitespace_on_block, get_text_before_cursor,
|
no_modifiers, get_leading_whitespace_on_block, get_text_before_cursor,
|
||||||
@ -288,6 +288,7 @@ class Smarts(NullSmarts):
|
|||||||
Smarts.closing_tag_pat = re.compile(r'<\s*/[^>]+>')
|
Smarts.closing_tag_pat = re.compile(r'<\s*/[^>]+>')
|
||||||
Smarts.closing_pat = re.compile(r'<\s*/')
|
Smarts.closing_pat = re.compile(r'<\s*/')
|
||||||
Smarts.self_closing_pat = re.compile(r'/\s*>')
|
Smarts.self_closing_pat = re.compile(r'/\s*>')
|
||||||
|
Smarts.complete_attr_pat = re.compile(r'''([a-zA-Z0-9_-]+)\s*=\s*(?:'([^']+)|"([^"]+))$''')
|
||||||
NullSmarts.__init__(self, *args, **kwargs)
|
NullSmarts.__init__(self, *args, **kwargs)
|
||||||
self.last_matched_tag = None
|
self.last_matched_tag = None
|
||||||
|
|
||||||
@ -625,7 +626,29 @@ class Smarts(NullSmarts):
|
|||||||
editor.setTextCursor(c)
|
editor.setTextCursor(c)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def get_completion_data(self, editor, ev=None):
|
||||||
|
c = editor.textCursor()
|
||||||
|
block, offset = c.block(), c.positionInBlock()
|
||||||
|
oblock, boundary = next_tag_boundary(block, offset, forward=False)
|
||||||
|
if boundary is None or not boundary.is_start or boundary.closing:
|
||||||
|
# Not inside a opening tag definition
|
||||||
|
return
|
||||||
|
tagname = boundary.name.lower()
|
||||||
|
startpos = oblock.position() + boundary.offset
|
||||||
|
c.setPosition(c.position()), c.setPosition(startpos, c.KeepAnchor)
|
||||||
|
text = c.selectedText()
|
||||||
|
m = self.complete_attr_pat.search(text)
|
||||||
|
if m is None:
|
||||||
|
return
|
||||||
|
attr = m.group(1).lower().split(':')[-1]
|
||||||
|
doc_name = editor.highlighter.doc_name
|
||||||
|
if doc_name and attr in {'href', 'src'}:
|
||||||
|
# A link
|
||||||
|
query = m.group(2) or m.group(3)
|
||||||
|
names_type = {'a':'text_link', 'img':'image', 'image':'image', 'link':'stylesheet'}.get(tagname)
|
||||||
|
return 'complete_names', (names_type, doc_name, current_container().root), query
|
||||||
|
|
||||||
|
if __name__ == '__main__': # {{{
|
||||||
from calibre.gui2.tweak_book.editor.widget import launch_editor
|
from calibre.gui2.tweak_book.editor.widget import launch_editor
|
||||||
launch_editor('''\
|
launch_editor('''\
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -657,3 +680,4 @@ if __name__ == '__main__':
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
''', path_is_raw=True, syntax='xml')
|
''', path_is_raw=True, syntax='xml')
|
||||||
|
# }}}
|
||||||
|
@ -19,6 +19,7 @@ from PyQt5.Qt import (
|
|||||||
from calibre import prepare_string_for_xml
|
from calibre import prepare_string_for_xml
|
||||||
from calibre.constants import isosx
|
from calibre.constants import isosx
|
||||||
from calibre.gui2.tweak_book import tprefs, TOP
|
from calibre.gui2.tweak_book import tprefs, TOP
|
||||||
|
from calibre.gui2.tweak_book.completion.popup import CompletionPopup
|
||||||
from calibre.gui2.tweak_book.editor import (
|
from calibre.gui2.tweak_book.editor import (
|
||||||
SYNTAX_PROPERTY, SPELL_PROPERTY, SPELL_LOCALE_PROPERTY, store_locale, LINK_PROPERTY)
|
SYNTAX_PROPERTY, SPELL_PROPERTY, SPELL_LOCALE_PROPERTY, store_locale, LINK_PROPERTY)
|
||||||
from calibre.gui2.tweak_book.editor.themes import get_theme, theme_color, theme_format
|
from calibre.gui2.tweak_book.editor.themes import get_theme, theme_color, theme_format
|
||||||
@ -138,6 +139,8 @@ class TextEdit(PlainTextEdit):
|
|||||||
|
|
||||||
def __init__(self, parent=None, expected_geometry=(100, 50)):
|
def __init__(self, parent=None, expected_geometry=(100, 50)):
|
||||||
PlainTextEdit.__init__(self, parent)
|
PlainTextEdit.__init__(self, parent)
|
||||||
|
self.completion_popup = CompletionPopup(self)
|
||||||
|
self.request_completion = self.completion_doc_name = None
|
||||||
self.gutter_width = 0
|
self.gutter_width = 0
|
||||||
self.tw = 2
|
self.tw = 2
|
||||||
self.expected_geometry = expected_geometry
|
self.expected_geometry = expected_geometry
|
||||||
@ -769,8 +772,21 @@ class TextEdit(PlainTextEdit):
|
|||||||
ev.setAccepted(False)
|
ev.setAccepted(False)
|
||||||
return
|
return
|
||||||
if self.smarts.handle_key_press(ev, self):
|
if self.smarts.handle_key_press(ev, self):
|
||||||
|
self.handle_keypress_completion(ev)
|
||||||
return
|
return
|
||||||
QPlainTextEdit.keyPressEvent(self, ev)
|
QPlainTextEdit.keyPressEvent(self, ev)
|
||||||
|
self.handle_keypress_completion(ev)
|
||||||
|
|
||||||
|
def handle_keypress_completion(self, ev):
|
||||||
|
if self.request_completion is None:
|
||||||
|
return
|
||||||
|
result = self.smarts.get_completion_data(self, ev)
|
||||||
|
if result is None:
|
||||||
|
return
|
||||||
|
self.request_completion(*result)
|
||||||
|
|
||||||
|
def handle_completion_result(self, result):
|
||||||
|
print (result)
|
||||||
|
|
||||||
def replace_possible_unicode_sequence(self):
|
def replace_possible_unicode_sequence(self):
|
||||||
c = self.textCursor()
|
c = self.textCursor()
|
||||||
|
@ -173,6 +173,7 @@ class Editor(QMainWindow):
|
|||||||
|
|
||||||
def change_document_name(self, newname):
|
def change_document_name(self, newname):
|
||||||
self.editor.change_document_name(newname)
|
self.editor.change_document_name(newname)
|
||||||
|
self.editor.completion_doc_name = newname
|
||||||
|
|
||||||
def get_raw_data(self):
|
def get_raw_data(self):
|
||||||
# The EPUB spec requires NFC normalization, see section 1.3.6 of
|
# The EPUB spec requires NFC normalization, see section 1.3.6 of
|
||||||
@ -220,6 +221,13 @@ class Editor(QMainWindow):
|
|||||||
tprefs['insert_tag_mru'] = mru
|
tprefs['insert_tag_mru'] = mru
|
||||||
self._build_insert_tag_button_menu()
|
self._build_insert_tag_button_menu()
|
||||||
|
|
||||||
|
def set_request_completion(self, callback=None, doc_name=None):
|
||||||
|
self.editor.request_completion = callback
|
||||||
|
self.editor.completion_doc_name = doc_name
|
||||||
|
|
||||||
|
def handle_completion_result(self, result):
|
||||||
|
return self.editor.handle_completion_result(result)
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
self.editor.undo()
|
self.editor.undo()
|
||||||
|
|
||||||
@ -367,6 +375,7 @@ class Editor(QMainWindow):
|
|||||||
self.editor.smart_highlighting_updated.disconnect()
|
self.editor.smart_highlighting_updated.disconnect()
|
||||||
self.editor.setPlainText('')
|
self.editor.setPlainText('')
|
||||||
self.editor.smarts = None
|
self.editor.smarts = None
|
||||||
|
self.editor.request_completion = None
|
||||||
|
|
||||||
def _modification_state_changed(self):
|
def _modification_state_changed(self):
|
||||||
self.is_synced_to_container = self.is_modified
|
self.is_synced_to_container = self.is_modified
|
||||||
|
Loading…
x
Reference in New Issue
Block a user