Skip to content

Commit

Permalink
Show meaningful descriptions for autocompleted classes and components
Browse files Browse the repository at this point in the history
  • Loading branch information
atrosinenko authored and adeas31 committed Feb 4, 2019
1 parent ce509a3 commit 502f86f
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 22 deletions.
6 changes: 6 additions & 0 deletions OMEdit/OMEditGUI/Component/Component.cpp
Expand Up @@ -393,6 +393,12 @@ bool ComponentInfo::operator!=(const ComponentInfo &componentInfo) const
return !operator==(componentInfo);
}

QString ComponentInfo::getHTMLDescription() const
{
return QString("<b>%1</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;%2 <i>\"%3\"<i>")
.arg(mClassName, mName, Utilities::escapeForHtmlNonSecure(mComment));
}

/*!
* \brief ComponentInfo::isModiferClassRecord
* Returns true if a modifier class is a record.
Expand Down
1 change: 1 addition & 0 deletions OMEdit/OMEditGUI/Component/Component.h
Expand Up @@ -127,6 +127,7 @@ class ComponentInfo : public QObject
// operator overloading
bool operator==(const ComponentInfo &componentInfo) const;
bool operator!=(const ComponentInfo &componentInfo) const;
QString getHTMLDescription() const;
private:
QString mClassName;
QString mName;
Expand Down
29 changes: 21 additions & 8 deletions OMEdit/OMEditGUI/Editors/BaseEditor.cpp
Expand Up @@ -754,24 +754,37 @@ bool PlainTextEdit::eventFilter(QObject *pObject, QEvent *pEvent)
* The constructor is set from outside depending on which editor is used (eg.) MetaModelicaEditor,
* ModelicaEditor,CEditor etc..
*/
CompleterItem::CompleterItem(QString key, QString value, QString select)
CompleterItem::CompleterItem(const QString &key, const QString &value, const QString &select)
: mKey(key), mValue(value), mSelect(select)
{
int ind = value.indexOf(select, 0);
if (ind < 0) {
mDescription = value;
} else {
mDescription = QString("<b>%1</b><i>%2</i>%3").arg(
QStringRef(&value).left(ind).toString(),
select,
QStringRef(&value).right(value.size() - select.size() - ind).toString()
).replace("\n", "<br/>");
}
}

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

void PlainTextEdit::clearCompleter()
{
mpStandardItemModel->clear();
}

void PlainTextEdit::insertCompleterSymbols(QStringList symbols)
void PlainTextEdit::insertCompleterSymbols(QList<CompleterItem> symbols)
{
for (int i = 0; i < symbols.size(); ++i) {
QStandardItem *pStandardItem = new QStandardItem(symbols[i]);
QStandardItem *pStandardItem = new QStandardItem(symbols[i].mKey);
pStandardItem->setIcon(QIcon(":/Resources/icons/completerSymbol.svg"));
pStandardItem->setData(QVariant::fromValue(CompleterItem(symbols[i], symbols[i], "")), Qt::UserRole);
pStandardItem->setData(QVariant::fromValue(symbols[i]), Qt::UserRole);
mpStandardItemModel->appendRow(pStandardItem);
}
}
Expand Down Expand Up @@ -1545,7 +1558,7 @@ void PlainTextEdit::showCompletionItemToolTip(const QModelIndex &index)
if (pTextEditorPage->getAutoCompleteCheckBox()->isChecked()) {
QVariant value = index.data(Qt::UserRole);
CompleterItem completerItem = qvariant_cast<CompleterItem>(value);
mpCompleterToolTipLabel->setText(completerItem.mValue);
mpCompleterToolTipLabel->setText(completerItem.mDescription);
mpCompleterToolTipWidget->adjustSize();
QRect rect = mpCompleter->popup()->visualRect(index);
mpCompleterToolTipWidget->move(mpCompleter->popup()->mapToGlobal(QPoint(rect.x() + mpCompleter->popup()->width() + 2, rect.y() + 2)));
Expand Down
18 changes: 16 additions & 2 deletions OMEdit/OMEditGUI/Editors/BaseEditor.h
Expand Up @@ -214,10 +214,24 @@ class CompleterItem
{
public:
CompleterItem() {}
CompleterItem(QString key , QString value , QString select);
CompleterItem(const QString &key, const QString &value, const QString &select);
CompleterItem(const QString &value, const QString &description);
QString mKey;
QString mValue;
QString mSelect;
QString mDescription;

// Supposing two items with equal keys and different descriptions are
// different enough to show both and hoping that if the above two fields
// are identical, then other fields would be identical as well...
bool operator<(const CompleterItem &other) const
{
return (mKey < other.mKey) || ((mKey == other.mKey) && (mDescription == other.mDescription));
}
bool operator==(const CompleterItem &other) const
{
return mKey == other.mKey && mDescription == other.mDescription;
}
};

Q_DECLARE_METATYPE(CompleterItem)
Expand All @@ -232,7 +246,7 @@ class PlainTextEdit : public QPlainTextEdit
bool eventFilter(QObject *pObject, QEvent *pEvent);
LineNumberArea* getLineNumberArea() {return mpLineNumberArea;}
void clearCompleter();
void insertCompleterSymbols(QStringList symbols);
void insertCompleterSymbols(QList<CompleterItem> symbols);
void insertCompleterKeywords(QStringList keywords);
void insertCompleterTypes(QStringList types);
void insertCompleterCodeSnippets(QList<CompleterItem> items);
Expand Down
20 changes: 13 additions & 7 deletions OMEdit/OMEditGUI/Editors/ModelicaEditor.cpp
Expand Up @@ -81,8 +81,17 @@ void ModelicaEditor::popUpCompleter()
QList<CompleterItem> codesnippets = getCodeSnippets();
mpPlainTextEdit->insertCompleterCodeSnippets(codesnippets);
}
QStringList symbols = getCodeSymbols(word);
mpPlainTextEdit->insertCompleterSymbols(symbols);
QList<CompleterItem> classes, components;
getCompletionSymbols(word, classes, components);

std::sort(classes.begin(), classes.end());
classes.erase(std::unique(classes.begin(), classes.end()), classes.end());

std::sort(components.begin(), components.end());
components.erase(std::unique(components.begin(), components.end()), components.end());

mpPlainTextEdit->insertCompleterSymbols(classes);
mpPlainTextEdit->insertCompleterSymbols(components);

QCompleter *completer = mpPlainTextEdit->completer();
QRect cr = mpPlainTextEdit->cursorRect();
Expand Down Expand Up @@ -156,7 +165,7 @@ QString ModelicaEditor::wordUnderCursor()
return mpPlainTextEdit->document()->toPlainText().mid(begin, end - begin);
}

QStringList ModelicaEditor::getCodeSymbols(QString word)
void ModelicaEditor::getCompletionSymbols(QString word, QList<CompleterItem> &classes, QList<CompleterItem> &components)
{
QStringList nameComponents = word.split('.');
QString lastPart;
Expand All @@ -169,12 +178,9 @@ QStringList ModelicaEditor::getCodeSymbols(QString word)

QList<LibraryTreeItem*> contexts = getCandidateContexts(nameComponents);

QSet<QString> symbols;
for (int i = 0; i < contexts.size(); ++i) {
contexts[i]->tryToComplete(symbols, lastPart);
contexts[i]->tryToComplete(classes, components, lastPart);
}

return QStringList::fromSet(symbols);
}

/*!
Expand Down
2 changes: 1 addition & 1 deletion OMEdit/OMEditGUI/Editors/ModelicaEditor.h
Expand Up @@ -62,7 +62,7 @@ class ModelicaEditor : public BaseEditor
static LibraryTreeItem *deepResolve(LibraryTreeItem *pItem, QStringList nameComponents);
QList<LibraryTreeItem *> getCandidateContexts(QStringList nameComponents);
static void tryToCompleteInSingleContext(QStringList &result, LibraryTreeItem *pItem, QString lastPart);
QStringList getCodeSymbols(QString word);
void getCompletionSymbols(QString word, QList<CompleterItem> &classes, QList<CompleterItem> &components);
static QList<CompleterItem> getCodeSnippets();
private:
QString mLastValidText;
Expand Down
12 changes: 9 additions & 3 deletions OMEdit/OMEditGUI/Modeling/LibraryTreeWidget.cpp
Expand Up @@ -676,7 +676,7 @@ LibraryTreeItem *LibraryTreeItem::getComponentsClass(const QString &name)
return 0;
}

void LibraryTreeItem::tryToComplete(QSet<QString> &result, const QString &lastPart)
void LibraryTreeItem::tryToComplete(QList<CompleterItem> &completionClasses, QList<CompleterItem> &completionComponents, const QString &lastPart)
{
QList<LibraryTreeItem*> baseClasses = getInheritedClassesDeepList();

Expand All @@ -685,14 +685,14 @@ void LibraryTreeItem::tryToComplete(QSet<QString> &result, const QString &lastPa
for (int i = 0; i < classes.size(); ++i) {
if (classes[i]->getName().startsWith(lastPart) &&
classes[i]->getNameStructure().compare("OMEdit.Search.Feature") != 0)
result.insert(classes[i]->getName());
completionClasses << (CompleterItem(classes[i]->getName(), classes[i]->getHTMLDescription()));
}

const QList<ComponentInfo*> &components = baseClasses[bc]->getComponentsList();
if (!baseClasses[bc]->isRootItem() && baseClasses[bc]->getLibraryType() == LibraryTreeItem::Modelica) {
for (int i = 0; i < components.size(); ++i) {
if (components[i]->getName().startsWith(lastPart))
result.insert(components[i]->getName());
completionComponents << CompleterItem(components[i]->getName(), components[i]->getHTMLDescription() + QString("<br/>// Inside %1").arg(baseClasses[bc]->mNameStructure));
}
}
}
Expand Down Expand Up @@ -859,6 +859,12 @@ bool LibraryTreeItem::isInstantiated()
return mModelState == oms_modelState_instantiated;
}

QString LibraryTreeItem::getHTMLDescription() const
{
return QString("<b>%1</b> %2<br/>&nbsp;&nbsp;&nbsp;&nbsp;<i>\"%3\"</i><br/>...")
.arg(mClassInformation.restriction, mName, Utilities::escapeForHtmlNonSecure(mClassInformation.comment));
}

/*!
* \brief LibraryTreeItem::handleLoaded
* Handles the case when an undefined inherited class is loaded.
Expand Down
4 changes: 3 additions & 1 deletion OMEdit/OMEditGUI/Modeling/LibraryTreeWidget.h
Expand Up @@ -44,6 +44,7 @@
#include <QTreeView>
#include <QSortFilterProxyModel>

class CompleterItem;
class GraphicsView;
class ModelWidget;
class ShapeAnnotation;
Expand Down Expand Up @@ -165,7 +166,7 @@ class LibraryTreeItem : public QObject
QList<LibraryTreeItem*> getInheritedClassesDeepList();
LibraryTreeItem *getDirectComponentsClass(const QString &name);
LibraryTreeItem *getComponentsClass(const QString &name);
void tryToComplete(QSet<QString> &result, const QString &lastPart);
void tryToComplete(QList<CompleterItem> &completionClasses, QList<CompleterItem> &completionComponents, const QString &lastPart);
void removeChild(LibraryTreeItem *pLibraryTreeItem);
QVariant data(int column, int role = Qt::DisplayRole) const;
int row() const;
Expand All @@ -183,6 +184,7 @@ class LibraryTreeItem : public QObject
void emitConnectionAdded(LineAnnotation *pConnectionLineAnnotation) {emit connectionAdded(pConnectionLineAnnotation);}
void emitCoOrdinateSystemUpdated(GraphicsView *pGraphicsView) {emit coOrdinateSystemUpdated(pGraphicsView);}
bool isInstantiated();
QString getHTMLDescription() const;

OMCInterface::getClassInformation_res mClassInformation;
SimulationOptions mSimulationOptions;
Expand Down
7 changes: 7 additions & 0 deletions OMEdit/OMEditGUI/Util/Utilities.cpp
Expand Up @@ -421,6 +421,13 @@ void CodeColorsWidget::pickColor()
emit colorUpdated();
}

QString Utilities::escapeForHtmlNonSecure(const QString &str)
{
return QString(str)
.replace("& ", "&amp;") // should be the first replacement
.replace("< ", "&lt;");
}

/*!
* \brief Utilities::tempDirectory
* Returns the application temporary directory.
Expand Down
1 change: 1 addition & 0 deletions OMEdit/OMEditGUI/Util/Utilities.h
Expand Up @@ -434,6 +434,7 @@ namespace Utilities {
AlwaysDeleteBom = 2
};

QString escapeForHtmlNonSecure(const QString &str);
QString& tempDirectory();
QSettings* getApplicationSettings();
void parseCompositeModelText(MessageHandler *pMessageHandler, QString contents);
Expand Down

0 comments on commit 502f86f

Please sign in to comment.