diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index b8ac00a3..2d7b085b 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -3,8 +3,12 @@ add_files( qt/element/QtCodeFile.cpp qt/element/QtCodeFile.h + qt/element/QtButton.cpp + qt/element/QtButton.h qt/element/QtCodeSnippet.cpp qt/element/QtCodeSnippet.h + qt/element/QtEditBox.cpp + qt/element/QtEditBox.h qt/element/QtMainWindow.cpp qt/element/QtMainWindow.h @@ -23,6 +27,8 @@ add_files( qt/view/QtGraphView.h qt/view/QtMainView.cpp qt/view/QtMainView.h + qt/view/QtSearchView.cpp + qt/view/QtSearchView.h qt/QtGuiFactory.cpp qt/QtGuiFactory.h diff --git a/src/app/qt/QtGuiFactory.cpp b/src/app/qt/QtGuiFactory.cpp index 5f040101..2a5b21b1 100644 --- a/src/app/qt/QtGuiFactory.cpp +++ b/src/app/qt/QtGuiFactory.cpp @@ -3,6 +3,7 @@ #include "qt/view/QtCodeView.h" #include "qt/view/QtGraphView.h" #include "qt/view/QtMainView.h" +#include "qt/view/QtSearchView.h" QtGuiFactory::QtGuiFactory() { @@ -26,3 +27,8 @@ std::shared_ptr QtGuiFactory::createGraphView(ViewLayout* viewLayout) { return View::create(viewLayout); } + +std::shared_ptr QtGuiFactory::createSearchView(ViewLayout* viewLayout) const +{ + return View::create(viewLayout); +} diff --git a/src/app/qt/QtGuiFactory.h b/src/app/qt/QtGuiFactory.h index 95787346..853ca34a 100644 --- a/src/app/qt/QtGuiFactory.h +++ b/src/app/qt/QtGuiFactory.h @@ -12,6 +12,7 @@ public: virtual std::shared_ptr createMainView() const; virtual std::shared_ptr createCodeView(ViewLayout* viewLayout) const; virtual std::shared_ptr createGraphView(ViewLayout* viewLayout) const; + virtual std::shared_ptr createSearchView(ViewLayout* viewLayout) const; }; #endif // QT_GUI_FACTORY_H diff --git a/src/app/qt/element/QtButton.cpp b/src/app/qt/element/QtButton.cpp new file mode 100644 index 00000000..084d5b00 --- /dev/null +++ b/src/app/qt/element/QtButton.cpp @@ -0,0 +1,23 @@ +#include "qt/element/QtButton.h" + +QtButton::QtButton(QWidget *parent) + : QPushButton(parent) + , m_onClick(nullptr) +{ + connect(this, SIGNAL(clicked()), this, SLOT(slotOnClick())); +} + +QtButton::~QtButton() +{ +} + +void QtButton::setCallbackOnClick(std::function callback) +{ + m_onClick = callback; +} + +void QtButton::slotOnClick() +{ + if (m_onClick) + m_onClick(); +} diff --git a/src/app/qt/element/QtButton.h b/src/app/qt/element/QtButton.h new file mode 100644 index 00000000..a8e825f3 --- /dev/null +++ b/src/app/qt/element/QtButton.h @@ -0,0 +1,25 @@ +#ifndef QT_BUTTON_H +#define QT_BUTTON_H + +#include + +#include + +class QtButton: public QPushButton +{ + Q_OBJECT + +public: + QtButton(QWidget *parent); + ~QtButton(); + + void setCallbackOnClick(std::function callback); + +private slots: + void slotOnClick(); + +private: + std::function m_onClick; +}; + +#endif // QT_BUTTON_H diff --git a/src/app/qt/element/QtEditBox.cpp b/src/app/qt/element/QtEditBox.cpp new file mode 100644 index 00000000..c91ba832 --- /dev/null +++ b/src/app/qt/element/QtEditBox.cpp @@ -0,0 +1,23 @@ +#include "qt/element/QtEditBox.h" + +QtEditBox::QtEditBox(QWidget *parent) + : QLineEdit(parent) + , m_onReturnPressed(nullptr) +{ + connect(this, SIGNAL(returnPressed()), this, SLOT(slotOnReturnPressed())); +} + +QtEditBox::~QtEditBox() +{ +} + +void QtEditBox::setCallbackOnReturnPressed(std::function callback) +{ + m_onReturnPressed = callback; +} + +void QtEditBox::slotOnReturnPressed() +{ + if (m_onReturnPressed) + m_onReturnPressed(); +} diff --git a/src/app/qt/element/QtEditBox.h b/src/app/qt/element/QtEditBox.h new file mode 100644 index 00000000..faccaeb1 --- /dev/null +++ b/src/app/qt/element/QtEditBox.h @@ -0,0 +1,25 @@ +#ifndef QT_EDIT_BOX_H +#define QT_EDIT_BOX_H + +#include + +#include + +class QtEditBox: public QLineEdit +{ + Q_OBJECT + +public: + QtEditBox(QWidget *parent); + ~QtEditBox(); + + void setCallbackOnReturnPressed(std::function callback); + +private slots: + void slotOnReturnPressed(); + +private: + std::function m_onReturnPressed; +}; + +#endif // QT_EDIT_BOX_H diff --git a/src/app/qt/view/QtSearchView.cpp b/src/app/qt/view/QtSearchView.cpp new file mode 100644 index 00000000..aafcd4da --- /dev/null +++ b/src/app/qt/view/QtSearchView.cpp @@ -0,0 +1,58 @@ +#include "qt/view/QtSearchView.h" + +#include + +#include "qt/element/QtButton.h" +#include "qt/element/QtEditBox.h" +#include "qt/QtWidgetWrapper.h" +#include "qt/utility/utilityQt.h" +#include "component/controller/SearchController.h" + +QtSearchView::QtSearchView(ViewLayout* viewLayout) + : SearchView(viewLayout) +{ +} + +QtSearchView::~QtSearchView() +{ +} + +void QtSearchView::createWidgetWrapper() +{ + setWidgetWrapper(std::make_shared(std::make_shared())); +} + +void QtSearchView::initGui() +{ + QWidget* widget = QtWidgetWrapper::getWidgetOfView(this); + utility::setWidgetBackgroundColor(widget, Colori(190, 190, 190, 255)); + + QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight); + layout->setSpacing(3); + layout->setContentsMargins(3, 3, 3, 3); + widget->setLayout(layout); + + m_searchBox = new QtEditBox(widget); + m_searchBox->setPlaceholderText("Please enter your search string."); + m_searchBox->setCallbackOnReturnPressed(std::bind(&QtSearchView::onSeachButtonClick, this)); + + m_searchButton = new QtButton(widget); + m_searchButton->setText("Search"); + m_searchButton->setCallbackOnClick(std::bind(&QtSearchView::onSeachButtonClick, this)); + + widget->layout()->addWidget(m_searchBox); + widget->layout()->addWidget(m_searchButton); +} + +void QtSearchView::setText(const std::string& s) const +{ + if (m_searchBox->text() != s.c_str()) + { + m_searchBox->setText(s.c_str()); + } +} + +void QtSearchView::onSeachButtonClick() +{ + getController()->search(m_searchBox->text().toStdString()); +} diff --git a/src/app/qt/view/QtSearchView.h b/src/app/qt/view/QtSearchView.h new file mode 100644 index 00000000..f094659e --- /dev/null +++ b/src/app/qt/view/QtSearchView.h @@ -0,0 +1,29 @@ +#ifndef QT_SEARCH_VIEW_H +#define QT_SEARCH_VIEW_H + +#include "component/view/SearchView.h" + +class QtEditBox; +class QtButton; + +class QtSearchView: public SearchView +{ +public: + QtSearchView(ViewLayout* viewLayout); + ~QtSearchView(); + + // View implementation + virtual void createWidgetWrapper(); + virtual void initGui(); + + // SearchView implementation + virtual void setText(const std::string& s) const; + +private: + void onSeachButtonClick(); + + QtEditBox* m_searchBox; + QtButton* m_searchButton; +}; + +# endif // QT_SEARCH_VIEW_H diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f0c34300..c86d3b2d 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -22,6 +22,8 @@ add_files( component/controller/Controller.h component/controller/GraphController.cpp component/controller/GraphController.h + component/controller/SearchController.cpp + component/controller/SearchController.h component/view/graphElements/GraphNode.cpp component/view/graphElements/GraphNode.h @@ -32,6 +34,8 @@ add_files( component/view/GraphView.h component/view/MainView.cpp component/view/MainView.h + component/view/SearchView.cpp + component/view/SearchView.h component/view/View.cpp component/view/View.h component/view/ViewLayout.cpp diff --git a/src/lib/component/ComponentFactory.cpp b/src/lib/component/ComponentFactory.cpp index e144ddb9..2d6f1150 100644 --- a/src/lib/component/ComponentFactory.cpp +++ b/src/lib/component/ComponentFactory.cpp @@ -3,8 +3,10 @@ #include "component/Component.h" #include "component/controller/CodeController.h" #include "component/controller/GraphController.h" +#include "component/controller/SearchController.h" #include "component/view/CodeView.h" #include "component/view/GraphView.h" +#include "component/view/SearchView.h" #include "component/view/ViewLayout.h" #include "gui/GuiFactory.h" @@ -44,6 +46,15 @@ std::shared_ptr ComponentFactory::createGraphComponent() return component; } +std::shared_ptr ComponentFactory::createSearchComponent() +{ + std::shared_ptr view = m_guiFactory->createSearchView(m_viewLayout); + std::shared_ptr controller = std::make_shared(m_graphAccess); + + std::shared_ptr component = std::make_shared(view, controller); + return component; +} + ComponentFactory::ComponentFactory() { } diff --git a/src/lib/component/ComponentFactory.h b/src/lib/component/ComponentFactory.h index 05298103..a60b9d75 100644 --- a/src/lib/component/ComponentFactory.h +++ b/src/lib/component/ComponentFactory.h @@ -23,6 +23,7 @@ public: std::shared_ptr createCodeComponent(); std::shared_ptr createGraphComponent(); + std::shared_ptr createSearchComponent(); private: ComponentFactory(); diff --git a/src/lib/component/ComponentManager.cpp b/src/lib/component/ComponentManager.cpp index f5cfc12d..eada6b4d 100644 --- a/src/lib/component/ComponentManager.cpp +++ b/src/lib/component/ComponentManager.cpp @@ -28,11 +28,13 @@ void ComponentManager::setup() GraphView* graphView = graphComponent->getView(); graphView->addNode(Vec2i(-100, -100), "foo"); graphView->addNode(Vec2i(50, 50), "bar"); - m_components.push_back(graphComponent); std::shared_ptr codeComponent = m_componentFactory->createCodeComponent(); m_components.push_back(codeComponent); + + std::shared_ptr searchComponent = m_componentFactory->createSearchComponent(); + m_components.push_back(searchComponent); } ComponentManager::ComponentManager() diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index 8c0b40d9..305c2588 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -17,7 +17,9 @@ struct AnnotatedText Id tokenId; }; -class CodeController: public Controller, public MessageListener +class CodeController + : public Controller + , public MessageListener { public: CodeController(std::shared_ptr locationAccess); diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp new file mode 100644 index 00000000..31a60cfb --- /dev/null +++ b/src/lib/component/controller/SearchController.cpp @@ -0,0 +1,40 @@ +#include "component/controller/SearchController.h" + +#include "component/view/SearchView.h" +#include "data/access/GraphAccess.h" +#include "utility/messaging/type/MessageActivateToken.h" + +SearchController::SearchController(std::shared_ptr graphAccess) + : m_graphAccess(graphAccess) +{ +} + +SearchController::~SearchController() +{ +} + +void SearchController::search(const std::string& s) +{ + LOG_INFO("searching string: \"" + s + "\""); + Id nodeId = m_graphAccess->getIdForNodeWithName(s); + if (nodeId > 0) + { + LOG_INFO("Node with name \"" + s + "\" found."); + MessageActivateToken message(nodeId); + message.dispatch(); + } + else + { + LOG_INFO("Node with name \"" + s + "\" not found."); + } +} + +void SearchController::handleMessage(MessageActivateToken* message) +{ + getView()->setText(m_graphAccess->getNameForNodeWithId(message->tokenId)); +} + +SearchView* SearchController::getView() +{ + return Controller::getView(); +} diff --git a/src/lib/component/controller/SearchController.h b/src/lib/component/controller/SearchController.h new file mode 100644 index 00000000..de0f6b6e --- /dev/null +++ b/src/lib/component/controller/SearchController.h @@ -0,0 +1,31 @@ +#ifndef SEARCH_CONTROLLER_H +#define SEARCH_CONTROLLER_H + +#include + +#include "component/controller/Controller.h" +#include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/MessageActivateToken.h" + +class GraphAccess; +class SearchView; + +class SearchController + : public Controller + , public MessageListener +{ +public: + SearchController(std::shared_ptr graphAccess); + ~SearchController(); + + void search(const std::string& s); + //void autocomplete(const std::string& s); + +private: + virtual void handleMessage(MessageActivateToken* message); + SearchView* getView(); + + std::shared_ptr m_graphAccess; +}; + +#endif // SEARCH_CONTROLLER_H diff --git a/src/lib/component/view/SearchView.cpp b/src/lib/component/view/SearchView.cpp new file mode 100644 index 00000000..e111ff02 --- /dev/null +++ b/src/lib/component/view/SearchView.cpp @@ -0,0 +1,22 @@ +#include "component/view/SearchView.h" + +#include "component/controller/SearchController.h" + +SearchView::SearchView(ViewLayout* viewLayout) + : View(viewLayout, Vec2i(100, 100)) +{ +} + +SearchView::~SearchView() +{ +} + +std::string SearchView::getName() const +{ + return "SearchView"; +} + +SearchController* SearchView::getController() +{ + return View::getController(); +} diff --git a/src/lib/component/view/SearchView.h b/src/lib/component/view/SearchView.h new file mode 100644 index 00000000..9d2f2a91 --- /dev/null +++ b/src/lib/component/view/SearchView.h @@ -0,0 +1,22 @@ +#ifndef SEARCH_VIEW_H +#define SEARCH_VIEW_H + +#include "component/view/View.h" + +class SearchController; + +class SearchView : public View +{ +public: + SearchView(ViewLayout* viewLayout); + virtual ~SearchView(); + + virtual std::string getName() const; + + virtual void setText(const std::string& s) const = 0; + +protected: + SearchController* getController(); +}; + +#endif // SEARCH_VIEW_H \ No newline at end of file diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 53040772..d4d5fcb2 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -175,9 +175,20 @@ void Storage::logLocations() const LOG_INFO(str.str()); } -Token* Storage::getToken(Id tokenId) const + +Id Storage::getIdForNodeWithName(const std::string& name) const { - return m_graph.getTokenById(tokenId); // Todo: copy information. + Node* node = m_graph.findNode([&](Node* node){ + return node->getName() == name; + }); + + return (node ? node->getId() : 0); +} + +std::string Storage::getNameForNodeWithId(Id id) const +{ + Node* node = m_graph.getNodeById(id); + return (node ? node->getName() : ""); } TokenLocationCollection Storage::getTokenLocationsForTokenId(Id id) const diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 65533277..ca6f1829 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -45,8 +45,11 @@ public: void logGraph() const; void logLocations() const; - virtual Token* getToken(Id tokenId) const; + // GraphAccess implementation + virtual Id getIdForNodeWithName(const std::string& name) const; + virtual std::string getNameForNodeWithId(Id id) const; + // LocationAccess implementation virtual TokenLocationCollection getTokenLocationsForTokenId(Id locationId) const; virtual TokenLocationFile getTokenLocationsForLinesInFile( const std::string& fileName, unsigned int firstLineNumber, unsigned int lastLineNumber diff --git a/src/lib/data/access/GraphAccess.h b/src/lib/data/access/GraphAccess.h index 6c3d35bc..d2b231ed 100644 --- a/src/lib/data/access/GraphAccess.h +++ b/src/lib/data/access/GraphAccess.h @@ -1,6 +1,8 @@ #ifndef GRAPH_ACCESS_H #define GRAPH_ACCESS_H +#include + #include "utility/types.h" class Token; @@ -10,7 +12,8 @@ class GraphAccess public: virtual ~GraphAccess(); - virtual Token* getToken(Id tokenId) const = 0; + virtual Id getIdForNodeWithName(const std::string& name) const = 0; + virtual std::string getNameForNodeWithId(Id id) const = 0; }; diff --git a/src/lib/gui/GuiFactory.h b/src/lib/gui/GuiFactory.h index 736df1fe..17fdec75 100644 --- a/src/lib/gui/GuiFactory.h +++ b/src/lib/gui/GuiFactory.h @@ -6,6 +6,7 @@ class CodeView; class GraphView; class MainView; +class SearchView; class ViewLayout; class GuiFactory @@ -17,6 +18,7 @@ public: virtual std::shared_ptr createMainView() const = 0; virtual std::shared_ptr createCodeView(ViewLayout* viewLayout) const = 0; virtual std::shared_ptr createGraphView(ViewLayout* viewLayout) const = 0; + virtual std::shared_ptr createSearchView(ViewLayout* viewLayout) const = 0; }; #endif // GUI_FACTORY_H