Skip to content
This repository was archived by the owner on Apr 3, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions OMEdit/OMEditGUI/Editors/BaseEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,11 @@ CompleterItem::CompleterItem(const QString &key, const QString &value, const QSt
}
}

CompleterItem::CompleterItem(const QString &key, const QString &value, const QString &select, const QString &description)
: mKey(key), mValue(value), mSelect(select), mDescription(description)
{
}

CompleterItem::CompleterItem(const QString &value, const QString &description)
: mKey(value), mValue(value), mSelect(value), mDescription(description)
{
Expand Down Expand Up @@ -1579,7 +1584,6 @@ void PlainTextEdit::insertCompletionItem(const QModelIndex &index)
QTextCursor cursor = textCursor();
cursor.beginEditBlock();
int extra = completionlength[0].length() - mpCompleter->completionPrefix().length();
cursor.movePosition(QTextCursor::EndOfWord);
cursor.insertText(completionlength[0].right(extra));
// store the cursor position to be used for selecting text when inserting code snippets
int currentpos = cursor.position();
Expand All @@ -1606,13 +1610,6 @@ void PlainTextEdit::insertCompletionItem(const QModelIndex &index)
setTextCursor(cursor);
}

QString PlainTextEdit::textUnderCursor() const
{
QTextCursor cursor = textCursor();
cursor.select(QTextCursor::WordUnderCursor);
return cursor.selectedText();
}

/*!
* \brief PlainTextEdit::keyPressEvent
* Reimplementation of keyPressEvent.
Expand Down Expand Up @@ -1721,7 +1718,7 @@ void PlainTextEdit::keyPressEvent(QKeyEvent *pEvent)

static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
bool hasModifier = (pEvent->modifiers() != Qt::NoModifier) && !ctrlOrShift;
QString completionPrefix = textUnderCursor();
QString completionPrefix = mpBaseEditor->wordUnderCursor();
if ((!isCompleterShortcut && !isCompleterChar) && (hasModifier || pEvent->text().isEmpty()|| completionPrefix.length() < 1 || eow.contains(pEvent->text().right(1)))) {
mpCompleter->popup()->hide();
return;
Expand Down Expand Up @@ -1977,6 +1974,16 @@ BaseEditor::BaseEditor(QWidget *pParent)
initialize();
}

/*!
* \brief BaseEditor::wordUnderCursor
*/
QString BaseEditor::wordUnderCursor()
{
QTextCursor cursor = mpPlainTextEdit->textCursor();
cursor.select(QTextCursor::WordUnderCursor);
return cursor.selectedText();
}

/*!
* \brief BaseEditor::initialize
* Initializes the editor with default values.
Expand Down
3 changes: 2 additions & 1 deletion OMEdit/OMEditGUI/Editors/BaseEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ class CompleterItem
public:
CompleterItem() {}
CompleterItem(const QString &key, const QString &value, const QString &select);
CompleterItem(const QString &key, const QString &value, const QString &select, const QString &description);
CompleterItem(const QString &value, const QString &description);
QString mKey;
QString mValue;
Expand Down Expand Up @@ -286,7 +287,6 @@ class PlainTextEdit : public QPlainTextEdit
void foldOrUnfold(bool unFold);
void handleHomeKey(bool keepAnchor);
void toggleBlockVisible(const QTextBlock &block);
QString textUnderCursor() const;
private slots:
void showCompletionItemToolTip(const QModelIndex & index);
void insertCompletionItem(const QModelIndex & index);
Expand Down Expand Up @@ -330,6 +330,7 @@ class BaseEditor : public QWidget
DocumentMarker* getDocumentMarker() {return mpDocumentMarker;}
void setForceSetPlainText(bool forceSetPlainText) {mForceSetPlainText = forceSetPlainText;}
virtual void popUpCompleter () = 0;
virtual QString wordUnderCursor();
private:
void initialize();
void createActions();
Expand Down
125 changes: 124 additions & 1 deletion OMEdit/OMEditGUI/Editors/ModelicaEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ void ModelicaEditor::popUpCompleter()
QString word = wordUnderCursor();
mpPlainTextEdit->clearCompleter();

if (!word.contains('.')) {
QList<CompleterItem> annotations;
getCompletionAnnotations(stringAfterWord("annotation"), annotations);

if (!word.contains('.') && annotations.empty()) {
QStringList keywords = ModelicaHighlighter::getKeywords();
mpPlainTextEdit->insertCompleterKeywords(keywords);
QStringList types = ModelicaHighlighter::getTypes();
Expand All @@ -93,6 +96,8 @@ void ModelicaEditor::popUpCompleter()
mpPlainTextEdit->insertCompleterSymbols(classes, ":/Resources/icons/completerClass.svg");
mpPlainTextEdit->insertCompleterSymbols(components, ":/Resources/icons/completerComponent.svg");

mpPlainTextEdit->insertCompleterSymbols(annotations, ":/Resources/icons/completerAnnotation.svg");

QCompleter *completer = mpPlainTextEdit->completer();
QRect cr = mpPlainTextEdit->cursorRect();
cr.setWidth(completer->popup()->sizeHintForColumn(0)+ completer->popup()->verticalScrollBar()->sizeHint().width());
Expand Down Expand Up @@ -151,6 +156,10 @@ QList<LibraryTreeItem*> ModelicaEditor::getCandidateContexts(QStringList nameCom
return result;
}

/*!
* \brief ModelicaEditor::wordUnderCursor
* \return
*/
QString ModelicaEditor::wordUnderCursor()
{
int end = mpPlainTextEdit->textCursor().position();
Expand All @@ -165,6 +174,22 @@ QString ModelicaEditor::wordUnderCursor()
return mpPlainTextEdit->document()->toPlainText().mid(begin, end - begin);
}

