mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-02 01:13:19 +00:00
Change 'File' concept to a 'Resource' abstract concept
This commit is contained in:
parent
7eb54cddce
commit
ca34562a1c
23 changed files with 447 additions and 351 deletions
|
@ -16,7 +16,9 @@ qt_standard_project_setup(REQUIRES 6.7)
|
||||||
add_library(mirai-core
|
add_library(mirai-core
|
||||||
src/core/Mirai.h src/core/Mirai.cpp
|
src/core/Mirai.h src/core/Mirai.cpp
|
||||||
src/core/TaskItem.h src/core/TaskItem.cpp
|
src/core/TaskItem.h src/core/TaskItem.cpp
|
||||||
src/core/TasksFile.h src/core/TasksFile.cpp
|
src/core/BaseResource.h src/core/BaseResource.cpp
|
||||||
|
src/core/BaseFileResource.h
|
||||||
|
src/core/StdFileResource.h
|
||||||
src/core/TasksView.h src/core/TasksView.cpp
|
src/core/TasksView.h src/core/TasksView.cpp
|
||||||
src/core/TodoMd.h src/core/TodoMd.cpp
|
src/core/TodoMd.h src/core/TodoMd.cpp
|
||||||
src/core/utils.h src/core/utils.cpp
|
src/core/utils.h src/core/utils.cpp
|
||||||
|
@ -76,6 +78,9 @@ target_link_libraries(mirai PRIVATE mirai-core)
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
add_subdirectory(libs/Catch2)
|
add_subdirectory(libs/Catch2)
|
||||||
add_executable(tests tests/test.cpp)
|
add_executable(tests
|
||||||
|
tests/format.cpp
|
||||||
|
tests/saving.cpp
|
||||||
|
)
|
||||||
target_link_libraries(tests PRIVATE mirai-core)
|
target_link_libraries(tests PRIVATE mirai-core)
|
||||||
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
|
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
|
||||||
|
|
|
@ -6,12 +6,15 @@
|
||||||
|
|
||||||
#include "Backend.h"
|
#include "Backend.h"
|
||||||
#include "TaskItem.h"
|
#include "TaskItem.h"
|
||||||
|
#include "core/StdFileResource.h"
|
||||||
#include "core/TaskItem.h"
|
#include "core/TaskItem.h"
|
||||||
#include "core/TasksView.h"
|
#include "core/TasksView.h"
|
||||||
#include "core/TodoMd.h"
|
#include "core/TodoMd.h"
|
||||||
#include "cpp-utils/debug.h"
|
#include "cpp-utils/debug.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <qjsonarray.h>
|
#include <qjsonarray.h>
|
||||||
#include <qjsonvalue.h>
|
#include <qjsonvalue.h>
|
||||||
|
@ -46,7 +49,11 @@ Backend::Backend() : todoView(&mirai)
|
||||||
}
|
}
|
||||||
for (const QJsonValueRef &filePath : jsonFilesPath.toArray()) {
|
for (const QJsonValueRef &filePath : jsonFilesPath.toArray()) {
|
||||||
cpputils::debug::Timer loadingFileDuration;
|
cpputils::debug::Timer loadingFileDuration;
|
||||||
mirai.loadFile(filePath.toString().toStdString());
|
auto fileResource =
|
||||||
|
std::make_unique<mirai::StdFileResource>(mirai::BaseFileResourceConstructor{
|
||||||
|
.name = "[Can't load path]", .path = filePath.toString().toStdString()
|
||||||
|
});
|
||||||
|
mirai.loadResource(std::move(fileResource));
|
||||||
loadingFileDuration.printTimeElapsed(
|
loadingFileDuration.printTimeElapsed(
|
||||||
"Loading file duration of " + filePath.toString().toStdString()
|
"Loading file duration of " + filePath.toString().toStdString()
|
||||||
);
|
);
|
||||||
|
@ -72,23 +79,23 @@ Backend::Backend() : todoView(&mirai)
|
||||||
startDuration.printTimeElapsed("Start duration");
|
startDuration.printTimeElapsed("Start duration");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend::addTodo(QString newTodo, QString date)
|
|
||||||
{
|
|
||||||
mirai.addTask(newTodo.toStdString(), date.toStdString());
|
|
||||||
mirai.save();
|
|
||||||
todoView.update();
|
|
||||||
rebuildQMLTasksList();
|
|
||||||
emit tasksChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Backend::addTodoFromRawFormat(QString filePath, QString text, QString date)
|
void Backend::addTodoFromRawFormat(QString filePath, QString text, QString date)
|
||||||
{
|
{
|
||||||
auto file = mirai.getFileByPath(filePath.toStdString());
|
auto resource = std::ranges::find_if(
|
||||||
if (!file.has_value()) {
|
mirai.getResources(),
|
||||||
|
[&](std::unique_ptr<mirai::BaseResource> &resource) {
|
||||||
|
auto fsResource = dynamic_cast<mirai::BaseFileResource *>(resource.get());
|
||||||
|
if (!fsResource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return fsResource->getPath() == filePath.toStdString();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (resource == mirai.getResources().end()) {
|
||||||
qWarning() << "File path '" << filePath << "' doesn't exist" << Qt::endl;
|
qWarning() << "File path '" << filePath << "' doesn't exist" << Qt::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
file.value().get().addTask(
|
resource->get()->addTask(
|
||||||
mirai::TodoMdFormat::stringToTask(text.toStdString(), date.toStdString())
|
mirai::TodoMdFormat::stringToTask(text.toStdString(), date.toStdString())
|
||||||
);
|
);
|
||||||
mirai.save();
|
mirai.save();
|
||||||
|
@ -111,16 +118,16 @@ void Backend::removeTagFilter(QString tag)
|
||||||
emit tasksChanged();
|
emit tasksChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend::addFileFilter(QString fileName)
|
void Backend::addResourceFilter(QString fileName)
|
||||||
{
|
{
|
||||||
todoView.addFileFilter(fileName.toStdString());
|
todoView.addResourceFilter(fileName.toStdString());
|
||||||
rebuildQMLTasksList();
|
rebuildQMLTasksList();
|
||||||
emit tasksChanged();
|
emit tasksChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend::removeFileFilter(QString fileName)
|
void Backend::removeResourceFilter(QString fileName)
|
||||||
{
|
{
|
||||||
todoView.removeFileFilter(fileName.toStdString());
|
todoView.removeResourceFilter(fileName.toStdString());
|
||||||
rebuildQMLTasksList();
|
rebuildQMLTasksList();
|
||||||
emit tasksChanged();
|
emit tasksChanged();
|
||||||
}
|
}
|
||||||
|
@ -180,9 +187,9 @@ void Backend::hideCompletedTasks(bool shouldHide)
|
||||||
void Backend::rebuildQMLTasksList()
|
void Backend::rebuildQMLTasksList()
|
||||||
{
|
{
|
||||||
// TODO MOVE TO ANOTHER FILE
|
// TODO MOVE TO ANOTHER FILE
|
||||||
QMLTasksFiles.clear();
|
QMLResources.clear();
|
||||||
for (auto &file : mirai.getFiles()) {
|
for (auto &resource : mirai.getResources()) {
|
||||||
QMLTasksFiles.push_back({.tasksFile = file.get()});
|
QMLResources.push_back({.tasksFile = resource.get()});
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
QMLTasks.clear();
|
QMLTasks.clear();
|
||||||
|
@ -224,9 +231,9 @@ void Backend::rebuildQMLTasksList()
|
||||||
QMLActiveTagsFilter.push_back(QString::fromStdString(activeTagFilter));
|
QMLActiveTagsFilter.push_back(QString::fromStdString(activeTagFilter));
|
||||||
}
|
}
|
||||||
|
|
||||||
QMLActiveFilesFilter.clear();
|
QMLActiveResourcesFilter.clear();
|
||||||
for (auto &activeFileFilter : todoView.getActiveFilesFilter()) {
|
for (auto &activeFileFilter : todoView.getActiveFilesFilter()) {
|
||||||
QMLActiveFilesFilter.push_back(QString::fromStdString(activeFileFilter));
|
QMLActiveResourcesFilter.push_back(QString::fromStdString(activeFileFilter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,9 +252,9 @@ QVariant Backend::getActiveTagsFilter()
|
||||||
return QVariant::fromValue(QMLActiveTagsFilter);
|
return QVariant::fromValue(QMLActiveTagsFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant Backend::getActiveFilesFilter()
|
QVariant Backend::getActiveResourcesFilter()
|
||||||
{
|
{
|
||||||
return QVariant::fromValue(QMLActiveFilesFilter);
|
return QVariant::fromValue(QMLActiveResourcesFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Backend::shouldHideCompletedTasks()
|
bool Backend::shouldHideCompletedTasks()
|
||||||
|
@ -255,9 +262,9 @@ bool Backend::shouldHideCompletedTasks()
|
||||||
return shouldHideCompletedTasks_;
|
return shouldHideCompletedTasks_;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant Backend::getFiles()
|
QVariant Backend::getResources()
|
||||||
{
|
{
|
||||||
return QVariant::fromValue(QMLTasksFiles);
|
return QVariant::fromValue(QMLResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Backend::getTagColor(QString tag)
|
QString Backend::getTagColor(QString tag)
|
||||||
|
@ -289,13 +296,20 @@ void Backend::saveFilesPath(QVariant modifiedFilesPath)
|
||||||
auto paths = modifiedFilesPath.toStringList();
|
auto paths = modifiedFilesPath.toStringList();
|
||||||
QMLTags.clear();
|
QMLTags.clear();
|
||||||
QMLTasks.clear();
|
QMLTasks.clear();
|
||||||
QMLTasksFiles.clear();
|
QMLResources.clear();
|
||||||
emit tagsChanged();
|
emit tagsChanged();
|
||||||
emit tasksChanged();
|
emit tasksChanged();
|
||||||
emit filesChanged();
|
emit filesChanged();
|
||||||
mirai.unloadAllFiles();
|
mirai.unloadAllResources();
|
||||||
for (auto path : paths) {
|
for (auto path : paths) {
|
||||||
mirai.loadFile(path.toStdString());
|
if (path == "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto fileResource =
|
||||||
|
std::make_unique<mirai::StdFileResource>(mirai::BaseFileResourceConstructor{
|
||||||
|
.name = "[Can't load path]", .path = path.toStdString()
|
||||||
|
});
|
||||||
|
mirai.loadResource(std::move(fileResource));
|
||||||
}
|
}
|
||||||
todoView.update();
|
todoView.update();
|
||||||
rebuildQMLTasksList();
|
rebuildQMLTasksList();
|
||||||
|
@ -310,8 +324,11 @@ void Backend::saveConfig()
|
||||||
QJsonObject rootJson;
|
QJsonObject rootJson;
|
||||||
|
|
||||||
QJsonArray filesJson;
|
QJsonArray filesJson;
|
||||||
for (auto &file : mirai.getFiles()) {
|
for (auto &file : mirai.getResources()) {
|
||||||
filesJson.append(QString::fromStdString(file->getPath()));
|
auto fsResource = dynamic_cast<mirai::BaseFileResource *>(file.get());
|
||||||
|
if (fsResource) {
|
||||||
|
filesJson.append(QString::fromStdString(fsResource->getPath()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rootJson["files"] = filesJson;
|
rootJson["files"] = filesJson;
|
||||||
|
|
||||||
|
|
|
@ -33,22 +33,21 @@ class Backend : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
Q_PROPERTY(QVariant tasks READ getTasks NOTIFY tasksChanged)
|
Q_PROPERTY(QVariant tasks READ getTasks NOTIFY tasksChanged)
|
||||||
Q_PROPERTY(QVariant files READ getFiles NOTIFY filesChanged)
|
Q_PROPERTY(QVariant files READ getResources NOTIFY filesChanged)
|
||||||
Q_PROPERTY(QVariant tags READ getTags NOTIFY tagsChanged)
|
Q_PROPERTY(QVariant tags READ getTags NOTIFY tagsChanged)
|
||||||
Q_PROPERTY(QVariant activeTagsFilter READ getActiveTagsFilter NOTIFY tasksChanged)
|
Q_PROPERTY(QVariant activeTagsFilter READ getActiveTagsFilter NOTIFY tasksChanged)
|
||||||
Q_PROPERTY(QVariant activeFilesFilter READ getActiveFilesFilter NOTIFY tasksChanged)
|
Q_PROPERTY(QVariant activeResourcesFilter READ getActiveResourcesFilter NOTIFY tasksChanged)
|
||||||
Q_PROPERTY(bool shouldHideCompletedTasks READ shouldHideCompletedTasks WRITE hideCompletedTasks
|
Q_PROPERTY(bool shouldHideCompletedTasks READ shouldHideCompletedTasks WRITE hideCompletedTasks
|
||||||
NOTIFY tasksChanged)
|
NOTIFY tasksChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Backend();
|
Backend();
|
||||||
|
|
||||||
Q_INVOKABLE void addTodo(QString newTodo, QString date);
|
|
||||||
Q_INVOKABLE void addTodoFromRawFormat(QString filePath, QString text, QString date);
|
Q_INVOKABLE void addTodoFromRawFormat(QString filePath, QString text, QString date);
|
||||||
Q_INVOKABLE void addTagFilter(QString tag);
|
Q_INVOKABLE void addTagFilter(QString tag);
|
||||||
Q_INVOKABLE void removeTagFilter(QString tag);
|
Q_INVOKABLE void removeTagFilter(QString tag);
|
||||||
Q_INVOKABLE void addFileFilter(QString fileName);
|
Q_INVOKABLE void addResourceFilter(QString fileName);
|
||||||
Q_INVOKABLE void removeFileFilter(QString fileName);
|
Q_INVOKABLE void removeResourceFilter(QString fileName);
|
||||||
Q_INVOKABLE void removeFilters();
|
Q_INVOKABLE void removeFilters();
|
||||||
Q_INVOKABLE void updateTodoFromRawFormat(int todoIndex, QString text, QString date);
|
Q_INVOKABLE void updateTodoFromRawFormat(int todoIndex, QString text, QString date);
|
||||||
Q_INVOKABLE void updateTodo(int todoIndex, QString state, QString text, QString date);
|
Q_INVOKABLE void updateTodo(int todoIndex, QString state, QString text, QString date);
|
||||||
|
@ -62,10 +61,10 @@ class Backend : public QObject
|
||||||
void rebuildQMLTasksList();
|
void rebuildQMLTasksList();
|
||||||
|
|
||||||
QVariant getTasks();
|
QVariant getTasks();
|
||||||
QVariant getFiles();
|
QVariant getResources();
|
||||||
QVariant getTags();
|
QVariant getTags();
|
||||||
QVariant getActiveTagsFilter();
|
QVariant getActiveTagsFilter();
|
||||||
QVariant getActiveFilesFilter();
|
QVariant getActiveResourcesFilter();
|
||||||
bool shouldHideCompletedTasks();
|
bool shouldHideCompletedTasks();
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
|
|
||||||
|
@ -74,10 +73,10 @@ class Backend : public QObject
|
||||||
mirai::TasksView todoView;
|
mirai::TasksView todoView;
|
||||||
|
|
||||||
QList<QMLTaskItem> QMLTasks;
|
QList<QMLTaskItem> QMLTasks;
|
||||||
QList<QMLTasksFile> QMLTasksFiles;
|
QList<QMLTasksFile> QMLResources;
|
||||||
QList<QMLTag> QMLTags;
|
QList<QMLTag> QMLTags;
|
||||||
QList<QString> QMLActiveTagsFilter;
|
QList<QString> QMLActiveTagsFilter;
|
||||||
QList<QString> QMLActiveFilesFilter;
|
QList<QString> QMLActiveResourcesFilter;
|
||||||
QMap<QString, QString> tagsConfig;
|
QMap<QString, QString> tagsConfig;
|
||||||
|
|
||||||
bool shouldHideCompletedTasks_ = true;
|
bool shouldHideCompletedTasks_ = true;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TasksFile.h"
|
#include "TasksFile.h"
|
||||||
|
#include "core/BaseFileResource.h"
|
||||||
|
|
||||||
QString QMLTasksFile::getName()
|
QString QMLTasksFile::getName()
|
||||||
{
|
{
|
||||||
|
@ -13,5 +14,9 @@ QString QMLTasksFile::getName()
|
||||||
|
|
||||||
QString QMLTasksFile::getPath()
|
QString QMLTasksFile::getPath()
|
||||||
{
|
{
|
||||||
return QString::fromStdString(tasksFile->getPath());
|
auto fileResource = dynamic_cast<mirai::BaseFileResource *>(tasksFile);
|
||||||
|
if (!fileResource) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return QString::fromStdString(fileResource->getPath());
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
#define QML_TASKSFILE_H
|
#define QML_TASKSFILE_H
|
||||||
|
|
||||||
#include "QtCore/qvariant.h"
|
#include "QtCore/qvariant.h"
|
||||||
|
#include "core/BaseFileResource.h"
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtQml/qqmlregistration.h>
|
#include <QtQml/qqmlregistration.h>
|
||||||
|
|
||||||
#include "core/TasksFile.h"
|
|
||||||
|
|
||||||
struct QMLTasksFile {
|
struct QMLTasksFile {
|
||||||
|
|
||||||
Q_GADGET
|
Q_GADGET
|
||||||
|
@ -24,7 +23,7 @@ struct QMLTasksFile {
|
||||||
QString getName();
|
QString getName();
|
||||||
QString getPath();
|
QString getPath();
|
||||||
|
|
||||||
mirai::TasksFile *tasksFile;
|
mirai::BaseResource *tasksFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
42
src/core/BaseFileResource.h
Normal file
42
src/core/BaseFileResource.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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 MIRAI_BASE_FILE_RESOURCE_H
|
||||||
|
#define MIRAI_BASE_FILE_RESOURCE_H
|
||||||
|
|
||||||
|
#include "core/BaseResource.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace mirai
|
||||||
|
{
|
||||||
|
|
||||||
|
struct BaseFileResourceConstructor {
|
||||||
|
std::string name;
|
||||||
|
std::string path;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseFileResource : public BaseResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseFileResource(BaseFileResourceConstructor data) : BaseResource(data.name), path(data.path){};
|
||||||
|
|
||||||
|
BaseFileResource(BaseFileResource &) = delete;
|
||||||
|
BaseFileResource(BaseFileResource &&) = delete;
|
||||||
|
BaseFileResource operator=(BaseFileResource &) = delete;
|
||||||
|
BaseFileResource operator=(BaseFileResource &&) = delete;
|
||||||
|
|
||||||
|
~BaseFileResource() override = default;
|
||||||
|
|
||||||
|
const std::string &getPath() const
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string path;
|
||||||
|
};
|
||||||
|
} // namespace mirai
|
||||||
|
#endif
|
52
src/core/BaseResource.cpp
Normal file
52
src/core/BaseResource.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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 "BaseResource.h"
|
||||||
|
#include "TaskItem.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace mirai
|
||||||
|
{
|
||||||
|
|
||||||
|
void BaseResource::setDirty(bool shouldBeDirty)
|
||||||
|
{
|
||||||
|
isDirty_ = shouldBeDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseResource::isDirty() const
|
||||||
|
{
|
||||||
|
return isDirty_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<TaskItem>> &BaseResource::getTasks()
|
||||||
|
{
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseResource::addTask(TaskItemData taskItem)
|
||||||
|
{
|
||||||
|
tasks.push_back(std::make_unique<TaskItem>(this, taskItem));
|
||||||
|
setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseResource::removeTask(const TaskItem *taskToRemove)
|
||||||
|
{
|
||||||
|
auto findFunction = [&](const std::unique_ptr<TaskItem> &taskInFilter) {
|
||||||
|
return taskInFilter.get() == taskToRemove;
|
||||||
|
};
|
||||||
|
auto taskToDelete = std::remove_if(tasks.begin(), tasks.end(), findFunction);
|
||||||
|
if (taskToDelete == tasks.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tasks.erase(taskToDelete);
|
||||||
|
setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mirai
|
54
src/core/BaseResource.h
Normal file
54
src/core/BaseResource.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* 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 MIRAI_BASE_RESOURCE_H
|
||||||
|
#define MIRAI_BASE_RESOURCE_H
|
||||||
|
|
||||||
|
#include "core/TaskItem.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mirai
|
||||||
|
{
|
||||||
|
|
||||||
|
class BaseResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseResource(std::string name) : name(name){};
|
||||||
|
BaseResource(BaseResource &) = delete;
|
||||||
|
BaseResource(BaseResource &&) = delete;
|
||||||
|
BaseResource operator=(BaseResource &) = delete;
|
||||||
|
BaseResource operator=(BaseResource &&) = delete;
|
||||||
|
|
||||||
|
virtual ~BaseResource() = default;
|
||||||
|
virtual void save() = 0;
|
||||||
|
virtual void load() = 0;
|
||||||
|
|
||||||
|
void setName(std::string name)
|
||||||
|
{
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTask(TaskItemData TaskItem);
|
||||||
|
void removeTask(const TaskItem *taskToRemove);
|
||||||
|
std::vector<std::unique_ptr<TaskItem>> &getTasks();
|
||||||
|
|
||||||
|
void setDirty(bool shouldBeDirty);
|
||||||
|
bool isDirty() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::unique_ptr<TaskItem>> tasks;
|
||||||
|
bool isDirty_ = false;
|
||||||
|
};
|
||||||
|
} // namespace mirai
|
||||||
|
#endif
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "Mirai.h"
|
#include "Mirai.h"
|
||||||
#include "TaskItem.h"
|
#include "TaskItem.h"
|
||||||
#include "core/TasksFile.h"
|
|
||||||
#include "cpp-utils/debug.h"
|
#include "cpp-utils/debug.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -19,70 +18,53 @@
|
||||||
namespace mirai
|
namespace mirai
|
||||||
{
|
{
|
||||||
|
|
||||||
void Mirai::loadFile(const std::string &path)
|
void Mirai::loadResource(std::unique_ptr<BaseResource> &&resource)
|
||||||
{
|
{
|
||||||
try {
|
resource->load();
|
||||||
auto tasksFile = TodoMdFormat::readFile(path);
|
resources.push_back(std::move(resource));
|
||||||
files.push_back(std::move(tasksFile));
|
reloadTags();
|
||||||
reloadTags();
|
};
|
||||||
} catch (std::exception &e) {
|
|
||||||
std::cout << "Cannot load file " << path << " : " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mirai::unloadAllFiles()
|
void Mirai::unloadAllResources()
|
||||||
{
|
{
|
||||||
files.clear();
|
resources.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mirai::save()
|
void Mirai::save()
|
||||||
{
|
{
|
||||||
for (auto &file : files) {
|
for (auto &resource : resources) {
|
||||||
if (file->isDirty()) {
|
if (resource->isDirty()) {
|
||||||
file->sortByDate();
|
resource->save();
|
||||||
TodoMdFormat::writeFile(*file);
|
resource->setDirty(false);
|
||||||
file->setDirty(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reloadTags();
|
reloadTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mirai::addTask(TaskItemData taskItem)
|
|
||||||
{
|
|
||||||
files[0]->addTask(taskItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mirai::addTask(std::string text, std::string date)
|
|
||||||
{
|
|
||||||
/*std::time_t t = std::time(nullptr);*/
|
|
||||||
/*std::tm tm = *std::localtime(&t);*/
|
|
||||||
/*std::stringstream ssCreationDate;*/
|
|
||||||
/*ssCreationDate << std::put_time(&tm, "%Y-%m-%d");*/
|
|
||||||
files[0]->addTask(text, date);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mirai::removeTask(const TaskItem *taskItem)
|
void Mirai::removeTask(const TaskItem *taskItem)
|
||||||
{
|
{
|
||||||
for (auto &file : files) {
|
for (auto &resource : resources) {
|
||||||
file->removeTask(taskItem);
|
resource->removeTask(taskItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<TasksFile>> &Mirai::getFiles()
|
std::vector<std::unique_ptr<BaseResource>> &Mirai::getResources()
|
||||||
{
|
{
|
||||||
return files;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<TasksFile>> Mirai::getFileByPath(const std::string &path)
|
std::optional<std::reference_wrapper<BaseResource>> Mirai::getResourceByName(const std::string &name
|
||||||
|
)
|
||||||
{
|
{
|
||||||
auto fileIterator = std::ranges::find_if(files, [&](const std::unique_ptr<TasksFile> &file) {
|
auto resourceIterator =
|
||||||
return file->getPath() == path;
|
std::ranges::find_if(resources, [&](const std::unique_ptr<BaseResource> &resource) {
|
||||||
});
|
return resource->getName() == name;
|
||||||
|
});
|
||||||
|
|
||||||
if (fileIterator == files.end()) {
|
if (resourceIterator == resources.end()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return *(fileIterator->get());
|
return *(resourceIterator->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &Mirai::getTags()
|
const std::vector<std::string> &Mirai::getTags()
|
||||||
|
@ -94,8 +76,8 @@ void Mirai::reloadTags()
|
||||||
{
|
{
|
||||||
cpputils::debug::Timer reloadingTagsDuration;
|
cpputils::debug::Timer reloadingTagsDuration;
|
||||||
tags.clear();
|
tags.clear();
|
||||||
for (auto &file : files) {
|
for (auto &resource : resources) {
|
||||||
for (auto &task : file->getTasks()) {
|
for (auto &task : resource->getTasks()) {
|
||||||
for (auto &tag : task->getTags()) {
|
for (auto &tag : task->getTags()) {
|
||||||
if (!vectorUtils::contains(tags, tag)) {
|
if (!vectorUtils::contains(tags, tag)) {
|
||||||
tags.push_back(tag);
|
tags.push_back(tag);
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#define MIRAI_MIRAI_H
|
#define MIRAI_MIRAI_H
|
||||||
|
|
||||||
#include "TaskItem.h"
|
#include "TaskItem.h"
|
||||||
#include "TasksFile.h"
|
|
||||||
#include "TodoMd.h"
|
#include "TodoMd.h"
|
||||||
|
#include "core/BaseFileResource.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -23,22 +23,19 @@ class Mirai
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void loadFile(const std::string &path);
|
void loadResource(std::unique_ptr<BaseResource> &&resource);
|
||||||
void unloadAllFiles();
|
void unloadAllResources();
|
||||||
void save();
|
void save();
|
||||||
void addTask(TaskItemData taskItem);
|
|
||||||
void addTask(std::string text, std::string date);
|
|
||||||
void removeTask(const TaskItem *taskItem);
|
void removeTask(const TaskItem *taskItem);
|
||||||
void addFile(TasksFileConfig config);
|
std::optional<std::reference_wrapper<BaseResource>> getResourceByName(const std::string &name);
|
||||||
std::optional<std::reference_wrapper<TasksFile>> getFileByPath(const std::string &path);
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<TasksFile>> &getFiles();
|
std::vector<std::unique_ptr<BaseResource>> &getResources();
|
||||||
const std::vector<std::string> &getTags();
|
const std::vector<std::string> &getTags();
|
||||||
|
|
||||||
void reloadTags();
|
void reloadTags();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<TasksFile>> files = std::vector<std::unique_ptr<TasksFile>>();
|
std::vector<std::unique_ptr<BaseResource>> resources;
|
||||||
std::vector<std::string> tags;
|
std::vector<std::string> tags;
|
||||||
};
|
};
|
||||||
} // namespace mirai
|
} // namespace mirai
|
||||||
|
|
63
src/core/StdFileResource.h
Normal file
63
src/core/StdFileResource.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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 MIRAI_STD_FILE_RESOURCE_H
|
||||||
|
#define MIRAI_STD_FILE_RESOURCE_H
|
||||||
|
|
||||||
|
#include "core/BaseFileResource.h"
|
||||||
|
#include "core/TodoMd.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace mirai
|
||||||
|
{
|
||||||
|
|
||||||
|
class StdFileResource : public BaseFileResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StdFileResource(BaseFileResourceConstructor data) : BaseFileResource(data){};
|
||||||
|
StdFileResource(StdFileResource &) = delete;
|
||||||
|
StdFileResource(StdFileResource &&) = delete;
|
||||||
|
StdFileResource operator=(StdFileResource &) = delete;
|
||||||
|
StdFileResource operator=(StdFileResource &&) = delete;
|
||||||
|
|
||||||
|
~StdFileResource() override = default;
|
||||||
|
|
||||||
|
void save() override
|
||||||
|
{
|
||||||
|
std::ofstream file(getPath());
|
||||||
|
if (!file.is_open()) {
|
||||||
|
throw std::runtime_error("can't create " + getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string content = TodoMdFormat::stringifyTasks(getName(), getTasks());
|
||||||
|
|
||||||
|
file << content;
|
||||||
|
file.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
void load() override
|
||||||
|
{
|
||||||
|
std::ifstream file(getPath());
|
||||||
|
if (!file.is_open()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string content = "";
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
content += line + "\n";
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
auto result = TodoMdFormat::parse(content);
|
||||||
|
for (const auto &task : result.tasks) {
|
||||||
|
addTask(task);
|
||||||
|
}
|
||||||
|
setName(result.name);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace mirai
|
||||||
|
#endif
|
|
@ -5,14 +5,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TaskItem.h"
|
#include "TaskItem.h"
|
||||||
#include "TasksFile.h"
|
#include "BaseResource.h"
|
||||||
#include "core/utils.h"
|
#include "core/utils.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace mirai
|
namespace mirai
|
||||||
{
|
{
|
||||||
|
|
||||||
TaskItem::TaskItem(TasksFile *parent, TaskItemData data) : parent(parent), data(data)
|
TaskItem::TaskItem(BaseResource *parent, TaskItemData data) : parent(parent), data(data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,15 @@ struct TaskItemData {
|
||||||
Tags tags;
|
Tags tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TasksFile;
|
class BaseResource;
|
||||||
|
|
||||||
class TaskItem
|
class TaskItem
|
||||||
{
|
{
|
||||||
friend TasksFile;
|
friend BaseResource;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
public:
|
public:
|
||||||
TaskItem(TasksFile *parent, const TaskItemData data);
|
TaskItem(BaseResource *parent, const TaskItemData data);
|
||||||
|
|
||||||
TaskItem &operator=(const TaskItemData &newData)
|
TaskItem &operator=(const TaskItemData &newData)
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,7 @@ class TaskItem
|
||||||
private:
|
private:
|
||||||
void onChange();
|
void onChange();
|
||||||
|
|
||||||
TasksFile *parent;
|
BaseResource *parent;
|
||||||
TaskItemData data;
|
TaskItemData data;
|
||||||
};
|
};
|
||||||
} // namespace mirai
|
} // namespace mirai
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 "TasksFile.h"
|
|
||||||
#include "TaskItem.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace mirai
|
|
||||||
{
|
|
||||||
|
|
||||||
TasksFile::TasksFile(TasksFileConstructor params) : name(params.name), path(params.path)
|
|
||||||
{
|
|
||||||
for (const auto &task : params.tasks) {
|
|
||||||
auto taskPtr = std::make_unique<TaskItem>(task);
|
|
||||||
tasks.push_back(std::move(taskPtr));
|
|
||||||
}
|
|
||||||
sortByDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TasksFile::onTaskChanged(TaskItem &taskItem)
|
|
||||||
{
|
|
||||||
std::cout << "THIS PTR: " << this << std::endl;
|
|
||||||
setDirty(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TasksFile::setDirty(bool shouldBeDirty)
|
|
||||||
{
|
|
||||||
isDirty_ = shouldBeDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TasksFile::isDirty() const
|
|
||||||
{
|
|
||||||
return isDirty_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &TasksFile::getName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &TasksFile::getPath() const
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
TasksPtrs &TasksFile::getTasks()
|
|
||||||
{
|
|
||||||
return tasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TasksFile::addTask(TaskItemData taskItem)
|
|
||||||
{
|
|
||||||
tasks.push_back(std::make_unique<TaskItem>(this, taskItem));
|
|
||||||
setDirty(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TasksFile::addTask(std::string text, std::string date)
|
|
||||||
{
|
|
||||||
auto newTask = std::make_unique<TaskItem>(
|
|
||||||
TaskItem{this, {.text = text, .state = TODO, .date = date == "" ? "No date" : date}}
|
|
||||||
);
|
|
||||||
tasks.push_back(std::move(newTask));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TasksFile::removeTask(const TaskItem *taskToRemove)
|
|
||||||
{
|
|
||||||
auto findFunction = [&](const std::unique_ptr<TaskItem> &taskInFilter) {
|
|
||||||
return taskInFilter.get() == taskToRemove;
|
|
||||||
};
|
|
||||||
auto taskToDelete = std::remove_if(tasks.begin(), tasks.end(), findFunction);
|
|
||||||
if (taskToDelete == tasks.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tasks.erase(taskToDelete);
|
|
||||||
setDirty(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TasksFile::sortByDate()
|
|
||||||
{
|
|
||||||
std::sort(
|
|
||||||
tasks.begin(), tasks.end(),
|
|
||||||
[](const std::unique_ptr<TaskItem> &t1, const std::unique_ptr<TaskItem> &t2) {
|
|
||||||
if (t1->hasDate() && !t2->hasDate()) {
|
|
||||||
return true;
|
|
||||||
} else if (!t1->hasDate() && t2->hasDate()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return t1->getDate() < t2->getDate();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} // namespace mirai
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 MIRAI_TASKSFILE_H
|
|
||||||
#define MIRAI_TASKSFILE_H
|
|
||||||
|
|
||||||
#include "TaskItem.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace mirai
|
|
||||||
{
|
|
||||||
|
|
||||||
using TasksPtrs = std::vector<std::unique_ptr<TaskItem>>;
|
|
||||||
|
|
||||||
struct TasksFileConfig {
|
|
||||||
std::string name;
|
|
||||||
std::string path;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TasksFileConstructor {
|
|
||||||
const std::string &name;
|
|
||||||
const std::string &path;
|
|
||||||
std::vector<TaskItem> tasks;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TasksFile
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
TasksFile(const TasksFile &) = delete;
|
|
||||||
TasksFile &operator=(const TasksFile &) = delete;
|
|
||||||
TasksFile(TasksFileConstructor params);
|
|
||||||
void addTask(std::string text, std::string date);
|
|
||||||
void addTask(TaskItemData TaskItem);
|
|
||||||
void removeTask(const TaskItem *taskToRemove);
|
|
||||||
void sortByDate();
|
|
||||||
|
|
||||||
const std::string &getName() const;
|
|
||||||
const std::string &getPath() const;
|
|
||||||
TasksPtrs &getTasks();
|
|
||||||
|
|
||||||
void setDirty(bool shouldBeDirty);
|
|
||||||
bool isDirty() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void onTaskChanged(TaskItem &);
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
std::string path;
|
|
||||||
TasksPtrs tasks;
|
|
||||||
bool isDirty_ = false;
|
|
||||||
};
|
|
||||||
} // namespace mirai
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -39,8 +39,9 @@ size_t TasksView::count() const
|
||||||
void TasksView::update()
|
void TasksView::update()
|
||||||
{
|
{
|
||||||
tasksToShow.clear();
|
tasksToShow.clear();
|
||||||
for (auto &file : mirai->getFiles()) {
|
for (auto &file : mirai->getResources()) {
|
||||||
if (filesFilter.size() > 0 && !vectorUtils::contains(filesFilter, file->getName())) {
|
if (resourcesFilter.size() > 0 &&
|
||||||
|
!vectorUtils::contains(resourcesFilter, file->getName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (auto &task : file->getTasks()) {
|
for (auto &task : file->getTasks()) {
|
||||||
|
@ -88,16 +89,16 @@ void TasksView::removeTagFilter(const std::string &tag)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TasksView::addFileFilter(const std::string &fileName)
|
void TasksView::addResourceFilter(const std::string &fileName)
|
||||||
{
|
{
|
||||||
filesFilter.push_back(fileName);
|
resourcesFilter.push_back(fileName);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TasksView::removeFileFilter(const std::string &fileName)
|
void TasksView::removeResourceFilter(const std::string &fileName)
|
||||||
{
|
{
|
||||||
filesFilter.erase(std::remove_if(
|
resourcesFilter.erase(std::remove_if(
|
||||||
filesFilter.begin(), filesFilter.end(),
|
resourcesFilter.begin(), resourcesFilter.end(),
|
||||||
[&](const auto &fileInFilter) {
|
[&](const auto &fileInFilter) {
|
||||||
return fileName == fileInFilter;
|
return fileName == fileInFilter;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +119,6 @@ const std::vector<std::string> &TasksView::getActiveTagsFilter()
|
||||||
|
|
||||||
const std::vector<std::string> &TasksView::getActiveFilesFilter()
|
const std::vector<std::string> &TasksView::getActiveFilesFilter()
|
||||||
{
|
{
|
||||||
return filesFilter;
|
return resourcesFilter;
|
||||||
}
|
}
|
||||||
} // namespace mirai
|
} // namespace mirai
|
||||||
|
|
|
@ -6,11 +6,9 @@
|
||||||
|
|
||||||
#ifndef MIRAI_TASKSVIEW_H
|
#ifndef MIRAI_TASKSVIEW_H
|
||||||
#define MIRAI_TASKSVIEW_H
|
#define MIRAI_TASKSVIEW_H
|
||||||
#include "TasksFile.h"
|
|
||||||
#include "core/Mirai.h"
|
#include "core/Mirai.h"
|
||||||
#include "using.h"
|
#include "using.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace mirai
|
namespace mirai
|
||||||
|
@ -28,8 +26,8 @@ class TasksView
|
||||||
void update();
|
void update();
|
||||||
void addTagFilter(const std::string &tag);
|
void addTagFilter(const std::string &tag);
|
||||||
void removeTagFilter(const std::string &tag);
|
void removeTagFilter(const std::string &tag);
|
||||||
void addFileFilter(const std::string &fileName);
|
void addResourceFilter(const std::string &fileName);
|
||||||
void removeFileFilter(const std::string &fileName);
|
void removeResourceFilter(const std::string &fileName);
|
||||||
void removeFilters();
|
void removeFilters();
|
||||||
const Tags &getActiveTagsFilter();
|
const Tags &getActiveTagsFilter();
|
||||||
const std::vector<std::string> &getActiveFilesFilter();
|
const std::vector<std::string> &getActiveFilesFilter();
|
||||||
|
@ -38,7 +36,7 @@ class TasksView
|
||||||
Mirai *mirai;
|
Mirai *mirai;
|
||||||
std::vector<TaskItem *> tasksToShow;
|
std::vector<TaskItem *> tasksToShow;
|
||||||
Tags tagsFilter;
|
Tags tagsFilter;
|
||||||
std::vector<std::string> filesFilter;
|
std::vector<std::string> resourcesFilter;
|
||||||
};
|
};
|
||||||
} // namespace mirai
|
} // namespace mirai
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "TodoMd.h"
|
#include "TodoMd.h"
|
||||||
#include "TaskItem.h"
|
#include "TaskItem.h"
|
||||||
#include "core/TasksFile.h"
|
|
||||||
#include "cpp-utils/debug.h"
|
#include "cpp-utils/debug.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -17,50 +16,6 @@
|
||||||
namespace mirai
|
namespace mirai
|
||||||
{
|
{
|
||||||
|
|
||||||
std::unique_ptr<TasksFile> TodoMdFormat::readFile(const std::string &path)
|
|
||||||
{
|
|
||||||
cpputils::debug::Timer readMdFormatDuration;
|
|
||||||
std::ifstream file(path);
|
|
||||||
if (!file.is_open()) {
|
|
||||||
throw std::runtime_error("todo.txt file not found");
|
|
||||||
}
|
|
||||||
std::vector<TaskItem> taskItems;
|
|
||||||
std::string line;
|
|
||||||
|
|
||||||
if (!std::getline(file, line) || line.substr(0, 2) != "# ") {
|
|
||||||
std::cerr << "Couldn't find the task list name" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name = line.substr(2);
|
|
||||||
std::string currentDate = "";
|
|
||||||
|
|
||||||
auto tasksFile = std::make_unique<TasksFile>(
|
|
||||||
TasksFileConstructor{.name = name, .path = path, .tasks = taskItems}
|
|
||||||
);
|
|
||||||
|
|
||||||
cpputils::debug::Timer stringToTaskDuration;
|
|
||||||
stringToTaskDuration.reset();
|
|
||||||
cpputils::debug::Timer gelinesDuration;
|
|
||||||
while (std::getline(file, line)) {
|
|
||||||
if (std::string_view{line.data(), 3} == "## ") {
|
|
||||||
currentDate = line.substr(3);
|
|
||||||
} else if (std::string_view{line.data(), 5} == "- [ ]" || std::string_view{line.data(), 5} == "- [X]") {
|
|
||||||
stringToTaskDuration.start();
|
|
||||||
TaskItemData taskItemData = stringToTask(line, currentDate);
|
|
||||||
stringToTaskDuration.stop();
|
|
||||||
taskItemData.date = currentDate;
|
|
||||||
tasksFile->addTask(taskItemData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gelinesDuration.printTimeElapsed("getlinesDuration");
|
|
||||||
stringToTaskDuration.printTimeElapsed("stringToTaskDuration");
|
|
||||||
file.close();
|
|
||||||
tasksFile->setDirty(false);
|
|
||||||
readMdFormatDuration.printTimeElapsed("Reading MD File duration of " + path);
|
|
||||||
return tasksFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tags TodoMdFormat::extractTagsFromMetadata(std::string metadata)
|
Tags TodoMdFormat::extractTagsFromMetadata(std::string metadata)
|
||||||
{
|
{
|
||||||
Tags tags;
|
Tags tags;
|
||||||
|
@ -77,25 +32,6 @@ Tags TodoMdFormat::extractTagsFromMetadata(std::string metadata)
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TodoMdFormat::writeFile(TasksFile &tasks)
|
|
||||||
{
|
|
||||||
std::ofstream file(tasks.getPath());
|
|
||||||
if (!file.is_open()) {
|
|
||||||
throw std::runtime_error("can't create todo.txt");
|
|
||||||
}
|
|
||||||
std::string currentDate = "";
|
|
||||||
|
|
||||||
file << "# " << tasks.getName() << "\n";
|
|
||||||
for (const auto &task : tasks.getTasks()) {
|
|
||||||
if (currentDate != task->getDate()) {
|
|
||||||
currentDate = task->getDate();
|
|
||||||
file << "\n## " << (task->getDate() != "" ? task->getDate() : "No date") << "\n\n";
|
|
||||||
}
|
|
||||||
file << taskToString(*task) << '\n';
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string TodoMdFormat::fieldWithSpace(const std::string &field)
|
std::string TodoMdFormat::fieldWithSpace(const std::string &field)
|
||||||
{
|
{
|
||||||
if (field.length() == 0) {
|
if (field.length() == 0) {
|
||||||
|
|
|
@ -8,17 +8,76 @@
|
||||||
#define MIRAI_TODOMD_H
|
#define MIRAI_TODOMD_H
|
||||||
|
|
||||||
#include "TaskItem.h"
|
#include "TaskItem.h"
|
||||||
#include "TasksFile.h"
|
#include "cpp-utils/debug.h"
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace mirai
|
namespace mirai
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct MiraiMarkdownFormatParseResult {
|
||||||
|
std::string name;
|
||||||
|
std::vector<TaskItemData> tasks;
|
||||||
|
};
|
||||||
|
|
||||||
class TodoMdFormat
|
class TodoMdFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<TasksFile> readFile(const std::string &path);
|
static std::string
|
||||||
static void writeFile(TasksFile &tasks);
|
stringifyTasks(const std::string &name, const std::vector<std::unique_ptr<TaskItem>> &tasks)
|
||||||
|
{
|
||||||
|
std::string result = "";
|
||||||
|
std::string currentDate = "";
|
||||||
|
|
||||||
|
result += "# " + name + "\n";
|
||||||
|
for (const auto &task : tasks) {
|
||||||
|
if (currentDate != task->getDate()) {
|
||||||
|
currentDate = task->getDate();
|
||||||
|
result += "\n## " + (task->getDate() != "" ? task->getDate() : "No date") + "\n\n";
|
||||||
|
}
|
||||||
|
result += taskToString(*task) + '\n';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
static MiraiMarkdownFormatParseResult parse(const std::string &content)
|
||||||
|
{
|
||||||
|
cpputils::debug::Timer readMdFormatDuration;
|
||||||
|
std::vector<TaskItem> taskItems;
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
std::stringstream contentStream(content);
|
||||||
|
|
||||||
|
if (!std::getline(contentStream, line) || line.substr(0, 2) != "# ") {
|
||||||
|
std::cerr << "Couldn't find the task list name" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = line.substr(2);
|
||||||
|
std::string currentDate = "";
|
||||||
|
|
||||||
|
std::vector<TaskItemData> result;
|
||||||
|
|
||||||
|
cpputils::debug::Timer stringToTaskDuration;
|
||||||
|
stringToTaskDuration.reset();
|
||||||
|
cpputils::debug::Timer gelinesDuration;
|
||||||
|
while (std::getline(contentStream, line)) {
|
||||||
|
if (std::string_view{line.data(), 3} == "## ") {
|
||||||
|
currentDate = line.substr(3);
|
||||||
|
} else if (std::string_view{line.data(), 5} == "- [ ]" || std::string_view{line.data(), 5} == "- [X]") {
|
||||||
|
stringToTaskDuration.start();
|
||||||
|
TaskItemData taskItemData = stringToTask(line, currentDate);
|
||||||
|
stringToTaskDuration.stop();
|
||||||
|
taskItemData.date = currentDate;
|
||||||
|
result.push_back(taskItemData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gelinesDuration.printTimeElapsed("getlinesDuration");
|
||||||
|
stringToTaskDuration.printTimeElapsed("stringToTaskDuration");
|
||||||
|
readMdFormatDuration.printTimeElapsed("Reading MD File duration");
|
||||||
|
return {.name = name, .tasks = result};
|
||||||
|
}
|
||||||
|
|
||||||
static std::string taskToString(const TaskItem &task);
|
static std::string taskToString(const TaskItem &task);
|
||||||
static TaskItemData stringToTask(const std::string &str, const std::string &date);
|
static TaskItemData stringToTask(const std::string &str, const std::string &date);
|
||||||
|
|
|
@ -44,7 +44,7 @@ Rectangle {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.preferredHeight: childrenRect.height
|
Layout.preferredHeight: childrenRect.height
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: backend.activeFilesFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
|
color: backend.activeResourcesFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
|
||||||
radius: 4
|
radius: 4
|
||||||
AppText {
|
AppText {
|
||||||
text: modelData.name
|
text: modelData.name
|
||||||
|
@ -53,10 +53,10 @@ Rectangle {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (backend.activeFilesFilter.includes(modelData.name)) {
|
if (backend.activeResourcesFilter.includes(modelData.name)) {
|
||||||
backend.removeFileFilter(modelData.name)
|
backend.removeResourceFilter(modelData.name)
|
||||||
} else {
|
} else {
|
||||||
backend.addFileFilter(modelData.name)
|
backend.addResourceFilter(modelData.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
|
|
|
@ -44,8 +44,8 @@ ColumnLayout {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
|
currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
console.log(selectedFile)
|
console.log(selectedFile.toString())
|
||||||
internal.paths = [...internal.paths, selectedFile]
|
internal.paths = [...internal.paths, selectedFile.toString().replace(/^file:\/\//, "")]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
|
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO this is just a quick setup for later
|
|
||||||
|
|
||||||
#include "core/Mirai.h"
|
#include "core/Mirai.h"
|
||||||
#include "core/TaskItem.h"
|
#include "core/TaskItem.h"
|
||||||
#include "core/TodoMd.h"
|
#include "core/TodoMd.h"
|
48
tests/saving.cpp
Normal file
48
tests/saving.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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 "core/BaseFileResource.h"
|
||||||
|
#include "core/Mirai.h"
|
||||||
|
#include "core/StdFileResource.h"
|
||||||
|
#include "core/TaskItem.h"
|
||||||
|
#include "core/TodoMd.h"
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
TEST_CASE("Saving data")
|
||||||
|
{
|
||||||
|
SECTION("Saving using file resource")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
mirai::Mirai mirai;
|
||||||
|
auto fileResource = std::make_unique<mirai::StdFileResource>(
|
||||||
|
mirai::BaseFileResourceConstructor{.name = "Testing", .path = "testing.md"}
|
||||||
|
);
|
||||||
|
mirai.loadResource(std::move(fileResource));
|
||||||
|
|
||||||
|
auto task = mirai::TodoMdFormat::stringToTask(
|
||||||
|
"- [X] 08:00-10:00 > This is a test -- #mirai", "2024-04-19"
|
||||||
|
);
|
||||||
|
mirai.getResources()[0]->addTask(task);
|
||||||
|
mirai.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
mirai::Mirai mirai;
|
||||||
|
auto fileResource = std::make_unique<mirai::StdFileResource>(
|
||||||
|
mirai::BaseFileResourceConstructor{.name = "Testing", .path = "testing.md"}
|
||||||
|
);
|
||||||
|
mirai.loadResource(std::move(fileResource));
|
||||||
|
|
||||||
|
const auto &resources = mirai.getResources();
|
||||||
|
REQUIRE(resources.size() == 1);
|
||||||
|
REQUIRE(resources[0]->getName() == "Testing");
|
||||||
|
REQUIRE(resources[0]->getTasks().size() == 1);
|
||||||
|
REQUIRE(resources[0]->getTasks().at(0)->getText() == "This is a test");
|
||||||
|
REQUIRE(resources[0]->getTasks().at(0)->getDate() == "2024-04-19");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue