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 getAllNodeBookmarks() const; + NodeBookmark getNodeBookmarkById(const Id bookmarkId) const; + bool checkNodeBookmarkExistsByNames(const std::vector& names) const; + void removeNodeBookmark(Id id); + void editNodeBookmark(const NodeBookmark& bookmark); + + std::vector getAllEdgeBookmarks() const; + EdgeBookmark getEdgeBookmarkById(const Id bookmarkId) const; + bool checkEdgeBookmarkExistsByNames(const std::vector& names) const; + void removeEdgeBookmark(Id id); + void editEdgeBookmark(const EdgeBookmark& bookmark); + + std::vector getAllBookmarkCategories() const; + BookmarkCategory getBookmarkCategoryByName(const std::string& name) const; + BookmarkCategory getOrCreateBookmarkCategoryByName(const std::string& name); + bool checkBookmarkCategoryExists(const std::string& name) const; + void removeBookmarkCategory(Id id); + + Id getTokenIdByName(const std::string& name) const; + template ResultType getFirstById(const Id id) const { @@ -200,6 +231,8 @@ std::vector SqliteStorage::doGetAll(cons template <> std::vector SqliteStorage::doGetAll(const std::string& query) const; template <> +std::vector SqliteStorage::doGetAll(const std::string& query) const; +template <> std::vector SqliteStorage::doGetAll(const std::string& query) const; template <> std::vector SqliteStorage::doGetAll(const std::string& query) const; @@ -207,6 +240,11 @@ template <> std::vector SqliteStorage::doGetAll(const std::string& query) const; template <> std::vector SqliteStorage::doGetAll(const std::string& query) const; - +template <> +std::vector SqliteStorage::doGetAll(const std::string& query) const; +template <> +std::vector SqliteStorage::doGetAll(const std::string& query) const; +template <> +std::vector SqliteStorage::doGetAll(const std::string& query) const; #endif // SQLITE_STORAGE_H diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 517ecad6..475f3e07 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -5,6 +5,7 @@ #include #include +#include "data/bookmark/Bookmark.h" #include "data/name/NameHierarchy.h" #include "data/StorageTypes.h" #include "utility/types.h" diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 0f7beb02..a792f124 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -9,6 +9,10 @@ #include "utility/file/FileInfo.h" #include "utility/file/FilePath.h" +#include "data/bookmark/Bookmark.h" +#include "data/bookmark/BookmarkCategory.h" +#include "data/bookmark/EdgeBookmark.h" +#include "data/bookmark/NodeBookmark.h" #include "data/parser/ParseLocation.h" #include "data/graph/Node.h" #include "data/search/SearchMatch.h" @@ -32,9 +36,13 @@ public: virtual Id getIdForNodeWithNameHierarchy(const NameHierarchy& nameHierarchy) const = 0; virtual Id getIdForEdge( Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const = 0; + virtual StorageEdge getEdgeById(Id edgeId) const = 0; + + virtual bool checkEdgeExists(Id edgeId) const = 0; virtual NameHierarchy getNameHierarchyForNodeWithId(Id id) const = 0; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0; + virtual bool checkNodeExistsByName(const std::string& serializedName) const = 0; virtual std::shared_ptr getFullTextSearchLocations( const std::string& searchTerm, bool caseSensitive) const = 0; @@ -76,6 +84,26 @@ public: virtual void setErrorFilter(const ErrorFilter& filter); + virtual Id addNodeBookmark(const NodeBookmark& bookmark) = 0; + virtual Id addEdgeBookmark(const EdgeBookmark& bookmark) = 0; + virtual Id addBookmarkCategory(const BookmarkCategory& category) = 0; + + virtual std::vector getAllNodeBookmarks() const = 0; + virtual NodeBookmark getNodeBookmarkById(const Id bookmarkId) const = 0; + virtual bool checkNodeBookmarkExistsByTokens(const std::vector& tokenNames) const = 0; + virtual void removeNodeBookmark(Id id) = 0; + virtual void editNodeBookmark(const NodeBookmark& bookmark) = 0; + + virtual std::vector getAllEdgeBookmarks() const = 0; + virtual EdgeBookmark getEdgeBookmarkById(const Id bookmarkId) const = 0; + virtual bool checkEdgeBookmarkExistsByTokens(const std::vector& tokenNames) const = 0; + virtual void removeEdgeBookmark(Id id) = 0; + virtual void editEdgeBookmark(const EdgeBookmark& bookmark) = 0; + + virtual std::vector getAllBookmarkCategories() const = 0; + virtual bool checkBookmarkCategoryExists(const std::string& name) const = 0; + virtual void removeBookmarkCategory(Id id) = 0; + protected: ErrorFilter m_errorFilter; }; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 6397ac37..b820ca52 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -57,6 +57,24 @@ Id StorageAccessProxy::getIdForEdge( return 0; } +StorageEdge StorageAccessProxy::getEdgeById(Id edgeId) const +{ + if (hasSubject()) + { + return m_subject->getEdgeById(edgeId); + } +} + +bool StorageAccessProxy::checkEdgeExists(Id edgeId) const +{ + if (hasSubject()) + { + return m_subject->checkEdgeExists(edgeId); + } + + return false; +} + Node::NodeType StorageAccessProxy::getNodeTypeForNodeWithId(Id id) const { if (hasSubject()) @@ -66,6 +84,15 @@ Node::NodeType StorageAccessProxy::getNodeTypeForNodeWithId(Id id) const return Node::NODE_NON_INDEXED; } +bool StorageAccessProxy::checkNodeExistsByName(const std::string& serializedName) const +{ + if (hasSubject()) + { + return m_subject->checkNodeExistsByName(serializedName); + } + return false; +} + NameHierarchy StorageAccessProxy::getNameHierarchyForNodeWithId(Id id) const { if (hasSubject()) @@ -302,6 +329,156 @@ std::shared_ptr StorageAccessProxy::getErrorTokenLocati return std::make_shared(); } +Id StorageAccessProxy::addNodeBookmark(const NodeBookmark& bookmark) +{ + if (hasSubject()) + { + return m_subject->addNodeBookmark(bookmark); + } + + return -1; +} + +Id StorageAccessProxy::addEdgeBookmark(const EdgeBookmark& bookmark) +{ + if (hasSubject()) + { + return m_subject->addEdgeBookmark(bookmark); + } + + return -1; +} + +Id StorageAccessProxy::addBookmarkCategory(const BookmarkCategory& category) +{ + if (hasSubject()) + { + return m_subject->addBookmarkCategory(category); + } + + return -1; +} + +std::vector StorageAccessProxy::getAllNodeBookmarks() const +{ + if (hasSubject()) + { + return m_subject->getAllNodeBookmarks(); + } + + return std::vector(); +} + +NodeBookmark StorageAccessProxy::getNodeBookmarkById(const Id bookmarkId) const +{ + if (hasSubject()) + { + return m_subject->getNodeBookmarkById(bookmarkId); + } + + return NodeBookmark(); +} + +bool StorageAccessProxy::checkNodeBookmarkExistsByTokens(const std::vector& tokenNames) const +{ + if (hasSubject()) + { + return m_subject->checkNodeBookmarkExistsByTokens(tokenNames); + } + + return false; +} + +void StorageAccessProxy::removeNodeBookmark(Id id) +{ + if (hasSubject()) + { + m_subject->removeNodeBookmark(id); + } +} + +void StorageAccessProxy::editNodeBookmark(const NodeBookmark& bookmark) +{ + if (hasSubject()) + { + m_subject->editNodeBookmark(bookmark); + } +} + +std::vector StorageAccessProxy::getAllEdgeBookmarks() const +{ + if (hasSubject()) + { + return m_subject->getAllEdgeBookmarks(); + } + + return std::vector(); +} + +EdgeBookmark StorageAccessProxy::getEdgeBookmarkById(const Id bookmarkId) const +{ + if (hasSubject()) + { + return m_subject->getEdgeBookmarkById(bookmarkId); + } + + return EdgeBookmark(); +} + +bool StorageAccessProxy::checkEdgeBookmarkExistsByTokens(const std::vector& tokenNames) const +{ + if (hasSubject()) + { + return m_subject->checkEdgeBookmarkExistsByTokens(tokenNames); + } + + return false; +} + +void StorageAccessProxy::removeEdgeBookmark(Id id) +{ + if (hasSubject()) + { + m_subject->removeEdgeBookmark(id); + } +} + +void StorageAccessProxy::editEdgeBookmark(const EdgeBookmark& bookmark) +{ + if (hasSubject()) + { + m_subject->editEdgeBookmark(bookmark); + } +} + +std::vector StorageAccessProxy::getAllBookmarkCategories() const +{ + if (hasSubject()) + { + return m_subject->getAllBookmarkCategories(); + } + + return std::vector(); +} + +bool StorageAccessProxy::checkBookmarkCategoryExists(const std::string& name) const +{ + if (hasSubject()) + { + return m_subject->checkBookmarkCategoryExists(name); + } + + return false; +} + +void StorageAccessProxy::removeBookmarkCategory(Id id) +{ + if (hasSubject()) + { + m_subject->removeBookmarkCategory(id); + } +} + void StorageAccessProxy::setErrorFilter(const ErrorFilter& filter) { StorageAccess::setErrorFilter(filter); diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index 2c70102a..741d47af 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -21,9 +21,13 @@ 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 bool checkEdgeExists(Id edgeId) const; virtual NameHierarchy getNameHierarchyForNodeWithId(Id id) const; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const; + virtual bool checkNodeExistsByName(const std::string& serializedName) const; virtual std::shared_ptr getFullTextSearchLocations( const std::string& searchTerm, bool caseSensitive) const; @@ -66,6 +70,26 @@ public: virtual std::shared_ptr getErrorTokenLocations(std::vector* errors) const; + 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 virtual std::vector getAllBookmarkCategories() const; + virtual bool checkBookmarkCategoryExists(const std::string& name) const; + virtual void removeBookmarkCategory(Id id); + protected: virtual void setErrorFilter(const ErrorFilter& filter); diff --git a/src/lib/data/bookmark/Bookmark.cpp b/src/lib/data/bookmark/Bookmark.cpp new file mode 100644 index 00000000..b3309e30 --- /dev/null +++ b/src/lib/data/bookmark/Bookmark.cpp @@ -0,0 +1,116 @@ +#include "Bookmark.h" + +Bookmark::Bookmark() + : m_id(-1) + , m_tokenTypes() + , m_tokenIds() + , m_tokenNames() + , m_comment("") + , m_displayName("") + , m_valid(false) + , m_timeStamp() + , m_category() +{ +} + +Bookmark::Bookmark(const std::string& displayName, const std::vector& tokens, const std::vector& tokenNames, const std::string& comment, const TimePoint& timeStamp) + : m_id(-1) + , m_tokenTypes() + , m_tokenIds(tokens) + , m_tokenNames(tokenNames) + , m_comment(comment) + , m_displayName(displayName) + , m_valid(false) + , m_timeStamp(timeStamp) + , m_category() +{ +} + +Bookmark::~Bookmark() +{ +} + +Id Bookmark::getId() const +{ + return m_id; +} + +void Bookmark::setId(const Id id) +{ + m_id = id; +} + +std::vector Bookmark::getTokenTypes() const +{ + return m_tokenTypes; +} + +void Bookmark::setTokenTypes(const std::vector& types) +{ + m_tokenTypes = types; +} + +std::vector Bookmark::getTokenIds() const +{ + return m_tokenIds; +} + +void Bookmark::setTokenIds(const std::vector& ids) +{ + m_tokenIds = ids; +} + +std::vector Bookmark::getTokenNames() const +{ + return m_tokenNames; +} + +void Bookmark::setTokenNames(const std::vector& names) +{ + m_tokenNames = names; +} + +std::string Bookmark::getComment() const +{ + return m_comment; +} + +void Bookmark::setComment(const std::string& comment) +{ + m_comment = comment; +} + +std::string Bookmark::getDisplayName() const +{ + return m_displayName; +} + +void Bookmark::setDisplayName(const std::string& name) +{ + m_displayName = name; +} + +bool Bookmark::isValid() const +{ + return m_valid; +} + +void Bookmark::setValid(const bool valid) +{ + m_valid = valid; +} + +TimePoint Bookmark::getTimeStamp() const +{ + return m_timeStamp; +} + +BookmarkCategory Bookmark::getCategory() const +{ + return m_category; +} + +void Bookmark::setCategory(const BookmarkCategory& category) +{ + m_category = category; +} \ No newline at end of file diff --git a/src/lib/data/bookmark/Bookmark.h b/src/lib/data/bookmark/Bookmark.h new file mode 100644 index 00000000..210d4d41 --- /dev/null +++ b/src/lib/data/bookmark/Bookmark.h @@ -0,0 +1,60 @@ +#ifndef BOOKMARK_H +#define BOOKMARK_H + +#include +#include + +#include "utility/TimePoint.h" +#include "utility/types.h" + +#include "BookmarkCategory.h" + +class Bookmark +{ +public: + Bookmark(); + Bookmark(const std::string& displayName, const std::vector& tokens, const std::vector& tokenNames, const std::string& comment, const TimePoint& timeStamp); + virtual ~Bookmark(); + + Id getId() const; + void setId(const Id id); + + std::vector getTokenTypes() const; + void setTokenTypes(const std::vector& types); + + std::vector getTokenIds() const; + void setTokenIds(const std::vector& ids); + + std::vector getTokenNames() const; + void setTokenNames(const std::vector& names); + + std::string getComment() const; + void setComment(const std::string& comment); + + std::string getDisplayName() const; + void setDisplayName(const std::string& name); + + bool isValid() const; + void setValid(const bool valid); + + TimePoint getTimeStamp() const; + + BookmarkCategory getCategory() const; + void setCategory(const BookmarkCategory& category); + +private: + Id m_id; + std::vector m_tokenTypes; + std::vector m_tokenIds; + std::vector m_tokenNames; + std::string m_comment; + std::string m_displayName; + + bool m_valid; + + TimePoint m_timeStamp; + + BookmarkCategory m_category; +}; + +#endif // BOOKMARK_H \ No newline at end of file diff --git a/src/lib/data/bookmark/BookmarkCategory.cpp b/src/lib/data/bookmark/BookmarkCategory.cpp new file mode 100644 index 00000000..88fa7d54 --- /dev/null +++ b/src/lib/data/bookmark/BookmarkCategory.cpp @@ -0,0 +1,31 @@ +#include "BookmarkCategory.h" + +BookmarkCategory::BookmarkCategory() + : m_id(-1) + , m_name("") +{ +} + +BookmarkCategory::~BookmarkCategory() +{ +} + +Id BookmarkCategory::getId() const +{ + return m_id; +} + +void BookmarkCategory::setId(const Id id) +{ + m_id = id; +} + +std::string BookmarkCategory::getName() const +{ + return m_name; +} + +void BookmarkCategory::setName(const std::string& name) +{ + m_name = name; +} \ No newline at end of file diff --git a/src/lib/data/bookmark/BookmarkCategory.h b/src/lib/data/bookmark/BookmarkCategory.h new file mode 100644 index 00000000..65bbf52b --- /dev/null +++ b/src/lib/data/bookmark/BookmarkCategory.h @@ -0,0 +1,25 @@ +#ifndef BOOKMARK_CATEGORY_H +#define BOOKMARK_CATEGORY_H + +#include + +#include "utility/types.h" + +class BookmarkCategory +{ +public: + BookmarkCategory(); + ~BookmarkCategory(); + + Id getId() const; + void setId(const Id id); + + std::string getName() const; + void setName(const std::string& name); + +private: + Id m_id; + std::string m_name; +}; + +#endif // BOOKMARK_CATEGORY_H \ No newline at end of file diff --git a/src/lib/data/bookmark/EdgeBookmark.cpp b/src/lib/data/bookmark/EdgeBookmark.cpp new file mode 100644 index 00000000..253e2bd5 --- /dev/null +++ b/src/lib/data/bookmark/EdgeBookmark.cpp @@ -0,0 +1,55 @@ +#include "EdgeBookmark.h" + +EdgeBookmark::EdgeBookmark() + : Bookmark() +{ +} + +EdgeBookmark::EdgeBookmark(const std::string& displayName, const std::vector& tokens, const std::vector& tokenNames, const std::string& comment, const TimePoint& timeStamp) + : Bookmark(displayName, tokens, tokenNames, comment, timeStamp) +{ +} + +EdgeBookmark::~EdgeBookmark() +{ +} + +std::vector EdgeBookmark::getEdgeTokenTypes() const +{ + return m_edgeTokenTypes; +} + +void EdgeBookmark::setEdgeTokenTypes(const std::vector& tokenTypes) +{ + m_edgeTokenTypes = tokenTypes; +} + +std::vector EdgeBookmark::getEdgeTokenIds() const +{ + return m_edgeTokenIds; +} + +void EdgeBookmark::setEdgeTokenIds(const std::vector& tokenIds) +{ + m_edgeTokenIds = tokenIds; +} + +std::vector EdgeBookmark::getEdgeTokenNames() const +{ + return m_edgeTokenNames; +} + +void EdgeBookmark::setEdgeTokenNames(const std::vector& tokenNames) +{ + m_edgeTokenNames = tokenNames; +} + +NodeBookmark EdgeBookmark::getBaseBookmark() const +{ + return m_baseBookmark; +} + +void EdgeBookmark::setBaseBookmark(const NodeBookmark& baseBookmark) +{ + m_baseBookmark = baseBookmark; +} \ No newline at end of file diff --git a/src/lib/data/bookmark/EdgeBookmark.h b/src/lib/data/bookmark/EdgeBookmark.h new file mode 100644 index 00000000..3ec29535 --- /dev/null +++ b/src/lib/data/bookmark/EdgeBookmark.h @@ -0,0 +1,35 @@ +#ifndef EDGE_BOOKMARK_H +#define EDGE_BOOKMARK_H + +#include "Bookmark.h" +#include "NodeBookmark.h" + +class EdgeBookmark + : public Bookmark +{ +public: + EdgeBookmark(); + EdgeBookmark(const std::string& displayName, const std::vector& tokens, const std::vector& tokenNames, const std::string& comment, const TimePoint& timeStamp); + virtual ~EdgeBookmark(); + + std::vector getEdgeTokenTypes() const; + void setEdgeTokenTypes(const std::vector& tokenTypes); + + std::vector getEdgeTokenIds() const; + void setEdgeTokenIds(const std::vector& tokenIds); + + std::vector getEdgeTokenNames() const; + void setEdgeTokenNames(const std::vector& tokenNames); + + NodeBookmark getBaseBookmark() const; + void setBaseBookmark(const NodeBookmark& baseBookmark); + +private: + std::vector m_edgeTokenTypes; + std::vector m_edgeTokenIds; + std::vector m_edgeTokenNames; + + NodeBookmark m_baseBookmark; +}; + +#endif // EDGE_BOOKMARK_H \ No newline at end of file diff --git a/src/lib/data/bookmark/NodeBookmark.cpp b/src/lib/data/bookmark/NodeBookmark.cpp new file mode 100644 index 00000000..3691efd0 --- /dev/null +++ b/src/lib/data/bookmark/NodeBookmark.cpp @@ -0,0 +1,15 @@ +#include "NodeBookmark.h" + +NodeBookmark::NodeBookmark() + : Bookmark() +{ +} + +NodeBookmark::NodeBookmark(const std::string& displayName, const std::vector& tokens, const std::vector& tokenNames, const std::string& comment, const TimePoint& timeStamp) + : Bookmark(displayName, tokens, tokenNames, comment, timeStamp) +{ +} + +NodeBookmark::~NodeBookmark() +{ +} \ No newline at end of file diff --git a/src/lib/data/bookmark/NodeBookmark.h b/src/lib/data/bookmark/NodeBookmark.h new file mode 100644 index 00000000..793eb0d6 --- /dev/null +++ b/src/lib/data/bookmark/NodeBookmark.h @@ -0,0 +1,15 @@ +#ifndef NODE_BOOKMARK_H +#define NODE_BOOKMARK_H + +#include "Bookmark.h" + +class NodeBookmark + : public Bookmark +{ +public: + NodeBookmark(); + NodeBookmark(const std::string& displayName, const std::vector& tokens, const std::vector& tokenNames, const std::string& comment, const TimePoint& timeStamp); + virtual ~NodeBookmark(); +}; + +#endif // NODE_BOOKMARK_H diff --git a/src/lib/utility/TimePoint.cpp b/src/lib/utility/TimePoint.cpp index 37456ee3..8365b2e2 100644 --- a/src/lib/utility/TimePoint.cpp +++ b/src/lib/utility/TimePoint.cpp @@ -44,7 +44,35 @@ std::string TimePoint::toString() const return stream.str(); } +std::string TimePoint::getDDMMYYYYString() const +{ + std::stringstream stream; + boost::posix_time::time_facet* facet = new boost::posix_time::time_facet(); + facet->format("%d-%m-%Y"); + stream.imbue(std::locale(std::locale::classic(), facet)); + stream << m_time; + return stream.str(); +} + size_t TimePoint::deltaMS(const TimePoint& other) const { return (m_time - other.m_time).total_milliseconds(); } + +bool TimePoint::isSameDay(const TimePoint& other) const +{ + if (m_time.date().day() == other.m_time.date().day() && + m_time.date().month() == other.m_time.date().month() && + m_time.date().year() == other.m_time.date().year()) + { + return true; + } + + return false; +} + +size_t TimePoint::deltaDays(const TimePoint& other) const +{ + boost::gregorian::date_duration deltaDate = m_time.date() - other.m_time.date(); + return size_t(std::abs(deltaDate.days())); +} diff --git a/src/lib/utility/TimePoint.h b/src/lib/utility/TimePoint.h index 09f31da8..4cab32a8 100644 --- a/src/lib/utility/TimePoint.h +++ b/src/lib/utility/TimePoint.h @@ -3,7 +3,7 @@ #include "boost/date_time/posix_time/posix_time.hpp" -class TimePoint +class TimePoint // that name sounds pretty silly, was time stamp not ok? { public: static TimePoint now(); @@ -16,6 +16,7 @@ public: bool isValid() const; std::string toString() const; + std::string getDDMMYYYYString() const; inline bool operator==(const TimePoint& rhs){ return m_time == rhs.m_time; } inline bool operator!=(const TimePoint& rhs){ return m_time != rhs.m_time; } @@ -28,6 +29,9 @@ public: size_t deltaMS(const TimePoint& other) const; + bool isSameDay(const TimePoint& other) const; + size_t deltaDays(const TimePoint& other) const; // days are counted beginning at 00:00, so a tp of 1.1.2017 23:59 is 1 day ago if it's the 2.1.2017 00:01 + private: boost::posix_time::ptime m_time; }; diff --git a/src/lib/utility/logging/LogManager.cpp b/src/lib/utility/logging/LogManager.cpp index fc785db0..22059219 100644 --- a/src/lib/utility/logging/LogManager.cpp +++ b/src/lib/utility/logging/LogManager.cpp @@ -16,8 +16,15 @@ std::shared_ptr LogManager::createInstance() return s_instance; } +// what is this method for? why would you want to risk returning s_instance without checking whether it is initialized??? std::shared_ptr LogManager::getInstance() { + // return s_instance; // original implementation + + if (s_instance.use_count() == 0) + { + s_instance = std::shared_ptr(new LogManager()); + } return s_instance; } diff --git a/src/lib/utility/messaging/type/MessageActivateBookmark.h b/src/lib/utility/messaging/type/MessageActivateBookmark.h new file mode 100644 index 00000000..acc775f8 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateBookmark.h @@ -0,0 +1,29 @@ +#ifndef MESSAGE_ACTIVATE_BOOKMARK_H +#define MESSAGE_ACTIVATE_BOOKMARK_H + +#include "utility/messaging/Message.h" + +#include "data/bookmark/Bookmark.h" + +class MessageActivateBookmark + : public Message +{ +public: + MessageActivateBookmark(const std::shared_ptr& bookmark) + : bookmark(bookmark) + { + } + + virtual ~MessageActivateBookmark() + { + } + + static const std::string getStaticType() + { + return "MessageActivateBookmark"; + } + + const std::shared_ptr bookmark; +}; + +#endif // MESSAGE_ACTIVATE_BOOKMARK_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageCreateBookmark.h b/src/lib/utility/messaging/type/MessageCreateBookmark.h new file mode 100644 index 00000000..a595cbd0 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageCreateBookmark.h @@ -0,0 +1,31 @@ +#ifndef MESSAGE_CREATE_BOOKMARK_H +#define MESSAGE_CREATE_BOOKMARK_H + +#include "utility/messaging/Message.h" + +class MessageCreateBookmark + : public Message +{ +public: + MessageCreateBookmark(const std::string& comment, const std::string& displayName, const std::string& categoryName) + : comment(comment) + , displayName(displayName) + , categoryName(categoryName) + { + } + + ~MessageCreateBookmark() + { + } + + static const std::string getStaticType() + { + return "MessageCreateBookmark"; + } + + const std::string comment; + const std::string displayName; + const std::string categoryName; +}; + +#endif // MESSAGE_CREATE_BOOKMARK_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageCreateBookmarkCategory.h b/src/lib/utility/messaging/type/MessageCreateBookmarkCategory.h new file mode 100644 index 00000000..da56efcb --- /dev/null +++ b/src/lib/utility/messaging/type/MessageCreateBookmarkCategory.h @@ -0,0 +1,23 @@ +#ifndef MESSAGE_CREATE_BOOKMARK_CATEGORY_H +#define MESSAGE_CREATE_BOOKMARK_CATEGORY_H + +#include "utility/messaging/Message.h" + +class MessageCreateBookmarkCategory + : public Message +{ +public: + MessageCreateBookmarkCategory(const std::string& name) + : name(name) + { + } + + static const std::string getStaticType() + { + return "MessageCreateBookmarkCategory"; + } + + const std::string name; +}; + +#endif // MESSAGE_CREATE_BOOKMARK_CATEGORY_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageDeleteBookmark.h b/src/lib/utility/messaging/type/MessageDeleteBookmark.h new file mode 100644 index 00000000..13cc65e9 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageDeleteBookmark.h @@ -0,0 +1,30 @@ +#ifndef MESSAGE_DELETE_BOOKMARK_H +#define MESSAGE_DELETE_BOOKMARK_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +class MessageDeleteBookmark + : public Message +{ +public: + MessageDeleteBookmark(const Id bookmarkId, const bool isEdge) + : bookmarkId(bookmarkId) + , isEdge(isEdge) + { + } + + ~MessageDeleteBookmark() + { + } + + static const std::string getStaticType() + { + return "MessageDeleteBookmark"; + } + + const Id bookmarkId; + const bool isEdge; +}; + +#endif // MESSAGE_DELETE_BOOKMARK_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageDeleteBookmarkCategoryWithBookmarks.h b/src/lib/utility/messaging/type/MessageDeleteBookmarkCategoryWithBookmarks.h new file mode 100644 index 00000000..57eddcac --- /dev/null +++ b/src/lib/utility/messaging/type/MessageDeleteBookmarkCategoryWithBookmarks.h @@ -0,0 +1,28 @@ +#ifndef MESSAGE_DELETE_BOOKMARK_CATEGORY_WITH_BOOKMARKS_H +#define MESSAGE_DELETE_BOOKMARK_CATEGORY_WITH_BOOKMARKS_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +class MessageDeleteBookmarkCategoryWithBookmarks + : public Message +{ +public: + MessageDeleteBookmarkCategoryWithBookmarks(const Id id) + : categoryId(id) + { + } + + ~MessageDeleteBookmarkCategoryWithBookmarks() + { + } + + static const std::string getStaticType() + { + return "MessageDeleteBookmarkCategoryWithBookmarks"; + } + + const Id categoryId; +}; + +#endif // MESSAGE_DELETE_BOOKMARK_CATEGORY_WITH_BOOKMARKS_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageDeleteBookmarkForActiveTokens.h b/src/lib/utility/messaging/type/MessageDeleteBookmarkForActiveTokens.h new file mode 100644 index 00000000..39635c41 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageDeleteBookmarkForActiveTokens.h @@ -0,0 +1,24 @@ +#ifndef MESSAGE_DELETE_BOOKMARK_FOR_ACTIVE_TOKENS +#define MESSAGE_DELETE_BOOKMARK_FOR_ACTIVE_TOKENS + +#include "utility/messaging/Message.h" + +class MessageDeleteBookmarkForActiveTokens + : public Message +{ +public: + MessageDeleteBookmarkForActiveTokens() + { + } + + ~MessageDeleteBookmarkForActiveTokens() + { + } + + static const std::string getStaticType() + { + return "MessageDeleteBookmarkForActiveTokens"; + } +}; + +#endif // MESSAGE_DELETE_BOOKMARK_FOR_ACTIVE_TOKENS diff --git a/src/lib/utility/messaging/type/MessageDisplayBookmarkCreator.h b/src/lib/utility/messaging/type/MessageDisplayBookmarkCreator.h new file mode 100644 index 00000000..0fbe325b --- /dev/null +++ b/src/lib/utility/messaging/type/MessageDisplayBookmarkCreator.h @@ -0,0 +1,20 @@ +#ifndef MESSAGE_DISPLAY_BOOKMARK_CREATOR_H +#define MESSAGE_DISPLAY_BOOKMARK_CREATOR_H + +#include "utility/messaging/Message.h" + +class MessageDisplayBookmarkCreator + : public Message +{ +public: + MessageDisplayBookmarkCreator() + { + } + + static const std::string getStaticType() + { + return "MessageDisplayBookmarkCreator"; + } +}; + +#endif // MESSAGE_DISPLAY_BOOKMARK_CREATOR_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageDisplayBookmarkEditor.h b/src/lib/utility/messaging/type/MessageDisplayBookmarkEditor.h new file mode 100644 index 00000000..e450e916 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageDisplayBookmarkEditor.h @@ -0,0 +1,25 @@ +#ifndef MESSAGE_DISPLAY_BOOKMARK_EDITOR_H +#define MESSAGE_DISPLAY_BOOKMARK_EDITOR_H + +#include "data/bookmark/Bookmark.h" + +#include "utility/messaging/Message.h" + +class MessageDisplayBookmarkEditor + : public Message +{ +public: + MessageDisplayBookmarkEditor(std::shared_ptr bookmark) + : bookmark(bookmark) + { + } + + static const std::string getStaticType() + { + return "MessageDisplayBookmarkEditor"; + } + + std::shared_ptr bookmark; +}; + +#endif // MESSAGE_DISPLAY_BOOKMARK_EDITOR_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageDisplayBookmarks.h b/src/lib/utility/messaging/type/MessageDisplayBookmarks.h new file mode 100644 index 00000000..1dd22074 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageDisplayBookmarks.h @@ -0,0 +1,42 @@ +#ifndef MESSAGE_DISPLAY_BOOKMARKS_H +#define MESSAGE_DISPLAY_BOOKMARKS_H + +#include "utility/messaging/Message.h" + +class MessageDisplayBookmarks + : public Message +{ +public: + enum BookmarkFilter + { + UNKNOWN = 0, + ALL, + NODES, + EDGES + }; + + enum BookmarkOrder + { + NONE = 0, + DATE_ASCENDING, + DATE_DESCENDING, + NAME_ASCENDING, + NAME_DESCENDING + }; + + MessageDisplayBookmarks(const BookmarkFilter& filter, const BookmarkOrder& order) + : filter(filter) + , order(order) + { + } + + static const std::string getStaticType() + { + return "MessageDisplayBookmarks"; + } + + const BookmarkFilter filter; + const BookmarkOrder order; +}; + +#endif // MESSAGE_DISPLAY_BOOKMARKS_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessageEditBookmark.h b/src/lib/utility/messaging/type/MessageEditBookmark.h new file mode 100644 index 00000000..9801c2c7 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageEditBookmark.h @@ -0,0 +1,36 @@ +#ifndef MESSAGE_EDIT_BOOKMARK_H +#define MESSAGE_EDIT_BOOKMARK_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +class MessageEditBookmark + : public Message +{ +public: + MessageEditBookmark(const Id id, const std::string& comment, const std::string& displayName, const std::string& categoryName, const bool isEdge) + : bookmarkId(id) + , comment(comment) + , displayName(displayName) + , categoryName(categoryName) + , isEdge(isEdge) + { + } + + ~MessageEditBookmark() + { + } + + static const std::string getStaticType() + { + return "MessageEditBookmark"; + } + + const Id bookmarkId; + const std::string comment; + const std::string displayName; + const std::string categoryName; + const bool isEdge; +}; + +#endif // MESSAGE_EDIT_BOOKMARK_H \ No newline at end of file diff --git a/src/lib/utility/messaging/type/MessagePingReceived.h b/src/lib/utility/messaging/type/MessagePingReceived.h index d2c76f4e..5fce1118 100644 --- a/src/lib/utility/messaging/type/MessagePingReceived.h +++ b/src/lib/utility/messaging/type/MessagePingReceived.h @@ -9,6 +9,7 @@ class MessagePingReceived public: MessagePingReceived() : ideId("") + , ideName("") { } @@ -18,6 +19,7 @@ public: } std::string ideId; + std::string ideName; }; #endif // MESSAGE_PING_RECEIVED_H \ No newline at end of file diff --git a/src/lib_gui/CMakeLists.txt b/src/lib_gui/CMakeLists.txt index 4391c45c..21302540 100644 --- a/src/lib_gui/CMakeLists.txt +++ b/src/lib_gui/CMakeLists.txt @@ -8,6 +8,12 @@ add_files( qt/element/QtAutocompletionList.cpp qt/element/QtAutocompletionList.h + qt/element/QtBookmark.cpp + qt/element/QtBookmark.h + qt/element/QtBookmarkBar.cpp + qt/element/QtBookmarkBar.h + qt/element/QtBookmarkCategory.cpp + qt/element/QtBookmarkCategory.h qt/element/QtCodeArea.cpp qt/element/QtCodeArea.h qt/element/QtCodeFile.cpp @@ -101,6 +107,8 @@ add_files( qt/view/graphElements/QtGraphNodeText.cpp qt/view/graphElements/QtGraphNodeText.h + qt/view/QtBookmarkView.cpp + qt/view/QtBookmarkView.h qt/view/QtCodeView.cpp qt/view/QtCodeView.h qt/view/QtCompositeView.cpp @@ -165,6 +173,10 @@ add_files( qt/window/QtAbout.h qt/window/QtAboutLicense.cpp qt/window/QtAboutLicense.h + qt/window/QtBookmarkBrowser.cpp + qt/window/QtBookmarkBrowser.h + qt/window/QtBookmarkCreator.cpp + qt/window/QtBookmarkCreator.h qt/window/QtIndexingDialog.cpp qt/window/QtIndexingDialog.h qt/window/QtKeyboardShortcuts.cpp diff --git a/src/lib_gui/qt/element/QtBookmark.cpp b/src/lib_gui/qt/element/QtBookmark.cpp new file mode 100644 index 00000000..60182792 --- /dev/null +++ b/src/lib_gui/qt/element/QtBookmark.cpp @@ -0,0 +1,263 @@ +#include "QtBookmark.h" + +#include +#include + +#include "qt/window/QtBookmarkCreator.h" + +#include "data/bookmark/EdgeBookmark.h" + +#include "utility/messaging/type/MessageActivateBookmark.h" +#include "utility/messaging/type/MessageDisplayBookmarkEditor.h" + +#include "utility/ResourcePaths.h" + +#include "qt/utility/utilityQt.h" + +QtBookmark::QtBookmark() + : m_treeWidgetItem(NULL) +{ + setObjectName("bookmark"); + + m_layout = new QVBoxLayout(); + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setAlignment(Qt::AlignTop); + setLayout(m_layout); + + QHBoxLayout* buttonsLayout = new QHBoxLayout(); + buttonsLayout->setSpacing(0); + buttonsLayout->setContentsMargins(0, 0, 0, 0); + buttonsLayout->setAlignment(Qt::AlignTop); + + m_toggleCommentButton = new QPushButton(); + m_toggleCommentButton->setObjectName("comment_button"); + m_toggleCommentButton->setToolTip("Show Comment"); + m_toggleCommentButton->setText(""); + m_toggleCommentButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + buttonsLayout->addWidget(m_toggleCommentButton); + + m_dateLabel = new QLabel(); + m_dateLabel->setObjectName("date_label"); + m_dateLabel->setText("n/a"); + buttonsLayout->addWidget(m_dateLabel); + + m_activateButton = new QPushButton(); + m_activateButton->setObjectName("activate_button"); + m_activateButton->setToolTip("Activate bookmark"); + m_activateButton->setText("Bookmark"); + m_activateButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + buttonsLayout->addWidget(m_activateButton); + + m_editButton = new QPushButton(); + m_editButton->setObjectName("edit_button"); + m_editButton->setToolTip("Edit bookmark"); + m_editButton->setText("Edit"); + m_editButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + buttonsLayout->addWidget(m_editButton); + + m_deleteButton = new QPushButton(); + m_deleteButton->setObjectName("delete_button"); + m_deleteButton->setToolTip("Delete bookmark"); + m_deleteButton->setText("Delete"); + m_deleteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + buttonsLayout->addWidget(m_deleteButton); + + m_layout->addLayout(buttonsLayout); + + m_comment = new QLabel(); + m_comment->setText("no comment"); + m_comment->hide(); + m_comment->setWordWrap(true); + m_layout->addWidget(m_comment); + + + connect(m_activateButton, SIGNAL(clicked()), this, SLOT(activateClicked())); + connect(m_editButton, SIGNAL(clicked()), this, SLOT(editClicked())); + connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked())); + connect(m_toggleCommentButton, SIGNAL(clicked()), this, SLOT(commentToggled())); + + refreshStyle(); +} + +QtBookmark::~QtBookmark() +{ +} + +void QtBookmark::setName(const std::string& name) +{ + m_activateButton->setText(name.c_str()); +} + +std::string QtBookmark::getName() const +{ + return m_bookmark->getDisplayName(); +} + +void QtBookmark::setBookmark(const std::shared_ptr bookmark) +{ + m_bookmark = bookmark; + + m_activateButton->setText(bookmark->getDisplayName().c_str()); + + bool isValid = m_bookmark->isValid(); + + if (m_bookmark->isValid() == false) + { + m_activateButton->setEnabled(false); + m_editButton->setEnabled(false); + } + + if (m_bookmark->getComment().length() > 0) + { + m_comment->setText(m_bookmark->getComment().c_str()); + m_activateButton->setToolTip(bookmark->getComment().c_str()); + } + m_dateLabel->setText(getDateString().c_str()); + + getDateString(); +} + +Id QtBookmark::getBookmarkId() const +{ + return m_bookmark->getId(); +} + +QTreeWidgetItem* QtBookmark::getTreeWidgetItem() const +{ + return m_treeWidgetItem; +} + +void QtBookmark::setTreeWidgetItem(QTreeWidgetItem* treeWidgetItem) +{ + m_treeWidgetItem = treeWidgetItem; +} + +void QtBookmark::refreshStyle() +{ + if (m_editButton != NULL) + { + m_editButton->setText(""); + m_editButton->setIcon(QPixmap((ResourcePaths::getGuiPath() + "bookmark_view/images/bookmark_edit_icon.png").c_str())); + } + + if (m_deleteButton != NULL) + { + m_deleteButton->setText(""); + m_deleteButton->setIcon(QPixmap((ResourcePaths::getGuiPath() + "bookmark_view/images/bookmark_delete_icon.png").c_str())); + } + + if (m_toggleCommentButton != NULL) + { + m_toggleCommentButton->setText(""); + m_toggleCommentButton->setIcon(utility::createButtonIcon( + ResourcePaths::getGuiPath() + "bookmark_view/images/arrow_right.png", + "bookmark/button" + )); + m_toggleCommentButton->setIconSize(QSize(10, 10)); + } +} + +void QtBookmark::activateClicked() +{ + MessageActivateBookmark(m_bookmark).dispatch(); +} + +void QtBookmark::editClicked() +{ + MessageDisplayBookmarkEditor(m_bookmark).dispatch(); +} + +void QtBookmark::deleteClicked() +{ + QMessageBox msgBox; + msgBox.setText("Delete Bookmark"); + msgBox.setInformativeText("Do you really want to delete this bookmark?"); + QAbstractButton* yesButton = msgBox.addButton("Delete", QMessageBox::ButtonRole::YesRole); + QAbstractButton* noButton = msgBox.addButton("Keep", QMessageBox::ButtonRole::NoRole); + msgBox.setIcon(QMessageBox::Icon::Question); + int ret = msgBox.exec(); + + if (ret == 0) // QMessageBox::Yes) + { + MessageDeleteBookmark(m_bookmark->getId(), (dynamic_cast(m_bookmark.get()) != NULL)).dispatch(); + } +} + +void QtBookmark::commentToggled() +{ + // std::string text = m_toggleCommentButton->text().toStdString(); + + if (m_comment->isVisible() == false) + { + m_toggleCommentButton->setText(""); + m_toggleCommentButton->setText(""); + m_toggleCommentButton->setIcon(utility::createButtonIcon( + ResourcePaths::getGuiPath() + "bookmark_view/images/arrow_down.png", + "bookmark/button" + )); + m_toggleCommentButton->setIconSize(QSize(10, 10)); + m_comment->show(); + } + else + { + m_toggleCommentButton->setText(""); + m_toggleCommentButton->setText(""); + m_toggleCommentButton->setIcon(utility::createButtonIcon( + ResourcePaths::getGuiPath() + "bookmark_view/images/arrow_right.png", + "bookmark/button" + )); + m_toggleCommentButton->setIconSize(QSize(10, 10)); + m_comment->hide(); + } + + // forces the parent tree view to rescale + if (m_treeWidgetItem) + { + m_treeWidgetItem->setExpanded(false); + m_treeWidgetItem->setExpanded(true); + } +} + +void QtBookmark::handleMessage(MessageEditBookmark* message) +{ + if (m_bookmark->getId() == message->bookmarkId) + { + m_bookmark->setDisplayName(message->displayName); + m_bookmark->setComment(message->comment); + + m_activateButton->setText(message->displayName.c_str()); + } +} + +std::string QtBookmark::getDateString() const +{ + std::string result = "n/a"; + + TimePoint creationDate = m_bookmark->getTimeStamp(); + + float delta = TimePoint::now() - creationDate; + + if (delta < 3600.0f) // less than an hour ago + { + result = std::to_string(int(delta / 60.0f)) + " minutes ago"; + } + else if (delta < (3600.0f * 6.0f)) // less than 6 hours ago + { + result = std::to_string(int(delta / 3600.0f)) + " hours ago"; + } + else if (creationDate.isSameDay(TimePoint::now())) // today + { + result = "today"; + } + else if(creationDate.deltaDays(TimePoint::now()) == 1) // yesterday + { + result = "yesterday"; + } + else // whenever + { + result = creationDate.getDDMMYYYYString(); + } + + return result; +} diff --git a/src/lib_gui/qt/element/QtBookmark.h b/src/lib_gui/qt/element/QtBookmark.h new file mode 100644 index 00000000..c328b72d --- /dev/null +++ b/src/lib_gui/qt/element/QtBookmark.h @@ -0,0 +1,68 @@ +#ifndef QT_BOOKMARK_H +#define QT_BOOKMARK_H + +#include + +#include +#include +#include +#include + +#include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/MessageDeleteBookmark.h" +#include "utility/messaging/type/MessageEditBookmark.h" + +#include "data/bookmark/Bookmark.h" + +#include + +class QtBookmark + : public QFrame + , public MessageListener +{ + Q_OBJECT + +public: + QtBookmark(); + virtual ~QtBookmark(); + + void setName(const std::string& name); + std::string getName() const; + + void setBookmark(const std::shared_ptr bookmark); + + Id getBookmarkId() const; + + QTreeWidgetItem* getTreeWidgetItem() const; + void setTreeWidgetItem(QTreeWidgetItem* treeWidgetItem); + + void refreshStyle(); + +private slots: + void activateClicked(); + void editClicked(); + void deleteClicked(); + void commentToggled(); + +private: + void handleMessage(MessageEditBookmark* message); + + std::string getDateString() const; + + QVBoxLayout* m_layout; + + QPushButton* m_activateButton; + QPushButton* m_editButton; + QPushButton* m_deleteButton; + QPushButton* m_toggleCommentButton; + + QLabel* m_comment; + QLabel* m_dateLabel; + + std::shared_ptr m_bookmark; + + QTreeWidgetItem* m_treeWidgetItem; // pointer to the bookmark category item in the treeView, allows to refresh tree view when a node changes in size (e.g. toggle comment) + // not a nice solution to the problem, but couldn't find anything better yet (sizeHintChanged signal can't be emitted here...) +}; + +#endif // QT_BOOKMARK_H \ No newline at end of file diff --git a/src/lib_gui/qt/element/QtBookmarkBar.cpp b/src/lib_gui/qt/element/QtBookmarkBar.cpp new file mode 100644 index 00000000..36230339 --- /dev/null +++ b/src/lib_gui/qt/element/QtBookmarkBar.cpp @@ -0,0 +1,261 @@ +#include "QtBookmarkBar.h" + +#include +#include +#include + +#include "data/bookmark/EdgeBookmark.h" + +#include "utility/messaging/type/MessageDeleteBookmarkForActiveTokens.h" +#include "utility/messaging/type/MessageDisplayBookmarks.h" +#include "utility/messaging/type/MessageDisplayBookmarkCreator.h" +#include "utility/ResourcePaths.h" + +#include "qt/utility/utilityQt.h" +#include "settings/ApplicationSettings.h" +#include "settings/ColorScheme.h" + +#include "qt/window/QtBookmarkCreator.h" + +#include "qt/window/QtMainWindow.h" + +#include "qt/element/QtBookmark.h" + +QtBookmarkBar::QtBookmarkBar() + : m_displayBookmarksFunctor(std::bind(&QtBookmarkBar::doDisplayBookmarks, this, std::placeholders::_1)) + , m_displayBookmarkCreatorFunctor(std::bind(&QtBookmarkBar::doDisplayBookmarkCreator, this, std::placeholders::_1, std::placeholders::_2)) + , m_displayBookmarkEditorFunctor(std::bind(&QtBookmarkBar::doDisplayBookmarkEditor, this, std::placeholders::_1, std::placeholders::_2)) + , m_setCreateButtonStateFunctor(std::bind(&QtBookmarkBar::doSetCreateButtonState, this, std::placeholders::_1)) + , m_enableDisplayButtonFunctor(std::bind(&QtBookmarkBar::doEnableDisplayButton, this, std::placeholders::_1)) + , m_bookmarkBrowser(NULL) + , m_createButtonState(BookmarkView::CreateButtonState::CANNOT_CREATE) +{ + setObjectName("bookmark_bar"); + + QBoxLayout* layout = new QHBoxLayout(); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->setAlignment(Qt::AlignTop); + setLayout(layout); + + m_createBookmarkButton = new QPushButton(this); + m_createBookmarkButton->setObjectName("bookmark_button"); + m_createBookmarkButton->setToolTip("create a bookmark for the active symbol"); + m_createBookmarkButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + layout->addWidget(m_createBookmarkButton); + + m_createBookmarkButton->setEnabled(false); + + connect(m_createBookmarkButton, SIGNAL(clicked()), this, SLOT(createBookmarkClicked())); + + m_showBookmarksButton = new QPushButton(this); + m_showBookmarksButton->setObjectName("show_bookmark_button"); + m_showBookmarksButton->setToolTip("Show bookmarks"); + m_showBookmarksButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + layout->addWidget(m_showBookmarksButton); + + m_showBookmarksButton->setEnabled(false); + + connect(m_showBookmarksButton, SIGNAL(clicked()), this, SLOT(showBookmarksClicked())); + + refreshStyle(); +} + +QtBookmarkBar::~QtBookmarkBar() +{ + +} + +void QtBookmarkBar::refreshStyle() +{ + setStyleSheet(utility::getStyleSheet(ResourcePaths::getGuiPath() + "bookmark_view/bookmark_view.css").c_str()); + + float height = std::max(ApplicationSettings::getInstance()->getFontSize() + 16, 30); + + m_createBookmarkButton->setFixedHeight(height); + m_showBookmarksButton->setFixedHeight(height); + + std::string createImage = ResourcePaths::getGuiPath() + "bookmark_view/images/edit_bookmark_icon.png"; + std::string listImage = ResourcePaths::getGuiPath() + "bookmark_view/images/bookmark_list_icon.png"; + + m_createBookmarkButton->setIcon(utility::colorizePixmap( + QPixmap(createImage.c_str()), + ColorScheme::getInstance()->getColor("search/button/icon").c_str() + )); + + m_showBookmarksButton->setIcon(utility::colorizePixmap( + QPixmap(listImage.c_str()), + ColorScheme::getInstance()->getColor("search/button/icon").c_str() + )); +} + +void QtBookmarkBar::displayBookmarks(const std::vector>& bookmarks) +{ + m_displayBookmarksFunctor(bookmarks); +} + +void QtBookmarkBar::displayBookmarkCreator(const std::vector& names, const std::vector& categories) +{ + m_displayBookmarkCreatorFunctor(names, categories); +} + +void QtBookmarkBar::displayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories) +{ + m_displayBookmarkEditorFunctor(bookmark, categories); +} + +void QtBookmarkBar::setCreateButtonState(const BookmarkView::CreateButtonState& state) +{ + m_setCreateButtonStateFunctor(state); +} + +void QtBookmarkBar::enableDisplayButton(bool enable) +{ + m_enableDisplayButtonFunctor(enable); +} + +bool QtBookmarkBar::bookmarkBrowserIsVisible() const +{ + if (m_bookmarkBrowser != NULL) + { + return m_bookmarkBrowser->isVisible(); + } + else + { + return false; + } +} + +void QtBookmarkBar::createBookmarkClicked() +{ + if (m_createButtonState == BookmarkView::CreateButtonState::CAN_CREATE) + { + MessageDisplayBookmarkCreator().dispatch(); + } + else if (m_createButtonState == BookmarkView::CreateButtonState::ALREADY_CREATED) + { + QMessageBox msgBox; + msgBox.setText("Edit Bookmark"); + msgBox.setInformativeText("Do you want to update or delete the Bookmark for the active Token?"); + QAbstractButton* editButton = msgBox.addButton("Edit", QMessageBox::ButtonRole::YesRole); + QAbstractButton* deleteButton = msgBox.addButton("Delete", QMessageBox::ButtonRole::DestructiveRole); + QAbstractButton* cancelButton = msgBox.addButton("Cancel", QMessageBox::ButtonRole::NoRole); + msgBox.setIcon(QMessageBox::Icon::Question); + int ret = msgBox.exec(); + + if (ret == 0) // QMessageBox::Yes) + { + MessageDisplayBookmarkCreator().dispatch(); + } + else if (ret == 1) + { + MessageDeleteBookmarkForActiveTokens().dispatch(); + } + } +} + +void QtBookmarkBar::showBookmarksClicked() +{ + MessageDisplayBookmarks(MessageDisplayBookmarks::BookmarkFilter::ALL, MessageDisplayBookmarks::BookmarkOrder::NONE).dispatch(); +} + +void QtBookmarkBar::handleMessage(MessageEnteredLicense* message) +{ + m_onQtThread( + [=]() + { + // actually only want to enable this when a project is loaded + // maybe factor in licence later... + // m_createBookmarkButton->setEnabled(true); + // m_showBookmarksButton->setEnabled(true); + } + ); +} + +void QtBookmarkBar::doDisplayBookmarkCreator(const std::vector& names, const std::vector& categories) +{ + QtBookmarkCreator* bookmarkCreator = new QtBookmarkCreator(); + bookmarkCreator->setupBookmarkCreator(); + + std::string displayName = ""; + + for (unsigned int i = 0; i < names.size(); i++) + { + displayName += names[i]; + + if (i < names.size() - 1) + { + displayName += "; "; + } + } + + bookmarkCreator->setDisplayName(displayName); + bookmarkCreator->setBookmarkCategories(categories); + bookmarkCreator->show(); +} + +void QtBookmarkBar::doDisplayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories) +{ + QtBookmarkCreator* bookmarkCreator = new QtBookmarkCreator(NULL, true, bookmark->getId()); + bookmarkCreator->setupBookmarkCreator(); + bookmarkCreator->setDisplayName(bookmark->getDisplayName()); + bookmarkCreator->setComment(bookmark->getComment()); + bookmarkCreator->setBookmarkCategories(categories); + bookmarkCreator->setCurrentBookmarkCategory(bookmark->getCategory()); + bookmarkCreator->setIsEdge((dynamic_cast(bookmark.get()) != NULL)); + + bookmarkCreator->show(); +} + +void QtBookmarkBar::doDisplayBookmarks(const std::vector>& bookmarks) +{ + if (m_bookmarkBrowser == NULL) + { + m_bookmarkBrowser = new QtBookmarkBrowser(); + m_bookmarkBrowser->setupBookmarkBrowser(); + } + + m_bookmarkBrowser->setBookmarks(bookmarks); + m_bookmarkBrowser->show(); +} + +void QtBookmarkBar::doSetCreateButtonState(const BookmarkView::CreateButtonState& state) +{ + m_createButtonState = state; + + std::string createImage = ResourcePaths::getGuiPath() + "bookmark_view/images/edit_bookmark_icon.png"; + + m_createBookmarkButton->setIcon(utility::colorizePixmap( + QPixmap(createImage.c_str()), + ColorScheme::getInstance()->getColor("search/button/icon").c_str() + )); + + if (state == BookmarkView::CreateButtonState::CAN_CREATE) + { + m_createBookmarkButton->setEnabled(true); + } + else if (state == BookmarkView::CreateButtonState::CANNOT_CREATE) + { + m_createBookmarkButton->setEnabled(false); + } + else if (state == BookmarkView::CreateButtonState::ALREADY_CREATED) + { + m_createBookmarkButton->setEnabled(true); + + std::string createImage = ResourcePaths::getGuiPath() + "bookmark_view/images/bookmark_active.png"; + + m_createBookmarkButton->setIcon(utility::colorizePixmap( + QPixmap(createImage.c_str()), + ColorScheme::getInstance()->getColor("search/button/icon").c_str() + )); + } + else + { + m_createBookmarkButton->setEnabled(false); + } +} + +void QtBookmarkBar::doEnableDisplayButton(bool enable) +{ + m_showBookmarksButton->setEnabled(enable); +} \ No newline at end of file diff --git a/src/lib_gui/qt/element/QtBookmarkBar.h b/src/lib_gui/qt/element/QtBookmarkBar.h new file mode 100644 index 00000000..e47efb86 --- /dev/null +++ b/src/lib_gui/qt/element/QtBookmarkBar.h @@ -0,0 +1,69 @@ +#ifndef QT_BOOKMARK_BAR_H +#define QT_BOOKMARK_BAR_H + +#include +#include + +#include "data/bookmark/Bookmark.h" + +#include "component/view/BookmarkView.h" +#include "qt/window/QtBookmarkBrowser.h" +#include "qt/utility/QtThreadedFunctor.h" +#include "utility/messaging/type/MessageEnteredLicense.h" +#include "utility/messaging/MessageListener.h" + +#include "data/bookmark/Bookmark.h" + +class QPushButton; + +class QtBookmarkBar + : public QFrame + , public MessageListener +{ + Q_OBJECT + +public: + QtBookmarkBar(); + virtual ~QtBookmarkBar(); + + void refreshStyle(); + + virtual void displayBookmarks(const std::vector>& bookmarks); + virtual void displayBookmarkCreator(const std::vector& names, const std::vector& categories); + virtual void displayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories); + + void setCreateButtonState(const BookmarkView::CreateButtonState& state); + void enableDisplayButton(bool enable); + + bool bookmarkBrowserIsVisible() const; + +private slots: + void createBookmarkClicked(); + void showBookmarksClicked(); + +private: + virtual void handleMessage(MessageEnteredLicense* message); + + void doDisplayBookmarks(const std::vector>& bookmarks); + void doDisplayBookmarkCreator(const std::vector& names, const std::vector& categories); + void doDisplayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories); + void doSetCreateButtonState(const BookmarkView::CreateButtonState& state); + void doEnableDisplayButton(bool enable); + + QtThreadedLambdaFunctor m_onQtThread; + + QPushButton* m_createBookmarkButton; + QPushButton* m_showBookmarksButton; + + QtThreadedFunctor>> m_displayBookmarksFunctor; + QtThreadedFunctor, std::vector> m_displayBookmarkCreatorFunctor; + QtThreadedFunctor, std::vector> m_displayBookmarkEditorFunctor; + QtThreadedFunctor m_setCreateButtonStateFunctor; + QtThreadedFunctor m_enableDisplayButtonFunctor; + + QtBookmarkBrowser* m_bookmarkBrowser; + + BookmarkView::CreateButtonState m_createButtonState; +}; + +#endif // QT_BOOKMARK_BAR_H diff --git a/src/lib_gui/qt/element/QtBookmarkCategory.cpp b/src/lib_gui/qt/element/QtBookmarkCategory.cpp new file mode 100644 index 00000000..80a3d6b9 --- /dev/null +++ b/src/lib_gui/qt/element/QtBookmarkCategory.cpp @@ -0,0 +1,145 @@ +#include "QtBookmarkCategory.h" + +#include + +#include "utility/messaging/type/MessageDeleteBookmarkCategoryWithBookmarks.h" + +#include "utility/ResourcePaths.h" + +#include "qt/utility/utilityQt.h" + +QtBookmarkCategory::QtBookmarkCategory() + : m_name(NULL) + , m_layout(NULL) + , m_deleteButton(NULL) + , m_id(-1) + , m_treeItem(NULL) +{ + setObjectName("bookmark_category"); + + m_layout = new QHBoxLayout(); + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setAlignment(Qt::AlignTop); + setLayout(m_layout); + + m_expandButton = new QPushButton(); + m_expandButton->setObjectName("category_expand_button"); + m_expandButton->setToolTip("Show/Hide bookmarks in this category"); + m_expandButton->setIcon(utility::createButtonIcon( + ResourcePaths::getGuiPath() + "bookmark_view/images/arrow_down.png", + "bookmark/button" + )); + m_expandButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_layout->addWidget(m_expandButton); + + connect(m_expandButton, SIGNAL(clicked()), this, SLOT(expandClicked())); + + m_name = new QLabel(); + m_name->setObjectName("category_name"); + m_name->setText(""); + m_layout->addWidget(m_name); + + m_deleteButton = new QPushButton(); + m_deleteButton->setObjectName("category_delete_button"); + m_deleteButton->setToolTip("Delete this Bookmark Category and the containing Bookmarks"); + // m_deleteButton->setText("Delete"); + m_deleteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_deleteButton->setIcon(QPixmap((ResourcePaths::getGuiPath() + "bookmark_view/images/bookmark_delete_icon.png").c_str())); + m_layout->addWidget(m_deleteButton); + + connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked())); +} + +QtBookmarkCategory::~QtBookmarkCategory() +{ +} + +void QtBookmarkCategory::setName(const std::string& name) +{ + if (m_name != NULL) + { + m_name->setText(name.c_str()); + } +} + +std::string QtBookmarkCategory::getName() const +{ + std::string result = ""; + + if (m_name != NULL) + { + result = m_name->text().toStdString(); + } + + return result; +} + +void QtBookmarkCategory::setId(const Id id) +{ + m_id = id; +} + +Id QtBookmarkCategory::getId() const +{ + return m_id; +} + +void QtBookmarkCategory::setTreeWidgetItem(QTreeWidgetItem* treeItem) +{ + m_treeItem = treeItem; +} + +void QtBookmarkCategory::updateArrow() +{ + if (m_treeItem != NULL) + { + if (m_treeItem->isExpanded()) + { + m_expandButton->setIcon(utility::createButtonIcon( + ResourcePaths::getGuiPath() + "bookmark_view/images/arrow_down.png", + "bookmark/button" + )); + } + else + { + m_expandButton->setIcon(utility::createButtonIcon( + ResourcePaths::getGuiPath() + "bookmark_view/images/arrow_right.png", + "bookmark/button" + )); + } + } +} + +void QtBookmarkCategory::expandClicked() +{ + if (m_treeItem != NULL) + { + if (m_treeItem->isExpanded()) + { + m_treeItem->setExpanded(false); + } + else + { + m_treeItem->setExpanded(true); + } + + updateArrow(); + } +} + +void QtBookmarkCategory::deleteClicked() +{ + QMessageBox msgBox; + msgBox.setText("Delete Category"); + msgBox.setInformativeText("Do you really want to delete this category AND all containing bookmarks?"); + QAbstractButton* yesButton = msgBox.addButton("Delete", QMessageBox::ButtonRole::YesRole); + QAbstractButton* noButton = msgBox.addButton("Keep", QMessageBox::ButtonRole::NoRole); + msgBox.setIcon(QMessageBox::Icon::Question); + int ret = msgBox.exec(); + + if (ret == 0) + { + MessageDeleteBookmarkCategoryWithBookmarks(m_id).dispatch(); + } +} \ No newline at end of file diff --git a/src/lib_gui/qt/element/QtBookmarkCategory.h b/src/lib_gui/qt/element/QtBookmarkCategory.h new file mode 100644 index 00000000..a1fa210c --- /dev/null +++ b/src/lib_gui/qt/element/QtBookmarkCategory.h @@ -0,0 +1,48 @@ +#ifndef QT_BOOKMARK_CATEGORY_H +#define QT_BOOKMARK_CATEGORY_H + +#include + +#include +#include +#include +#include + +#include "utility/types.h" + +class QtBookmarkCategory + : public QFrame +{ + Q_OBJECT + +public: + QtBookmarkCategory(); + ~QtBookmarkCategory(); + + void setName(const std::string& name); + std::string getName() const; + + void setId(const Id id); + Id getId() const; + + void setTreeWidgetItem(QTreeWidgetItem* treeItem); + + void updateArrow(); + +private slots: + void expandClicked(); + void deleteClicked(); + +private: + QHBoxLayout* m_layout; + QLabel* m_name; + + QPushButton* m_expandButton; + QPushButton* m_deleteButton; + + QTreeWidgetItem* m_treeItem; // store a pointer to the 'parent' tree item to enable the custom expand button + + Id m_id; +}; + +#endif // QT_BOOKMARK_CATEGORY_H \ No newline at end of file diff --git a/src/lib_gui/qt/element/QtStatusBar.cpp b/src/lib_gui/qt/element/QtStatusBar.cpp index 201360a9..2599dd69 100644 --- a/src/lib_gui/qt/element/QtStatusBar.cpp +++ b/src/lib_gui/qt/element/QtStatusBar.cpp @@ -9,6 +9,7 @@ QtStatusBar::QtStatusBar() : m_text(this) + , m_ideStatusText(this) { addWidget(new QWidget()); // add some space @@ -42,6 +43,9 @@ QtStatusBar::QtStatusBar() addPermanentWidget(&m_errorButton); connect(&m_errorButton, SIGNAL(clicked()), this, SLOT(showErrors())); + + m_ideStatusText.setText("No IDE connected"); + addWidget(&m_ideStatusText); } QtStatusBar::~QtStatusBar() @@ -86,6 +90,11 @@ void QtStatusBar::setErrorCount(ErrorCountInfo errorCount) } } +void QtStatusBar::setIdeStatus(const std::string& text) +{ + m_ideStatusText.setText(text.c_str()); +} + void QtStatusBar::showStatus() { MessageShowStatus().dispatch(); diff --git a/src/lib_gui/qt/element/QtStatusBar.h b/src/lib_gui/qt/element/QtStatusBar.h index f780f7b5..700b732e 100644 --- a/src/lib_gui/qt/element/QtStatusBar.h +++ b/src/lib_gui/qt/element/QtStatusBar.h @@ -21,6 +21,8 @@ public: void setText(const std::string& text, bool isError, bool showLoader); void setErrorCount(ErrorCountInfo errorCount); + void setIdeStatus(const std::string& text); + private slots: void showStatus(); void showErrors(); @@ -29,6 +31,8 @@ private: QPushButton m_text; QLabel m_loader; QPushButton m_errorButton; + + QLabel m_ideStatusText; }; #endif // QT_STATUS_BAR_H diff --git a/src/lib_gui/qt/network/QtIDECommunicationController.cpp b/src/lib_gui/qt/network/QtIDECommunicationController.cpp index b8a09905..12c9e894 100644 --- a/src/lib_gui/qt/network/QtIDECommunicationController.cpp +++ b/src/lib_gui/qt/network/QtIDECommunicationController.cpp @@ -23,6 +23,8 @@ void QtIDECommunicationController::startListening() m_tcpWrapper.startListening(); } ); + + sendInitialPing(); } void QtIDECommunicationController::stopListening() diff --git a/src/lib_gui/qt/utility/utilityQt.cpp b/src/lib_gui/qt/utility/utilityQt.cpp index 22f70464..37314dc0 100644 --- a/src/lib_gui/qt/utility/utilityQt.cpp +++ b/src/lib_gui/qt/utility/utilityQt.cpp @@ -86,21 +86,49 @@ namespace utility if (key == "setting") { - if (val == "font_size") + if (val.find("font_size") != std::string::npos) { - val = std::to_string(ApplicationSettings::getInstance()->getFontSize()); - } - else if (val == "font_size+2") - { - val = std::to_string(ApplicationSettings::getInstance()->getFontSize() + 2); - } - else if (val == "font_size+5") - { - val = std::to_string(ApplicationSettings::getInstance()->getFontSize() + 5); - } - else if (val == "font_size-2") - { - val = std::to_string(ApplicationSettings::getInstance()->getFontSize() - 2); + // check for modifier + if (val.find("+") != std::string::npos) + { + int pos = val.find("+"); + std::string sub = val.substr(pos + 1); + + int mod = std::stoi(sub); + + val = std::to_string(ApplicationSettings::getInstance()->getFontSize() + mod); + } + else if (val.find("-") != std::string::npos) + { + int pos = val.find("-"); + std::string sub = val.substr(pos + 1); + + int mod = std::stoi(sub); + + val = std::to_string(ApplicationSettings::getInstance()->getFontSize() - mod); + } + else if (val.find("*") != std::string::npos) + { + int pos = val.find("*"); + std::string sub = val.substr(pos + 1); + + int mod = std::stoi(sub); + + val = std::to_string(ApplicationSettings::getInstance()->getFontSize() * mod); + } + else if (val.find("/") != std::string::npos) + { + int pos = val.find("/"); + std::string sub = val.substr(pos + 1); + + int mod = std::stoi(sub); + + val = std::to_string(ApplicationSettings::getInstance()->getFontSize() / mod); + } + else + { + val = std::to_string(ApplicationSettings::getInstance()->getFontSize()); + } } else if (val == "font_name") { diff --git a/src/lib_gui/qt/view/QtBookmarkView.cpp b/src/lib_gui/qt/view/QtBookmarkView.cpp new file mode 100644 index 00000000..b798b67f --- /dev/null +++ b/src/lib_gui/qt/view/QtBookmarkView.cpp @@ -0,0 +1,80 @@ +#include "qt/view/QtBookmarkView.h" + +#include "qt/window/QtBookmarkBrowser.h" +#include "qt/utility/utilityQt.h" + +#include "utility/ResourcePaths.h" + +#include "component/controller/RefreshController.h" +#include "qt/view/QtViewWidgetWrapper.h" + +#include "settings/ColorScheme.h" + +QtBookmarkView::QtBookmarkView(ViewLayout* viewLayout) + : BookmarkView(viewLayout) + , m_refreshViewFunctor(std::bind(&QtBookmarkView::doRefreshView, this)) +{ + m_widget = new QtBookmarkBar(); + setStyleSheet(); +} + +QtBookmarkView::~QtBookmarkView() +{ + +} + +void QtBookmarkView::createWidgetWrapper() +{ + setWidgetWrapper(std::make_shared(m_widget)); +} + +void QtBookmarkView::initView() +{ + +} + +void QtBookmarkView::refreshView() +{ + m_refreshViewFunctor(); +} + +void QtBookmarkView::setCreateButtonState(const CreateButtonState& state) +{ + m_widget->setCreateButtonState(state); +} + +void QtBookmarkView::enableDisplayBookmarks(bool enable) +{ + m_widget->enableDisplayButton(enable); +} + +bool QtBookmarkView::bookmarkBrowserIsVisible() const +{ + return m_widget->bookmarkBrowserIsVisible(); +} + +void QtBookmarkView::doRefreshView() +{ + setStyleSheet(); + m_widget->refreshStyle(); +} + +void QtBookmarkView::setStyleSheet() +{ + m_widget->setStyleSheet(utility::getStyleSheet(ResourcePaths::getGuiPath() + "bookmark_view/bookmark_view.css").c_str()); +} + +void QtBookmarkView::displayBookmarks(const std::vector>& bookmarks) +{ + m_widget->displayBookmarks(bookmarks); +} + +void QtBookmarkView::displayBookmarkCreator(const std::vector& names, const std::vector& categories) +{ + m_widget->displayBookmarkCreator(names, categories); +} + +void QtBookmarkView::displayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories) +{ + m_widget->displayBookmarkEditor(bookmark, categories); +} \ No newline at end of file diff --git a/src/lib_gui/qt/view/QtBookmarkView.h b/src/lib_gui/qt/view/QtBookmarkView.h new file mode 100644 index 00000000..e31926b9 --- /dev/null +++ b/src/lib_gui/qt/view/QtBookmarkView.h @@ -0,0 +1,40 @@ +#ifndef QT_BOOKMARK_VIEW_H +#define QT_BOOKMARK_VIEW_H + +#include "component/view/BookmarkView.h" + +#include "qt/element/QtBookmarkBar.h" +#include "qt/utility/QtThreadedFunctor.h" + +class QtBookmarkView + : public BookmarkView +{ +public: + QtBookmarkView(ViewLayout* viewLayout); + virtual ~QtBookmarkView(); + + // View implementation + virtual void createWidgetWrapper(); + virtual void initView(); + virtual void refreshView(); + + virtual void setCreateButtonState(const CreateButtonState& state); + virtual void enableDisplayBookmarks(bool enable); + + virtual bool bookmarkBrowserIsVisible() const; + +private: + void doRefreshView(); + + void setStyleSheet(); + + virtual void displayBookmarks(const std::vector>& bookmarks); + virtual void displayBookmarkCreator(const std::vector& names, const std::vector& categories); + virtual void displayBookmarkEditor(std::shared_ptr bookmark, const std::vector& categories); + + QtThreadedFunctor<> m_refreshViewFunctor; + + QtBookmarkBar* m_widget; +}; + +#endif // QT_BOOKMARK_VIEW_H \ No newline at end of file diff --git a/src/lib_gui/qt/view/QtStatusBarView.cpp b/src/lib_gui/qt/view/QtStatusBarView.cpp index 44b3bcbd..fb7d21f0 100644 --- a/src/lib_gui/qt/view/QtStatusBarView.cpp +++ b/src/lib_gui/qt/view/QtStatusBarView.cpp @@ -45,6 +45,11 @@ void QtStatusBarView::setErrorCount(ErrorCountInfo errorCount) m_setErrorCountFunctor(errorCount); } +void QtStatusBarView::showIdeStatus(const std::string& message) +{ + m_widget->setIdeStatus(message); +} + void QtStatusBarView::doShowMessage(const std::string& message, bool isError, bool showLoader) { m_widget->setText(message, isError, showLoader); diff --git a/src/lib_gui/qt/view/QtStatusBarView.h b/src/lib_gui/qt/view/QtStatusBarView.h index 8fa5ab9d..3a99b592 100644 --- a/src/lib_gui/qt/view/QtStatusBarView.h +++ b/src/lib_gui/qt/view/QtStatusBarView.h @@ -25,6 +25,8 @@ public: virtual void showMessage(const std::string& message, bool isError, bool showLoader); virtual void setErrorCount(ErrorCountInfo errorCount); + virtual void showIdeStatus(const std::string& message); + private: void doShowMessage(const std::string& message, bool isError, bool showLoader); void doSetErrorCount(ErrorCountInfo errorCount); diff --git a/src/lib_gui/qt/view/QtViewFactory.cpp b/src/lib_gui/qt/view/QtViewFactory.cpp index 542ce1eb..cb84a37e 100644 --- a/src/lib_gui/qt/view/QtViewFactory.cpp +++ b/src/lib_gui/qt/view/QtViewFactory.cpp @@ -1,6 +1,7 @@ #include "qt/view/QtViewFactory.h" #include "component/view/GraphViewStyle.h" +#include "qt/view/QtBookmarkView.h" #include "qt/view/QtCodeView.h" #include "qt/view/QtCompositeView.h" #include "qt/view/QtDialogView.h" @@ -46,6 +47,11 @@ std::shared_ptr QtViewFactory::createTabbedView(ViewLayout* viewLayo return ptr; } +std::shared_ptr QtViewFactory::createBookmarkView(ViewLayout* viewLayout) const +{ + return View::createInitAndAddToLayout(viewLayout); +} + std::shared_ptr QtViewFactory::createCodeView(ViewLayout* viewLayout) const { return View::createInitAndAddToLayout(viewLayout); diff --git a/src/lib_gui/qt/view/QtViewFactory.h b/src/lib_gui/qt/view/QtViewFactory.h index 8f074c0d..343d35c1 100644 --- a/src/lib_gui/qt/view/QtViewFactory.h +++ b/src/lib_gui/qt/view/QtViewFactory.h @@ -14,6 +14,7 @@ public: ViewLayout* viewLayout, CompositeView::CompositeDirection direction, const std::string& name) const; virtual std::shared_ptr createTabbedView(ViewLayout* viewLayout, const std::string& name) const; + virtual std::shared_ptr createBookmarkView(ViewLayout* viewLayout) const; virtual std::shared_ptr createCodeView(ViewLayout* viewLayout) const; virtual std::shared_ptr createErrorView(ViewLayout* viewLayout) const; virtual std::shared_ptr createGraphView(ViewLayout* viewLayout) const; diff --git a/src/lib_gui/qt/window/QtBookmarkBrowser.cpp b/src/lib_gui/qt/window/QtBookmarkBrowser.cpp new file mode 100644 index 00000000..1a3d9b62 --- /dev/null +++ b/src/lib_gui/qt/window/QtBookmarkBrowser.cpp @@ -0,0 +1,283 @@ +#include "QtBookmarkBrowser.h" + +#include "qt/element/QtBookmark.h" +#include "qt/element/QtBookmarkCategory.h" +#include + +#include "data/bookmark/Bookmark.h" + +#include "qt/utility/utilityQt.h" +#include "utility/ResourcePaths.h" + +QtBookmarkBrowser::QtBookmarkBrowser(QWidget* parent) + : QtWindow(parent) + , m_headerBackground(NULL) +{ +} + +QtBookmarkBrowser::~QtBookmarkBrowser() +{ +} + +void QtBookmarkBrowser::setupBookmarkBrowser() +{ + m_layout = new QHBoxLayout(); + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setAlignment(Qt::AlignTop); + setLayout(m_layout); + + m_headerBackground = new QWidget(m_window); + m_headerBackground->setObjectName("header_background"); + m_headerBackground->setGeometry(0, 0, 0, 0); + m_headerBackground->show(); + m_headerBackground->lower(); + + m_headerLayout = new QVBoxLayout(this); + m_headerLayout->setObjectName("header"); + m_headerLayout->setSpacing(0); + m_headerLayout->setContentsMargins(0, 0, 0, 0); + m_headerLayout->setAlignment(Qt::AlignTop); + m_layout->addLayout(m_headerLayout); + + m_bodyLayout = new QVBoxLayout(this); + m_bodyLayout->setObjectName("body"); + m_bodyLayout->setSpacing(0); + m_bodyLayout->setContentsMargins(0, 0, 0, 0); + m_bodyLayout->setAlignment(Qt::AlignLeft); + m_layout->addLayout(m_bodyLayout); + + m_title = new QLabel(this); + m_title->setObjectName("title"); + m_title->setText("Bookmarks"); + m_headerLayout->addWidget(m_title); + + m_filterLabel = new QLabel(this); + m_filterLabel->setObjectName("filter_label"); + m_filterLabel->setText("Show:"); + m_headerLayout->addWidget(m_filterLabel); + + m_filterComboBox = new QComboBox(this); + m_filterComboBox->addItem("All"); + m_filterComboBox->addItem("Nodes"); + m_filterComboBox->addItem("Edges"); + m_filterComboBox->setObjectName("filter_box"); + m_headerLayout->addWidget(m_filterComboBox); + + connect(m_filterComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(filterBoxChanged(const QString&))); + + m_orderLabel = new QLabel(this); + m_orderLabel->setObjectName("order_label"); + m_orderLabel->setText("Sort by:"); + m_headerLayout->addWidget(m_orderLabel); + + m_orderNames.push_back("Date des."); + m_orderNames.push_back("Date asc."); + m_orderNames.push_back("Name des."); + m_orderNames.push_back("Name asc."); + m_currentOrderIndex = 0; + + m_orderComboBox = new QComboBox(this); + // m_orderComboBox->setToolTip("Select Bookmark Order"); + m_orderComboBox->addItem(m_orderNames[0].c_str()); + m_orderComboBox->addItem(m_orderNames[1].c_str()); + m_orderComboBox->addItem(m_orderNames[2].c_str()); + m_orderComboBox->addItem(m_orderNames[3].c_str()); + m_orderComboBox->setObjectName("order_box"); + m_headerLayout->addWidget(m_orderComboBox); + + connect(m_orderComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(orderBoxChanged(const QString&))); + + + m_headerLayout->addWidget(m_orderComboBox); + + m_bookmarkTree = new QTreeWidget(); + m_bookmarkTree->setObjectName("bookmark_tree"); + m_bookmarkTree->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection); + m_bookmarkTree->header()->close(); + m_bookmarkTree->setAlternatingRowColors(true); + m_bookmarkTree->setIndentation(0); + m_bookmarkTree->setHeaderLabel("Bookmarks"); + + connect(m_bookmarkTree, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(itemExpanded(QTreeWidgetItem*))); + connect(m_bookmarkTree, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(itemCollapsed(QTreeWidgetItem*))); + + // m_bookmarkTree->icon + + m_bodyLayout->addWidget(m_bookmarkTree); + + m_closeButton = new QPushButton(this); + m_closeButton->setObjectName("close_button"); + m_closeButton->setToolTip("Close Window"); + m_closeButton->setText("Close"); + m_closeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + m_bodyLayout->addWidget(m_closeButton); + m_bodyLayout->setAlignment(m_closeButton, Qt::AlignRight); + + connect(m_closeButton, SIGNAL(clicked()), this, SLOT(closeButtonClicked())); + + setFixedSize(QSize(790, 600)); + setStyleSheet(utility::getStyleSheet(ResourcePaths::getGuiPath() + "bookmark_view/bookmark_view.css").c_str()); + + m_headerBackground->setGeometry(0, 0, 247, size().height()-20); +} + +void QtBookmarkBrowser::setBookmarks(const std::vector>& bookmarks) +{ + m_bookmarkTree->clear(); + // m_bookmarkTree->adjustSize(); + + for (unsigned int i = 0; i < bookmarks.size(); i++) + { + QtBookmark* bookmark = new QtBookmark(); + bookmark->setName(bookmarks[i]->getDisplayName()); + bookmark->setBookmark(bookmarks[i]); + + QTreeWidgetItem* top = findOrCreateTreeCategory(bookmarks[i]->getCategory().getName(), bookmarks[i]->getCategory().getId()); + QTreeWidgetItem* treeWidgetItem = new QTreeWidgetItem(top); + // treeWidgetItem->setText(0, bookmarks[i]->getDisplayName().c_str()); + treeWidgetItem->setSizeHint(0, bookmark->minimumSizeHint()); + m_bookmarkTree->setItemWidget(treeWidgetItem, 0, bookmark); + top->addChild(treeWidgetItem); + + bookmark->setTreeWidgetItem(top); + + top->setExpanded(true); + } +} + +void QtBookmarkBrowser::closeButtonClicked() +{ + try + { + close(); + } + catch (std::exception& e) + { + std::string message = e.what(); + + LOG_ERROR(message); + } +} + +void QtBookmarkBrowser::filterBoxChanged(const QString& text) +{ + MessageDisplayBookmarks(getSelectedFilter(), getSelectedOrder()).dispatch(); +} + +void QtBookmarkBrowser::orderBoxChanged(const QString& text) +{ + MessageDisplayBookmarks(getSelectedFilter(), getSelectedOrder()).dispatch(); +} + +void QtBookmarkBrowser::itemExpanded(QTreeWidgetItem* item) +{ + QWidget* widget = m_bookmarkTree->itemWidget(item, 0); + + QtBookmarkCategory* category = dynamic_cast(widget); + + if (category != NULL) + { + category->updateArrow(); + } +} + +void QtBookmarkBrowser::itemCollapsed(QTreeWidgetItem* item) +{ + QWidget* widget = m_bookmarkTree->itemWidget(item, 0); + + QtBookmarkCategory* category = dynamic_cast(widget); + + if (category != NULL) + { + category->updateArrow(); + } +} + +void QtBookmarkBrowser::handleMessage(MessageDeleteBookmark* message) +{ + MessageDisplayBookmarks(getSelectedFilter(), getSelectedOrder()).dispatch(); +} + +void QtBookmarkBrowser::handleMessage(MessageEditBookmark* message) +{ + MessageDisplayBookmarks(getSelectedFilter(), getSelectedOrder()).dispatch(); +} + +MessageDisplayBookmarks::BookmarkFilter QtBookmarkBrowser::getSelectedFilter() +{ + std::string text = m_filterComboBox->currentText().toStdString(); + + if (text == "Nodes") + { + return MessageDisplayBookmarks::BookmarkFilter::NODES; + } + else if (text == "Edges") + { + return MessageDisplayBookmarks::BookmarkFilter::EDGES; + } + + return MessageDisplayBookmarks::BookmarkFilter::ALL; +} + +MessageDisplayBookmarks::BookmarkOrder QtBookmarkBrowser::getSelectedOrder() +{ + std::string orderString = m_orderComboBox->currentText().toStdString(); // m_orderButton->text().toStdString(); + + if (orderString == m_orderNames[0]) + { + return MessageDisplayBookmarks::BookmarkOrder::DATE_DESCENDING; + } + else if (orderString == m_orderNames[1]) + { + return MessageDisplayBookmarks::BookmarkOrder::DATE_ASCENDING; + } + else if (orderString == m_orderNames[2]) + { + return MessageDisplayBookmarks::BookmarkOrder::NAME_DESCENDING; + } + else if (orderString == m_orderNames[3]) + { + return MessageDisplayBookmarks::BookmarkOrder::NAME_ASCENDING; + } + else + { + return MessageDisplayBookmarks::BookmarkOrder::NONE; + } +} + +QTreeWidgetItem* QtBookmarkBrowser::findOrCreateTreeCategory(const std::string& name, const Id id) +{ + for (int i = 0; i < m_bookmarkTree->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = m_bookmarkTree->topLevelItem(i); + + if (item->whatsThis(0).toStdString() == name) + { + return item; + } + } + + QtBookmarkCategory* category = new QtBookmarkCategory(); + if (name.length() > 0) + { + category->setName(name); + } + else + { + category->setName("No Category"); + } + category->setId(id); + + QTreeWidgetItem* newItem = new QTreeWidgetItem(m_bookmarkTree); + newItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); + newItem->setSizeHint(0, category->minimumSizeHint()); + newItem->setWhatsThis(0, name.c_str()); + category->setTreeWidgetItem(newItem); + + m_bookmarkTree->setItemWidget(newItem, 0, category); + + m_bookmarkTree->addTopLevelItem(newItem); + + return newItem; +} diff --git a/src/lib_gui/qt/window/QtBookmarkBrowser.h b/src/lib_gui/qt/window/QtBookmarkBrowser.h new file mode 100644 index 00000000..c89dccc4 --- /dev/null +++ b/src/lib_gui/qt/window/QtBookmarkBrowser.h @@ -0,0 +1,74 @@ +#ifndef QT_BOOKMARK_BROWSER_H +#define QT_BOOKMARK_BROWSER_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "qt/window/QtWindow.h" + +#include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/MessageDeleteBookmark.h" +#include "utility/messaging/type/MessageDisplayBookmarks.h" +#include "utility/messaging/type/MessageEditBookmark.h" + +class Bookmark; +class QtBookmark; + +class QtBookmarkBrowser + : public QtWindow + , public MessageListener + , public MessageListener +{ + Q_OBJECT + +public: + QtBookmarkBrowser(QWidget* parent = nullptr); + ~QtBookmarkBrowser(); + + void setupBookmarkBrowser(); + void setBookmarks(const std::vector>& bookmarks); + +private slots: + void closeButtonClicked(); + void filterBoxChanged(const QString& text); + void orderBoxChanged(const QString& text); + void itemExpanded(QTreeWidgetItem* item); + void itemCollapsed(QTreeWidgetItem* item); + +private: + virtual void handleMessage(MessageDeleteBookmark* message); + virtual void handleMessage(MessageEditBookmark* message); + + MessageDisplayBookmarks::BookmarkFilter getSelectedFilter(); + MessageDisplayBookmarks::BookmarkOrder getSelectedOrder(); + + QTreeWidgetItem* findOrCreateTreeCategory(const std::string& name, const Id id); + + QHBoxLayout* m_layout; + QVBoxLayout* m_headerLayout; + QVBoxLayout* m_bodyLayout; + + QTreeWidget* m_bookmarkTree; + QPushButton* m_closeButton; + + QLabel* m_title; + QLabel* m_filterLabel; + QLabel* m_orderLabel; + QComboBox* m_filterComboBox; + QComboBox* m_orderComboBox; + std::vector m_orderNames; + int m_currentOrderIndex; + + QWidget* m_headerBackground; +}; + +#endif // QT_BOOKMARK_BROWSER_H diff --git a/src/lib_gui/qt/window/QtBookmarkCreator.cpp b/src/lib_gui/qt/window/QtBookmarkCreator.cpp new file mode 100644 index 00000000..8ed4b1f4 --- /dev/null +++ b/src/lib_gui/qt/window/QtBookmarkCreator.cpp @@ -0,0 +1,233 @@ +#include "QtBookmarkCreator.h" + +#include + +#include "data/bookmark/BookmarkCategory.h" + +#include "utility/messaging/type/MessageCreateBookmark.h" +#include "utility/messaging/type/MessageCreateBookmarkCategory.h" +#include "utility/messaging/type/MessageEditBookmark.h" +#include "utility/messaging/type/MessageStatus.h" +#include "utility/ResourcePaths.h" + +#include "qt/utility/utilityQt.h" +#include "settings/ApplicationSettings.h" +#include "settings/ColorScheme.h" + +QString QtBookmarkCreator::m_namePlaceholder = "Name"; +QString QtBookmarkCreator::m_commentPlaceholder = "Comment"; +QString QtBookmarkCreator::m_categoryPlaceholder = "Category"; + +QtBookmarkCreator::QtBookmarkCreator(QWidget* parent, bool edit, Id id) + : QtWindow(parent) + , m_edit(edit) + , m_bookmarkId(id) + , m_categoryCount(0) +{ +} + +QtBookmarkCreator::~QtBookmarkCreator() +{ +} + +void QtBookmarkCreator::setupBookmarkCreator() +{ + m_displayName = new QLineEdit(this); + m_displayName->setObjectName("display_name_edit"); + m_commentBox = new QTextEdit(this); + m_commentBox->setObjectName("comment_box"); + m_categoryBox = new QComboBox(this); + m_categoryBox->setObjectName("category_box"); + + m_title = new QLabel(); + if (m_edit == true) + { + m_title->setText("Edit Bookmark"); + } + else + { + m_title->setText("Create Bookmark"); + } + m_title->setObjectName("creator_title_label"); + m_nameLabel = new QLabel(); + m_nameLabel->setText("Bookmark:"); + m_nameLabel->setObjectName("creator_name_label"); + m_commentLabel = new QLabel(); + m_commentLabel->setText("Comment:"); + m_commentLabel->setObjectName("creator_comment_label"); + m_categoryLabel = new QLabel(); + m_categoryLabel->setText("Choose or Create Bookmark:"); + m_categoryLabel->setObjectName("category_label"); + + m_categoryBox->addItem(""); + m_categoryBox->setEditable(true); + m_categoryBox->setInsertPolicy(QComboBox::InsertPolicy::InsertAtTop); + + m_categoryCount = m_categoryBox->count(); + + m_cancelButton = new QPushButton(this); + m_cancelButton->setObjectName("creator_cancel_button"); + m_cancelButton->setText("Cancel"); + m_createButton = new QPushButton(this); + m_createButton->setObjectName("creator_create_button"); + if (m_edit) + { + m_createButton->setText("Save"); + } + else + { + m_createButton->setText("Create"); + } + + m_commentBox->setPlaceholderText(m_commentPlaceholder); + m_displayName->setPlaceholderText(m_namePlaceholder); + m_categoryBox->lineEdit()->setPlaceholderText(m_categoryPlaceholder); + + m_createButton->setEnabled(false); + + connect(m_displayName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); + connect(m_commentBox, SIGNAL(textChanged()), this, SLOT(onCommentChanged())); + connect(m_categoryBox, SIGNAL(currentTextChanged(const QString&)), this, SLOT(onCategoryChanged(const QString&))); + connect(m_categoryBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxIndexChanged(int))); + connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); + connect(m_createButton, SIGNAL(clicked()), this, SLOT(create())); + + m_layout = new QVBoxLayout(this); + m_layout->addWidget(m_title); + m_layout->addWidget(m_nameLabel); + m_layout->addWidget(m_displayName); + m_layout->addWidget(m_commentLabel); + m_layout->addWidget(m_commentBox); + m_layout->addWidget(m_categoryLabel); + m_layout->addWidget(m_categoryBox); + + QHBoxLayout* buttonLayout = new QHBoxLayout(this); + + buttonLayout->addWidget(m_cancelButton); + buttonLayout->setAlignment(m_cancelButton, Qt::AlignLeft); + buttonLayout->addWidget(m_createButton); + buttonLayout->setAlignment(m_createButton, Qt::AlignRight); + + m_layout->addLayout(buttonLayout); + + m_headerBackground = new QWidget(m_window); + m_headerBackground->setObjectName("creator_header_background"); + m_headerBackground->setGeometry(0, 0, 0, 0); + m_headerBackground->show(); + m_headerBackground->lower(); + + setFixedSize(QSize(500, 580)); + refreshStyle(); + + m_headerBackground->setGeometry(0, 0, size().width() - 10, 70); +} + +void QtBookmarkCreator::refreshStyle() +{ + setStyleSheet(utility::getStyleSheet(ResourcePaths::getGuiPath() + "bookmark_view/bookmark_view.css").c_str()); +} + +void QtBookmarkCreator::setDisplayName(const std::string& name) +{ + m_displayName->setText(name.c_str()); +} + +void QtBookmarkCreator::setComment(const std::string& comment) +{ + m_commentBox->setText(comment.c_str()); +} + +void QtBookmarkCreator::setBookmarkCategories(const std::vector& categories) +{ + for (unsigned int i = 0; i < categories.size(); i++) + { + m_categoryBox->addItem(categories[i].getName().c_str()); + } +} + +void QtBookmarkCreator::setCurrentBookmarkCategory(const BookmarkCategory& category) +{ + int index = m_categoryBox->findText(category.getName().c_str()); + + if (index > -1) + { + m_categoryBox->setCurrentIndex(index); + } + else + { + m_categoryBox->addItem(category.getName().c_str()); + m_categoryBox->setCurrentIndex(1); + } +} + +bool QtBookmarkCreator::getIsEdge() const +{ + return m_isEdge; +} + +void QtBookmarkCreator::setIsEdge(const bool isEdge) +{ + m_isEdge = isEdge; +} + +void QtBookmarkCreator::onNameChanged(const QString& text) +{ + if (text.length() > 0) + { + m_createButton->setEnabled(true); + } + else + { + m_createButton->setEnabled(false); + } +} + +void QtBookmarkCreator::onCommentChanged() +{ + /*if (m_commentBox->toPlainText().size() <= 0) + { + m_commentBox-> + }*/ +} + +void QtBookmarkCreator::onCategoryChanged(const QString& text) +{ + +} + +void QtBookmarkCreator::onComboBoxIndexChanged(int index) +{ + if (m_categoryBox->count() > m_categoryCount) + { + std::string categoryName = m_categoryBox->currentText().toStdString(); + + MessageCreateBookmarkCategory(categoryName).dispatch(); + + m_categoryCount = m_categoryBox->count(); + } +} + +void QtBookmarkCreator::cancel() +{ + close(); +} + +void QtBookmarkCreator::create() +{ + QString qComment = m_commentBox->toPlainText(); + QString qDisplayName = m_displayName->text(); + QString qCategory = m_categoryBox->currentText(); + + if (m_edit) + { + MessageEditBookmark(m_bookmarkId, qComment.toStdString(), qDisplayName.toStdString(), qCategory.toStdString(), m_isEdge).dispatch(); + } + else + { + MessageCreateBookmark(qComment.toStdString(), qDisplayName.toStdString(), qCategory.toStdString()).dispatch(); + } + + MessageStatus("Creating Bookmark for active Token").dispatch(); + + close(); +} diff --git a/src/lib_gui/qt/window/QtBookmarkCreator.h b/src/lib_gui/qt/window/QtBookmarkCreator.h new file mode 100644 index 00000000..d4bbdde5 --- /dev/null +++ b/src/lib_gui/qt/window/QtBookmarkCreator.h @@ -0,0 +1,79 @@ +#ifndef QT_BOOKMARK_CREATOR_H +#define QT_BOOKMARK_CREATOR_H + +#include +#include +#include +#include +#include +#include + +#include + +#include "qt/window/QtWindow.h" + +#include "utility/types.h" + +class BookmarkCategory; + +class QtBookmarkCreator + : public QtWindow +{ + Q_OBJECT + +public: + QtBookmarkCreator(QWidget* parent = nullptr, bool edit = false, Id id = -1); + ~QtBookmarkCreator(); + + void setupBookmarkCreator(); + + void refreshStyle(); + + void setDisplayName(const std::string& name); + void setComment(const std::string& comment); + + void setBookmarkCategories(const std::vector& categories); + void setCurrentBookmarkCategory(const BookmarkCategory& category); + + bool getIsEdge() const; + void setIsEdge(const bool isEdge); + +private slots: + void onNameChanged(const QString& text); + void onCommentChanged(); + void onCategoryChanged(const QString& text); + void onComboBoxIndexChanged(int index); + + void cancel(); + void create(); + +private: + bool m_edit; + Id m_bookmarkId; // important for editing + + QLabel* m_title; + QLabel* m_nameLabel; + QLabel* m_commentLabel; + QLabel* m_categoryLabel; + + QLineEdit* m_displayName; + QTextEdit* m_commentBox; + QComboBox* m_categoryBox; + + QPushButton* m_cancelButton; + QPushButton* m_createButton; + + QVBoxLayout* m_layout; + + int m_categoryCount; + + static QString m_namePlaceholder; + static QString m_commentPlaceholder; + static QString m_categoryPlaceholder; + + bool m_isEdge; + + QWidget* m_headerBackground; +}; + +#endif // QT_BOOKMARK_CREATOR_H \ No newline at end of file diff --git a/src/lib_gui/qt/window/QtStartScreen.cpp b/src/lib_gui/qt/window/QtStartScreen.cpp index e8a6f1bf..d5c04a39 100644 --- a/src/lib_gui/qt/window/QtStartScreen.cpp +++ b/src/lib_gui/qt/window/QtStartScreen.cpp @@ -53,9 +53,18 @@ void QtRecentProjectButton::handleButtonClick() { std::string text = "Couldn't find " + m_projectFilePath.str() + " in your filesystem. Delete it from this recent Proejct list?"; - int ret = QMessageBox::question(this, "Missing Project File", text.c_str(), QMessageBox::Yes | QMessageBox::No); + // int ret = QMessageBox::question(this, "Missing Project File", text.c_str(), QMessageBox::Yes | QMessageBox::No); - if (ret == QMessageBox::Yes) + + QMessageBox msgBox; + msgBox.setText("Missing Project File"); + msgBox.setInformativeText(text.c_str()); + QAbstractButton* yesButton = msgBox.addButton("Delete", QMessageBox::ButtonRole::YesRole); + QAbstractButton* noButton = msgBox.addButton("Keep", QMessageBox::ButtonRole::NoRole); + msgBox.setIcon(QMessageBox::Icon::Question); + int ret = msgBox.exec(); + + if (ret == 0) // QMessageBox::Yes) { std::vector recentProjects = ApplicationSettings::getInstance()->getRecentProjects(); const int maxRecentProjectsCount = ApplicationSettings::getInstance()->getMaxRecentProjectsCount();