/*!
* \brief Returns the substring from the last occurrence of `word` to the cursor position
* \param word Starting word of the substring
* \return Resulting substring or Null QString if no `word` occurrence found up to the cursor position
*/
QString ModelicaEditor::stringAfterWord(const QString &word)
{
int pos = mpPlainTextEdit->textCursor().position();
QString plainText = mpPlainTextEdit->document()->toPlainText();
int index = plainText.lastIndexOf(word, pos);
if (index == -1)
return QString();
else
return plainText.mid(index, pos - index);
}

void ModelicaEditor::getCompletionSymbols(QString word, QList<CompleterItem> &classes, QList<CompleterItem> &components)
{
QStringList nameComponents = word.split('.');
Expand All @@ -183,6 +208,104 @@ void ModelicaEditor::getCompletionSymbols(QString word, QList<CompleterItem> &cl
}
}

/*!
* \brief Looks up the root for annotation auto completion information
*/
LibraryTreeItem *ModelicaEditor::getAnnotationCompletionRoot()
{
LibraryTreeItem *pLibraryRoot = MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->getRootLibraryTreeItem();
LibraryTreeItem *pModelicaReference = 0;

for (int i = 0; i < pLibraryRoot->childrenSize(); ++i) {
if (pLibraryRoot->childAt(i)->getName() == "OpenModelica")
pModelicaReference = pLibraryRoot->childAt(i);
}

if (pModelicaReference) {
return deepResolve(pModelicaReference, QStringList() << "AutoCompletion" << "Annotations");
} else {
return 0;
}
}

/*!
* \brief Returns a collection of completion items for the parsed `stack` of nested annotations
* \param stack A stack of nested annotations (f.e. "annotation(uses(Modelica(ver|" becomes ["uses", "Modelica"]
* \param annotations Resulting collection of compeltion items
*/
void ModelicaEditor::getCompletionAnnotations(const QStringList &stack, QList<CompleterItem> &annotations)
{
LibraryTreeItem *pReference = getAnnotationCompletionRoot();
if (pReference) {
LibraryTreeItem *pAnnotation = deepResolve(pReference, stack);
if (pAnnotation) {
for (int i = 0; i < pAnnotation->childrenSize(); ++i) {
QString name = pAnnotation->childAt(i)->getName();
annotations << CompleterItem(name, name + "(", name, pAnnotation->childAt(i)->getHTMLDescription());
}
QList<ComponentInfo *> components = pAnnotation->getComponentsList();
for (int i = 0; i < components.size(); ++i) {
QString componentName = components[i]->getName();
annotations << CompleterItem(componentName, componentName + " = ", componentName, components[i]->getHTMLDescription());
}
}
}
}

/*!
* \brief Resolves the annotation under cursor as a stack of nested names and returns completions
* \param str A string starting with the "annotation" word up to the cursor position
* \param annotations Resulting collection of completion items
*/
void ModelicaEditor::getCompletionAnnotations(const QString &str, QList<CompleterItem> &annotations)
{
QStringList stack;
int lastWordStart = 0;
bool insideWord = false;

if (str.isEmpty())
return;

for (int i = 0; i < str.size(); ++i) {
QChar ch = str[i];

// First, handle string literals
if (ch == '"') {
for (++i; i < str.size() && str[i] != '"'; ++i) {
if (str[i] == '\\')
++i;
}
// skipped, restarting as usual
--i;
continue;
}

// Now, handle the stack of annotations
if (ch == '(') {
stack << str.mid(lastWordStart, i - lastWordStart).trimmed();
}
if (ch == ')') {
if (stack.isEmpty()) {
return; // not in an annotation at all
}
stack.pop_back();
}

// Last, account for boundaries of words to be placed in stack
bool partOfLiteral = ch.isLetterOrNumber() || ch == '_';
if (!insideWord && partOfLiteral) {
lastWordStart = i;
}
insideWord = partOfLiteral;
}

if (stack.isEmpty()) {
return;
}
stack.pop_front(); // pop 'annotation'
getCompletionAnnotations(stack, annotations);
}

/*!
* \brief ModelicaEditor::getClassNames
* Uses the OMC parseString API to check the class names inside the Modelica Text
Expand Down
6 changes: 5 additions & 1 deletion OMEdit/OMEditGUI/Editors/ModelicaEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ class ModelicaEditor : public BaseEditor
void setTextChanged(bool changed) {mTextChanged = changed;}
bool isTextChanged() {return mTextChanged;}
virtual void popUpCompleter();
QString wordUnderCursor();
virtual QString wordUnderCursor();
QString stringAfterWord(const QString &word);
static LibraryTreeItem *deepResolve(LibraryTreeItem *pItem, QStringList nameComponents);
QList<LibraryTreeItem *> getCandidateContexts(QStringList nameComponents);
static void tryToCompleteInSingleContext(QStringList &result, LibraryTreeItem *pItem, QString lastPart);
void getCompletionSymbols(QString word, QList<CompleterItem> &classes, QList<CompleterItem> &components);
LibraryTreeItem *getAnnotationCompletionRoot();
void getCompletionAnnotations(const QStringList &stack, QList<CompleterItem> &annotations);
void getCompletionAnnotations(const QString &str, QList<CompleterItem> &annotations);
static QList<CompleterItem> getCodeSnippets();
private:
QString mLastValidText;
Expand Down
2 changes: 1 addition & 1 deletion OMEdit/OMEditGUI/Modeling/LibraryTreeWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,8 @@ void LibraryTreeItem::tryToComplete(QList<CompleterItem> &completionClasses, QLi
completionClasses << (CompleterItem(classes[i]->getName(), classes[i]->getHTMLDescription()));
}

const QList<ComponentInfo*> &components = baseClasses[bc]->getComponentsList();
if (!baseClasses[bc]->isRootItem() && baseClasses[bc]->getLibraryType() == LibraryTreeItem::Modelica) {
const QList<ComponentInfo*> &components = baseClasses[bc]->getComponentsList();
for (int i = 0; i < components.size(); ++i) {
if (components[i]->getName().startsWith(lastPart))
completionComponents << CompleterItem(components[i]->getName(), components[i]->getHTMLDescription() + QString("<br/>// Inside %1").arg(baseClasses[bc]->mNameStructure));
Expand Down
2 changes: 1 addition & 1 deletion OMEdit/OMEditGUI/Modeling/LibraryTreeWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ class LibraryTreeItem : public QObject
OMCInterface::getClassInformation_res mClassInformation;
SimulationOptions mSimulationOptions;
OMSSimulationOptions mOMSSimulationOptions;
const QList<ComponentInfo *> &getComponentsList();
private:
bool mIsRootItem;
LibraryTreeItem *mpParentLibraryTreeItem;
QList<LibraryTreeItem*> mChildren;
QList<LibraryTreeItem*> mInheritedClasses;
QList<ComponentInfo*> mComponents;
bool mComponentsLoaded;
const QList<ComponentInfo *> &getComponentsList();
LibraryType mLibraryType;
bool mSystemLibrary;
ModelWidget *mpModelWidget;
Expand Down
63 changes: 63 additions & 0 deletions OMEdit/OMEditGUI/Resources/icons/completerAnnotation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions OMEdit/OMEditGUI/resource_omedit.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,6 @@
<file>Resources/icons/instantiate.svg</file>
<file>Resources/icons/completerComponent.svg</file>
<file>Resources/icons/completerClass.svg</file>
<file>Resources/icons/completerAnnotation.svg</file>
</qresource>
</RCC>