Skip to content

Commit

Permalink
Implement navigation to inline style attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
kovidgoyal committed May 21, 2014
1 parent 35d3531 commit 062d38a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/calibre/gui2/tweak_book/editor/smart/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ def verify_for_spellcheck(self, cursor, highlighter):
def cursor_position_with_sourceline(self, cursor):
return None, None

def goto_sourceline(self, editor, sourceline, tags, attribute=None):
return False
50 changes: 49 additions & 1 deletion src/calibre/gui2/tweak_book/editor/smart/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from calibre import prepare_string_for_xml
from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END
from calibre.gui2.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END, ATTR_START, ATTR_VALUE

get_offset = itemgetter(0)
PARAGRAPH_SEPARATOR = '\u2029'
Expand Down Expand Up @@ -117,6 +117,28 @@ def find_containing_attribute(block, offset):
return boundary.data
return None

def find_attribute_in_tag(block, offset, attr_name):
end_block, boundary = next_tag_boundary(block, offset)
if boundary.is_start:
return None, None
end_offset = boundary.offset
end_pos = (end_block.blockNumber(), end_offset)
current_block, current_offset = block, offset
found_attr = False
while True:
current_block, boundary = next_attr_boundary(current_block, current_offset)
if current_block is None or (current_block.blockNumber(), boundary.offset) > end_pos:
return None, None
current_offset = boundary.offset
if found_attr:
if boundary.type is not ATTR_VALUE or boundary.data is not ATTR_START:
return None, None
return current_block, current_offset
else:
if boundary.type is ATTR_NAME and boundary.data.lower() == attr_name.lower():
found_attr = True
current_offset += 1

def find_closing_tag(tag, max_tags=sys.maxint):
''' Find the closing tag corresponding to the specified tag. To find it we
search for the first closing tag after the specified tag that does not
Expand Down Expand Up @@ -335,3 +357,29 @@ def cursor_position_with_sourceline(self, cursor):
return None, None
all_tags = [t.name for t in ud.tags if (t.is_start and not t.closing and t.offset <= start_offset)]
return sourceline, all_tags

def goto_sourceline(self, editor, sourceline, tags, attribute=None):
''' Move the cursor to the tag identified by sourceline and tags (a
list of tags names on the specified line). If attribute is specified
the cursor will be placed at the start of the attribute value. '''
block = editor.document().findBlockByNumber(sourceline - 1) # blockNumber() is zero based
found_tag = False
if not block.isValid():
return found_tag
c = editor.textCursor()
ud = block.userData()
all_tags = [] if ud is None else [t for t in ud.tags if (t.is_start and not t.closing)]
tag_names = [t.name for t in all_tags]
if tag_names[:len(tags)] == tags:
c.setPosition(block.position() + all_tags[len(tags)-1].offset)
found_tag = True
else:
c.setPosition(block.position())
if found_tag and attribute is not None:
start_offset = c.position() - block.position()
nblock, offset = find_attribute_in_tag(block, start_offset, attribute)
if nblock is not None:
c.setPosition(nblock.position() + offset)
editor.setTextCursor(c)
return found_tag

3 changes: 3 additions & 0 deletions src/calibre/gui2/tweak_book/editor/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,3 +752,6 @@ def rename_block_tag(self, new_name):
def current_tag(self):
return self.smarts.cursor_position_with_sourceline(self.textCursor())

def goto_sourceline(self, sourceline, tags, attribute=None):
return self.smarts.goto_sourceline(self, sourceline, tags, attribute=attribute)

3 changes: 3 additions & 0 deletions src/calibre/gui2/tweak_book/editor/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,9 @@ def show_context_menu(self, pos):
m.addAction(actions['multisplit'])
m.exec_(self.editor.mapToGlobal(pos))

def goto_sourceline(self, *args, **kwargs):
return self.editor.goto_sourceline(*args, **kwargs)

def _nuke_word(self, dic, word, locale):
if dic is None:
dictionaries.ignore_word(word, locale)
Expand Down
8 changes: 5 additions & 3 deletions src/calibre/gui2/tweak_book/live_css.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def mousePressEvent(self, ev):
pos = ev.pos()
if self.hyperlink_rect.contains(pos):
self.emit_hyperlink_activated()
return QWidget.mouseMoveEvent(self, ev)
return QWidget.mousePressEvent(self, ev)

def emit_hyperlink_activated(self):
dt = self.data['type']
Expand Down Expand Up @@ -316,7 +316,7 @@ def __init__(self, preview, parent=None):
s.addWidget(la)

self.box = box = Box(self)
box.hyperlink_activated.connect(self.goto_declaration)
box.hyperlink_activated.connect(self.goto_declaration, type=Qt.QueuedConnection)
self.scroll = sc = QScrollArea(self)
sc.setWidget(box)
sc.setWidgetResizable(True)
Expand Down Expand Up @@ -409,5 +409,7 @@ def stop_update_timer(self):
self.update_timer.stop()

def navigate_to_declaration(self, data, editor):
print (data) # TODO: Implement this
if data['type'] == 'inline':
sourceline, tags = data['sourceline_address']
editor.goto_sourceline(sourceline, tags, attribute='style')

0 comments on commit 062d38a

Please sign in to comment.