diff --git a/bin/app/data/color_schemes/bad_rainbow.xml b/bin/app/data/color_schemes/bad_rainbow.xml
index 96a60d48..cbe55b37 100644
--- a/bin/app/data/color_schemes/bad_rainbow.xml
+++ b/bin/app/data/color_schemes/bad_rainbow.xml
@@ -455,4 +455,13 @@
#878787
#878787
+
+
+
+
+
diff --git a/bin/app/data/color_schemes/bright.xml b/bin/app/data/color_schemes/bright.xml
index 6a7c524d..fcc87ba3 100644
--- a/bin/app/data/color_schemes/bright.xml
+++ b/bin/app/data/color_schemes/bright.xml
@@ -422,4 +422,13 @@
grey
+
+
+
+
+
diff --git a/bin/app/data/color_schemes/dark.xml b/bin/app/data/color_schemes/dark.xml
index 71d51b35..dc0db031 100644
--- a/bin/app/data/color_schemes/dark.xml
+++ b/bin/app/data/color_schemes/dark.xml
@@ -429,4 +429,13 @@
#878787
#878787
+
+
+
+
+
diff --git a/bin/app/data/gui/bookmark_view/bookmark_view.css b/bin/app/data/gui/bookmark_view/bookmark_view.css
new file mode 100644
index 00000000..1bb3ca9b
--- /dev/null
+++ b/bin/app/data/gui/bookmark_view/bookmark_view.css
@@ -0,0 +1,310 @@
+/* General settings */
+* {
+ font-size: px;
+ /* font-family: ""; */
+}
+
+QPushButton {
+ border: 2px;
+ border-style: solid;
+ border-color: #dadada;
+ background: #f6f6f6;
+ background-position: 15px 5px;
+ border-radius: 12px;
+ margin: 2px;
+ width: 30px;
+ height: 25px;
+}
+
+QPushButton:hover {
+ background: #dadada;
+ /* color: white; */
+}
+
+#header {
+ background-color: #2d3e88;
+ /* background-color: transparent; */
+}
+
+#body {
+ background-color: white;
+}
+
+/* window */
+
+
+/* header */
+
+#header_background {
+ background-color: #2e3f83;
+ border-top-left-radius: 15px;
+ border-bottom-left-radius: 15px;
+}
+
+#filter_box, #order_box {
+ /* background-color: #227abf;
+ color: white; */
+ max-width: 100px;
+ min-width: 100px;
+ margin-left: 50px;
+ margin-right: 100px;
+}
+
+#title {
+ color: white;
+ font-size: px;
+ font-weight: bold;
+ margin-top: 40px;
+ margin-left: 30px;
+ margin-right: 20px;
+}
+
+#filter_label, #order_label {
+ color: white;
+ font-size: px;
+ font-weight: bold;
+ margin-top: 65px;
+ margin-left: 40px;
+ margin-right: 20px;
+}
+
+/* body */
+
+#bookmark_tree {
+ border: none;
+ margin: 0px;
+ margin-top: 50px;
+ margin-bottom: 25px;
+ max-width: 532px;
+ max-height: 460px;
+ background-color: white;
+ alternate-background-color: #dadada; /* color every single line alternating, however I want to color complete categories alternating */
+}
+
+#category_name {
+ font-size: px;
+}
+
+#bookmark_category {
+ margin-top: 14px;
+}
+
+#bookmark {
+ margin-top: 0px;
+}
+
+#close_button {
+ min-width: 150px;
+ max-width: 150px;
+}
+
+#close_button {
+ margin-right: 20px;
+ background-color: white;
+ color: black;
+ border-color: black;
+}
+
+#close_button:hover {
+ background: #2e3f83;
+ color: white;
+}
+
+/* bookmark category */
+
+#bookmark_category {
+ margin-left: 15px;
+ margin-right: 50px;
+}
+
+#category_expand_button {
+ border: none;
+ background: transparent;
+ min-width: 30px;
+ max-width: 30px;
+}
+
+#category_delete_button {
+ min-width: 30px;
+ max-width: 30px;
+ border: none;
+ background: transparent;
+}
+
+/* bookmark */
+
+#bookmark {
+ margin-left: 15px;
+ margin-right: 50px;
+}
+
+#comment_button {
+ background: transparent;
+ border: none;
+ min-width: 30px;
+ max-width: 30px;
+}
+
+#comment_button:hover {
+ color: #2D3C86;
+}
+
+#edit_button {
+ min-width: 30px;
+ max-width: 30px;
+ border: none;
+ background: transparent;
+}
+
+#delete_button {
+ min-width: 30px;
+ max-width: 30px;
+ border: none;
+ background: transparent;
+}
+
+#date_label {
+ font-size: px;
+ min-width: 100px;
+ max-width: 100px;
+}
+
+/* Search bar buttons */
+
+#bookmark_button, #show_bookmark_button {
+ background: ;
+ border: none;
+ border-radius: 12px;
+}
+
+#bookmark_button:disabled, #show_bookmark_button:disabled {
+ background: ;
+}
+
+#bookmark_button:hover, #show_bookmark_button:hover {
+ background: ;
+}
+
+#bookmark_button:pressed, #show_bookmark_button:pressed {
+ background: ;
+}
+
+#bookmark_button {
+ border-bottom-right-radius: 0px;
+ border-top-right-radius: 0px;
+ margin: 0px;
+ margin-right: 2px;
+}
+
+#show_bookmark_button {
+ border-bottom-left-radius: 0px;
+ border-top-left-radius: 0px;
+ margin: 0px;
+}
+
+/* Bookmark creator */
+
+#creator_header_background {
+ background-color: #2e3f83;
+ border-top-left-radius: 15px;
+ border-top-right-radius: 15px;
+}
+
+#display_name_edit {
+ border: 2px;
+ border-style: solid;
+ border-color: #dadada;
+ background: white;
+ border-radius: 12px;
+ margin-left: 30px;
+ margin-right: 30px;
+ min-height: 30px;
+ max-height: 30px;
+}
+
+#comment_box {
+ border: 2px;
+ border-style: solid;
+ border-color: #dadada;
+ background: white;
+ border-radius: 12px;
+ margin-left: 30px;
+ margin-right: 30px;
+ max-height: 160px;
+ min-height: 160px;
+}
+
+/*
+#category_box {
+ border: 2px;
+ border-style: solid;
+ border-color: #dadada;
+ background: white;
+ border-radius: 8px;
+ margin-left: 30px;
+ margin-right: 30px;
+ margin-bottom: 50px;
+ min-height: 30px;
+ max-height: 30px;
+}
+
+#category_box::down-arrow {
+ image: url(bookmark_view/images/arrow_down.png);
+}
+/**/
+
+#category_box {
+ margin-left: 30px;
+ margin-right: 30px;
+ margin-bottom: 50px;
+ min-height: 30px;
+ max-height: 30px;
+ border-color: #dadada;
+}
+
+#creator_title_label, #creator_name_label, #creator_comment_label, #category_label {
+ font-size: px;
+ font-weight: bold;
+ margin-left: 30px;
+ margin-right: 30px;
+}
+
+#creator_title_label {
+ font-size: px;
+ color: white;
+ margin-top: 25px;
+ margin-bottom: 0px;
+}
+
+#creator_name_label {
+ margin-top: 40px;
+}
+
+#creator_comment_label {
+ margin-top: 30px;
+}
+
+#category_label {
+ margin-top: 35px;
+}
+
+#creator_cancel_button, #creator_create_button {
+ min-width: 130px;
+ max-width: 130px;
+ margin-left: 30px;
+ margin-right: 30px;
+ margin-bottom: 20px;
+ background-color: white;
+ border-color: black;
+}
+
+
+#creator_cancel_button:hover {
+ background: #2e3f83;
+ color: white;
+}
+
+#creator_create_button:hover {
+ background: #2e3f83;
+ color: white;
+}
\ No newline at end of file
diff --git a/bin/app/data/gui/bookmark_view/images/arrow_down.png b/bin/app/data/gui/bookmark_view/images/arrow_down.png
new file mode 100644
index 00000000..2f5c56c8
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/arrow_down.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/arrow_right.png b/bin/app/data/gui/bookmark_view/images/arrow_right.png
new file mode 100644
index 00000000..f12ba7df
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/arrow_right.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/bookmark_active.png b/bin/app/data/gui/bookmark_view/images/bookmark_active.png
new file mode 100644
index 00000000..5fc72521
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/bookmark_active.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/bookmark_delete_icon.png b/bin/app/data/gui/bookmark_view/images/bookmark_delete_icon.png
new file mode 100644
index 00000000..bc8dfc75
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/bookmark_delete_icon.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/bookmark_edit_icon.png b/bin/app/data/gui/bookmark_view/images/bookmark_edit_icon.png
new file mode 100644
index 00000000..8ab52cd8
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/bookmark_edit_icon.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/bookmark_icon.png b/bin/app/data/gui/bookmark_view/images/bookmark_icon.png
new file mode 100644
index 00000000..2f4366a3
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/bookmark_icon.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/bookmark_icon_2.png b/bin/app/data/gui/bookmark_view/images/bookmark_icon_2.png
new file mode 100644
index 00000000..3114024f
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/bookmark_icon_2.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/bookmark_list_icon.png b/bin/app/data/gui/bookmark_view/images/bookmark_list_icon.png
new file mode 100644
index 00000000..10f40556
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/bookmark_list_icon.png differ
diff --git a/bin/app/data/gui/bookmark_view/images/edit_bookmark_icon.png b/bin/app/data/gui/bookmark_view/images/edit_bookmark_icon.png
new file mode 100644
index 00000000..a9f61f9f
Binary files /dev/null and b/bin/app/data/gui/bookmark_view/images/edit_bookmark_icon.png differ
diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt
index 079df710..75d76378 100644
--- a/bin/test/data/log/test_log.txt
+++ b/bin/test/data/log/test_log.txt
@@ -2,6 +2,49 @@ Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
Token.cpp ERROR: Location Id was not referenced by this Token.
Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class
Edge.cpp ERROR: Nodes are not plain copies.
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
+ INFO: Indexer - indexing source file: input.cc
INFO: send MessageStatus Enabled console and file logging.
INFO: send TestMessage
INFO: send TestMessage
@@ -30,46 +73,3 @@ TextAccess.cpp WARNING: Line numbers start with one, is 0
TextAccess.cpp WARNING: Line numbers start with one, is 0
TokenLocationCollection.cpp ERROR: TokenLocation has wrong boundaries: file.c 2:3 2:1
TokenLocationCollection.cpp ERROR: TokenLocation has wrong boundaries: file.c 4:1 1:10
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
- INFO: Indexer - indexing source file: input.cc
diff --git a/cmake/publicKey.cmake b/cmake/publicKey.cmake
index aa0d5b48..b948d0d6 100644
--- a/cmake/publicKey.cmake
+++ b/cmake/publicKey.cmake
@@ -4,9 +4,9 @@
string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_VERSION_NUMBER}")
message(STATUS "Get Public Key for Coati version: ${VERSION_MAJOR}")
-message(STATUS "${CMAKE_SOURCE_DIR}/setup/RSA_keys/public-${VERSION_MAJOR}.pem")
+message(STATUS "${CMAKE_SOURCE_DIR}/setup/RSA_keys/public-0.pem") # explain in Readme.md how to get this to work first
-set(pubKeyFile "${CMAKE_SOURCE_DIR}/setup/RSA_keys/public-${VERSION_MAJOR}.pem")
+set(pubKeyFile "${CMAKE_SOURCE_DIR}/setup/RSA_keys/public-0.pem") # explain in Readme.md how to get this to work first
# message(STATUS "file: ${pubKeyFile}")
if(EXISTS ${pubKeyFile})
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 46fc5bc7..4f5b81b1 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -102,6 +102,8 @@ int main(int argc, char *argv[])
{
QApplication::setApplicationName("Coati");
+ setupLogging();
+
if (QSysInfo::windowsVersion() != QSysInfo::WV_None)
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
@@ -127,7 +129,7 @@ int main(int argc, char *argv[])
setupApp(argc, argv);
- setupLogging();
+ // setupLogging(); // why would you setup logging that late? the logger is possibly already in use before this line!!
Application::createInstance(version, nullptr, nullptr);
ScopedFunctor f([](){
@@ -179,7 +181,7 @@ int main(int argc, char *argv[])
setupApp(argc, argv);
- setupLogging();
+ // setupLogging(); // why would you setup logging that late? the logger is possibly already in use before this line!!
qtApp.setAttribute(Qt::AA_UseHighDpiPixmaps);
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 36819a57..e7bc0c67 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -13,6 +13,8 @@ add_files(
component/controller/helper/SnippetMerger.cpp
component/controller/helper/SnippetMerger.h
+ component/controller/BookmarkController.cpp
+ component/controller/BookmarkController.h
component/controller/CodeController.cpp
component/controller/CodeController.h
component/controller/Controller.cpp
@@ -42,6 +44,8 @@ add_files(
component/view/helper/CodeSnippetParams.cpp
component/view/helper/CodeSnippetParams.h
+ component/view/BookmarkView.cpp
+ component/view/BookmarkView.h
component/view/CodeView.cpp
component/view/CodeView.h
component/view/CompositeView.cpp
@@ -92,6 +96,15 @@ add_files(
data/access/StorageAccessProxy.cpp
data/access/StorageAccessProxy.h
+ data/bookmark/Bookmark.cpp
+ data/bookmark/Bookmark.h
+ data/bookmark/BookmarkCategory.cpp
+ data/bookmark/BookmarkCategory.h
+ data/bookmark/EdgeBookmark.cpp
+ data/bookmark/EdgeBookmark.h
+ data/bookmark/NodeBookmark.cpp
+ data/bookmark/NodeBookmark.h
+
data/fulltextsearch/FullTextSearchIndex.cpp
data/fulltextsearch/FullTextSearchIndex.h
data/fulltextsearch/SuffixArray.cpp
@@ -249,6 +262,7 @@ add_files(
utility/math/VectorBase.h
utility/messaging/type/MessageActivateAll.h
+ utility/messaging/type/MessageActivateBookmark.h
utility/messaging/type/MessageActivateEdge.h
utility/messaging/type/MessageActivateFile.h
utility/messaging/type/MessageActivateLocalSymbols.h
@@ -264,8 +278,17 @@ add_files(
utility/messaging/type/MessageCodeReference.h
utility/messaging/type/MessageCodeViewExpandedInitialFiles.h
utility/messaging/type/MessageColorSchemeTest.h
+ utility/messaging/type/MessageCreateBookmark.h
+ utility/messaging/type/MessageCreateBookmarkCategory.h
utility/messaging/type/MessageDeactivateEdge.h
+ utility/messaging/type/MessageDeleteBookmark.h
+ utility/messaging/type/MessageDeleteBookmarkCategoryWithBookmarks.h
+ utility/messaging/type/MessageDeleteBookmarkForActiveTokens.h
utility/messaging/type/MessageDispatchWhenLicenseValid.h
+ utility/messaging/type/MessageDisplayBookmarkCreator.h
+ utility/messaging/type/MessageDisplayBookmarkEditor.h
+ utility/messaging/type/MessageDisplayBookmarks.h
+ utility/messaging/type/MessageEditBookmark.h
utility/messaging/type/MessageEnteredLicense.h
utility/messaging/type/MessageErrorFilterChanged.h
utility/messaging/type/MessageFind.h
diff --git a/src/lib/component/ComponentFactory.cpp b/src/lib/component/ComponentFactory.cpp
index bb2aa278..5f24f953 100644
--- a/src/lib/component/ComponentFactory.cpp
+++ b/src/lib/component/ComponentFactory.cpp
@@ -1,6 +1,7 @@
#include "component/ComponentFactory.h"
#include "component/Component.h"
+#include "component/controller/BookmarkController.h"
#include "component/controller/CodeController.h"
#include "component/controller/ErrorController.h"
#include "component/controller/FeatureController.h"
@@ -11,6 +12,7 @@
#include "component/controller/StatusBarController.h"
#include "component/controller/StatusController.h"
#include "component/controller/UndoRedoController.h"
+#include "component/view/BookmarkView.h"
#include "component/view/CodeView.h"
#include "component/view/ErrorView.h"
#include "component/view/GraphView.h"
@@ -48,6 +50,14 @@ StorageAccess* ComponentFactory::getStorageAccess() const
return m_storageAccess;
}
+std::shared_ptr ComponentFactory::createBookmarkComponent(ViewLayout* viewLayout)
+{
+ std::shared_ptr view = m_viewFactory->createBookmarkView(viewLayout);
+ std::shared_ptr controller = std::make_shared(m_storageAccess);
+
+ return std::make_shared(view, controller);
+}
+
std::shared_ptr ComponentFactory::createCodeComponent(ViewLayout* viewLayout)
{
std::shared_ptr view = m_viewFactory->createCodeView(viewLayout);
diff --git a/src/lib/component/ComponentFactory.h b/src/lib/component/ComponentFactory.h
index c0fddce5..5c3990bd 100644
--- a/src/lib/component/ComponentFactory.h
+++ b/src/lib/component/ComponentFactory.h
@@ -19,6 +19,7 @@ public:
ViewFactory* getViewFactory() const;
StorageAccess* getStorageAccess() const;
+ std::shared_ptr createBookmarkComponent(ViewLayout* viewLayout);
std::shared_ptr createCodeComponent(ViewLayout* viewLayout);
std::shared_ptr createErrorComponent(ViewLayout* viewLayout);
std::shared_ptr createFeatureComponent();
diff --git a/src/lib/component/ComponentManager.cpp b/src/lib/component/ComponentManager.cpp
index 437ea2e5..dbfc9183 100644
--- a/src/lib/component/ComponentManager.cpp
+++ b/src/lib/component/ComponentManager.cpp
@@ -33,6 +33,9 @@ void ComponentManager::setup(ViewLayout* viewLayout)
m_componentFactory->getViewFactory()->createCompositeView(viewLayout, CompositeView::DIRECTION_HORIZONTAL, "Search");
m_compositeViews.push_back(compositeView);
+ std::shared_ptr bookmarkComponent = m_componentFactory->createBookmarkComponent(compositeView.get());
+ m_components.push_back(bookmarkComponent);
+
std::shared_ptr undoRedoComponent = m_componentFactory->createUndoRedoComponent(compositeView.get());
m_components.push_back(undoRedoComponent);
diff --git a/src/lib/component/controller/BookmarkController.cpp b/src/lib/component/controller/BookmarkController.cpp
new file mode 100644
index 00000000..bbaa9042
--- /dev/null
+++ b/src/lib/component/controller/BookmarkController.cpp
@@ -0,0 +1,727 @@
+#include "BookmarkController.h"
+
+#include "component/view/BookmarkView.h"
+
+#include "data/access/StorageAccess.h"
+#include "data/bookmark/Bookmark.h"
+
+#include "data/location/TokenLocation.h"
+#include "data/location/TokenLocationCollection.h"
+#include "data/location/TokenLocationFile.h"
+
+#include "utility/messaging/type/MessageActivateEdge.h"
+#include "utility/messaging/type/MessageActivateNodes.h"
+
+#include "utility/logging/logging.h"
+#include "utility/utilityString.h"
+
+#include "data/bookmark/EdgeBookmark.h"
+#include "data/bookmark/NodeBookmark.h"
+
+const std::string BookmarkController::m_edgeSeperatorToken = "=>";
+
+BookmarkController::BookmarkController(StorageAccess* storageAccess)
+ : m_storageAccess(storageAccess)
+ , m_activeTokens()
+ , m_activeTokenNames()
+ , m_activeTokenDisplayNames()
+ , m_activeTokenTypes()
+ , m_activeEdges()
+ , m_activeEdgeNames()
+ , m_activeEdgeDisplayNames()
+ , m_activeEdgeTypes()
+ , m_activeTokenExists(false)
+{
+}
+
+BookmarkController::~BookmarkController()
+{
+}
+
+void BookmarkController::clear()
+{
+}
+
+std::vector> BookmarkController::getAllBookmarks() const
+{
+ LOG_INFO_STREAM(<< "Retrieving all bookmarks");
+
+ std::vector> bookmarks;
+
+ std::vector nodeBookmarks = m_storageAccess->getAllNodeBookmarks();
+
+ for (unsigned int i = 0; i < nodeBookmarks.size(); i++)
+ {
+ bookmarks.push_back(std::make_shared(nodeBookmarks[i]));
+ }
+
+ std::vector edgeBookmarks = m_storageAccess->getAllEdgeBookmarks();
+
+ for (unsigned int i = 0; i < edgeBookmarks.size(); i++)
+ {
+ bookmarks.push_back(std::make_shared(edgeBookmarks[i]));
+ }
+
+ // std::vector bookmarks = m_storageAccess->getAllBookmarks();
+
+ // check whether bookmarks are still valid (so, no referenced tokens have been removed)
+ for (unsigned int i = 0; i < bookmarks.size(); i++)
+ {
+ for (unsigned int j = 0; j < bookmarks[i]->getTokenNames().size(); j++)
+ {
+ std::string name = bookmarks[i]->getTokenNames()[j];
+ int type = bookmarks[i]->getTokenTypes()[j];
+
+ bool exists = false;
+
+ if (dynamic_cast(bookmarks[i].get()) != NULL)
+ {
+ TempEdge tmpEdge = getEdge(name, type);
+
+ exists = m_storageAccess->checkEdgeExists(tmpEdge.edgeId);
+ }
+ else
+ {
+ exists = m_storageAccess->checkNodeExistsByName(name);
+ }
+
+ std::vector tokenIds = bookmarks[i]->getTokenIds();
+
+ bookmarks[i]->setValid(exists);
+ }
+ }
+
+
+
+ return bookmarks;
+}
+
+std::vector> BookmarkController::getBookmarks(const MessageDisplayBookmarks::BookmarkFilter& filter, const MessageDisplayBookmarks::BookmarkOrder& order) const
+{
+ LOG_INFO_STREAM(<< "Retrieving bookmarks with filter '" << std::to_string(filter) << "' and order '" << std::to_string(order) << "'");
+
+ std::vector> bookmarks = getAllBookmarks();
+
+ int bookmarkCount = bookmarks.size();
+ bookmarks = getFilteredBookmarks(bookmarks, filter);
+
+ bookmarkCount = bookmarks.size();
+ bookmarks = getOrderedBookmarks(bookmarks, order);
+
+ return bookmarks;
+}
+
+std::vector BookmarkController::getActiveTokenNames() const
+{
+ return m_activeTokenNames;
+}
+
+std::vector BookmarkController::getActiveTokenDisplayNames() const
+{
+ if (m_activeEdgeDisplayNames.size() > 0)
+ {
+ return m_activeEdgeDisplayNames;
+ }
+ else
+ {
+ return m_activeTokenDisplayNames;
+ }
+}
+
+std::vector BookmarkController::getAllBookmarkCategories() const
+{
+ return m_storageAccess->getAllBookmarkCategories();
+}
+
+bool BookmarkController::activeTokenExists() const
+{
+ return m_activeTokenExists;
+}
+
+std::shared_ptr BookmarkController::getBookmarkForActiveToken() const
+{
+ if (m_activeEdgeNames.size() > 0)
+ {
+ std::vector bookmarks = m_storageAccess->getAllEdgeBookmarks();
+
+ for (unsigned int i = 0; i < bookmarks.size(); i++)
+ {
+ if (bookmarks[i].getTokenNames() == m_activeEdgeNames)
+ {
+ return std::make_shared(bookmarks[i]);
+ }
+ }
+ }
+ else
+ {
+ std::vector bookmarks = m_storageAccess->getAllNodeBookmarks();
+
+ for (unsigned int i = 0; i < bookmarks.size(); i++)
+ {
+ if (bookmarks[i].getTokenNames() == m_activeTokenNames)
+ {
+ return std::make_shared(bookmarks[i]);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void BookmarkController::handleMessage(MessageActivateBookmark* message)
+{
+ LOG_INFO_STREAM(<< "Attempting to activate Bookmark");
+
+ if (dynamic_cast(message->bookmark.get()) != NULL)
+ {
+ EdgeBookmark* bookmark = dynamic_cast(message->bookmark.get());
+
+ NodeBookmark baseBookmark = bookmark->getBaseBookmark();
+
+ MessageActivateNodes activateNodes;
+
+ for (unsigned int i = 0; i < baseBookmark.getTokenNames().size(); i++)
+ {
+ NameHierarchy nh = NameHierarchy::deserialize(baseBookmark.getTokenNames()[i]);
+ activateNodes.addNode(nh);
+ }
+
+ activateNodes.dispatch();
+
+ NameHierarchy source;
+ NameHierarchy target;
+ for (unsigned int i = 0; i < bookmark->getTokenNames().size(); i++)
+ {
+ int tokenType = bookmark->getTokenTypes()[i];
+ TempEdge tmpEdge = getEdge(bookmark->getTokenNames()[i], tokenType);
+
+ MessageActivateEdge activateEdge(tmpEdge.edgeId, Edge::intToType(tokenType), tmpEdge.source, tmpEdge.target);
+ activateEdge.dispatch();
+ }
+ }
+ else
+ {
+ NodeBookmark* bookmark = dynamic_cast(message->bookmark.get());
+
+ MessageActivateNodes activateNodes;
+
+ for (unsigned int i = 0; i < bookmark->getTokenNames().size(); i++)
+ {
+ NameHierarchy nh = NameHierarchy::deserialize(bookmark->getTokenNames()[i]);
+ activateNodes.addNode(nh);
+ }
+
+ activateNodes.dispatch();
+ }
+}
+
+void BookmarkController::handleMessage(MessageActivateTokens* message)
+{
+ LOG_INFO_STREAM(<< "Registering new active token");
+
+ if (message->isEdge)
+ {
+ LOG_INFO_STREAM(<< "Registering new Edge");
+
+ std::vector tokenNames;
+ std::vector tokenDisplayNames;
+ std::vector tokenTypes;
+
+ for (unsigned int i = 0; i < message->tokenIds.size(); i++)
+ {
+ StorageEdge edge = m_storageAccess->getEdgeById(message->tokenIds[i]);
+
+ int typeId = edge.type;
+
+ tokenTypes.push_back(typeId);
+
+ NameHierarchy sourceHierarchy = m_storageAccess->getNameHierarchyForNodeWithId(edge.sourceNodeId);
+ NameHierarchy targetHierarchy = m_storageAccess->getNameHierarchyForNodeWithId(edge.targetNodeId);
+
+ std::string sourceNode = NameHierarchy::serialize(sourceHierarchy);
+ std::string targetNode = NameHierarchy::serialize(targetHierarchy);
+
+ std::string tokenName = sourceNode + m_edgeSeperatorToken + targetNode;
+
+ tokenNames.push_back(tokenName);
+
+ tokenDisplayNames.push_back(sourceHierarchy.getRawName() + m_edgeSeperatorToken + targetHierarchy.getRawName());
+ }
+
+ m_activeEdges = message->tokenIds;
+ m_activeEdgeNames = tokenNames;
+ m_activeEdgeTypes = tokenTypes;
+ m_activeEdgeDisplayNames = tokenDisplayNames;
+
+ if (m_storageAccess->checkEdgeBookmarkExistsByTokens(tokenNames))
+ {
+ m_activeTokenExists = true;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::ALREADY_CREATED);
+ }
+ else
+ {
+ m_activeTokenExists = false;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::CAN_CREATE);
+ }
+ }
+ else
+ {
+ LOG_INFO_STREAM(<< "Registering new Node");
+
+ m_activeTokens = message->tokenIds;
+ m_activeTokenNames = getTokenNames(m_activeTokens);
+ m_activeTokenTypes = getTokenTypes(m_activeTokens);
+ m_activeTokenDisplayNames = getTokenDisplayNames(m_activeTokens);
+
+ m_activeEdges.clear();
+ m_activeEdgeNames.clear();
+ m_activeEdgeTypes.clear();
+ m_activeEdgeDisplayNames.clear();
+
+ if (m_storageAccess->checkNodeBookmarkExistsByTokens(m_activeTokenNames))
+ {
+ m_activeTokenExists = true;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::ALREADY_CREATED);
+ }
+ else
+ {
+ m_activeTokenExists = false;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::CAN_CREATE);
+ }
+ }
+}
+
+void BookmarkController::handleMessage(MessageCreateBookmark* message)
+{
+ LOG_INFO_STREAM(<< "Attempting to create new bookmark");
+
+ if (m_activeTokens.size() > 0)
+ {
+ if (m_activeEdges.size() > 0)
+ {
+ LOG_INFO_STREAM(<< "Creating Edge Bookmark");
+
+ std::string displayName = message->displayName;
+ if (displayName.size() <= 0)
+ {
+ displayName = getDisplayName(m_activeTokens[0]);
+ }
+
+ EdgeBookmark bookmark(displayName, m_activeTokens, m_activeTokenNames, message->comment, TimePoint::now());
+
+ bookmark.setDisplayName(message->displayName);
+ bookmark.setComment(message->comment);
+ bookmark.setTokenTypes(m_activeTokenTypes);
+
+ BookmarkCategory category;
+ category.setName(message->categoryName);
+
+ bookmark.setCategory(category);
+
+ bookmark.setEdgeTokenIds(m_activeEdges);
+ bookmark.setEdgeTokenNames(m_activeEdgeNames);
+ bookmark.setEdgeTokenTypes(m_activeEdgeTypes);
+
+ Id id = m_storageAccess->addEdgeBookmark(bookmark);
+
+ bookmark.setId(id);
+
+ m_activeTokenExists = true;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::ALREADY_CREATED);
+ getView()->update();
+ }
+ else
+ {
+ LOG_INFO_STREAM(<< "Creating Node Bookmark");
+
+ std::string displayName = message->displayName;
+ if (displayName.size() <= 0)
+ {
+ displayName = getDisplayName(m_activeTokens[0]);
+ }
+
+ NodeBookmark bookmark(displayName, m_activeTokens, m_activeTokenNames, message->comment, TimePoint::now());
+
+ bookmark.setTokenTypes(m_activeTokenTypes);
+
+ BookmarkCategory category;
+ category.setName(message->categoryName);
+
+ bookmark.setCategory(category);
+
+ Id id = m_storageAccess->addNodeBookmark(bookmark);
+
+ bookmark.setId(id);
+
+ m_activeTokenExists = true;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::ALREADY_CREATED);
+ getView()->update();
+ }
+ }
+}
+
+void BookmarkController::handleMessage(MessageCreateBookmarkCategory* message)
+{
+ std::string categoryName = message->name;
+ LOG_INFO_STREAM(<< "Attempting to create new Bookmark category '" << categoryName << "'");
+
+ if (m_storageAccess->checkBookmarkCategoryExists(message->name) == false)
+ {
+ BookmarkCategory category;
+ category.setName(message->name);
+
+ m_storageAccess->addBookmarkCategory(category);
+ }
+}
+
+void BookmarkController::handleMessage(MessageDeleteBookmark* message)
+{
+ LOG_INFO_STREAM(<< "Attempting to delete Bookmark " << std::to_string(message->bookmarkId));
+
+ if (message->isEdge)
+ {
+ m_storageAccess->removeEdgeBookmark(message->bookmarkId);
+ }
+ else
+ {
+ m_storageAccess->removeNodeBookmark(message->bookmarkId);
+ }
+
+ cleanBookmarkCategories();
+
+ getView()->update();
+}
+
+void BookmarkController::handleMessage(MessageDeleteBookmarkCategoryWithBookmarks* message)
+{
+ std::vector categories = m_storageAccess->getAllBookmarkCategories();
+
+ for (unsigned int i = 0; i < categories.size(); i++)
+ {
+ if (categories[i].getId() == message->categoryId)
+ {
+ std::vector nodeBookmarks = m_storageAccess->getAllNodeBookmarks();
+ for (unsigned int j = 0; j < nodeBookmarks.size(); j++)
+ {
+ if (nodeBookmarks[j].getCategory().getName() == categories[i].getName())
+ {
+ m_storageAccess->removeNodeBookmark(nodeBookmarks[j].getId());
+ }
+ }
+
+ std::vector edgeBookmarks = m_storageAccess->getAllEdgeBookmarks();
+ for (unsigned int j = 0; j < edgeBookmarks.size(); j++)
+ {
+ if (edgeBookmarks[j].getCategory().getName() == categories[i].getName())
+ {
+ m_storageAccess->removeEdgeBookmark(edgeBookmarks[j].getId());
+ }
+ }
+
+ cleanBookmarkCategories();
+ getView()->update();
+
+ return;
+ }
+ }
+}
+
+void BookmarkController::handleMessage(MessageDeleteBookmarkForActiveTokens* message)
+{
+ std::shared_ptr bookmark = getBookmarkForActiveToken();
+
+ if (bookmark != NULL)
+ {
+ LOG_INFO_STREAM(<< "Deleting bookmark " << bookmark->getDisplayName());
+
+ if (dynamic_cast(bookmark.get()) != NULL)
+ {
+ m_storageAccess->removeEdgeBookmark(bookmark->getId());
+ }
+ else if(dynamic_cast(bookmark.get()) != NULL)
+ {
+ m_storageAccess->removeNodeBookmark(bookmark->getId());
+ }
+
+ cleanBookmarkCategories();
+
+ m_activeTokenExists = false;
+ getView()->setCreateButtonState(BookmarkView::CreateButtonState::CAN_CREATE);
+ getView()->update();
+ }
+ else
+ {
+ LOG_WARNING_STREAM(<< "No Bookmark to delete for active tokens.");
+ }
+}
+
+void BookmarkController::handleMessage(MessageEditBookmark* message)
+{
+ LOG_INFO_STREAM(<< "Attempting to update Bookmark " << std::to_string(message->bookmarkId));
+
+ if (message->isEdge)
+ {
+ EdgeBookmark bookmark = m_storageAccess->getEdgeBookmarkById(message->bookmarkId);
+
+ bookmark.setDisplayName(message->displayName);
+ bookmark.setComment(message->comment);
+ BookmarkCategory category;
+ category.setName(message->categoryName);
+ bookmark.setCategory(category);
+
+ m_storageAccess->editEdgeBookmark(bookmark);
+ }
+ else
+ {
+ NodeBookmark bookmark = m_storageAccess->getNodeBookmarkById(message->bookmarkId);
+
+ bookmark.setDisplayName(message->displayName);
+ bookmark.setComment(message->comment);
+ BookmarkCategory category;
+ category.setName(message->categoryName);
+ bookmark.setCategory(category);
+
+ m_storageAccess->editNodeBookmark(bookmark);
+ }
+
+ getView()->update();
+}
+
+void BookmarkController::handleMessage(MessageFinishedParsing* message)
+{
+ getView()->enableDisplayBookmarks(true);
+}
+
+std::vector BookmarkController::getTokenNames(const std::vector& ids) const
+{
+ std::vector names;
+
+ for (unsigned int i = 0; i < ids.size(); i++)
+ {
+ NameHierarchy nameHierarchy = m_storageAccess->getNameHierarchyForNodeWithId(ids[i]);
+ names.push_back(NameHierarchy::serialize(nameHierarchy));
+ }
+
+ return names;
+}
+
+std::vector BookmarkController::getTokenDisplayNames(const std::vector& ids) const
+{
+ std::vector names;
+
+ for (unsigned int i = 0; i < ids.size(); i++)
+ {
+ NameHierarchy nameHierarchy = m_storageAccess->getNameHierarchyForNodeWithId(ids[i]);
+ names.push_back(nameHierarchy.getRawName());
+ }
+
+ return names;
+}
+
+std::vector BookmarkController::getTokenTypes(const std::vector& ids) const
+{
+ std::vector types;
+
+ for (unsigned int i = 0; i < ids.size(); i++)
+ {
+ int type = m_storageAccess->getNodeTypeForNodeWithId(ids[i]);
+ types.push_back(type);
+ }
+
+ return types;
+}
+
+std::string BookmarkController::getDisplayName(Id id) const
+{
+ NameHierarchy nameHierarchy = m_storageAccess->getNameHierarchyForNodeWithId(id);
+ return nameHierarchy.getRawName();
+}
+
+BookmarkController::TempEdge BookmarkController::getEdge(const std::string& tokenName, const int tokenType) const
+{
+ std::pair edgeTokens = seperateEdgeToken(tokenName);
+
+ NameHierarchy source = NameHierarchy::deserialize(edgeTokens.first);
+ NameHierarchy target = NameHierarchy::deserialize(edgeTokens.second);
+
+ Id edgeId = m_storageAccess->getIdForEdge(Edge::intToType(tokenType), source, target);
+
+ TempEdge result;
+
+ result.edgeId = edgeId;
+ result.source = source;
+ result.target = target;
+ result.type = tokenType;
+
+ return result;
+}
+
+std::pair BookmarkController::seperateEdgeToken(const std::string& token) const
+{
+ std::pair result;
+
+ if (token.find(m_edgeSeperatorToken) != std::string::npos)
+ {
+ std::vector st = utility::splitToVector(token, m_edgeSeperatorToken);
+
+ if (st.size() != 2)
+ {
+ LOG_ERROR_STREAM(<< "Invalid edge token found: " << token);
+
+ return result;
+ }
+ else
+ {
+ result.first = st[0];
+ result.second = st[1];
+ }
+ }
+
+ return result;
+}
+
+std::vector> BookmarkController::getFilteredBookmarks(const std::vector>& bookmarks, const MessageDisplayBookmarks::BookmarkFilter& filter) const
+{
+ std::vector> result;
+
+ if (filter == MessageDisplayBookmarks::BookmarkFilter::ALL)
+ {
+ return bookmarks;
+ }
+ else if (filter == MessageDisplayBookmarks::BookmarkFilter::NODES)
+ {
+ for (unsigned int i = 0; i < bookmarks.size(); i++)
+ {
+ if (dynamic_cast(bookmarks[i].get()) == NULL)
+ {
+ result.push_back(bookmarks[i]);
+ }
+ }
+
+ return result;
+ }
+ else if (filter == MessageDisplayBookmarks::BookmarkFilter::EDGES)
+ {
+ for (unsigned int i = 0; i < bookmarks.size(); i++)
+ {
+ if (dynamic_cast(bookmarks[i].get()) != NULL)
+ {
+ result.push_back(bookmarks[i]);
+ }
+ }
+
+ return result;
+ }
+
+ return result;
+}
+
+std::vector> BookmarkController::getOrderedBookmarks(const std::vector>& bookmarks, const MessageDisplayBookmarks::BookmarkOrder& order) const
+{
+ std::vector> result = bookmarks;
+
+ if (order == MessageDisplayBookmarks::BookmarkOrder::DATE_ASCENDING)
+ {
+ return getDateOrderedBookmarks(result, true);
+ }
+ else if (order == MessageDisplayBookmarks::BookmarkOrder::DATE_DESCENDING)
+ {
+ return getDateOrderedBookmarks(result, false);
+ }
+ else if (order == MessageDisplayBookmarks::BookmarkOrder::NAME_ASCENDING)
+ {
+ return getNameOrderedBookmarks(result, true);
+ }
+ else if (order == MessageDisplayBookmarks::BookmarkOrder::NAME_DESCENDING)
+ {
+ return getNameOrderedBookmarks(result, false);
+ }
+
+ return result;
+}
+
+std::vector> BookmarkController::getDateOrderedBookmarks(const std::vector>& bookmarks, const bool ascending) const
+{
+ std::vector> result = bookmarks;
+
+ std::sort(result.begin(), result.end(), BookmarkController::bookmarkDateCompare);
+
+ if (ascending == false)
+ {
+ std::reverse(result.begin(), result.end());
+ }
+
+ return result;
+}
+
+std::vector> BookmarkController::getNameOrderedBookmarks(const std::vector>& bookmarks, const bool ascending) const
+{
+ std::vector> result = bookmarks;
+
+ std::sort(result.begin(), result.end(), BookmarkController::bookmarkNameCompare);
+
+ if (ascending == false)
+ {
+ std::reverse(result.begin(), result.end());
+ }
+
+ return result;
+}
+
+void BookmarkController::cleanBookmarkCategories()
+{
+ std::vector> bookmarks = getAllBookmarks();
+
+ std::vector categories = getAllBookmarkCategories();
+
+ for (unsigned int i = 0; i < categories.size(); i++)
+ {
+ BookmarkCategory category = categories[i];
+ bool used = false;
+
+ for (unsigned int j = 0; j < bookmarks.size(); j++)
+ {
+ if (bookmarks[j]->getCategory().getName() == category.getName())
+ {
+ used = true;
+ break;
+ }
+ }
+
+ if (used == false)
+ {
+ m_storageAccess->removeBookmarkCategory(category.getId());
+ }
+ }
+}
+
+bool BookmarkController::bookmarkDateCompare(const std::shared_ptr a, const std::shared_ptr b)
+{
+ return a->getTimeStamp() < b->getTimeStamp();
+}
+
+bool BookmarkController::bookmarkNameCompare(const std::shared_ptr a, const std::shared_ptr b)
+{
+ std::string aName = a->getDisplayName();
+ std::string bName = b->getDisplayName();
+
+ aName = utility::toLowerCase(aName);
+ bName = utility::toLowerCase(bName);
+
+ unsigned int i = 0;
+ while (i < aName.length() && i < bName.length())
+ {
+ if (std::tolower(aName[i]) < std::tolower(bName[i]))
+ {
+ return true;
+ }
+ else if (std::tolower(aName[i]) > std::tolower(bName[i]))
+ {
+ return false;
+ }
+
+ ++i;
+ }
+
+ return aName.length() < bName.length();
+}
\ No newline at end of file
diff --git a/src/lib/component/controller/BookmarkController.h b/src/lib/component/controller/BookmarkController.h
new file mode 100644
index 00000000..0ec3aef0
--- /dev/null
+++ b/src/lib/component/controller/BookmarkController.h
@@ -0,0 +1,104 @@
+#ifndef BOOKMARK_CONTROLLER_H
+#define BOOKMARK_CONTROLLER_H
+
+#include "data/bookmark/Bookmark.h"
+#include "data/name/NameHierarchy.h"
+
+#include "utility/messaging/MessageListener.h"
+#include "utility/messaging/type/MessageActivateBookmark.h"
+#include "utility/messaging/type/MessageActivateTokens.h"
+#include "utility/messaging/type/MessageCreateBookmark.h"
+#include "utility/messaging/type/MessageCreateBookmarkCategory.h"
+#include "utility/messaging/type/MessageDeleteBookmark.h"
+#include "utility/messaging/type/MessageDeleteBookmarkCategoryWithBookmarks.h"
+#include "utility/messaging/type/MessageDeleteBookmarkForActiveTokens.h"
+#include "utility/messaging/type/MessageDisplayBookmarks.h"
+#include "utility/messaging/type/MessageEditBookmark.h"
+#include "utility/messaging/type/MessageFinishedParsing.h"
+
+#include "component/controller/Controller.h"
+
+class StorageAccess;
+
+class BookmarkController
+ : public Controller
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+{
+public:
+ BookmarkController(StorageAccess* storageAccess);
+ virtual ~BookmarkController();
+
+ virtual void clear();
+
+ std::vector> getAllBookmarks() const;
+ std::vector> getBookmarks(const MessageDisplayBookmarks::BookmarkFilter& filter, const MessageDisplayBookmarks::BookmarkOrder& order) const;
+
+ std::vector getActiveTokenNames() const;
+ std::vector getActiveTokenDisplayNames() const;
+ std::vector getAllBookmarkCategories() const;
+ bool activeTokenExists() const;
+ std::shared_ptr getBookmarkForActiveToken() const; // or null if no bookmark for that token exists
+
+private:
+ struct TempEdge
+ {
+ public:
+ Id edgeId;
+ NameHierarchy source;
+ NameHierarchy target;
+ int type;
+ };
+
+ virtual void handleMessage(MessageActivateBookmark* message);
+ virtual void handleMessage(MessageActivateTokens* message);
+ virtual void handleMessage(MessageCreateBookmark* message);
+ virtual void handleMessage(MessageCreateBookmarkCategory* message);
+ virtual void handleMessage(MessageDeleteBookmark* message);
+ virtual void handleMessage(MessageDeleteBookmarkCategoryWithBookmarks* message);
+ virtual void handleMessage(MessageDeleteBookmarkForActiveTokens* message);
+ virtual void handleMessage(MessageEditBookmark* message);
+ virtual void handleMessage(MessageFinishedParsing* message);
+
+ std::vector getTokenNames(const std::vector& ids) const;
+ std::vector getTokenDisplayNames(const std::vector& ids) const;
+ std::vector getTokenTypes(const std::vector& ids) const;
+ std::string getDisplayName(Id id) const;
+ TempEdge getEdge(const std::string& tokenName, const int tokenType) const;
+
+ std::pair seperateEdgeToken(const std::string& token) const;
+
+ std::vector> getFilteredBookmarks(const std::vector>& bookmarks, const MessageDisplayBookmarks::BookmarkFilter& filter) const;
+ std::vector> getOrderedBookmarks(const std::vector>& bookmarks, const MessageDisplayBookmarks::BookmarkOrder& order) const;
+ std::vector> getDateOrderedBookmarks(const std::vector>& bookmarks, const bool ascending) const;
+ std::vector> getNameOrderedBookmarks(const std::vector>& bookmarks, const bool ascending) const;
+
+ void cleanBookmarkCategories();
+
+ static bool bookmarkDateCompare(const std::shared_ptr a, const std::shared_ptr b);
+ static bool bookmarkNameCompare(const std::shared_ptr a, const std::shared_ptr b);
+
+ static const std::string m_edgeSeperatorToken;
+
+ StorageAccess* m_storageAccess;
+ std::vector m_activeTokens;
+ std::vector m_activeTokenNames;
+ std::vector m_activeTokenDisplayNames;
+ std::vector m_activeTokenTypes;
+
+ std::vector m_activeEdges;
+ std::vector m_activeEdgeNames;
+ std::vector m_activeEdgeDisplayNames;
+ std::vector m_activeEdgeTypes;
+
+ bool m_activeTokenExists;
+};
+
+#endif // BOOKMARK_CONTROLLER_H
diff --git a/src/lib/component/controller/IDECommunicationController.cpp b/src/lib/component/controller/IDECommunicationController.cpp
index ef86435d..791433b1 100644
--- a/src/lib/component/controller/IDECommunicationController.cpp
+++ b/src/lib/component/controller/IDECommunicationController.cpp
@@ -69,6 +69,11 @@ void IDECommunicationController::setEnabled(const bool enabled)
m_enabled = enabled;
}
+void IDECommunicationController::sendInitialPing()
+{
+ sendMessage(NetworkProtocolHelper::buildPingMessage());
+}
+
void IDECommunicationController::handleSetActiveTokenMessage(
const NetworkProtocolHelper::SetActiveTokenMessage& message
)
@@ -175,6 +180,7 @@ void IDECommunicationController::handlePing(const NetworkProtocolHelper::PingMes
if (msg.ideId == "vs")
{
ideName = "Visual Studio";
+ msg.ideName = ideName;
}
// TODO: add the other ides
diff --git a/src/lib/component/controller/IDECommunicationController.h b/src/lib/component/controller/IDECommunicationController.h
index 73301c73..15855cdb 100644
--- a/src/lib/component/controller/IDECommunicationController.h
+++ b/src/lib/component/controller/IDECommunicationController.h
@@ -34,6 +34,9 @@ public:
bool getEnabled() const;
void setEnabled(const bool enabled);
+protected:
+ void sendInitialPing();
+
private:
void handleSetActiveTokenMessage(const NetworkProtocolHelper::SetActiveTokenMessage& message);
void handleCreateProjectMessage(const NetworkProtocolHelper::CreateProjectMessage& message);
diff --git a/src/lib/component/controller/StatusBarController.cpp b/src/lib/component/controller/StatusBarController.cpp
index 028fa0bf..0128a1f6 100644
--- a/src/lib/component/controller/StatusBarController.cpp
+++ b/src/lib/component/controller/StatusBarController.cpp
@@ -35,6 +35,14 @@ void StatusBarController::handleMessage(MessageFinishedParsing* message)
getView()->setErrorCount(errorCount);
}
+void StatusBarController::handleMessage(MessagePingReceived* message)
+{
+ std::string status = "Connected to ";
+ status += message->ideName;
+
+ getView()->showIdeStatus(status);
+}
+
void StatusBarController::handleMessage(MessageRefresh* message)
{
getView()->setErrorCount(m_storageAccess->getErrorCount());
diff --git a/src/lib/component/controller/StatusBarController.h b/src/lib/component/controller/StatusBarController.h
index 8f0cedbc..c98e286b 100644
--- a/src/lib/component/controller/StatusBarController.h
+++ b/src/lib/component/controller/StatusBarController.h
@@ -8,6 +8,7 @@
#include "utility/messaging/MessageListener.h"
#include "utility/messaging/type/MessageClearErrorCount.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
+#include "utility/messaging/type/MessagePingReceived.h"
#include "utility/messaging/type/MessageRefresh.h"
#include "utility/messaging/type/MessageShowErrors.h"
#include "utility/messaging/type/MessageStatus.h"
@@ -19,6 +20,7 @@ class StatusBarController
: public Controller
, public MessageListener
, public MessageListener
+ , public MessageListener
, public MessageListener
, public MessageListener
, public MessageListener
@@ -34,6 +36,7 @@ public:
private:
virtual void handleMessage(MessageClearErrorCount* message);
virtual void handleMessage(MessageFinishedParsing* message);
+ virtual void handleMessage(MessagePingReceived* message);
virtual void handleMessage(MessageRefresh* message);
virtual void handleMessage(MessageShowErrors* message);
virtual void handleMessage(MessageStatus* message);
diff --git a/src/lib/component/view/BookmarkView.cpp b/src/lib/component/view/BookmarkView.cpp
new file mode 100644
index 00000000..9bc99ace
--- /dev/null
+++ b/src/lib/component/view/BookmarkView.cpp
@@ -0,0 +1,85 @@
+#include "component/view/BookmarkView.h"
+
+#include "component/controller/BookmarkController.h"
+
+BookmarkView::BookmarkView(ViewLayout* viewLayout)
+ : View(viewLayout)
+ , m_filter(MessageDisplayBookmarks::BookmarkFilter::ALL)
+ , m_order(MessageDisplayBookmarks::BookmarkOrder::DATE_DESCENDING)
+{
+}
+
+BookmarkView::~BookmarkView()
+{
+}
+
+std::string BookmarkView::getName() const
+{
+ return "BookmarkView";
+}
+
+void BookmarkView::update()
+{
+ if (bookmarkBrowserIsVisible())
+ {
+ displayBookmarks(getController()->getBookmarks(m_filter, m_order));
+ }
+}
+
+BookmarkController* BookmarkView::getController()
+{
+ return View::getController();
+}
+
+void BookmarkView::handleMessage(MessageDisplayBookmarks* message)
+{
+ if (bookmarkBrowserIsVisible() == true)
+ {
+ m_filter = message->filter;
+ m_order = message->order;
+
+ displayBookmarks(getController()->getBookmarks(message->filter, message->order));
+ }
+
+ displayBookmarks(getController()->getBookmarks(m_filter, m_order));
+}
+
+void BookmarkView::handleMessage(MessageDisplayBookmarkCreator* message)
+{
+ std::vector names = getController()->getActiveTokenDisplayNames();
+
+ if (getController()->activeTokenExists())
+ {
+ std::vector categories = getController()->getAllBookmarkCategories();
+
+ displayBookmarkEditor(getController()->getBookmarkForActiveToken(), categories);
+ }
+ else
+ {
+ for (unsigned int i = 0; i < names.size(); i++)
+ {
+ std::string name = names[i];
+
+ // skip the first letter as to not insert a leading space
+ for (unsigned int i = 1; i < name.size(); i++)
+ {
+ if (std::isupper(name[i]))
+ {
+ name.insert(i, 1, ' ');
+ i++;
+ }
+ }
+
+ names[i] = name;
+ }
+
+ displayBookmarkCreator(names, getController()->getAllBookmarkCategories());
+ }
+}
+
+void BookmarkView::handleMessage(MessageDisplayBookmarkEditor* message)
+{
+ std::vector categories = getController()->getAllBookmarkCategories();
+
+ displayBookmarkEditor(message->bookmark, categories);
+}
\ No newline at end of file
diff --git a/src/lib/component/view/BookmarkView.h b/src/lib/component/view/BookmarkView.h
new file mode 100644
index 00000000..c4dda329
--- /dev/null
+++ b/src/lib/component/view/BookmarkView.h
@@ -0,0 +1,56 @@
+#ifndef BOOKMARK_VIEW_H
+#define BOOKMARK_VIEW_H
+
+#include "data/bookmark/Bookmark.h"
+
+#include "component/view/View.h"
+
+#include "utility/messaging/MessageListener.h"
+#include "utility/messaging/type/MessageDisplayBookmarks.h"
+#include "utility/messaging/type/MessageDisplayBookmarkCreator.h"
+#include "utility/messaging/type/MessageDisplayBookmarkEditor.h"
+
+class BookmarkController;
+
+class BookmarkView
+ : public View
+ , public MessageListener
+ , public MessageListener
+ , public MessageListener
+{
+public:
+ BookmarkView(ViewLayout* viewLayout);
+ virtual ~BookmarkView();
+
+ virtual std::string getName() const;
+
+ enum CreateButtonState
+ {
+ CAN_CREATE = 0,
+ CANNOT_CREATE,
+ ALREADY_CREATED
+ };
+
+ virtual void setCreateButtonState(const CreateButtonState& state) = 0;
+ virtual void enableDisplayBookmarks(bool enable) = 0;
+
+ virtual void update();
+
+ virtual bool bookmarkBrowserIsVisible() const = 0;
+
+private:
+ BookmarkController* getController();
+
+ virtual void handleMessage(MessageDisplayBookmarks* message);
+ virtual void handleMessage(MessageDisplayBookmarkCreator* message);
+ virtual void handleMessage(MessageDisplayBookmarkEditor* message);
+
+ virtual void displayBookmarks(const std::vector>& bookmarks) = 0;
+ virtual void displayBookmarkCreator(const std::vector& names, const std::vector& categories) = 0;
+ virtual void displayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories) = 0;
+
+ MessageDisplayBookmarks::BookmarkFilter m_filter;
+ MessageDisplayBookmarks::BookmarkOrder m_order;
+};
+
+#endif // BOOKMARK_VIEW_H
diff --git a/src/lib/component/view/StatusBarView.h b/src/lib/component/view/StatusBarView.h
index 7a57e3ca..f38afb18 100644
--- a/src/lib/component/view/StatusBarView.h
+++ b/src/lib/component/view/StatusBarView.h
@@ -16,6 +16,8 @@ public:
virtual void showMessage(const std::string& message, bool isError, bool showLoader) = 0;
virtual void setErrorCount(ErrorCountInfo errorCount) = 0;
+ virtual void showIdeStatus(const std::string& message) = 0;
+
protected:
StatusBarController* getController();
};
diff --git a/src/lib/component/view/ViewFactory.h b/src/lib/component/view/ViewFactory.h
index 8f7d94dd..9260f70b 100644
--- a/src/lib/component/view/ViewFactory.h
+++ b/src/lib/component/view/ViewFactory.h
@@ -5,6 +5,7 @@
#include "component/view/CompositeView.h"
+class BookmarkView;
class CodeView;
class DialogView;
class ErrorView;
@@ -31,6 +32,7 @@ public:
ViewLayout* viewLayout, CompositeView::CompositeDirection direction, const std::string& name) const = 0;
virtual std::shared_ptr createTabbedView(ViewLayout* viewLayout, const std::string& name) const = 0;
+ virtual std::shared_ptr createBookmarkView(ViewLayout* viewLayout) const = 0;
virtual std::shared_ptr createCodeView(ViewLayout* viewLayout) const = 0;
virtual std::shared_ptr createErrorView(ViewLayout* viewLayout) const = 0;
virtual std::shared_ptr createGraphView(ViewLayout* viewLayout) const = 0;
diff --git a/src/lib/data/IntermediateStorage.cpp b/src/lib/data/IntermediateStorage.cpp
index b57e6738..07cfe2c4 100644
--- a/src/lib/data/IntermediateStorage.cpp
+++ b/src/lib/data/IntermediateStorage.cpp
@@ -167,6 +167,13 @@ void IntermediateStorage::addError(const std::string& message, const FilePath& f
));
}
+Id IntermediateStorage::addBookmark(const Bookmark& bookmark)
+{
+ m_bookmarks.push_back(bookmark);
+
+ return -1;
+}
+
void IntermediateStorage::forEachNode(std::function callback) const
{
for (std::map>::const_iterator it = m_nodeIdsToData.begin(); it != m_nodeIdsToData.end(); it++)
diff --git a/src/lib/data/IntermediateStorage.h b/src/lib/data/IntermediateStorage.h
index 8f3db55d..25935de5 100644
--- a/src/lib/data/IntermediateStorage.h
+++ b/src/lib/data/IntermediateStorage.h
@@ -27,6 +27,7 @@ public:
virtual void addComponentAccess(Id nodeId , int type);
virtual void addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
virtual void addError(const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed);
+ virtual Id addBookmark(const Bookmark& bookmark);
virtual void forEachNode(std::function callback) const;
virtual void forEachFile(std::function callback) const;
@@ -65,6 +66,7 @@ private:
std::vector m_componentAccesses;
std::vector m_commentLocations;
std::vector m_errors;
+ std::vector m_bookmarks;
Id m_nextId;
};
diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp
index 8b5c3586..99431670 100644
--- a/src/lib/data/PersistentStorage.cpp
+++ b/src/lib/data/PersistentStorage.cpp
@@ -149,6 +149,86 @@ void PersistentStorage::addError(
);
}
+Id PersistentStorage::addNodeBookmark(const NodeBookmark& bookmark)
+{
+ return m_sqliteStorage.addNodeBookmark(bookmark);
+}
+
+Id PersistentStorage::addEdgeBookmark(const EdgeBookmark& bookmark)
+{
+ return m_sqliteStorage.addEdgeBookmark(bookmark);
+}
+
+Id PersistentStorage::addBookmarkCategory(const BookmarkCategory& category)
+{
+ return m_sqliteStorage.addBookmarkCategory(category.getName());
+}
+
+std::vector PersistentStorage::getAllNodeBookmarks() const
+{
+ return m_sqliteStorage.getAllNodeBookmarks();
+}
+
+NodeBookmark PersistentStorage::getNodeBookmarkById(const Id bookmarkId) const
+{
+ return m_sqliteStorage.getNodeBookmarkById(bookmarkId);
+}
+
+bool PersistentStorage::checkNodeBookmarkExistsByTokens(const std::vector& tokenNames) const
+{
+ return m_sqliteStorage.checkNodeBookmarkExistsByNames(tokenNames);
+}
+
+void PersistentStorage::removeNodeBookmark(Id id)
+{
+ m_sqliteStorage.removeNodeBookmark(id);
+}
+
+void PersistentStorage::editNodeBookmark(const NodeBookmark& bookmark)
+{
+ m_sqliteStorage.editNodeBookmark(bookmark);
+}
+
+std::vector PersistentStorage::getAllEdgeBookmarks() const
+{
+ return m_sqliteStorage.getAllEdgeBookmarks();
+}
+
+EdgeBookmark PersistentStorage::getEdgeBookmarkById(const Id bookmarkId) const
+{
+ return m_sqliteStorage.getEdgeBookmarkById(bookmarkId);
+}
+
+bool PersistentStorage::checkEdgeBookmarkExistsByTokens(const std::vector& tokenNames) const
+{
+ return m_sqliteStorage.checkEdgeBookmarkExistsByNames(tokenNames);
+}
+
+void PersistentStorage::removeEdgeBookmark(Id id)
+{
+ m_sqliteStorage.removeEdgeBookmark(id);
+}
+
+void PersistentStorage::editEdgeBookmark(const EdgeBookmark& bookmark)
+{
+ m_sqliteStorage.editEdgeBookmark(bookmark);
+}
+
+bool PersistentStorage::checkBookmarkCategoryExists(const std::string& name) const
+{
+ return m_sqliteStorage.checkBookmarkCategoryExists(name);
+}
+
+std::vector PersistentStorage::getAllBookmarkCategories() const
+{
+ return m_sqliteStorage.getAllBookmarkCategories();
+}
+
+void PersistentStorage::removeBookmarkCategory(Id id)
+{
+ m_sqliteStorage.removeBookmarkCategory(id);
+}
+
void PersistentStorage::forEachNode(std::function callback) const
{
for (StorageNode& node: m_sqliteStorage.getAll())
@@ -394,6 +474,11 @@ Id PersistentStorage::getIdForEdge(
return m_sqliteStorage.getEdgeBySourceTargetType(sourceId, targetId, type).id;
}
+StorageEdge PersistentStorage::getEdgeById(Id edgeId) const
+{
+ return m_sqliteStorage.getEdgeById(edgeId);
+}
+
NameHierarchy PersistentStorage::getNameHierarchyForNodeWithId(Id nodeId) const
{
TRACE();
@@ -907,6 +992,11 @@ std::vector PersistentStorage::getActiveTokenIdsForId(Id tokenId, Id* declar
return activeTokenIds;
}
+bool PersistentStorage::checkEdgeExists(Id edgeId) const
+{
+ return m_sqliteStorage.checkEdgeExists(edgeId);
+}
+
std::vector PersistentStorage::getNodeIdsForLocationIds(const std::vector& locationIds) const
{
TRACE();
@@ -975,6 +1065,11 @@ std::vector PersistentStorage::getLocalSymbolIdsForLocationIds(const std::ve
return utility::toVector(localSymbolIds);
}
+bool PersistentStorage::checkNodeExistsByName(const std::string& serializedName) const
+{
+ return m_sqliteStorage.checkNodeExistsByName(serializedName);
+}
+
std::vector PersistentStorage::getTokenIdsForMatches(const std::vector& matches) const
{
FilePath rootPath = getDbFilePath().parentDirectory();
diff --git a/src/lib/data/PersistentStorage.h b/src/lib/data/PersistentStorage.h
index 13040d4b..6200183a 100644
--- a/src/lib/data/PersistentStorage.h
+++ b/src/lib/data/PersistentStorage.h
@@ -37,6 +37,25 @@ public:
virtual void addComponentAccess(Id nodeId , int type);
virtual void addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
virtual void addError(const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed);
+ virtual Id addNodeBookmark(const NodeBookmark& bookmark);
+ virtual Id addEdgeBookmark(const EdgeBookmark& bookmark);
+ virtual Id addBookmarkCategory(const BookmarkCategory& category);
+
+ virtual std::vector getAllNodeBookmarks() const;
+ virtual NodeBookmark getNodeBookmarkById(const Id bookmarkId) const;
+ virtual bool checkNodeBookmarkExistsByTokens(const std::vector& tokenNames) const;
+ virtual void removeNodeBookmark(Id id);
+ virtual void editNodeBookmark(const NodeBookmark& bookmark);
+
+ virtual std::vector getAllEdgeBookmarks() const;
+ virtual EdgeBookmark getEdgeBookmarkById(const Id bookmarkId) const;
+ virtual bool checkEdgeBookmarkExistsByTokens(const std::vector& tokenNames) const;
+ virtual void removeEdgeBookmark(Id id);
+ virtual void editEdgeBookmark(const EdgeBookmark& bookmark);
+
+ virtual bool checkBookmarkCategoryExists(const std::string& name) const;
+ virtual std::vector getAllBookmarkCategories() const;
+ virtual void removeBookmarkCategory(Id id);
virtual void forEachNode(std::function callback) const;
virtual void forEachFile(std::function callback) const;
@@ -80,6 +99,7 @@ public:
virtual Id getIdForNodeWithNameHierarchy(const NameHierarchy& nameHierarchy) const;
virtual Id getIdForEdge(
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const;
+ virtual StorageEdge getEdgeById(Id edgeId) const;
virtual NameHierarchy getNameHierarchyForNodeWithId(Id nodeId) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const;
@@ -97,8 +117,11 @@ public:
virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
+ virtual bool checkEdgeExists(Id edgeId) const;
+
virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const;
virtual std::vector getLocalSymbolIdsForLocationIds(const std::vector& locationIds) const;
+ virtual bool checkNodeExistsByName(const std::string& serializedName) const;
virtual std::vector getTokenIdsForMatches(const std::vector& matches) const;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp
index d18ba556..1f5053e0 100644
--- a/src/lib/data/SqliteStorage.cpp
+++ b/src/lib/data/SqliteStorage.cpp
@@ -328,6 +328,203 @@ Id SqliteStorage::addError(const std::string& message, const FilePath& filePath,
return m_database.lastRowId();
}
+Id SqliteStorage::addNodeBookmark(const NodeBookmark& bookmark)
+{
+ std::string tokenName = bookmark.getDisplayName();
+ std::string comment = bookmark.getComment();
+ std::string timeStamp = bookmark.getTimeStamp().toString();
+
+ tokenName = utility::replace(tokenName, "'", "''");
+ comment = utility::replace(comment, "'", "''");
+
+ /*tokenName = utility::replace(tokenName, "\\", "/");
+ comment = utility::replace(comment, "\\", "/");*/
+
+ // for backwards compatibility
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS nodeBookmark("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "comment TEXT, "
+ "timestamp TEXT, "
+ "category INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(category) REFERENCES bookmarkCategory(id));"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS nodeBookmarkToken("
+ "id INTEGER NOT NULL, "
+ "bookmarkId INTEGER NOT NULL, "
+ "name TEXT, "
+ "type INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(bookmarkId) REFERENCES nodeBookmark(id) ON DELETE CASCADE);"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS bookmarkCategory("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "PRIMARY KEY(id));"
+ );
+
+ std::string statement = "INSERT INTO nodeBookmark(name, comment, timestamp, category) "
+ "VALUES (?, ?, ?, ?);";
+
+ int categoryId = getOrCreateBookmarkCategoryByName(bookmark.getCategory().getName()).getId();
+
+ CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, tokenName.c_str());
+ stmt.bind(2, comment.c_str());
+ stmt.bind(3, timeStamp.c_str());
+ stmt.bind(4, categoryId);
+
+ stmt.execDML();
+
+ Id id = m_database.lastRowId();
+
+ for (unsigned int i = 0; i < bookmark.getTokenNames().size(); i++)
+ {
+ std::string name = bookmark.getTokenNames()[i];
+ int type = bookmark.getTokenTypes()[i];
+
+ statement = "INSERT INTO nodeBookmarkToken(bookmarkId, name, type) "
+ "VALUES (" + std::to_string(id) + ", ?, " + std::to_string(type) + ");";
+
+ stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, name.c_str());
+
+ stmt.execDML();
+ }
+
+ return id;
+}
+
+Id SqliteStorage::addEdgeBookmark(const EdgeBookmark& bookmark)
+{
+ std::string tokenName = bookmark.getDisplayName();
+ std::string comment = bookmark.getComment();
+ std::string timeStamp = bookmark.getTimeStamp().toString();
+
+ tokenName = utility::replace(tokenName, "'", "''");
+ comment = utility::replace(comment, "'", "''");
+
+ // for backwards compatibility
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBookmark("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "comment TEXT, "
+ "timestamp TEXT, "
+ "category INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(category) REFERENCES bookmarkCategory(id));"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBookmarkToken("
+ "id INTEGER NOT NULL, "
+ "bookmarkId INTEGER NOT NULL, "
+ "name TEXT, "
+ "type INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(bookmarkId) REFERENCES edgeBookmark(id) ON DELETE CASCADE);"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBaseBookmark("
+ "id INTEGER NOT NULL, "
+ "edgeId INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(edgeId) REFERENCES edgeBookmark(id) ON DELETE CASCADE);"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBaseBookmarkToken("
+ "id INTEGER NOT NULL, "
+ "bookmarkId INTEGER NOT NULL, "
+ "name TEXT, "
+ "type INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(bookmarkId) REFERENCES edgeBaseBookmark(id) ON DELETE CASCADE);"
+ );
+
+ std::string statement = "INSERT INTO edgeBookmark(name, comment, timestamp, category) "
+ "VALUES (?, ?, ?, ?);";
+
+ int categoryId = getOrCreateBookmarkCategoryByName(bookmark.getCategory().getName()).getId();
+
+ CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, tokenName.c_str());
+ stmt.bind(2, comment.c_str());
+ stmt.bind(3, timeStamp.c_str());
+ stmt.bind(4, categoryId);
+
+ stmt.execDML();
+
+ Id id = m_database.lastRowId();
+
+ for (unsigned int i = 0; i < bookmark.getEdgeTokenNames().size(); i++)
+ {
+ std::string name = bookmark.getEdgeTokenNames()[i];
+ int type = bookmark.getEdgeTokenTypes()[i];
+
+ statement = "INSERT INTO edgeBookmarkToken(bookmarkId, name, type) "
+ "VALUES (" + std::to_string(id) + ", ?, " + std::to_string(type) + ");";
+
+ stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, name.c_str());
+
+ stmt.execDML();
+ }
+
+ statement = "INSERT INTO edgeBaseBookmark(edgeId) "
+ "VALUES (" + std::to_string(id) + ");";
+ stmt = m_database.compileStatement(statement.c_str());
+ stmt.execDML();
+ Id baseId = m_database.lastRowId();
+
+ for (unsigned int i = 0; i < bookmark.getTokenNames().size(); i++)
+ {
+ std::string name = bookmark.getTokenNames()[i];
+ int type = bookmark.getTokenTypes()[i];
+
+ statement = "INSERT INTO edgeBaseBookmarkToken(bookmarkId, name, type) "
+ "VALUES (" + std::to_string(baseId) + ", ?, " + std::to_string(bookmark.getTokenTypes()[i]) + ");";
+
+ stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, bookmark.getTokenNames()[i].c_str());
+
+ stmt.execDML();
+ }
+
+ return id;
+}
+
+Id SqliteStorage::addBookmarkCategory(const std::string& name)
+{
+ // for backwards compatibility
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS bookmarkCategory("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "PRIMARY KEY(id));"
+ );
+
+ std::string statement = "INSERT INTO bookmarkCategory(name) "
+ "VALUES (?);";
+
+ CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, name.c_str());
+
+ stmt.execDML();
+
+ Id id = m_database.lastRowId();
+
+ return id;
+}
+
void SqliteStorage::removeElement(Id id)
{
std::vector ids;
@@ -509,6 +706,18 @@ bool SqliteStorage::isFile(Id elementId) const
return (count > 0);
}
+StorageEdge SqliteStorage::getEdgeById(Id edgeId) const
+{
+ std::vector candidates = doGetAll("WHERE id = " + std::to_string(edgeId));
+
+ if (candidates.size() > 0)
+ {
+ return candidates[0];
+ }
+
+ return StorageEdge();
+}
+
StorageEdge SqliteStorage::getEdgeBySourceTargetType(Id sourceId, Id targetId, int type) const
{
return doGetFirst("WHERE "
@@ -568,6 +777,39 @@ std::vector SqliteStorage::getEdgesByTargetsType(const std::vector<
return doGetAll("WHERE target_node_id IN (" + utility::join(utility::toStrings(targetIds), ',') + ") AND type == " + std::to_string(type));
}
+bool SqliteStorage::checkEdgeExists(Id edgeId) const
+{
+ CppSQLite3Statement stmt = m_database.compileStatement(
+ ("SELECT type FROM edge WHERE id == " + std::to_string(edgeId) + ";").c_str()
+ );
+
+ CppSQLite3Query q = executeQuery(stmt);
+
+ if (!q.eof())
+ {
+ const int type = q.getIntField(0, -1);
+
+ if (type != -1)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+StorageNode SqliteStorage::getNodeById(Id id) const
+{
+ std::vector candidates = doGetAll("WHERE id = " + std::to_string(id));
+
+ if (candidates.size() > 0)
+ {
+ return candidates[0];
+ }
+
+ return StorageNode();
+}
+
StorageNode SqliteStorage::getNodeBySerializedName(const std::string& serializedName) const
{
CppSQLite3Statement stmt = m_database.compileStatement(
@@ -592,6 +834,28 @@ StorageNode SqliteStorage::getNodeBySerializedName(const std::string& serialized
return StorageNode();
}
+bool SqliteStorage::checkNodeExistsByName(const std::string& serializedName) const
+{
+ CppSQLite3Statement stmt = m_database.compileStatement(
+ "SELECT id FROM node WHERE serialized_name == ? LIMIT 1;"
+ );
+
+ stmt.bind(1, serializedName.c_str());
+ CppSQLite3Query q = executeQuery(stmt);
+
+ if (!q.eof())
+ {
+ const Id id = q.getIntField(0, 0);
+
+ if (id != -1)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
StorageLocalSymbol SqliteStorage::getLocalSymbolByName(const std::string& name) const
{
return doGetFirst("WHERE name == '" + name + "'");
@@ -735,6 +999,278 @@ std::vector SqliteStorage::getCommentLocationsInFile(con
return doGetAll("WHERE file_node_id == " + std::to_string(fileNodeId));
}
+std::vector SqliteStorage::getAllNodeBookmarks() const
+{
+ return doGetAll("");
+}
+
+NodeBookmark SqliteStorage::getNodeBookmarkById(const Id bookmarkId) const
+{
+ std::vector candidates = doGetAll("WHERE id = " + std::to_string(bookmarkId));
+
+ if (candidates.size() > 0)
+ {
+ return candidates[0];
+ }
+
+ return NodeBookmark();
+}
+
+bool SqliteStorage::checkNodeBookmarkExistsByNames(const std::vector& names) const
+{
+ // bookmarks can only be uniquly identified by their token names.
+ // therefore, a bookmark exists if there is an exactly matching set of 'bookmarkToken's with a common foreign key
+
+ if (names.size() <= 0)
+ {
+ return false;
+ }
+
+ std::set bookmarkIds;
+ bool insert = true;
+
+ for (unsigned int i = 0; i < names.size(); i++)
+ {
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT bookmarkId FROM nodeBookmarkToken WHERE name = '" + names[i] +"';"
+ ).c_str());
+
+ bool contains = false;
+
+ while (!q.eof())
+ {
+ int id = q.getIntField(0, -1);
+
+ if (insert)
+ {
+ bookmarkIds.insert(id);
+ }
+ else
+ {
+ if (bookmarkIds.find(id) != bookmarkIds.end())
+ {
+ contains = true;
+ }
+ }
+
+ q.nextRow();
+ }
+
+ if ((contains == false && insert == false)
+ || bookmarkIds.size() <= 0)
+ {
+ return false;
+ }
+
+ insert = false;
+ }
+
+ return true;
+}
+
+void SqliteStorage::removeNodeBookmark(Id id)
+{
+ executeStatement(
+ "DELETE FROM nodeBookmark WHERE id = (" + std::to_string(id) + ");"
+ );
+}
+
+void SqliteStorage::editNodeBookmark(const NodeBookmark& bookmark)
+{
+ std::string statement = "UPDATE nodeBookmark SET name=?, comment=?, category=? WHERE id=" + std::to_string(bookmark.getId()) + ";";
+
+ BookmarkCategory category = getBookmarkCategoryByName(bookmark.getCategory().getName());
+ if (category.getId() == -1)
+ {
+ category.setId(addBookmarkCategory(bookmark.getCategory().getName()));
+ category.setName(bookmark.getCategory().getName());
+ }
+
+ CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, bookmark.getDisplayName().c_str());
+ stmt.bind(2, bookmark.getComment().c_str());
+ stmt.bind(3, (int)category.getId());
+
+ stmt.execDML();
+}
+
+std::vector SqliteStorage::getAllEdgeBookmarks() const
+{
+ return doGetAll("");
+}
+
+EdgeBookmark SqliteStorage::getEdgeBookmarkById(const Id bookmarkId) const
+{
+ std::vector candidates = doGetAll("WHERE id = " + std::to_string(bookmarkId));
+
+ if (candidates.size() > 0)
+ {
+ return candidates[0];
+ }
+
+ return EdgeBookmark();
+}
+
+bool SqliteStorage::checkEdgeBookmarkExistsByNames(const std::vector& names) const
+{
+ if (names.size() <= 0)
+ {
+ return false;
+ }
+
+ std::set bookmarkIds;
+ bool insert = true;
+
+ for (unsigned int i = 0; i < names.size(); i++)
+ {
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT bookmarkId FROM edgeBookmarkToken WHERE name = '" + names[i] + "';"
+ ).c_str());
+
+ bool contains = false;
+
+ while (!q.eof())
+ {
+ int id = q.getIntField(0, -1);
+
+ if (insert)
+ {
+ bookmarkIds.insert(id);
+ }
+ else
+ {
+ if (bookmarkIds.find(id) != bookmarkIds.end())
+ {
+ contains = true;
+ }
+ }
+
+ q.nextRow();
+ }
+
+ if ((contains == false && insert == false)
+ || bookmarkIds.size() <= 0)
+ {
+ return false;
+ }
+
+ insert = false;
+ }
+
+ return true;
+}
+
+void SqliteStorage::removeEdgeBookmark(Id id)
+{
+ executeStatement(
+ "DELETE FROM edgeBookmark WHERE id = (" + std::to_string(id) + ");"
+ );
+}
+
+void SqliteStorage::editEdgeBookmark(const EdgeBookmark& bookmark)
+{
+ std::string statement = "UPDATE edgeBookmark SET name=?, comment=?, category=? WHERE id=" + std::to_string(bookmark.getId()) + ";";
+
+ BookmarkCategory category = getBookmarkCategoryByName(bookmark.getCategory().getName());
+ if (category.getId() == -1)
+ {
+ category.setId(addBookmarkCategory(bookmark.getCategory().getName()));
+ category.setName(bookmark.getCategory().getName());
+ }
+
+ CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
+ stmt.bind(1, bookmark.getDisplayName().c_str());
+ stmt.bind(2, bookmark.getComment().c_str());
+ stmt.bind(3, (int)category.getId());
+
+ stmt.execDML();
+}
+
+std::vector SqliteStorage::getAllBookmarkCategories() const
+{
+ return doGetAll("");
+}
+
+BookmarkCategory SqliteStorage::getBookmarkCategoryByName(const std::string& name) const
+{
+ BookmarkCategory category;
+ category.setName("");
+ category.setId(-1);
+
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT id FROM bookmarkCategory WHERE name = '" + name + "';"
+ ).c_str());
+
+ while (!q.eof())
+ {
+ int id = q.getIntField(0, -1);
+
+ if (id > -1)
+ {
+ category.setName(name);
+ category.setId(id);
+ }
+
+ q.nextRow();
+ }
+
+ return category;
+}
+
+BookmarkCategory SqliteStorage::getOrCreateBookmarkCategoryByName(const std::string& name)
+{
+ if (checkBookmarkCategoryExists(name))
+ {
+ return getBookmarkCategoryByName(name);
+ }
+ else
+ {
+ Id id = addBookmarkCategory(name);
+ BookmarkCategory result;
+ result.setName(name);
+ result.setId(id);
+
+ return result;
+ }
+}
+
+bool SqliteStorage::checkBookmarkCategoryExists(const std::string& name) const
+{
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT id FROM bookmarkCategory WHERE name = '" + name + "';"
+ ).c_str());
+
+ while (!q.eof())
+ {
+ int id = q.getIntField(0, -1);
+
+ if (id > -1)
+ {
+ return true;
+ }
+
+ q.nextRow();
+ }
+
+ return false;
+}
+
+void SqliteStorage::removeBookmarkCategory(Id id)
+{
+ executeStatement(
+ "DELETE FROM bookmarkCategory WHERE id = (" + std::to_string(id) + ");"
+ );
+}
+
+Id SqliteStorage::getTokenIdByName(const std::string& name) const
+{
+ /*CppSQLite3Query q = m_database.execQuery((
+ "SELECT id FROM bookmark WHERE " + " foo " + ";"
+ ).c_str());*/
+
+ return -1;
+}
+
int SqliteStorage::getNodeCount() const
{
return executeScalar("SELECT COUNT(*) FROM node;");
@@ -913,10 +1449,81 @@ void SqliteStorage::setupTables()
"column_number INTEGER, "
"PRIMARY KEY(id));"
);
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS bookmarkCategory("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "PRIMARY KEY(id));"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS nodeBookmark("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "comment TEXT, "
+ "timestamp TEXT, "
+ "category INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(category) REFERENCES bookmarkCategory(id));"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBookmark("
+ "id INTEGER NOT NULL, "
+ "name TEXT, "
+ "comment TEXT, "
+ "timestamp TEXT, "
+ "category INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(category) REFERENCES bookmarkCategory(id));"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS nodeBookmarkToken("
+ "id INTEGER NOT NULL, "
+ "bookmarkId INTEGER NOT NULL, "
+ "name TEXT, "
+ "type INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(bookmarkId) REFERENCES nodeBookmark(id) ON DELETE CASCADE);"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBookmarkToken("
+ "id INTEGER NOT NULL, "
+ "bookmarkId INTEGER NOT NULL, "
+ "name TEXT, "
+ "type INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(bookmarkId) REFERENCES edgeBookmark(id) ON DELETE CASCADE);"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBaseBookmark("
+ "id INTEGER NOT NULL, "
+ "edgeId INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(edgeId) REFERENCES edgeBookmark(id) ON DELETE CASCADE);"
+ );
+
+ m_database.execDML(
+ "CREATE TABLE IF NOT EXISTS edgeBaseBookmarkToken("
+ "id INTEGER NOT NULL, "
+ "bookmarkId INTEGER NOT NULL, "
+ "name TEXT, "
+ "type INTEGER, "
+ "PRIMARY KEY(id), "
+ "FOREIGN KEY(bookmarkId) REFERENCES edgeBaseBookmark(id) ON DELETE CASCADE);"
+ );
}
catch (CppSQLite3Exception& e)
{
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
+
+ throw(std::exception("fail"));
+
+ // todo: cancel project creation and destroy created files, display message
}
}
@@ -1318,3 +1925,186 @@ std::vector SqliteStorage::doGetAll(const std::strin
return errors;
}
+
+template <>
+std::vector SqliteStorage::doGetAll(const std::string& query) const
+{
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT id, name, comment, timestamp, category FROM nodeBookmark " + query + ";"
+ ).c_str());
+
+ std::vector bookmarks;
+ bookmarks.clear();
+
+ while (!q.eof())
+ {
+ const int id = q.getIntField(0, -1);
+ const std::string name = q.getStringField(1, "");
+ const std::string comment = q.getStringField(2, "");
+ const std::string timeStamp = q.getStringField(3, "");
+ const int categoryId = q.getIntField(4, -1);
+
+ CppSQLite3Query qSub = m_database.execQuery((
+ "SELECT name, type FROM nodeBookmarkToken WHERE bookmarkId = " + std::to_string(id) + ";"
+ ).c_str());
+
+ std::vector tokenNames;
+ std::vector tokenTypes;
+
+ while (!qSub.eof())
+ {
+ const std::string tokenName = qSub.getStringField(0, "");
+ const int tokenType = qSub.getIntField(1, -1);
+ tokenNames.push_back(tokenName);
+ tokenTypes.push_back(tokenType);
+ qSub.nextRow();
+ }
+
+ NodeBookmark bookmark(name, std::vector(), tokenNames, comment, TimePoint(timeStamp));
+ bookmark.setId(id);
+ bookmark.setTokenTypes(tokenTypes);
+
+ qSub = m_database.execQuery((
+ "SELECT id, name FROM bookmarkCategory WHERE id = " + std::to_string(categoryId) + ";"
+ ).c_str());
+
+ while (!qSub.eof())
+ {
+ const int categoryId = qSub.getIntField(0, -1);
+ const std::string name = qSub.getStringField(1, "");
+ BookmarkCategory category;
+ category.setId(categoryId);
+ category.setName(name);
+ bookmark.setCategory(category);
+
+ qSub.nextRow();
+ }
+
+ bookmarks.push_back(bookmark);
+
+ q.nextRow();
+ }
+
+ return bookmarks;
+}
+
+template <>
+std::vector SqliteStorage::doGetAll(const std::string& query) const
+{
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT id, name, comment, timestamp, category FROM edgeBookmark " + query + ";"
+ ).c_str());
+
+ std::vector bookmarks;
+ bookmarks.clear();
+
+ while (!q.eof())
+ {
+ const int id = q.getIntField(0, -1);
+ const std::string name = q.getStringField(1, "");
+ const std::string comment = q.getStringField(2, "");
+ const std::string timeStamp = q.getStringField(3, "");
+ const int categoryId = q.getIntField(4, -1);
+
+ CppSQLite3Query qSub = m_database.execQuery((
+ "SELECT name, type FROM edgeBookmarkToken WHERE bookmarkId = " + std::to_string(id) + ";"
+ ).c_str());
+
+
+ std::vector tokenNames;
+ std::vector tokenTypes;
+ while (!qSub.eof())
+ {
+ const std::string tokenName = qSub.getStringField(0, "");
+ const int tokenType = qSub.getIntField(1, -1);
+ tokenNames.push_back(tokenName);
+ tokenTypes.push_back(tokenType);
+ qSub.nextRow();
+ }
+
+ qSub = m_database.execQuery((
+ "SELECT id FROM edgeBaseBookmark WHERE edgeId = " + std::to_string(id) + ";"
+ ).c_str());
+
+ NodeBookmark baseBookmark; // there should only be one base bookmark, if there are more use the last one
+ while (!qSub.eof())
+ {
+ const int baseId = qSub.getIntField(0, -1);
+
+ baseBookmark.setId(baseId);
+
+ CppSQLite3Query qSubSub = m_database.execQuery((
+ "SELECT id, name, type FROM edgeBaseBookmarkToken WHERE bookmarkId = " + std::to_string(baseId) + ";"
+ ).c_str());
+
+ std::vector baseTokenNames;
+ std::vector baseTokenTypes;
+ while (!qSubSub.eof())
+ {
+ const std::string baseTokenName = qSubSub.getStringField(1, "");
+ const int baseTokenType = qSubSub.getIntField(2, -1);
+ baseTokenNames.push_back(baseTokenName);
+ baseTokenTypes.push_back(baseTokenType);
+ qSubSub.nextRow();
+ }
+
+ baseBookmark.setTokenNames(baseTokenNames);
+ baseBookmark.setTokenTypes(baseTokenTypes);
+
+ qSub.nextRow();
+ }
+
+ EdgeBookmark bookmark(name, std::vector(), tokenNames, comment, TimePoint(timeStamp));
+ bookmark.setTokenTypes(tokenTypes);
+ bookmark.setBaseBookmark(baseBookmark);
+ bookmark.setId(id);
+
+ qSub = m_database.execQuery((
+ "SELECT id, name FROM bookmarkCategory WHERE id = " + std::to_string(categoryId) + ";"
+ ).c_str());
+
+ while (!qSub.eof())
+ {
+ const int categoryId = qSub.getIntField(0, -1);
+ const std::string name = qSub.getStringField(1, "");
+ BookmarkCategory category;
+ category.setId(categoryId);
+ category.setName(name);
+ bookmark.setCategory(category);
+
+ qSub.nextRow();
+ }
+
+ bookmarks.push_back(bookmark);
+
+ q.nextRow();
+ }
+
+ return bookmarks;
+}
+
+template <>
+std::vector SqliteStorage::doGetAll(const std::string& query) const
+{
+ std::vector categories;
+
+ CppSQLite3Query q = m_database.execQuery((
+ "SELECT id, name FROM bookmarkCategory " + query + ";"
+ ).c_str());
+
+ while (!q.eof())
+ {
+ const int id = q.getIntField(0, -1);
+ const std::string name = q.getStringField(1, "");
+
+ BookmarkCategory category;
+ category.setId(id);
+ category.setName(name);
+
+ categories.push_back(category);
+
+ q.nextRow();
+ }
+
+ return categories;
+}
diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h
index ba74b6d2..11618285 100644
--- a/src/lib/data/SqliteStorage.h
+++ b/src/lib/data/SqliteStorage.h
@@ -7,6 +7,9 @@
#include "sqlite/CppSQLite3.h"
+#include "data/bookmark/BookmarkCategory.h"
+#include "data/bookmark/EdgeBookmark.h"
+#include "data/bookmark/NodeBookmark.h"
#include "data/location/TokenLocationFile.h"
#include "data/location/TokenLocationCollection.h"
#include "data/name/NameHierarchy.h"
@@ -66,6 +69,9 @@ public:
Id addComponentAccess(Id nodeId, int type);
Id addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
Id addError(const std::string& message, const FilePath& filePath, uint lineNumber, uint columnNumber, bool fatal, bool indexed);
+ Id addNodeBookmark(const NodeBookmark& bookmark);
+ Id addEdgeBookmark(const EdgeBookmark& bookmark);
+ Id addBookmarkCategory(const std::string& name);
void removeElement(Id id);
void removeElements(const std::vector& ids);
@@ -77,6 +83,7 @@ public:
bool isNode(Id elementId) const;
bool isFile(Id elementId) const;
+ StorageEdge getEdgeById(Id edgeId) const;
StorageEdge getEdgeBySourceTargetType(Id sourceId, Id targetId, int type) const;
std::vector getEdgesBySourceId(Id sourceId) const;
@@ -91,7 +98,11 @@ public:
std::vector getEdgesByTargetType(Id targetId, int type) const;
std::vector getEdgesByTargetsType(const std::vector& targetIds, int type) const;
+ bool checkEdgeExists(Id edgeId) const;
+
+ StorageNode getNodeById(Id id) const;
StorageNode getNodeBySerializedName(const std::string& serializedName) const;
+ bool checkNodeExistsByName(const std::string& serializedName) const;
StorageLocalSymbol getLocalSymbolByName(const std::string& name) const;
@@ -121,6 +132,26 @@ public:
return doGetAll("");
}
+ std::vector