Commit 46a1f81e authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Enabling advanced autocompletion

parent a09b255d
......@@ -350,6 +350,7 @@ class Signalroute(Connection):
def update_completion_list(self, pr_text):
''' Called after text has been edited '''
# TODO - call parseSingleElement, check sdlSymbols for examples
pass
def resize_item(self, new_rect):
......
......@@ -86,7 +86,7 @@ def _process(ast, scene, **_):
signal['name'] for signal in ast.input_signals}
sdlSymbols.Output.completion_list = {
signal['name'] for signal in ast.output_signals}
sdlSymbols.Task.completion_list = set(ast.variables.keys())
#sdlSymbols.Task.completion_list = set(ast.variables.keys())
sdlSymbols.ProcedureCall.completion_list = {
proc.inputString for proc in ast.procedures}
......
......@@ -14,7 +14,7 @@
Contact: maxime.perrotin@esa.int
"""
import string
import logging
from PySide.QtCore import Qt, QRegExp, Slot
......@@ -40,7 +40,7 @@ class Completer(QGraphicsProxyWidget, object):
self.setWidget(widget)
self.string_list = QStringListModel()
self._completer = QCompleter()
self.completion_list = parent.parentItem().completion_list
self.parent = parent
self._completer.setCaseSensitivity(Qt.CaseInsensitive)
# For some reason the default minimum size is (61,61)
# Set it to 0 so that the size of the box is not taken
......@@ -52,7 +52,8 @@ class Completer(QGraphicsProxyWidget, object):
def set_completer_list(self):
''' Set list of items for the autocompleter popup '''
self.string_list.setStringList(list(self.completion_list))
compl = list(self.parent.parentItem().completion_list)
self.string_list.setStringList(compl)
self._completer.setModel(self.string_list)
def set_completion_prefix(self, completion_prefix):
......@@ -165,6 +166,8 @@ class EditableText(QGraphicsTextItem, object):
# Increase the Z value of the text area so that the autocompleter
# always appear on top of text's siblings (parents's followers)
self.setZValue(1)
# context is used for advanced autocompletion
self.context = ''
# Set cursor when mouse goes over the text
self.setCursor(self.default_cursor)
# Activate cache mode to boost rendering by calling paint less often
......@@ -242,6 +245,31 @@ class EditableText(QGraphicsTextItem, object):
self.completer.hide()
self.try_resize()
def context_completion_list(self):
''' Advanced context-dependent autocompletion for SEQUENCE fields '''
# Select text from the begining of a line to the cursor position
# Then keep the last word including separators ('!' and '.')
# This word (e.g. variable!field!subfield) is then used to update
# the autocompletion list.
cursor = self.textCursor()
pos = cursor.positionInBlock() - 1
cursor.select(QTextCursor.BlockUnderCursor)
context = self.context
try:
# If not the first line of the text, Qt adds u+2029 as 1st char
line = cursor.selectedText().replace(u'\u2029', '')
if line[pos] in string.ascii_letters + '!' + '.' + '_':
self.context = line[slice(0, pos + 1)].split()[-1]
else:
self.context = ''
except IndexError:
pass
if context != self.context:
#print 'refreshing list with', self.context.encode('utf-8')
self.completer.set_completer_list()
# pylint: disable=C0103
def keyPressEvent(self, event):
'''
......@@ -263,23 +291,7 @@ class EditableText(QGraphicsTextItem, object):
text_cursor.select(QTextCursor.WordUnderCursor)
self.completion_prefix = text_cursor.selectedText()
# Work in progress - to support advanced autocompletion
tmp = self.textCursor()
pos = tmp.positionInBlock()
tmp.select(QTextCursor.BlockUnderCursor)
try:
import string
line = tmp.selectedText()
if line[pos] in string.ascii_letters + '!' + '.' + '_':
last_word = line[slice(0, pos + 1)].split()[-1]
else:
last_word = ''
except IndexError:
pass
else:
pass
# print last_word.encode('utf-8')
# -- END
self.context_completion_list()
completion_count = self.completer.set_completion_prefix(
self.completion_prefix)
......@@ -377,6 +389,7 @@ class EditableText(QGraphicsTextItem, object):
# Some parents may not be selectable (e.g. Signalroute)
pass
# Update completer list of keywords
self.context = ''
self.completer.set_completer_list()
# Clear selection otherwise the "Delete" key may delete other items
self.scene().clearSelection()
......
......@@ -29,6 +29,7 @@ from itertools import chain
# Added to please py2exe - NOQA makes flake8 ignore the following lines:
# pylint: disable=W0611
import enum # NOQA
import string # NOQA
import fnmatch # NOQA
import operator # NOQA
import subprocess # NOQA
......@@ -1389,7 +1390,8 @@ class SDL_View(QtGui.QGraphicsView, object):
self.scene().undo_stack.clear()
# Emit a signal for the application to update the ASN.1 scene
self.update_asn1_dock.emit(ast)
#return ast
# Set AST to be used as data dictionnary and updated on the fly
sdlSymbols.AST = ast
def open_diagram(self):
''' Load one or several .pr file and display the state machine '''
......
......@@ -37,6 +37,7 @@ import ogAST
LOG = logging.getLogger('sdlSymbols')
AST = ogAST.AST()
# SDL-specific: reserved keywords, to be highlighted in textboxes
# Two kind of formatting are possible: black bold, and red bold
......@@ -481,7 +482,7 @@ class Task(VerticalSymbol):
# Define reserved keywords for the syntax highlighter
blackbold = SDL_BLACKBOLD
redbold = SDL_REDBOLD
completion_list = set()
#completion_list = set()
def __init__(self, parent=None, ast=None):
''' Initializes the TASK symbol '''
......@@ -506,6 +507,16 @@ class Task(VerticalSymbol):
self.setPath(path)
super(Task, self).set_shape(width, height)
@property
def completion_list(self):
''' Dynamically set completion list depending on current context '''
# Need access to the AST
try:
print self.text.context.encode('utf-8')
except AttributeError:
pass # text not set yet
return ['hello', 'world']
# pylint: disable=R0904
class ProcedureCall(VerticalSymbol):
......@@ -575,7 +586,7 @@ class TextSymbol(HorizontalSymbol):
''' When text was entered, update TASK completion list '''
# Get AST for the symbol
ast, _, _, _, _ = self.parser.parseSingleElement('text_area', pr_text)
Task.completion_list |= {dcl for dcl in ast.variables.keys()}
#Task.completion_list |= {dcl for dcl in ast.variables.keys()}
def set_shape(self, width, height):
''' Define the polygon of the text symbol '''
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment