/* * 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 */ #include "Backend.h" #include "TaskItem.h" #include "core/TaskItem.h" #include "core/TasksView.h" #include "core/TodoMd.h" #include #include #include #include #include #include Backend::Backend() : view(&mirai) { std::cout << "Backend created" << std::endl; QDir().mkdir(QDir::homePath() + "/.config/mirai"); QFile loadFile(QDir::homePath() + "/.config/mirai/config.json"); if (!loadFile.open(QIODevice::ReadOnly)) { qWarning() << "Couldn't find existing config file"; exit(1); } QByteArray loadData = loadFile.readAll(); QJsonDocument json = QJsonDocument::fromJson(loadData); loadFile.close(); if (!json.isObject()) { qWarning() << "config.json is not a valid config file"; exit(1); } QJsonObject jsonRootObject = json.object(); auto jsonFilesPath = json["files"]; if (!jsonFilesPath.isArray()) { qWarning() << "config.json should contains a 'files' string array"; exit(1); } for (const QJsonValueRef &filePath : jsonFilesPath.toArray()) { mirai.loadFile(filePath.toString().toStdString()); } auto jsonTagsConfig = json["tags"]; if (jsonTagsConfig.isObject()) { for (auto &jsonTagConfigKey : jsonTagsConfig.toObject().keys()) { tagsConfig[jsonTagConfigKey] = jsonTagsConfig.toObject()[jsonTagConfigKey].toObject()["color"].toString(); } } view.update(); rebuildQMLTasksList(); } void Backend::addTodo(QString newTodo, QString date) { mirai.addTask(newTodo.toStdString(), date.toStdString()); mirai.save(); view.update(); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::addTodoFromRawFormat(QString filePath, QString text, QString date) { auto file = mirai.getFileByPath(filePath.toStdString()); if (!file.has_value()) { qWarning() << "File path '" << filePath << "' doesn't exist" << Qt::endl; return; } file.value().get().addTask( mirai::TodoMdFormat::StringToTask(text.toStdString(), date.toStdString()) ); mirai.save(); view.update(); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::addTagFilter(QString tag) { view.addTagFilter(tag.toStdString()); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::removeTagFilter(QString tag) { view.removeTagFilter(tag.toStdString()); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::addFileFilter(QString fileName) { view.addFileFilter(fileName.toStdString()); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::removeFileFilter(QString fileName) { view.removeFileFilter(fileName.toStdString()); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::removeFilters() { view.removeFilters(); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::updateTodoFromRawFormat(int todoIndex, QString text, QString date) { QMLTaskItem &taskItem = QMLTasks[todoIndex]; taskItem.taskItem->setText(taskItem.taskItem->getText()); *(taskItem.taskItem) = mirai::TodoMdFormat::StringToTask(text.toStdString(), date.toStdString()); mirai.save(); view.update(); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::updateTodo(int todoIndex, QString state, QString text, QString date) { QMLTaskItem &taskItem = QMLTasks[todoIndex]; if (state == "DONE") { taskItem.taskItem->markAsDone(); } else if (state == "TODO") { taskItem.taskItem->markAsUndone(); } taskItem.taskItem->setText(text.toStdString()); taskItem.taskItem->setDate(date.toStdString()); mirai.save(); view.update(); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::removeTodo(int todoIndex) { QMLTaskItem &taskItem = QMLTasks[todoIndex]; mirai.removeTask(taskItem.taskItem); mirai.save(); view.update(); rebuildQMLTasksList(); emit tasksChanged(); } void Backend::hideCompletedTasks(bool shouldHide) { shouldHideCompletedTasks_ = shouldHide; rebuildQMLTasksList(); emit tasksChanged(); } void Backend::rebuildQMLTasksList() { // TODO MOVE TO ANOTHER FILE QMLTasksFiles.clear(); for (auto &file : mirai.getFiles()) { QMLTasksFiles.push_back({.tasksFile = file.get()}); } // ---- QMLTasks.clear(); std::string lastDate = ""; std::time_t t = std::time(nullptr); std::tm tm = *std::localtime(&t); std::stringstream currentDate; currentDate << std::put_time(&tm, "%Y-%m-%d"); for (int i = 0; i < view.count(); ++i) { mirai::TaskItem &task = view[i]; if (shouldHideCompletedTasks_ && task.getState() == mirai::DONE && task.hasDate() && task.getDate() < currentDate.str()) { continue; } bool shouldShowDate = false; if (lastDate != task.getDate()) { lastDate = task.getDate(); shouldShowDate = true; } QList qStringTags; for (auto &tag : task.getTags()) { qStringTags.push_back(QString::fromStdString(tag)); } QMLTasks.push_back( {.taskItem = &task, .shouldShowDate = shouldShowDate, .tags = qStringTags} ); } QMLTags.clear(); for (auto &tag : mirai.getTags()) { QMLTags.push_back({ .name = QString::fromStdString(tag), .color = getTagColor(QString::fromStdString(tag)), }); } QMLActiveTagsFilter.clear(); for (auto &activeTagFilter : view.getActiveTagsFilter()) { QMLActiveTagsFilter.push_back(QString::fromStdString(activeTagFilter)); } QMLActiveFilesFilter.clear(); for (auto &activeFileFilter : view.getActiveFilesFilter()) { QMLActiveFilesFilter.push_back(QString::fromStdString(activeFileFilter)); } } QVariant Backend::getTasks() { return QVariant::fromValue(QMLTasks); } QVariant Backend::getTags() { return QVariant::fromValue(QMLTags); } QVariant Backend::getActiveTagsFilter() { return QVariant::fromValue(QMLActiveTagsFilter); } QVariant Backend::getActiveFilesFilter() { return QVariant::fromValue(QMLActiveFilesFilter); } bool Backend::shouldHideCompletedTasks() { return shouldHideCompletedTasks_; } QVariant Backend::getFiles() { return QVariant::fromValue(QMLTasksFiles); } QString Backend::getTagColor(QString tag) { if (!tagsConfig.contains(tag)) { return "#c6d0f5"; // TODO: currently hard coded but should match the default Text color. } return tagsConfig[tag]; } void Backend::saveTagsColor(QVariant modifiedTags) { auto aa = modifiedTags.toList(); for (auto bb : aa) { auto cc = bb.toMap(); std::cout << cc["name"].toString().toStdString() << ": " << cc["color"].toString().toStdString() << std::endl; tagsConfig[cc["name"].toString()] = cc["color"].toString(); } rebuildQMLTasksList(); emit tagsChanged(); emit tasksChanged(); saveConfig(); } void Backend::saveConfig() { QJsonObject rootJson; QJsonArray filesJson; for (auto &file : mirai.getFiles()) { filesJson.append(QString::fromStdString(file->getPath())); } rootJson["files"] = filesJson; QJsonObject tagsJson; for (auto &tag : tagsConfig.keys()) { QJsonObject tagConfig; tagConfig["color"] = getTagColor(tag); tagsJson[tag] = tagConfig; } rootJson["tags"] = tagsJson; QFile configFile(QDir::homePath() + "/.config/mirai/config.json"); if (!configFile.open(QIODevice::WriteOnly)) { qWarning() << "Cannot save config"; return; } configFile.write(QJsonDocument(rootJson).toJson()); configFile.close(); }