diff --git a/bin/app/data/ApplicationSettings_template.xml b/bin/app/data/ApplicationSettings_template.xml index 83c51a4e..4d2d9329 100644 --- a/bin/app/data/ApplicationSettings_template.xml +++ b/bin/app/data/ApplicationSettings_template.xml @@ -22,4 +22,83 @@ + + + + + + #FFE47A + #FFCC00 + + + #FCA47E + #F97A4E + + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ffe47a + #ffcc00 + + + #ffe47a + #ffcc00 + + + #9ab4ad + #62b29d + + + #9ab4ad + #62b29d + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #ededed + #dddddd + + + #9ab4ad + #62b29d + + + #ededed + #dddddd + + } + diff --git a/bin/app/data/gui/search_view/search_element.css b/bin/app/data/gui/search_view/search_element.css index b89f7d52..08079121 100644 --- a/bin/app/data/gui/search_view/search_element.css +++ b/bin/app/data/gui/search_view/search_element.css @@ -6,36 +6,3 @@ QPushButton { padding-left: 4px; padding-right: 4px; } - -#search_element_token { - background-color: #CC8D91; -} - -#search_element_token:checked, #search_element_token:hover { - background-color: #CC5E69; -} - -#search_element_command { - background-color: #FFE47A; -} - -#search_element_command:checked, #search_element_command:hover { - background-color: #FFCC00; -} - -#search_element_operator { - background-color: #FCA47E; -} - -#search_element_operator:checked, #search_element_operator:hover { - background-color: #F97A4E; -} - -#search_element_none { - background-color: none; - color: #878787; -} - -#search_element_none:checked, #search_element_none:hover { - color: black; -} diff --git a/src/app/qt/element/QtAutocompletionList.cpp b/src/app/qt/element/QtAutocompletionList.cpp index 05619934..f5d2e553 100644 --- a/src/app/qt/element/QtAutocompletionList.cpp +++ b/src/app/qt/element/QtAutocompletionList.cpp @@ -3,6 +3,8 @@ #include #include +#include "ApplicationSettings.h" + QtAutocompletionModel::QtAutocompletionModel(QObject* parent) : QAbstractTableModel(parent) { @@ -26,7 +28,7 @@ int QtAutocompletionModel::rowCount(const QModelIndex &parent) const int QtAutocompletionModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return 3; + return 4; } QVariant QtAutocompletionModel::data(const QModelIndex &index, int role) const @@ -53,6 +55,8 @@ QVariant QtAutocompletionModel::data(const QModelIndex &index, int role) const } return indices; } + case 3: + return match.nodeType; default: return QVariant(); } @@ -69,7 +73,7 @@ const SearchMatch* QtAutocompletionModel::getSearchMatchAt(int idx) const QtAutocompletionDelegate::QtAutocompletionDelegate(QObject* parent) - : QItemDelegate(parent) + : QStyledItemDelegate(parent) { } @@ -79,6 +83,8 @@ QtAutocompletionDelegate::~QtAutocompletionDelegate() void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + painter->save(); + if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.color(QPalette::Highlight)); @@ -92,12 +98,19 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt float charWidth = option.fontMetrics.width("FontWidth") / 9.0f; QString type = index.sibling(index.row(), index.column() + 1).data().toString(); + QColor color("#FFFFFF"); - QColor color("#FFE47A"); - if (type.size()) + Node::NodeType nodeType = static_cast(index.sibling(index.row(), index.column() + 3).data().toInt()); + if(type.size() && nodeType) { - color = QColor("#CC8D91"); + color = QColor(ApplicationSettings::getInstance()->getNodeTypeColor(nodeType).c_str()); } + else + { + color = QColor(ApplicationSettings::getInstance()->getQueryNodeTypeColor(QueryNode::QUERYNODETYPE_COMMAND).c_str()); + } + + QList indices = index.sibling(index.row(), index.column() + 2).data().toList(); if (indices.size()) @@ -146,8 +159,16 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt painter->setFont(font); painter->setPen(pen); } + + painter->restore(); } +QSize QtAutocompletionDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const +{ + QString name = index.data().toString(); + QString type = index.sibling(index.row(), index.column() + 1).data().toString(); + return QSize( option.fontMetrics.width(name+type)+5, option.fontMetrics.height()); +} QtAutocompletionList::QtAutocompletionList(QWidget* parent) : QCompleter(parent) @@ -172,6 +193,7 @@ QtAutocompletionList::~QtAutocompletionList() { } + void QtAutocompletionList::completeAt(const QPoint& pos, const std::vector& autocompletionList) { m_model->setMatchList(autocompletionList); @@ -191,6 +213,7 @@ void QtAutocompletionList::completeAt(const QPoint& pos, const std::vectorsetCurrentIndex(index); complete(QRect(pos.x(), pos.y(), minSize.width(), 1)); + //complete(); QRect rect = list->visualRect(index); minSize.setHeight(std::min(minSize.height(), m_model->rowCount(index) * rect.height() + 16)); diff --git a/src/app/qt/element/QtAutocompletionList.h b/src/app/qt/element/QtAutocompletionList.h index 343369fb..fd8b047b 100644 --- a/src/app/qt/element/QtAutocompletionList.h +++ b/src/app/qt/element/QtAutocompletionList.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include "data/search/SearchMatch.h" @@ -35,13 +35,14 @@ private: class QtAutocompletionDelegate - : public QItemDelegate + : public QStyledItemDelegate { public: explicit QtAutocompletionDelegate(QObject* parent = 0); virtual ~QtAutocompletionDelegate(); virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; }; diff --git a/src/app/qt/element/QtSearchBar.cpp b/src/app/qt/element/QtSearchBar.cpp index accb27d1..1006ea06 100644 --- a/src/app/qt/element/QtSearchBar.cpp +++ b/src/app/qt/element/QtSearchBar.cpp @@ -64,6 +64,11 @@ void QtSearchBar::setText(const std::string& text) m_searchBox->setQuery(text); } +void QtSearchBar::setMatch(const SearchMatch& match) +{ + m_searchBox->setQuery(match); +} + void QtSearchBar::setFocus() { m_searchBox->setFocus(); diff --git a/src/app/qt/element/QtSearchBar.h b/src/app/qt/element/QtSearchBar.h index 2706cc7d..d4f489e7 100644 --- a/src/app/qt/element/QtSearchBar.h +++ b/src/app/qt/element/QtSearchBar.h @@ -23,6 +23,7 @@ public: virtual QSize sizeHint() const; void setText(const std::string& text); + void setMatch(const SearchMatch& match); void setFocus(); void setAutocompletionList(const std::vector& autocompletionList); diff --git a/src/app/qt/element/QtSmartSearchBox.cpp b/src/app/qt/element/QtSmartSearchBox.cpp index 49f0febc..dd4d6f07 100644 --- a/src/app/qt/element/QtSmartSearchBox.cpp +++ b/src/app/qt/element/QtSmartSearchBox.cpp @@ -6,6 +6,9 @@ #include #include +#include "ApplicationSettings.h" + +#include "utility/logging/logging.h" #include "utility/messaging/type/MessageSearch.h" #include "utility/messaging/type/MessageSearchAutocomplete.h" #include "utility/text/TextAccess.h" @@ -14,6 +17,8 @@ #include "data/query/QueryTree.h" #include "qt/element/QtAutocompletionList.h" +#include + QtQueryElement::QtQueryElement(const QString& text, QWidget* parent) : QPushButton(text, parent) { @@ -31,7 +36,8 @@ void QtQueryElement::onChecked(bool) void QtSmartSearchBox::search() { editTextToElement(); - MessageSearch(utility::join(m_tokens, "") + text().toStdString()).dispatch(); + LOG_INFO(utility::join(SearchMatch::searchMatchDequeToStringDeque(m_tokens), "")+ text().toStdString()); + MessageSearch(utility::join(SearchMatch::searchMatchDequeToStringDeque(m_tokens), "") + text().toStdString()).dispatch(); } QtSmartSearchBox::QtSmartSearchBox(QWidget* parent) @@ -72,10 +78,19 @@ void QtSmartSearchBox::setAutocompletionList(const std::vector& aut } } +void QtSmartSearchBox::setQuery(const SearchMatch& match) +{ + clearLineEdit(); + m_tokens.clear(); + m_tokens.push_back(match); + m_cursorIndex = m_tokens.size(); + updateElements(); +} + void QtSmartSearchBox::setQuery(const std::string& text) { clearLineEdit(); - m_tokens = QueryTree::tokenizeQuery(text); + m_tokens = SearchMatch::stringDequeToSearchMatchDeque(QueryTree::tokenizeQuery(text)); m_cursorIndex = m_tokens.size(); updateElements(); @@ -343,24 +358,25 @@ void QtSmartSearchBox::onTextEdited(const QString& text) bool tokensChanged = false; - std::string token; - std::deque tokens = QueryTree::tokenizeQuery(text.toStdString()); + SearchMatch token; + std::deque tokens = SearchMatch::stringDequeToSearchMatchDeque(QueryTree::tokenizeQuery(text.toStdString())); + while (tokens.size()) { token = tokens.front(); tokens.pop_front(); - if (tokens.size() || QueryTree::getTokenTypeName(token) != "none") + if (tokens.size() || token.queryNodeType != QueryNode::QUERYNODETYPE_NONE) { - textToToken(token); - token.clear(); + matchToToken(token); + token.decodeFromQuery(""); tokensChanged = true; } } if (tokensChanged) { - setEditText(QString::fromStdString(token)); + setEditText(QString::fromStdString(token.fullName)); updateElements(); } else @@ -368,7 +384,7 @@ void QtSmartSearchBox::onTextEdited(const QString& text) layoutElements(); } - if (token.size() || m_elements.size()) + if (token.fullName.size() || m_elements.size()) { requestAutoCompletions(); } @@ -466,23 +482,25 @@ void QtSmartSearchBox::moveCursorTo(int target) } } -void QtSmartSearchBox::textToToken(std::string text) + +void QtSmartSearchBox::matchToToken(const SearchMatch& match) { - if (!text.size()) + if(!match.fullName.size()) { return; } - if (completer()->popup()->isVisible()) + const SearchMatch* matchPtr = &match; + + if(completer()->popup()->isVisible()) { - const SearchMatch* match = dynamic_cast(completer())->getSearchMatchAt(0); - if (match && utility::equalsCaseInsensitive(text, match->fullName)) + const SearchMatch* m = dynamic_cast(completer())->getSearchMatchAt(0); + if (m && utility::equalsCaseInsensitive(match.fullName, m->fullName)) { - text = match->encodeForQuery(); + matchPtr = m; } } - - m_tokens.insert(m_tokens.begin() + m_cursorIndex, text); + m_tokens.insert(m_tokens.begin() + m_cursorIndex, *matchPtr); m_cursorIndex++; } @@ -493,8 +511,7 @@ void QtSmartSearchBox::searchMatchToToken(const SearchMatch& match) m_oldText.clear(); clearLineEdit(); - std::string name = match.encodeForQuery(); - textToToken(name); + matchToToken(match); updateElements(); } } @@ -509,7 +526,7 @@ bool QtSmartSearchBox::editTextToElement() { if (text().size()) { - textToToken(text().toStdString()); + matchToToken(SearchMatch(text().toStdString())); clearLineEdit(); updateElements(); @@ -530,7 +547,7 @@ void QtSmartSearchBox::editElement(QtQueryElement* element) } } - std::string token = QueryTree::getTokenName(m_tokens[m_cursorIndex]); + std::string token = m_tokens[m_cursorIndex].fullName; m_tokens.erase(m_tokens.begin() + m_cursorIndex); setEditText(QString::fromStdString(token)); @@ -543,16 +560,37 @@ void QtSmartSearchBox::updateElements() { m_elements.clear(); - for (const std::string& token : m_tokens) + for (const SearchMatch& token : m_tokens) { - std::string name = QueryTree::getTokenName(token); + std::string name = token.fullName; name = utility::replace(name, "&", "&&"); std::shared_ptr element = std::make_shared(QString::fromStdString(name), this); m_elements.push_back(element); + std::string color = "#000000"; + std::string hoverColor = "#000000"; - element->setObjectName(QString::fromStdString("search_element_" + QueryTree::getTokenTypeName(token))); + if(token.queryNodeType == QueryNode::QUERYNODETYPE_TOKEN) + { + element->setObjectName(QString::fromStdString("search_element_" + token.getNodeTypeAsString())); + color = ApplicationSettings::getInstance()->getNodeTypeColor(token.nodeType); + hoverColor = ApplicationSettings::getInstance()->getNodeTypeColor(token.nodeType, "hover"); + } + else + { + element->setObjectName(QString::fromStdString("search_element_" + QueryTree::getTokenTypeName(token.queryNodeType))); + color = ApplicationSettings::getInstance()->getQueryNodeTypeColor(token.queryNodeType); + hoverColor = ApplicationSettings::getInstance()->getQueryNodeTypeColor(token.queryNodeType, "hover"); + } + + std::string stylesheet = "QPushButton {background-color:"; + stylesheet += color; + stylesheet += ";} QPushButton:hover{ background-color:"; + stylesheet += hoverColor; + stylesheet += ";}"; + + element->setStyleSheet(stylesheet.c_str()); connect(element.get(), SIGNAL(wasChecked(QtQueryElement*)), this, SLOT(onElementSelected(QtQueryElement*))); } @@ -650,7 +688,6 @@ bool QtSmartSearchBox::hasSelectedElements() const return true; } } - return false; } @@ -661,7 +698,7 @@ std::string QtSmartSearchBox::getSelectedString() const { if (m_elements[i]->isChecked()) { - str += m_tokens[i]; + str += m_tokens[i].encodeForQuery(); } } return str; @@ -748,7 +785,7 @@ void QtSmartSearchBox::requestAutoCompletions() const for (size_t i = 0; i < m_tokens.size() && i < m_cursorIndex; i++) { - query += m_tokens[i]; + query += m_tokens[i].encodeForQuery(); } MessageSearchAutocomplete(query, text().toStdString()).dispatch(); diff --git a/src/app/qt/element/QtSmartSearchBox.h b/src/app/qt/element/QtSmartSearchBox.h index 9a825d85..9443fe29 100644 --- a/src/app/qt/element/QtSmartSearchBox.h +++ b/src/app/qt/element/QtSmartSearchBox.h @@ -39,6 +39,7 @@ public: virtual ~QtSmartSearchBox(); void setAutocompletionList(const std::vector& autocompletionList); + void setQuery(const SearchMatch& match); void setQuery(const std::string& text); void setFocus(); @@ -65,7 +66,7 @@ private: void moveCursor(int offset); void moveCursorTo(int goal); - void textToToken(std::string text); + void matchToToken(const SearchMatch& match); void searchMatchToToken(const SearchMatch& match); void setEditText(const QString& text); bool editTextToElement(); @@ -90,7 +91,7 @@ private: bool m_allowTextChange; QString m_oldText; - std::deque m_tokens; + std::deque m_tokens; std::vector> m_elements; size_t m_cursorIndex; diff --git a/src/app/qt/view/QtSearchView.cpp b/src/app/qt/view/QtSearchView.cpp index bbde5c8e..184f4592 100644 --- a/src/app/qt/view/QtSearchView.cpp +++ b/src/app/qt/view/QtSearchView.cpp @@ -8,6 +8,7 @@ QtSearchView::QtSearchView(ViewLayout* viewLayout) : SearchView(viewLayout) , m_refreshViewFunctor(std::bind(&QtSearchView::doRefreshView, this)) , m_setTextFunctor(std::bind(&QtSearchView::doSetText, this, std::placeholders::_1)) + , m_setMatchFunctor(std::bind(&QtSearchView::doSetMatch, this, std::placeholders::_1)) , m_setFocusFunctor(std::bind(&QtSearchView::doSetFocus, this)) , m_setAutocompletionListFunctor(std::bind(&QtSearchView::doSetAutocompletionList, this, std::placeholders::_1)) { @@ -38,6 +39,11 @@ void QtSearchView::setText(const std::string& text) m_setTextFunctor(text); } +void QtSearchView::setMatch(const SearchMatch& match) +{ + m_setMatchFunctor(match); +} + void QtSearchView::setFocus() { m_setFocusFunctor(); @@ -53,6 +59,11 @@ void QtSearchView::doRefreshView() setStyleSheet(); } +void QtSearchView::doSetMatch(const SearchMatch& match) +{ + m_widget->setMatch(match); +} + void QtSearchView::doSetText(const std::string& text) { m_widget->setText(text); diff --git a/src/app/qt/view/QtSearchView.h b/src/app/qt/view/QtSearchView.h index 01f639f4..e1067366 100644 --- a/src/app/qt/view/QtSearchView.h +++ b/src/app/qt/view/QtSearchView.h @@ -20,11 +20,13 @@ public: // SearchView implementation virtual void setText(const std::string& text); + virtual void setMatch(const SearchMatch& match); virtual void setFocus(); virtual void setAutocompletionList(const std::vector& autocompletionList); private: void doRefreshView(); + void doSetMatch(const SearchMatch& match); void doSetText(const std::string& text); void doSetFocus(); void doSetAutocompletionList(const std::vector& autocompletionList); @@ -33,6 +35,7 @@ private: QtThreadedFunctor<> m_refreshViewFunctor; QtThreadedFunctor m_setTextFunctor; + QtThreadedFunctor m_setMatchFunctor; QtThreadedFunctor<> m_setFocusFunctor; QtThreadedFunctor&> m_setAutocompletionListFunctor; diff --git a/src/app/qt/view/graphElements/QtGraphNode.cpp b/src/app/qt/view/graphElements/QtGraphNode.cpp index a1c23581..1948d3b3 100644 --- a/src/app/qt/view/graphElements/QtGraphNode.cpp +++ b/src/app/qt/view/graphElements/QtGraphNode.cpp @@ -4,6 +4,8 @@ #include #include +#include "ApplicationSettings.h" + #include "utility/messaging/type/MessageActivateTokens.h" #include "utility/messaging/type/MessageGraphNodeMove.h" @@ -337,7 +339,7 @@ void QtGraphNode::setStyle() m_rect->setShadow(QColor(0, 0, 0, 128), 5); } - color = "#ededed"; + color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType()).c_str(); if (m_subNodes.size()) { radius = 20.0f; @@ -359,12 +361,12 @@ void QtGraphNode::setStyle() case Node::NODE_METHOD: if (m_isActive || m_isHovering) { - color = "#ffcc00"; + color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType(), "hover").c_str(); font.setWeight(QFont::Bold); } else { - color = "#ffe47a"; + color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType()).c_str(); } radius = 8.0f; @@ -380,12 +382,12 @@ void QtGraphNode::setStyle() case Node::NODE_ENUM_CONSTANT: if (m_isActive || m_isHovering) { - color = "#62b29d"; + color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType(), "hover").c_str(); font.setWeight(QFont::Bold); } else { - color = "#9ab4ad"; + color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType()).c_str(); } radius = 8.0f; diff --git a/src/lib/ApplicationSettings.cpp b/src/lib/ApplicationSettings.cpp index d7f16ea6..c694b94f 100644 --- a/src/lib/ApplicationSettings.cpp +++ b/src/lib/ApplicationSettings.cpp @@ -83,6 +83,31 @@ void ApplicationSettings::setCodeActiveLinkColor(Colori color) setValue("code/ActiveLinkColor", color.toString()); } +std::string ApplicationSettings::getNodeTypeColor(Node::NodeType type, const std::string& state) const +{ + std::string path = "colors/" + Node::getTypeString(type) + "/" + state; + return getValue(path, "#FFFFFF"); +} + +void ApplicationSettings::setNodeTypeColor(Node::NodeType type, const std::string& color, const std::string& state) +{ + std::string path = "colors/" + Node::getTypeString(type) + "/" + state; + setValue(path, color); +} + +std::string ApplicationSettings::getQueryNodeTypeColor(QueryNode::QueryNodeType type, const std::string& state) const +{ + std::string path = "colors/" + QueryNode::queryNodeTypeToString(type) + "/" + state; + return getValue(path, "#FFFFFF"); +} + +void ApplicationSettings::setQueryNodeTypeColor(QueryNode::QueryNodeType type, + const std::string& color, const std::string& state) +{ + std::string path = "colors/" + QueryNode::queryNodeTypeToString(type) + "/" + state; + setValue(path, color); +} + ApplicationSettings::ApplicationSettings() { } diff --git a/src/lib/ApplicationSettings.h b/src/lib/ApplicationSettings.h index 0a6d3fac..73a0cca0 100644 --- a/src/lib/ApplicationSettings.h +++ b/src/lib/ApplicationSettings.h @@ -5,6 +5,8 @@ #include "Settings.h" #include "utility/math/Color.h" +#include "data/graph/Node.h" +#include "data/query/QueryNode.h" class ApplicationSettings: public Settings { @@ -34,6 +36,12 @@ public: Colori getCodeActiveLinkColor() const; void setCodeActiveLinkColor(Colori color); + std::string getNodeTypeColor(Node::NodeType type, const std::string& state = "normal") const; + void setNodeTypeColor(Node::NodeType type, const std::string& color, const std::string& state = "normal"); + + std::string getQueryNodeTypeColor(QueryNode::QueryNodeType type , const std::string& state = "normal") const; + void setQueryNodeTypeColor(QueryNode::QueryNodeType type, const std::string& color, const std::string& state = "normal"); + private: ApplicationSettings(); ApplicationSettings(const ApplicationSettings&); diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index 2b803570..ed561a72 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -13,15 +13,19 @@ SearchController::~SearchController() { } +#include void SearchController::handleMessage(MessageActivateTokens* message) { if (!m_ignoreNextMessageActivateTokens && message->tokenIds.size()) { SearchMatch match; match.fullName = m_graphAccess->getNameForNodeWithId(message->tokenIds[0]); + match.nodeType = m_graphAccess->getNodeTypeForNodeWithId(message->tokenIds[0]); match.tokenIds.insert(message->tokenIds[0]); + match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; - getView()->setText(match.encodeForQuery()); + + getView()->setMatch(match); } m_ignoreNextMessageActivateTokens = false; diff --git a/src/lib/component/view/SearchView.h b/src/lib/component/view/SearchView.h index 8e3e42f0..26cd9922 100644 --- a/src/lib/component/view/SearchView.h +++ b/src/lib/component/view/SearchView.h @@ -15,6 +15,7 @@ public: virtual std::string getName() const; virtual void setText(const std::string& s) = 0; + virtual void setMatch(const SearchMatch& m) = 0; virtual void setFocus() = 0; virtual void setAutocompletionList(const std::vector& autocompletionList) = 0; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 176e2754..ebf9186a 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -686,6 +686,20 @@ std::string Storage::getNameForNodeWithId(Id id) const } } +Node::NodeType Storage::getNodeTypeForNodeWithId(Id id) const +{ + Token* token = m_graph.getTokenById(id); + if(!token) + { + return Node::NODE_UNDEFINED; + } + if(!token->isEdge()) + { + return dynamic_cast(token)->getType(); + } + return Node::NODE_UNDEFINED; +} + std::vector Storage::getAutocompletionMatches(const std::string& query, const std::string& word) const { SearchResults tokenResults; @@ -711,11 +725,17 @@ std::vector Storage::getAutocompletionMatches(const std::string& qu { if (!match.tokenIds.size()) { + match.queryNodeType = QueryNode::QUERYNODETYPE_COMMAND; continue; } Token* token = m_graph.getTokenById(*match.tokenIds.cbegin()); + if(!token->isEdge()) + { + match.nodeType = dynamic_cast(token)->getType(); + } match.typeName = token->getTypeString(); + match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; } return matches; diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 45203d1f..adb97434 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -108,6 +108,7 @@ public: // GraphAccess implementation virtual Id getIdForNodeWithName(const std::string& fullName) const; virtual std::string getNameForNodeWithId(Id id) const; + virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const; virtual std::vector getAutocompletionMatches( const std::string& query, const std::string& word) const; diff --git a/src/lib/data/access/GraphAccess.h b/src/lib/data/access/GraphAccess.h index de0717ad..1d59f743 100644 --- a/src/lib/data/access/GraphAccess.h +++ b/src/lib/data/access/GraphAccess.h @@ -16,6 +16,7 @@ public: virtual Id getIdForNodeWithName(const std::string& name) const = 0; virtual std::string getNameForNodeWithId(Id id) const = 0; + virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0; virtual std::vector getAutocompletionMatches( const std::string& query, const std::string& word) const = 0; diff --git a/src/lib/data/access/GraphAccessProxy.cpp b/src/lib/data/access/GraphAccessProxy.cpp index 3784b104..4156c518 100644 --- a/src/lib/data/access/GraphAccessProxy.cpp +++ b/src/lib/data/access/GraphAccessProxy.cpp @@ -37,6 +37,15 @@ Id GraphAccessProxy::getIdForNodeWithName(const std::string& name) const return 0; } +Node::NodeType GraphAccessProxy::getNodeTypeForNodeWithId(Id id) const +{ + if(hasSubject()) + { + return m_subject->getNodeTypeForNodeWithId(id); + } + return Node::NODE_UNDEFINED; +} + std::string GraphAccessProxy::getNameForNodeWithId(Id id) const { if (hasSubject()) diff --git a/src/lib/data/access/GraphAccessProxy.h b/src/lib/data/access/GraphAccessProxy.h index b45fa41f..9a05b52b 100644 --- a/src/lib/data/access/GraphAccessProxy.h +++ b/src/lib/data/access/GraphAccessProxy.h @@ -15,6 +15,7 @@ public: // GraphAccess implementation virtual Id getIdForNodeWithName(const std::string& name) const; virtual std::string getNameForNodeWithId(Id id) const; + virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const; virtual std::vector getAutocompletionMatches( const std::string& query, const std::string& word) const; diff --git a/src/lib/data/graph/Node.cpp b/src/lib/data/graph/Node.cpp index 0b6e75f4..597f9116 100644 --- a/src/lib/data/graph/Node.cpp +++ b/src/lib/data/graph/Node.cpp @@ -317,7 +317,7 @@ void Node::addComponentSignature(std::shared_ptr compon } } -std::string Node::getTypeString(NodeType type) const +std::string Node::getTypeString(NodeType type) { switch (type) { @@ -346,11 +346,11 @@ std::string Node::getTypeString(NodeType type) const case NODE_ENUM: return "enum"; case NODE_ENUM_CONSTANT: - return "enum constant"; + return "enum_constant"; case NODE_TYPEDEF: return "typedef"; case NODE_TEMPLATE_PARAMETER_TYPE: - return "template parameter type"; + return "template_parameter_type"; case NODE_FILE: return "file"; } diff --git a/src/lib/data/graph/Node.h b/src/lib/data/graph/Node.h index 34a7aff9..975135f2 100644 --- a/src/lib/data/graph/Node.h +++ b/src/lib/data/graph/Node.h @@ -42,6 +42,8 @@ public: NODE_FILE = 0x8000 }; + static std::string getTypeString(NodeType type); + Node(NodeType type, std::shared_ptr nameComponent); Node(const Node& other); virtual ~Node(); @@ -85,7 +87,6 @@ public: void addComponentSignature(std::shared_ptr component); // Logging. - std::string getTypeString(NodeType type) const; virtual std::string getTypeString() const; std::string getAsString() const; diff --git a/src/lib/data/query/QueryCommand.cpp b/src/lib/data/query/QueryCommand.cpp index 01f46d64..2e54ffc6 100644 --- a/src/lib/data/query/QueryCommand.cpp +++ b/src/lib/data/query/QueryCommand.cpp @@ -54,7 +54,8 @@ std::map QueryCommand::getCommandTypeMap } QueryCommand::QueryCommand(std::string name) - : m_type(COMMAND_INVALID) + : QueryNode(QueryNode::QUERYNODETYPE_COMMAND) + , m_type(COMMAND_INVALID) { name.erase(std::remove(name.begin(), name.end(), BOUNDARY), name.end()); m_name = name; diff --git a/src/lib/data/query/QueryNode.cpp b/src/lib/data/query/QueryNode.cpp index c54b73c2..003a3d9e 100644 --- a/src/lib/data/query/QueryNode.cpp +++ b/src/lib/data/query/QueryNode.cpp @@ -1,7 +1,8 @@ #include "data/query/QueryNode.h" -QueryNode::QueryNode() - : m_isGroup(false) +QueryNode::QueryNode(QueryNodeType queryNodeType) + : m_nodeType(queryNodeType) + , m_isGroup(false) , m_isComplete(true) { } @@ -56,3 +57,28 @@ void QueryNode::setIsComplete(bool isComplete) { m_isComplete = isComplete; } + +QueryNode::QueryNodeType QueryNode::getQueryNodeType() const +{ + return m_nodeType; +} + +std::string QueryNode::queryNodeTypeToString(const QueryNodeType& type) +{ + switch(type) + { + case QUERYNODETYPE_NONE: + return "none"; + case QUERYNODETYPE_COMMAND: + return "command"; + case QUERYNODETYPE_TOKEN: + return "token"; + case QUERYNODETYPE_OPERATOR: + return "operator"; + } +} + +std::string QueryNode::getQueryNodeTypeAsString() const +{ + return queryNodeTypeToString(m_nodeType); +} \ No newline at end of file diff --git a/src/lib/data/query/QueryNode.h b/src/lib/data/query/QueryNode.h index 47b47cf7..16ee8aae 100644 --- a/src/lib/data/query/QueryNode.h +++ b/src/lib/data/query/QueryNode.h @@ -7,7 +7,17 @@ class QueryNode { public: - QueryNode(); + enum QueryNodeType + { + QUERYNODETYPE_NONE, + QUERYNODETYPE_TOKEN, + QUERYNODETYPE_COMMAND, + QUERYNODETYPE_OPERATOR + }; + + static std::string queryNodeTypeToString(const QueryNodeType& type); + + QueryNode(QueryNodeType queryNodeType = QUERYNODETYPE_NONE); virtual ~QueryNode(); virtual bool isCommand() const = 0; @@ -16,6 +26,7 @@ public: virtual bool derivedIsComplete() const = 0; + virtual std::string getName() const = 0; virtual void print(std::ostream& ostream) const = 0; @@ -27,7 +38,11 @@ public: bool isComplete() const; void setIsComplete(bool isComplete); + QueryNodeType getQueryNodeType() const; + std::string getQueryNodeTypeAsString() const; + private: + QueryNodeType m_nodeType; bool m_isGroup; bool m_isComplete; }; diff --git a/src/lib/data/query/QueryOperator.cpp b/src/lib/data/query/QueryOperator.cpp index 9dafab33..41910ec2 100644 --- a/src/lib/data/query/QueryOperator.cpp +++ b/src/lib/data/query/QueryOperator.cpp @@ -56,7 +56,8 @@ char QueryOperator::getOperator(OperatorType t) } QueryOperator::QueryOperator(OperatorType type, bool isImplicit) - : m_type(type) + : QueryNode(QueryNode::QUERYNODETYPE_OPERATOR) + , m_type(type) , m_isImplicit(isImplicit) { } diff --git a/src/lib/data/query/QueryToken.cpp b/src/lib/data/query/QueryToken.cpp index 2643ec5e..2196e269 100644 --- a/src/lib/data/query/QueryToken.cpp +++ b/src/lib/data/query/QueryToken.cpp @@ -6,6 +6,7 @@ #include "utility/utilityString.h" QueryToken::QueryToken(std::string name) + : QueryNode(QueryNode::QUERYNODETYPE_TOKEN) { name.erase(std::remove(name.begin(), name.end(), BOUNDARY), name.end()); std::deque names = utility::split(name, DELIMITER); diff --git a/src/lib/data/query/QueryTree.cpp b/src/lib/data/query/QueryTree.cpp index 64db8d2e..4647cb04 100644 --- a/src/lib/data/query/QueryTree.cpp +++ b/src/lib/data/query/QueryTree.cpp @@ -67,22 +67,27 @@ std::string QueryTree::getTokenName(const std::string& token) return token; } -std::string QueryTree::getTokenTypeName(const std::string& token) +std::string QueryTree::getTokenTypeName(const QueryNode::QueryNodeType& type) +{ + return QueryNode::queryNodeTypeToString(type); +} + +QueryNode::QueryNodeType QueryTree::getTokenType(const std::string& token) { if (token.size() > 2 && token.front() == QueryToken::BOUNDARY && token.back() == QueryToken::BOUNDARY) { - return "token"; + return QueryNode::QUERYNODETYPE_TOKEN; } else if (token.size() > 2 && token.front() == QueryCommand::BOUNDARY && token.back() == QueryCommand::BOUNDARY) { - return "command"; + return QueryNode::QUERYNODETYPE_COMMAND; } else if (token.size() == 1 && QueryOperator::getOperatorType(token.front()) != QueryOperator::OPERATOR_NONE) { - return "operator"; + return QueryNode::QUERYNODETYPE_OPERATOR; } - return "none"; + return QueryNode::QUERYNODETYPE_NONE; } QueryTree::QueryTree() diff --git a/src/lib/data/query/QueryTree.h b/src/lib/data/query/QueryTree.h index 74fb0235..73322aee 100644 --- a/src/lib/data/query/QueryTree.h +++ b/src/lib/data/query/QueryTree.h @@ -6,6 +6,7 @@ #include #include +#include "data/query/QueryNode.h" #include "data/query/QueryOperator.h" class QueryTree @@ -13,7 +14,8 @@ class QueryTree public: static std::deque tokenizeQuery(const std::string& query); static std::string getTokenName(const std::string& token); - static std::string getTokenTypeName(const std::string& token); + static QueryNode::QueryNodeType getTokenType(const std::string& token); + static std::string getTokenTypeName(const QueryNode::QueryNodeType& token); QueryTree(); QueryTree(const std::string& query); diff --git a/src/lib/data/search/SearchMatch.cpp b/src/lib/data/search/SearchMatch.cpp index d2f9e16c..2fdadf85 100644 --- a/src/lib/data/search/SearchMatch.cpp +++ b/src/lib/data/search/SearchMatch.cpp @@ -1,11 +1,25 @@ #include "data/search/SearchMatch.h" #include - -#include "utility/logging/logging.h" +#include #include "data/query/QueryCommand.h" +#include "data/query/QueryOperator.h" #include "data/query/QueryToken.h" +#include "utility/logging/logging.h" +#include "utility/utilityString.h" + +SearchMatch::SearchMatch() + : fullName("") + , typeName("") + , queryNodeType(QueryNode::QUERYNODETYPE_NONE) +{ +} + +SearchMatch::SearchMatch(const std::string& query) +{ + decodeFromQuery(query); +} void SearchMatch::log(const std::vector& matches, const std::string& query) { @@ -39,17 +53,89 @@ void SearchMatch::print(std::ostream& ostream) const std::string SearchMatch::encodeForQuery() const { - if (!tokenIds.size()) + switch(queryNodeType) { + case QueryNode::QUERYNODETYPE_COMMAND: return QueryCommand::BOUNDARY + fullName + QueryCommand::BOUNDARY; + case QueryNode::QUERYNODETYPE_TOKEN: + { + std::stringstream ss; + ss << QueryToken::BOUNDARY << fullName; + ss << QueryToken::DELIMITER << nodeType; + for (Id tokenId : tokenIds) + { + ss << QueryToken::DELIMITER << tokenId; + } + ss << QueryToken::BOUNDARY; + return ss.str(); } - std::stringstream ss; - ss << QueryToken::BOUNDARY << fullName; - for (Id tokenId : tokenIds) - { - ss << QueryToken::DELIMITER << tokenId; + case QueryNode::QUERYNODETYPE_OPERATOR: + case QueryNode::QUERYNODETYPE_NONE: + return fullName; } - ss << QueryToken::BOUNDARY; - return ss.str(); +} + +void SearchMatch::decodeFromQuery(std::string query) +{ + if (query.size() > 2 && query.front() == QueryToken::BOUNDARY && query.back() == QueryToken::BOUNDARY) + { + queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; + query.erase(query.begin()); + query.pop_back(); + } + else if (query.size() > 2 && query.front() == QueryCommand::BOUNDARY && query.back() == QueryCommand::BOUNDARY) + { + queryNodeType = QueryNode::QUERYNODETYPE_COMMAND; + query.erase(query.begin()); + query.pop_back(); + } + else if (query.size() == 1 && QueryOperator::getOperatorType(query.front()) != QueryOperator::OPERATOR_NONE) + { + queryNodeType = QueryNode::QUERYNODETYPE_OPERATOR; + } + else + { + queryNodeType = QueryNode::QUERYNODETYPE_NONE; + } + + std::vector queryParts = utility::splitToVector(query, QueryToken::DELIMITER); + + fullName = queryParts[0]; + + if(queryParts.size() > 1) + { + for(int i = 2; i < queryParts.size(); ++i) + { + tokenIds.insert(std::strtoul(queryParts[i].c_str(),nullptr,0)); + } + } + +} + + +std::deque SearchMatch::stringDequeToSearchMatchDeque(const std::deque& stringDeque) +{ + std::deque matchDeque; + for(std::string str : stringDeque) + { + matchDeque.push_back(SearchMatch(str)); + } + return matchDeque; +} + +std::deque SearchMatch::searchMatchDequeToStringDeque(const std::deque& searchMatchDeque) +{ + std::deque stringDeque; + for(SearchMatch match : searchMatchDeque) + { + stringDeque.push_back(match.encodeForQuery()); + } + return stringDeque; + +} + +std::string SearchMatch::getNodeTypeAsString() const +{ + return Node::getTypeString(nodeType); } diff --git a/src/lib/data/search/SearchMatch.h b/src/lib/data/search/SearchMatch.h index 8141ed7d..a5ba0138 100644 --- a/src/lib/data/search/SearchMatch.h +++ b/src/lib/data/search/SearchMatch.h @@ -1,25 +1,41 @@ #ifndef SEARCH_MATCH_H #define SEARCH_MATCH_H +#include #include #include #include #include +#include "data/graph/Node.h" +#include "data/query/QueryNode.h" #include "utility/types.h" struct SearchMatch { static void log(const std::vector& matches, const std::string& query); + static std::deque stringDequeToSearchMatchDeque(const std::deque& deque); + static std::deque searchMatchDequeToStringDeque(const std::deque& deque); + + SearchMatch(); + SearchMatch(const std::string& query); + void print(std::ostream& ostream) const; std::string encodeForQuery() const; + void decodeFromQuery(std::string query); + std::string getNodeTypeAsString() const; + std::string fullName; std::string typeName; + Node::NodeType nodeType; + QueryNode::QueryNodeType queryNodeType; + std::set tokenIds; std::vector indices; size_t weight; }; + #endif // SEARCH_MATCH_H diff --git a/src/lib/data/search/SearchResult.cpp b/src/lib/data/search/SearchResult.cpp index 90276dab..5dc5492f 100644 --- a/src/lib/data/search/SearchResult.cpp +++ b/src/lib/data/search/SearchResult.cpp @@ -8,6 +8,7 @@ SearchResult::SearchResult() { } + SearchResult::SearchResult(size_t weight, const SearchNode* node, const SearchNode* parent) : weight(weight) , node(node)