diff --git a/src/frames/mainwindow.cpp b/src/frames/mainwindow.cpp index 25ca5f8..c98c5b8 100644 --- a/src/frames/mainwindow.cpp +++ b/src/frames/mainwindow.cpp @@ -1,8 +1,15 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#define PRIORITIES_KEY "priorities" +#define STATUS_KEY "status" +#define BOARDS_KEY "boards" + #include #include +#include +#include +#include #include "prefdialog.h" #include "aboutdialog.h" @@ -15,6 +22,7 @@ MainWindow::MainWindow(QWidget *parent) , ui(new Ui::MainWindow) { ui->setupUi(this); + init(); this->selectedBoardIndex = -1; connect(ui->actionPreferences, &QAction::triggered, this, &MainWindow::openPreferences); connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::openAbout); @@ -22,8 +30,6 @@ MainWindow::MainWindow(QWidget *parent) connect(ui->listWidget, &QListWidget::currentRowChanged, this, &MainWindow::onBoardSelected); connect(ui->actionNew_task, &QAction::triggered, this, &MainWindow::onNewTaskClick); connect(ui->treeWidget, &QTreeWidget::itemDoubleClicked, this, &MainWindow::onEditTask); - this->priorities = defaultPriorities(); - this->status = defaultStatus(); } MainWindow::~MainWindow() @@ -43,6 +49,7 @@ void MainWindow::openPreferences() { this->priorities = dialog.getPriorities(); this->status = dialog.getStatus(); + save(); } } @@ -62,6 +69,7 @@ void MainWindow::onNewBoardClick() boards.append(b); QListWidgetItem *item = new QListWidgetItem(name); ui->listWidget->addItem(item); + save(); } } @@ -98,6 +106,7 @@ void MainWindow::onNewTaskClick() item->setForeground(2, fgColor); ui->treeWidget->addTopLevelItem(item); + save(); } } } @@ -153,11 +162,38 @@ void MainWindow::onEditTask(QTreeWidgetItem *item) fgColor.setColor(Tools::getForegroundColor(bgColor.color())); item->setBackground(2, bgColor); item->setForeground(2, fgColor); + save(); } } } } +void MainWindow::init() +{ + if (Tools::isSaveFileExist()) + { + QJsonDocument doc; + if (Tools::readSaveFile(doc)) + { + QJsonObject save = doc.object(); + for (QJsonValue value : save[PRIORITIES_KEY].toArray()) { + priorities.append(Priority(value.toObject())); + } + for (QJsonValue value : save[STATUS_KEY].toArray()) { + status.append(Status(value.toObject())); + } + for (QJsonValue value : save[BOARDS_KEY].toArray()) { + boards.append(new Board(value.toObject())); + } + redrawBoardList(); + return; + } + } + this->priorities = defaultPriorities(); + this->status = defaultStatus(); + save(); +} + QVector MainWindow::defaultPriorities() { QVector res; @@ -228,10 +264,34 @@ const QColor MainWindow::getStatusColor(QString uuid, QColor defaultColor) return color; } +const QJsonDocument MainWindow::getJsonSave() +{ + QJsonDocument doc; + QJsonObject obj; + QJsonArray jsonPriorities; + foreach (Priority p, this->priorities) { + jsonPriorities.append(p.toJson()); + } + QJsonArray jsonStatus; + foreach (Status s, this->status) { + jsonStatus.append(s.toJson()); + } + QJsonArray jsonBoards; + foreach (Board *b, this->boards) { + jsonBoards.append(b->toJson()); + } + obj[PRIORITIES_KEY] = jsonPriorities; + obj[STATUS_KEY] = jsonStatus; + obj[BOARDS_KEY] = jsonBoards; + doc.setObject(obj); + return doc; +} + void MainWindow::redrawBoardList() { QListWidget *l = ui->listWidget; - for (uint16_t i = 0; i < l->count(); i++) + uint16_t itemCount = l->count(); + for (int16_t i = itemCount; i >= 0; i--) { delete l->takeItem(i); } @@ -245,7 +305,8 @@ void MainWindow::redrawBoardList() void MainWindow::redrawTaskTree() { QTreeWidget *l = ui->treeWidget; - for (uint16_t i = 0; i < l->topLevelItemCount(); i++) + uint16_t itemCount = l->topLevelItemCount(); + for (int16_t i = itemCount; i >= 0; i--) { delete l->takeTopLevelItem(i); } @@ -282,3 +343,12 @@ void MainWindow::redrawTaskTree() } +void MainWindow::save() +{ + QJsonDocument doc = getJsonSave(); + if (!Tools::writeSaveToFile(doc)) + { + QMessageBox::critical(this, "Failed to save", "Failed to write the save to the file", QMessageBox::StandardButton::Ok); + } +} + diff --git a/src/frames/mainwindow.h b/src/frames/mainwindow.h index e19c33e..a24726b 100644 --- a/src/frames/mainwindow.h +++ b/src/frames/mainwindow.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "../models/priority.h" #include "../models/status.h" @@ -32,6 +33,8 @@ private slots: private: Ui::MainWindow *ui; + void init(); + int16_t selectedBoardIndex; QVector priorities; QVector status; @@ -46,7 +49,10 @@ private: const QColor getPriorityColor(QString uuid, QColor defaultColor); const QColor getStatusColor(QString uuid, QColor defaultColor); + const QJsonDocument getJsonSave(); + void redrawBoardList(); void redrawTaskTree(); + void save(); }; #endif // MAINWINDOW_H diff --git a/src/frames/prefdialog.cpp b/src/frames/prefdialog.cpp index 6daac64..1935909 100644 --- a/src/frames/prefdialog.cpp +++ b/src/frames/prefdialog.cpp @@ -47,10 +47,10 @@ PrefDialog::~PrefDialog() QVector PrefDialog::getPriorities() { - int count = ui->priorityListWidget->count(); + uint16_t count = ui->priorityListWidget->count(); QVector res; - for (int i = 0; i < count; i++) + for (uint16_t i = 0; i < count; i++) { QListWidgetItem *item = ui->priorityListWidget->item(i); Priority p(priorityUUIDRef[i], item->text(), item->background().color()); @@ -62,10 +62,10 @@ QVector PrefDialog::getPriorities() QVector PrefDialog::getStatus() { - int count = ui->statusListWidget->count(); + uint16_t count = ui->statusListWidget->count(); QVector res; - for (int i = 0; i < count; i++) + for (uint16_t i = 0; i < count; i++) { QListWidgetItem *item = ui->statusListWidget->item(i); Status s(statusUUIDRef[i], item->text(), item->background().color()); diff --git a/src/models/board.cpp b/src/models/board.cpp index 3e2f9d9..62d37aa 100644 --- a/src/models/board.cpp +++ b/src/models/board.cpp @@ -1,10 +1,25 @@ #include "board.h" +#define NAME_KEY "name" +#define TASKS_KEY "tasks" + +#include +#include + Board::Board(QString name) { this->name = name; } +Board::Board(QJsonObject obj) +{ + this->name = obj[NAME_KEY].toString(); + foreach (QJsonValue value, obj[TASKS_KEY].toArray()) { + Task *t = new Task(value.toObject()); + this->tasks.append(t); + } +} + Board::~Board() { for (uint16_t i = 0; i < tasks.count(); i++) @@ -38,3 +53,15 @@ const QVector Board::getTasks() return tasks; } +const QJsonObject Board::toJson() +{ + QJsonArray array; + foreach (Task *t, this->tasks) { + array.append(t->toJson()); + } + QJsonObject obj; + obj[NAME_KEY] = this->name; + obj[TASKS_KEY] = array; + return obj; +} + diff --git a/src/models/board.h b/src/models/board.h index e40bbad..3979dfd 100644 --- a/src/models/board.h +++ b/src/models/board.h @@ -3,6 +3,7 @@ #include #include +#include #include "task.h" @@ -10,6 +11,7 @@ class Board { public: Board(QString name); + Board(QJsonObject); ~Board(); const QString getName(); @@ -17,6 +19,8 @@ public: Task *taskAt(uint16_t); const QVector getTasks(); + const QJsonObject toJson(); + private: QVector tasks; QString name; diff --git a/src/models/priority.cpp b/src/models/priority.cpp index 2507636..59460f7 100644 --- a/src/models/priority.cpp +++ b/src/models/priority.cpp @@ -1,5 +1,9 @@ #include "priority.h" +#define UUID_KEY "uuid" +#define NAME_KEY "name" +#define COLOR_KEY "color" + Priority::Priority(QString uuid, QString name, QColor color) { this->uuid = uuid; @@ -7,6 +11,13 @@ Priority::Priority(QString uuid, QString name, QColor color) this->color = color; } +Priority::Priority(QJsonObject obj) +{ + this->uuid = obj[UUID_KEY].toString(); + this->name = obj[NAME_KEY].toString(); + this->color = QColor::fromString(obj[COLOR_KEY].toString()); +} + const QString Priority::getName() { return this->name; @@ -21,3 +32,12 @@ const QColor Priority::getColor() { return this->color; } + +const QJsonObject Priority::toJson() +{ + QJsonObject obj; + obj[UUID_KEY] = this->uuid; + obj[NAME_KEY] = this->name; + obj[COLOR_KEY] = this->color.name(QColor::HexRgb); + return obj; +} diff --git a/src/models/priority.h b/src/models/priority.h index 63a1e5b..7b4e508 100644 --- a/src/models/priority.h +++ b/src/models/priority.h @@ -3,15 +3,18 @@ #include #include +#include class Priority { public: Priority(QString uuid, QString name, QColor color); + Priority(QJsonObject); const QString getName(); const QString getUUID(); const QColor getColor(); + const QJsonObject toJson(); private: QString uuid; diff --git a/src/models/status.cpp b/src/models/status.cpp index 0bce06b..f78b6f3 100644 --- a/src/models/status.cpp +++ b/src/models/status.cpp @@ -1,5 +1,9 @@ #include "status.h" +#define UUID_KEY "uuid" +#define NAME_KEY "name" +#define COLOR_KEY "color" + Status::Status(QString uuid, QString name, QColor color) { this->uuid = uuid; @@ -7,6 +11,13 @@ Status::Status(QString uuid, QString name, QColor color) this->color = color; } +Status::Status(QJsonObject obj) +{ + this->uuid = obj[UUID_KEY].toString(); + this->name = obj[NAME_KEY].toString(); + this->color = QColor::fromString(obj[COLOR_KEY].toString()); +} + const QString Status::getName() { return this->name; @@ -21,3 +32,12 @@ const QColor Status::getColor() { return this->color; } + +const QJsonObject Status::toJson() +{ + QJsonObject obj; + obj[UUID_KEY] = this->uuid; + obj[NAME_KEY] = this->name; + obj[COLOR_KEY] = this->color.name(QColor::HexRgb); + return obj; +} diff --git a/src/models/status.h b/src/models/status.h index e4d7fc1..16bec9c 100644 --- a/src/models/status.h +++ b/src/models/status.h @@ -3,15 +3,18 @@ #include #include +#include class Status { public: Status(QString uuid, QString name, QColor color); + Status(QJsonObject); const QString getName(); const QString getUUID(); const QColor getColor(); + const QJsonObject toJson(); private: QString uuid; diff --git a/src/models/task.cpp b/src/models/task.cpp index 7d56906..eb36cae 100644 --- a/src/models/task.cpp +++ b/src/models/task.cpp @@ -1,5 +1,11 @@ #include "task.h" +#define TITLE_KEY "title" +#define DESCRIPTION_KEY "description" +#define EXPECTEDFOR_KEY "expected_for" +#define PRIORITY_KEY "priority" +#define STATUS_KEY "status" + Task::Task(QString title, QString description, QDate expectedFor, QString priorityUUID, QString statusUUID) { this->title = title; @@ -9,6 +15,15 @@ Task::Task(QString title, QString description, QDate expectedFor, QString priori this->statusUUID = statusUUID; } +Task::Task(QJsonObject obj) +{ + this->title = obj[TITLE_KEY].toString(); + this->description = obj[DESCRIPTION_KEY].toString(); + this->expectedFor = QDate::fromString(obj[EXPECTEDFOR_KEY].toString(), Qt::DateFormat::ISODate); + this->priorityUUID = obj[PRIORITY_KEY].toString(); + this->statusUUID = obj[STATUS_KEY].toString(); +} + const QString Task::getTitle() { return this->title; @@ -34,6 +49,17 @@ const QString Task::getStatusUUID() return this->statusUUID; } +const QJsonObject Task::toJson() +{ + QJsonObject obj; + obj[TITLE_KEY] = this->title; + obj[DESCRIPTION_KEY] = this->description; + obj[EXPECTEDFOR_KEY] = this->expectedFor.toString(Qt::DateFormat::ISODate); + obj[PRIORITY_KEY] = this->priorityUUID; + obj[STATUS_KEY] = this->statusUUID; + return obj; +} + void Task::update(Task t) { this->title = t.title; diff --git a/src/models/task.h b/src/models/task.h index 75606e3..c07cc84 100644 --- a/src/models/task.h +++ b/src/models/task.h @@ -3,17 +3,20 @@ #include #include +#include class Task { public: Task(QString title, QString description, QDate expectedFor, QString priorityUUID, QString statusUUID); + Task(QJsonObject); const QString getTitle(); const QString getDescription(); const QDate getExpectedFor(); const QString getPriorityUUID(); const QString getStatusUUID(); + const QJsonObject toJson(); void update(Task); diff --git a/src/tools.cpp b/src/tools.cpp index 99a7284..8b9f174 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -3,13 +3,17 @@ #define BRIGHTNESS_THRESHOLD 170 #define WHITECOLOR 240 #define BLACKCOLOR 15 +#define FILENAME "data.json" + +#include +#include Tools::Tools() { } -QColor Tools::getRandomColor() +const QColor Tools::getRandomColor() { srand(time(0)); #ifdef __linux__ @@ -24,24 +28,12 @@ QColor Tools::getRandomColor() return QColor(r, g, b); } -QColor Tools::getForegroundColor(QColor background) +const QColor Tools::getForegroundColor(QColor background) { - uint8_t avg = background.red(); - avg += background.green(); - avg += background.blue(); - avg = avg / 3; - - uint8_t avg2 = background.red(); - avg2 += background.green(); - avg2 = avg2 / 2; - - uint8_t avg3 = background.red(); - avg3 += background.blue(); - avg3 = avg3 / 2; - - uint8_t avg4 = background.green(); - avg4 += background.blue(); - avg4 = avg4 / 2; + uint8_t avg = (background.red() + background.green() + background.blue()) / 3; + uint8_t avg2 = (background.red() + background.green()) / 2; + uint8_t avg3 = (background.red() + background.blue()) / 2; + uint8_t avg4 = (background.green() + background.blue()) / 2; if (avg < BRIGHTNESS_THRESHOLD && avg2 < BRIGHTNESS_THRESHOLD && avg3 < BRIGHTNESS_THRESHOLD && avg4 < BRIGHTNESS_THRESHOLD) { @@ -52,3 +44,54 @@ QColor Tools::getForegroundColor(QColor background) return QColor(BLACKCOLOR, BLACKCOLOR, BLACKCOLOR); } } + +const QString Tools::getSaveFilePath() { + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (!QDir(path).exists()) + { + QDir().mkpath(path); + } + + path += "/data/"; + if (!QDir(path).exists()) + { + QDir().mkpath(path); + } + path += FILENAME; + return QDir::cleanPath(path); +} + +bool Tools::isSaveFileExist() +{ + return QFile::exists(Tools::getSaveFilePath()); +} + +bool Tools::writeSaveToFile(QJsonDocument doc) +{ + bool success = false; + QFile *f = new QFile(getSaveFilePath()); + if (f->open(QIODevice::WriteOnly)) + { + f->write(doc.toJson()); + f->close(); + success = true; + } + delete f; + return success; +} + +bool Tools::readSaveFile(QJsonDocument &doc) { + QFile* file = new QFile(getSaveFilePath()); + if (!file->open(QIODevice::ReadOnly)) + { + file->close(); + delete file; + return false; + } + QString json = QString(file->readAll()); + file->close(); + delete file; + + doc = QJsonDocument::fromJson(json.toUtf8()); + return true; +} diff --git a/src/tools.h b/src/tools.h index 97e0e22..86ca753 100644 --- a/src/tools.h +++ b/src/tools.h @@ -2,14 +2,21 @@ #define TOOLS_H #include +#include class Tools { public: Tools(); - static QColor getRandomColor(); - static QColor getForegroundColor(QColor background); + static const QColor getRandomColor(); + static const QColor getForegroundColor(QColor background); + static bool isSaveFileExist(); + static bool writeSaveToFile(QJsonDocument doc); + static bool readSaveFile(QJsonDocument &doc); + +private: + static const QString getSaveFilePath(); };