From ed00feb8fae729387cc62476658d8467765f952d Mon Sep 17 00:00:00 2001 From: altffour <56314286+realaltffour@users.noreply.github.com> Date: Fri, 20 Dec 2019 13:30:36 +0300 Subject: [PATCH] Add search functionality --- .vscode/launch.json | 28 ++++++++++++++++++++++++++ .vscode/tasks.json | 13 ++++++++++++ src/addCategoryWin.cpp | 1 + src/addContractWin.cpp | 1 + src/lib/db.h | 45 +++++++++++++++++++++++++++++++++++++++++- src/lib/notify.h | 7 +++++++ src/mainwindow.cpp | 25 ++++++++++++++++++++++- src/mainwindow.h | 1 + 8 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8bf2427 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/bin/contractNotifier", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/bin/", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "Build Debug" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..c28ed52 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,13 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Debug", + "type": "shell", + "command": "./build.sh", + "group": "build", + } + ] +} \ No newline at end of file diff --git a/src/addCategoryWin.cpp b/src/addCategoryWin.cpp index 647bbef..e267908 100644 --- a/src/addCategoryWin.cpp +++ b/src/addCategoryWin.cpp @@ -20,5 +20,6 @@ auto addCategoryWindow::on_addBtn_clicked() -> void { category._desc = this->descBox->text().toUtf8().constData(); _db->_categories.push_back(category); ((MainWindow*)(this->parent()))->updateDB(); + db_makeList(*(this->_db)); this->close(); } diff --git a/src/addContractWin.cpp b/src/addContractWin.cpp index 9083fea..d0d0868 100644 --- a/src/addContractWin.cpp +++ b/src/addContractWin.cpp @@ -35,5 +35,6 @@ auto addContractWindow::on_addBtn_clicked() -> void { } } ((MainWindow*)(this->parent()))->updateDB(); + db_makeList(*(this->_db)); this->close(); } diff --git a/src/lib/db.h b/src/lib/db.h index 163460f..c56494b 100644 --- a/src/lib/db.h +++ b/src/lib/db.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include "contract.h" #include "category.h" #include @@ -15,6 +17,7 @@ struct DB { std::string _notifier_email = ""; bool _notify_by_email = true; bool _notify_by_notify = true; + std::vector *_contractList = nullptr; template void serialize(Archive & ar, const unsigned int version) { @@ -26,7 +29,47 @@ struct DB { } }; -static auto db_addCategory(DB db, Category item) -> void { +static auto db_search_getCorrectness(const std::string &str, const Contract &contract) -> int { + int val = 0; + if (contract._name.size() < str.size()) + for (auto c : contract._name) + if (c == str[val]) val++; + else if (contract._name.size() > str.size()) + for (auto c : str) + if (c == contract._name[val++]) val++; + return val; +} + +static auto db_search_sort(DB &db, const std::string &str) -> void { + std::stable_sort(db._contractList->begin(), db._contractList->end(), [=](const Contract *l, const Contract *r) -> bool {return db_search_getCorrectness(str, *l)>db_search_getCorrectness(str, *r);}); +} + +static auto db_makeList(DB &db) -> void { + std::mutex mtx; + mtx.lock(); + // Make the list + if (!db._contractList) + db._contractList = new std::vector(); + db._contractList->clear(); + + // Iterate over deactivated category. + for (int i = 0; i < db._deactivatedCategory._contracts.size(); i++) + db._contractList->push_back(&db._deactivatedCategory._contracts[i]); + // Iterate over categories. + for (int i = 0; i < db._categories.size(); i++) + for (int j = 0; j < db._categories[i]._contracts.size(); j++) + db._contractList->push_back(&db._categories[i]._contracts[j]); + + // Sort the list. + std::stable_sort(db._contractList->begin(), db._contractList->end(), [=](const Contract *l, const Contract *r) -> bool {return l->_name[0]>r->_name[0];}); + mtx.unlock(); +} + +static auto db_cleanList(DB &db) -> void { + delete db._contractList; +} + +static auto db_addCategory(DB &db, Category &item) -> void { // Check if category is already present. for (auto i : db._categories) if (i == item) diff --git a/src/lib/notify.h b/src/lib/notify.h index 707eff4..0c25206 100644 --- a/src/lib/notify.h +++ b/src/lib/notify.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -73,14 +74,20 @@ static auto notify_check(DB &db, bool by_email = true, bool by_notification = tr } // change states/switches. + std::mutex mtx; + mtx.lock(); contract._did_notify = true; res = true; + mtx.unlock(); } } if (current_date > expiry_date) { // expire the contract. + std::mutex mtx; + mtx.lock(); contract._expired = true; category_moveContract(category, db._deactivatedCategory, contract); + mtx.unlock(); res = true; } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ea12413..e0d022d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -48,9 +48,12 @@ MainWindow::MainWindow(QWidget *parent) connect(this->_checker, SIGNAL(checkDBepoch()), this, SLOT(updateDB())); this->treeView->setSelectionMode(QAbstractItemView::SingleSelection); + + db_makeList(this->_db); } MainWindow::~MainWindow() { + db_cleanList(this->_db); this->_checker->setClosing(true); this->_checkingThread->join(); export_db_as_db(_db, "db.db"); @@ -75,6 +78,25 @@ auto MainWindow::listDB() -> void { this->treeView->expandItem(t); }; +auto MainWindow::on_searchBox_textChanged(const QString &text) -> void { + auto str = text.toStdString(); + if (str == "") { + this->listDB(); + } + else { + db_search_sort(this->_db, str); + // Print contract list to screen. + this->treeView->clear(); + auto t = new QTreeWidgetItem(QStringList() << "Search Results"); + for (auto contract : *(this->_db._contractList)) { + auto item = new QTreeWidgetItem(QStringList() << contract->_name.c_str()); + t->addChild(item); + } + this->treeView->addTopLevelItem(t); + this->treeView->expandItem(t); + } +} + auto MainWindow::closeEvent(QCloseEvent *event) -> void { if(closing) { event->accept(); @@ -108,7 +130,7 @@ auto MainWindow::on_infoBtn_clicked() -> void { auto MainWindow::on_deleteBtn_clicked() -> void { // Get item selected - auto item = this->treeView->currentItem()->text(0).toUtf8().constData(); + auto item = this->treeView->currentItem()->text(0).toStdString(); // Check if it is the expired category. if (item == "Expired") { @@ -138,6 +160,7 @@ auto MainWindow::on_deleteBtn_clicked() -> void { } this->updateDB(); + db_makeList(this->_db); } auto MainWindow::on_treeView_itemClicked(QTreeWidgetItem* _item, int col) -> void { diff --git a/src/mainwindow.h b/src/mainwindow.h index a6c14f2..2bb69fa 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -43,6 +43,7 @@ public slots: void on_deleteBtn_clicked(); void closeEvent(QCloseEvent *event) override; void on_treeView_itemClicked(QTreeWidgetItem* _item, int column); + void on_searchBox_textChanged(const QString &text); void on_actionExport_triggered(); void on_actionImport_triggered(); void on_actionAdd_Contract_triggered();