diff --git a/CMakeLists.txt b/CMakeLists.txt index f794912..7106285 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD 20) find_package(Qt6 6.6 REQUIRED COMPONENTS Quick) include_directories(src) +include_directories(libs) qt_standard_project_setup(REQUIRES 6.6) diff --git a/libs/cpp-utils/string.h b/libs/cpp-utils/string.h new file mode 100644 index 0000000..674efaa --- /dev/null +++ b/libs/cpp-utils/string.h @@ -0,0 +1,27 @@ +/* + * Mirai. Copyright (C) 2024 Vyn + * This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only) + * The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt + */ + +#ifndef CPP_UTILS_STRING_H +#define CPP_UTILS_STRING_H + +#include +#include + +namespace cpputils::string { + + inline std::string trim(std::string str) { + str.erase(str.begin(), std::ranges::find_if(str, [](unsigned char ch) { + return !std::isspace(ch); + })); + str.erase(std::ranges::find_if(str.rbegin(), str.rend(), [](unsigned char ch) { + return !std::isspace(ch); + }).base(), str.end()); + return str; + } + +} + +#endif diff --git a/libs/cpp-utils/vector.h b/libs/cpp-utils/vector.h new file mode 100644 index 0000000..a7b7c04 --- /dev/null +++ b/libs/cpp-utils/vector.h @@ -0,0 +1,44 @@ +/* + * Mirai. Copyright (C) 2024 Vyn + * This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only) + * The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt + */ + +#ifndef CPP_UTILS_VECTOR_H +#define CPP_UTILS_VECTOR_H + +#include +#include +#include +#include +#include + +namespace cpputils::vector { + + template + concept AnyIterable = + std::same_as && + requires (C c) { + { c.begin() } -> std::forward_iterator; + { c.end() } -> std::forward_iterator; + { const_cast(c).begin() } -> std::forward_iterator; + { const_cast(c).end() } -> std::forward_iterator; + }; + + template + bool contains(const std::vector& vec, const T& value) { + return std::ranges::find(vec, value) != vec.end(); + } + + template + bool containsAll(const std::vector& vec, const AnyIterable auto vec2) { + for (auto& elem : vec) { + if (!contains(vec2, elem)) { + return false; + } + } + return true; + } +} + +#endif diff --git a/src/core/Mirai.cpp b/src/core/Mirai.cpp index d9a90fc..bc2ab9a 100644 --- a/src/core/Mirai.cpp +++ b/src/core/Mirai.cpp @@ -6,7 +6,7 @@ #include "Mirai.h" #include "TaskItem.h" -#include +#include "cpp-utils/vector.h" namespace mirai { @@ -16,7 +16,7 @@ namespace mirai { tags.clear(); for (auto& task : (*files)[0].getTasks()) { for (auto& tag : task->getTags()) { - if (std::find(tags.begin(), tags.end(), tag) == tags.end()) { + if (vectorUtils::contains(tags, tag)) { tags.push_back(tag); } } diff --git a/src/core/TaskItem.cpp b/src/core/TaskItem.cpp index 7a1aad1..118daf3 100644 --- a/src/core/TaskItem.cpp +++ b/src/core/TaskItem.cpp @@ -6,7 +6,7 @@ #include "TaskItem.h" -#include +#include "cpp-utils/vector.h" namespace mirai { @@ -36,6 +36,6 @@ namespace mirai { bool TaskItem::hasTag(const std::string& tag) const { - return std::find(tags.begin(), tags.end(), tag) != tags.end(); + return vectorUtils::contains(tags, tag); } } diff --git a/src/core/TasksView.cpp b/src/core/TasksView.cpp index 980ce1e..092f248 100644 --- a/src/core/TasksView.cpp +++ b/src/core/TasksView.cpp @@ -5,6 +5,9 @@ */ #include "TasksView.h" +#include "cpp-utils/vector.h" +#include +#include namespace mirai { @@ -23,10 +26,10 @@ namespace mirai { tasksToShow.clear(); for (auto& file : *files) { for (auto& task : file.getTasks()) { - if (tagsFilter.size() != 0 - && std::find_if(tagsFilter.begin(), tagsFilter.end(), [&](const std::string& tag) { + std::function f = [&](const std::string& tag) { return task->hasTag(tag); - }) == tagsFilter.end()) + }; + if (tagsFilter.size() > 0 && !vectorUtils::containsAll(tagsFilter, task->getTags())) continue; tasksToShow.push_back(task.get()); } diff --git a/src/core/TodoMd.cpp b/src/core/TodoMd.cpp index bc777fd..78072d1 100644 --- a/src/core/TodoMd.cpp +++ b/src/core/TodoMd.cpp @@ -6,6 +6,7 @@ #include "TodoMd.h" #include "TaskItem.h" +#include "cpp-utils/vector.h" namespace mirai { @@ -50,7 +51,7 @@ namespace mirai { while (std::regex_search(metadata, matches, regex)) { - if (std::find(tags.begin(), tags.end(), matches[0]) == tags.end()) { + if (!vectorUtils::contains(tags, matches[0].str())) { tags.push_back(matches[0]); } metadata = matches.suffix(); @@ -97,8 +98,7 @@ namespace mirai { /*std::cout << "M 6 " << matches[6] << std::endl;*/ /*std::cout << "M 7 " << matches[7] << std::endl;*/ - std::string text = matches[5]; - trim(text); + std::string text = stringUtils::trim(matches[5]); TaskItem taskItem = { .text = text, diff --git a/src/core/TodoTxt.h b/src/core/TodoTxt.h index a05aff9..36d437b 100644 --- a/src/core/TodoTxt.h +++ b/src/core/TodoTxt.h @@ -7,89 +7,89 @@ #ifndef MIRAI_TODOTXT_H #define MIRAI_TODOTXT_H -#include "TaskItem.h" -#include "utils.h" -#include -#include -#include -#include -#include -#include -#include -#include +/*#include "TaskItem.h"*/ +/*#include "utils.h"*/ +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ -namespace mirai { +/*namespace mirai {*/ - class TodoTxtFormat { - public: + /*class TodoTxtFormat {*/ + /*public:*/ - static TaskList readFile() { - std::ifstream file("../newqml/todo.txt"); - if (!file.is_open()) { - throw std::runtime_error("todo.txt file not found"); - } - std::vector taskItems; - std::string line; - while (std::getline(file, line)) { - auto taskItem = parseLine(line); - taskItems.push_back(taskItem); - } - file.close(); - TaskList tasks({ - .tasks = taskItems - }); - return tasks; - } + /*static TaskList readFile() {*/ + /*std::ifstream file("../newqml/todo.txt");*/ + /*if (!file.is_open()) {*/ + /*throw std::runtime_error("todo.txt file not found");*/ + /*}*/ + /*std::vector taskItems;*/ + /*std::string line;*/ + /*while (std::getline(file, line)) {*/ + /*auto taskItem = parseLine(line);*/ + /*taskItems.push_back(taskItem);*/ + /*}*/ + /*file.close();*/ + /*TaskList tasks({*/ + /*.tasks = taskItems*/ + /*});*/ + /*return tasks;*/ + /*}*/ - static void writeFile(TaskList& tasks) { - std::ofstream file("../newqml/todo.txt"); - if (!file.is_open()) { - throw std::runtime_error("can't create todo.txt"); - } - for (const auto& task : tasks.getTasks()) { - file << fieldWithSpace(task->state == DONE ? "x" : task->priority); - file << fieldWithSpace(task->state == DONE ? task->getDate() : ""); - file << fieldWithSpace(task->getCreationDate()); - file << task->getText() << '\n'; - } - file.close(); - } + /*static void writeFile(TaskList& tasks) {*/ + /*std::ofstream file("../newqml/todo.txt");*/ + /*if (!file.is_open()) {*/ + /*throw std::runtime_error("can't create todo.txt");*/ + /*}*/ + /*for (const auto& task : tasks.getTasks()) {*/ + /*file << fieldWithSpace(task->state == DONE ? "x" : task->priority);*/ + /*file << fieldWithSpace(task->state == DONE ? task->getDate() : "");*/ + /*file << fieldWithSpace(task->getCreationDate());*/ + /*file << task->getText() << '\n';*/ + /*}*/ + /*file.close();*/ + /*}*/ - private: + /*private:*/ - static std::string fieldWithSpace(const std::string& field) { - if (field.length() == 0) - return ""; - return (field + " "); - } + /*static std::string fieldWithSpace(const std::string& field) {*/ + /*if (field.length() == 0)*/ + /*return "";*/ + /*return (field + " ");*/ + /*}*/ - static TaskItem parseLine(const std::string& line) { - std::smatch matches; - std::regex regex("(^x )?(\\([A-Z]\\) )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?(.*)"); - std::regex_match(line, matches, regex); + /*static TaskItem parseLine(const std::string& line) {*/ + /*std::smatch matches;*/ + /*std::regex regex("(^x )?(\\([A-Z]\\) )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?(.*)");*/ + /*std::regex_match(line, matches, regex);*/ - for (size_t i = 0; i < matches.size(); ++i) { - std::ssub_match sub_match = matches[i]; - std::string piece = sub_match.str(); - } + /*for (size_t i = 0; i < matches.size(); ++i) {*/ + /*std::ssub_match sub_match = matches[i];*/ + /*std::string piece = sub_match.str();*/ + /*}*/ - const TaskItemState taskState = trim_copy(matches[1].str()) == "x" ? DONE : TODO; - const std::string priority = trim_copy(matches[2].str()); - const std::string firstDate = trim_copy(matches[3].str()); - const std::string secondDate = trim_copy(matches[4].str()); - const std::string text = trim_copy(matches[5].str()); + /*const TaskItemState taskState = trim_copy(matches[1].str()) == "x" ? DONE : TODO;*/ + /*const std::string priority = trim_copy(matches[2].str());*/ + /*const std::string firstDate = trim_copy(matches[3].str());*/ + /*const std::string secondDate = trim_copy(matches[4].str());*/ + /*const std::string text = trim_copy(matches[5].str());*/ - const std::string date = taskState == DONE ? firstDate : ""; + /*const std::string date = taskState == DONE ? firstDate : "";*/ - return { - .text = text, - .state = taskState, - .date = date, - }; - } - }; -} + /*return {*/ + /*.text = text,*/ + /*.state = taskState,*/ + /*.date = date,*/ + /*};*/ + /*}*/ + /*};*/ +/*}*/ #endif diff --git a/src/core/utils.cpp b/src/core/utils.cpp index e075ac4..56614bd 100644 --- a/src/core/utils.cpp +++ b/src/core/utils.cpp @@ -6,39 +6,9 @@ #include "utils.h" -void ltrim(std::string& s) { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { - return !std::isspace(ch); - })); -} - -void rtrim(std::string& s) { - s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { - return !std::isspace(ch); - }).base(), s.end()); -} - -void trim(std::string& s) { - rtrim(s); - ltrim(s); -} - -std::string ltrim_copy(std::string s) { - ltrim(s); - return s; -} - -std::string rtrim_copy(std::string s) { - rtrim(s); - return s; -} - -std::string trim_copy(std::string s) { - trim(s); - return s; -} - -bool isDate(const std::string& dateStr) { - std::regex regex("[0-9]{4}-[0-9]{2}-[0-9]{2}"); - return std::regex_match(dateStr, regex); +namespace mirai { + bool isDate(const std::string& dateStr) { + std::regex regex("[0-9]{4}-[0-9]{2}-[0-9]{2}"); + return std::regex_match(dateStr, regex); + } } diff --git a/src/core/utils.h b/src/core/utils.h index 504abad..c43f2dc 100644 --- a/src/core/utils.h +++ b/src/core/utils.h @@ -11,15 +11,15 @@ #include #include #include +#include +#include -void ltrim(std::string& s); -void rtrim(std::string& s); -void trim(std::string& s); +namespace mirai { + namespace stringUtils = cpputils::string; + namespace vectorUtils = cpputils::vector; -std::string ltrim_copy(std::string s); -std::string rtrim_copy(std::string s); -std::string trim_copy(std::string s); + bool isDate(const std::string& dateStr); +} -bool isDate(const std::string& dateStr); #endif