10 Commits

Author SHA1 Message Date
Aurélie Delhaie
69f4ec570a No status option for boards, starting dev general prefs 2023-06-12 17:34:39 +02:00
Aurélie
e961e7642e Merge pull request #1 from mojitaurelie/dev_0.3
v0.3.0
2023-02-21 18:29:54 +01:00
Aurelie Delhaie
22ebe6eded fix out of bound crash when edit or remove a board, add board config dialog, fix glibc version in about dialog 2023-02-20 16:52:05 +01:00
Aurelie Delhaie
93026b1373 Merge branch 'main' into dev_0.3 2023-02-20 15:24:46 +01:00
Aurelie Delhaie
1b56b5eec5 auto determine board status, show board status 2023-02-16 21:53:07 +01:00
Aurélie Delhaie
4c95000b8f compiler version 2023-02-13 08:25:58 +01:00
Aurelie Delhaie
35dee6684f Status and Priority service singleton 2023-02-12 22:33:22 +01:00
Aurelie Delhaie
d0186d0759 aboutbox: linux compiler version 2023-02-12 19:22:06 +01:00
Aurelie Delhaie
3af0771b55 fix context menu, fix filter on boards 2023-02-12 19:06:09 +01:00
Aurélie Delhaie
961dbd8aa0 Fix date column color after update the date 2023-01-29 14:12:34 +01:00
26 changed files with 1080 additions and 199 deletions

View File

@@ -4,8 +4,8 @@ greaterThan(QT_MAJOR_VERSION, 5): QT += widgets
CONFIG += c++17 CONFIG += c++17
win32:VERSION = 0.2.0.0 # major.minor.patch.build win32:VERSION = 0.3.1.0 # major.minor.patch.build
else:VERSION = 0.2.0 # major.minor.patch else:VERSION = 0.3.1 # major.minor.patch
DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\" DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\"
DEFINES += APP_NAME=\"\\\"TaskBoard\\\"\" DEFINES += APP_NAME=\"\\\"TaskBoard\\\"\"
@@ -68,6 +68,7 @@ linux-* {
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \ SOURCES += \
src/frames/boardconfigdialog.cpp \
src/frames/filterdialog.cpp \ src/frames/filterdialog.cpp \
src/frames/aboutdialog.cpp \ src/frames/aboutdialog.cpp \
src/models/board.cpp \ src/models/board.cpp \
@@ -76,13 +77,17 @@ SOURCES += \
src/frames/namedialog.cpp \ src/frames/namedialog.cpp \
src/frames/prefdialog.cpp \ src/frames/prefdialog.cpp \
src/models/filter.cpp \ src/models/filter.cpp \
src/models/generalpreferences.cpp \
src/models/priority.cpp \ src/models/priority.cpp \
src/models/status.cpp \ src/models/status.cpp \
src/models/task.cpp \ src/models/task.cpp \
src/frames/taskdialog.cpp \ src/frames/taskdialog.cpp \
src/services/configservice.cpp \
src/services/taskstateservice.cpp \
src/tools.cpp src/tools.cpp
HEADERS += \ HEADERS += \
src/frames/boardconfigdialog.h \
src/frames/filterdialog.h \ src/frames/filterdialog.h \
src/frames/aboutdialog.h \ src/frames/aboutdialog.h \
src/models/board.h \ src/models/board.h \
@@ -90,13 +95,17 @@ HEADERS += \
src/frames/namedialog.h \ src/frames/namedialog.h \
src/frames/prefdialog.h \ src/frames/prefdialog.h \
src/models/filter.h \ src/models/filter.h \
src/models/generalpreferences.h \
src/models/priority.h \ src/models/priority.h \
src/models/status.h \ src/models/status.h \
src/models/task.h \ src/models/task.h \
src/frames/taskdialog.h \ src/frames/taskdialog.h \
src/services/configservice.h \
src/services/taskstateservice.h \
src/tools.h src/tools.h
FORMS += \ FORMS += \
src/frames/boardconfigdialog.ui \
src/frames/filterdialog.ui \ src/frames/filterdialog.ui \
src/frames/aboutdialog.ui \ src/frames/aboutdialog.ui \
src/frames/mainwindow.ui \ src/frames/mainwindow.ui \

View File

@@ -6,10 +6,13 @@ AboutDialog::AboutDialog(QWidget *parent) :
ui(new Ui::AboutDialog) ui(new Ui::AboutDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
#ifdef APP_ARCH
ui->appName->setText(QString("%1 (%2)").arg(APP_NAME, APP_ARCH)); ui->appName->setText(QString("%1 (%2)").arg(APP_NAME, APP_ARCH));
QString os_version = APP_OS_VERSION; #else
os_version = os_version.replace("-D", ""); ui->appName->setText(APP_NAME);
ui->version->setText(QString("v%1 %2/%3 (qt %4)").arg(APP_VERSION, APP_OS, os_version, QT_VERSION_STR)); #endif
QString compiler = getCompilerInfo();
ui->version->setText(QString("v%1-%3 (qt %4)").arg(APP_VERSION, compiler, QT_VERSION_STR));
ui->textEdit_2->append(QString("Qt Open Source %1").arg(QT_VERSION_STR)); ui->textEdit_2->append(QString("Qt Open Source %1").arg(QT_VERSION_STR));
} }
@@ -17,3 +20,20 @@ AboutDialog::~AboutDialog()
{ {
delete ui; delete ui;
} }
QString AboutDialog::getCompilerInfo()
{
#ifdef __APPLE__
return QString("clang_%1").arg(__clang_version__);
#elif __GNUC__
#ifdef __MINGW32__
return QString("MinGW_%1.%2").arg(QString::number(__MINGW32_MAJOR_VERSION), QString::number(__MINGW32_MINOR_VERSION));
#else
return QString("GLIBC_%1.%2").arg(QString::number(__GLIBC__), QString::number(__GLIBC_MINOR__));
#endif
#elif _MSC_VER
return QString("MSVC_%1").arg(_MSC_VER);
#else
return "unknown";
#endif
}

View File

@@ -2,6 +2,7 @@
#define ABOUTDIALOG_H #define ABOUTDIALOG_H
#include <QDialog> #include <QDialog>
#include <QString>
namespace Ui { namespace Ui {
class AboutDialog; class AboutDialog;
@@ -17,6 +18,7 @@ public:
private: private:
Ui::AboutDialog *ui; Ui::AboutDialog *ui;
QString getCompilerInfo();
}; };
#endif // ABOUTDIALOG_H #endif // ABOUTDIALOG_H

View File

@@ -0,0 +1,75 @@
#include "boardconfigdialog.h"
#include "ui_boardconfigdialog.h"
#include "../services/taskstateservice.h"
#include <QVector>
BoardConfigDialog::BoardConfigDialog(Board *b, QWidget *parent) :
QDialog(parent),
ui(new Ui::BoardConfigDialog)
{
ui->setupUi(this);
ui->nameField->setText(b->getName());
ui->descriptionField->setPlainText(b->getDescription());
ui->boardStatusModeComboBox->setCurrentIndex(b->getStatusMode());
if (b->getStatusMode() == CUSTOM_STATUS_MODE)
{
QVector<Status> statuses = TaskStateService::getInstance()->getStatuses();
foreach (Status s, statuses)
{
ui->statusCombobox->addItem(s.getName(), s.getUUID());
}
ui->statusCombobox->setEnabled(true);
}
connect(ui->boardStatusModeComboBox, &QComboBox::currentIndexChanged, this, &BoardConfigDialog::onAutoStatusCheckboxChange);
}
BoardConfigDialog::~BoardConfigDialog()
{
delete ui;
}
const QString BoardConfigDialog::getName()
{
return ui->nameField->text();
}
const QString BoardConfigDialog::getDescription()
{
return ui->descriptionField->toPlainText();
}
uint8_t BoardConfigDialog::getBoardStatusMode()
{
return ui->boardStatusModeComboBox->currentIndex();
}
const QString BoardConfigDialog::getStatus()
{
if (ui->boardStatusModeComboBox->currentIndex() == CUSTOM_STATUS_MODE)
{
if (!ui->statusCombobox->currentData().isNull())
{
return ui->statusCombobox->currentData().toString();
}
}
return "";
}
void BoardConfigDialog::onAutoStatusCheckboxChange(int status)
{
if (status == CUSTOM_STATUS_MODE)
{
QVector<Status> statuses = TaskStateService::getInstance()->getStatuses();
foreach (Status s, statuses)
{
ui->statusCombobox->addItem(s.getName(), s.getUUID());
}
ui->statusCombobox->setEnabled(true);
}
else
{
ui->statusCombobox->setEnabled(false);
ui->statusCombobox->clear();
}
}

View File

@@ -0,0 +1,32 @@
#ifndef BOARDCONFIGDIALOG_H
#define BOARDCONFIGDIALOG_H
#include <QDialog>
#include "../models/board.h"
namespace Ui {
class BoardConfigDialog;
}
class BoardConfigDialog : public QDialog
{
Q_OBJECT
public:
explicit BoardConfigDialog(Board *b, QWidget *parent = nullptr);
~BoardConfigDialog();
const QString getName();
const QString getDescription();
uint8_t getBoardStatusMode();
const QString getStatus();
private slots:
void onAutoStatusCheckboxChange(int);
private:
Ui::BoardConfigDialog *ui;
};
#endif // BOARDCONFIGDIALOG_H

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BoardConfigDialog</class>
<widget class="QDialog" name="BoardConfigDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>379</height>
</rect>
</property>
<property name="windowTitle">
<string>Board Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nameField"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="descriptionField"/>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Board status mode</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="boardStatusModeComboBox">
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>Manual</string>
</property>
</item>
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="statusContainer">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Status</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="statusCombobox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>BoardConfigDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>BoardConfigDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -3,22 +3,24 @@
#include <QMessageBox> #include <QMessageBox>
FilterDialog::FilterDialog(QString dialogTitle, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent) : #include "../services/taskstateservice.h"
FilterDialog::FilterDialog(QString dialogTitle, QVector<Board*> boards, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::FilterDialog) ui(new Ui::FilterDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
this->setWindowTitle(dialogTitle); this->setWindowTitle(dialogTitle);
init(boards, status, priorities); init(boards);
} }
FilterDialog::FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent) : FilterDialog::FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::FilterDialog) ui(new Ui::FilterDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
this->setWindowTitle(dialogTitle); this->setWindowTitle(dialogTitle);
init(boards, status, priorities); init(boards);
ui->nameEdit->setText(f.getName()); ui->nameEdit->setText(f.getName());
ui->descriptionEdit->setPlainText(f.getDescription()); ui->descriptionEdit->setPlainText(f.getDescription());
@@ -59,7 +61,7 @@ FilterDialog::FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards
} }
void FilterDialog::init(QVector<Board *> boards, QVector<Status> status, QVector<Priority> priorities) void FilterDialog::init(QVector<Board *> boards)
{ {
for (Board *b : boards) for (Board *b : boards)
{ {
@@ -71,7 +73,8 @@ void FilterDialog::init(QVector<Board *> boards, QVector<Status> status, QVector
ui->boardListWidget->addItem(item); ui->boardListWidget->addItem(item);
} }
for (Status s : status) QVector<Status> statuses = TaskStateService::getInstance()->getStatuses();
for (Status s : statuses)
{ {
QListWidgetItem *item = new QListWidgetItem(); QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
@@ -81,6 +84,7 @@ void FilterDialog::init(QVector<Board *> boards, QVector<Status> status, QVector
ui->statusListWidget->addItem(item); ui->statusListWidget->addItem(item);
} }
QVector<Priority> priorities = TaskStateService::getInstance()->getPriorities();
for (Priority p : priorities) for (Priority p : priorities)
{ {
QListWidgetItem *item = new QListWidgetItem(); QListWidgetItem *item = new QListWidgetItem();
@@ -137,7 +141,7 @@ const Filter FilterDialog::getFilter()
void FilterDialog::validateAndAccept() void FilterDialog::validateAndAccept()
{ {
if (ui->nameEdit->text().count() == 0) if (ui->nameEdit->text().length() == 0)
{ {
QMessageBox::critical(this, "This filter needs a name", "You need to enter a name to save this filter"); QMessageBox::critical(this, "This filter needs a name", "You need to enter a name to save this filter");
return; return;

View File

@@ -17,8 +17,8 @@ class FilterDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit FilterDialog(QString dialogTitle, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent = nullptr); explicit FilterDialog(QString dialogTitle, QVector<Board*> boards, QWidget *parent = nullptr);
FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent = nullptr); FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards, QWidget *parent = nullptr);
~FilterDialog(); ~FilterDialog();
const Filter getFilter(); const Filter getFilter();
@@ -28,7 +28,7 @@ private slots:
private: private:
Ui::FilterDialog *ui; Ui::FilterDialog *ui;
void init(QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities); void init(QVector<Board*> boards);
}; };
#endif // FILTERDIALOG_H #endif // FILTERDIALOG_H

View File

@@ -17,13 +17,19 @@
#include "namedialog.h" #include "namedialog.h"
#include "taskdialog.h" #include "taskdialog.h"
#include "filterdialog.h" #include "filterdialog.h"
#include "boardconfigdialog.h"
#include "../tools.h" #include "../tools.h"
#include "../services/taskstateservice.h"
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->boardStatus->setVisible(false);
this->menuSelectedBoardItem = nullptr;
this->menuSelectedFilterItem = nullptr;
this->menuSelectedTaskItem = nullptr;
init(); init();
this->selectedBoardIndex = -1; this->selectedBoardIndex = -1;
// Change "name" column size // Change "name" column size
@@ -58,11 +64,11 @@ MainWindow::~MainWindow()
void MainWindow::openPreferences() void MainWindow::openPreferences()
{ {
PrefDialog dialog(status, priorities, this); PrefDialog dialog(this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
this->priorities = dialog.getPriorities(); TaskStateService::getInstance()->updatePriorities(dialog.getPriorities());
this->status = dialog.getStatus(); TaskStateService::getInstance()->updateStatuses(dialog.getStatus());
save(); save();
redrawTaskTree(); redrawTaskTree();
} }
@@ -77,7 +83,8 @@ void MainWindow::openAbout()
void MainWindow::prepareBoardMenu(const QPoint &pos) void MainWindow::prepareBoardMenu(const QPoint &pos)
{ {
QMenu menu(this); QMenu menu(this);
if (ui->boardList->selectedItems().length() == 1) { this->menuSelectedBoardItem = ui->boardList->itemAt(pos);
if (this->menuSelectedBoardItem != nullptr) {
QAction *renameAction = new QAction(tr("Edit board"), this); QAction *renameAction = new QAction(tr("Edit board"), this);
connect(renameAction, &QAction::triggered, this, &MainWindow::onEditNameBoardMenu); connect(renameAction, &QAction::triggered, this, &MainWindow::onEditNameBoardMenu);
menu.addAction(renameAction); menu.addAction(renameAction);
@@ -99,15 +106,19 @@ void MainWindow::prepareTaskMenu(const QPoint &pos)
{ {
bool show = false; bool show = false;
QMenu menu(this); QMenu menu(this);
if (ui->taskList->selectedItems().length() == 1) { this->menuSelectedTaskItem = ui->taskList->itemAt(pos);
if (menuSelectedTaskItem != nullptr) {
show = true; show = true;
QAction *renameAction = new QAction(tr("Edit the task"), this); QAction *renameAction = new QAction(tr("Edit the task"), this);
connect(renameAction, &QAction::triggered, this, &MainWindow::onEditNameTaskMenu); connect(renameAction, &QAction::triggered, this, &MainWindow::onEditNameTaskMenu);
menu.addAction(renameAction); menu.addAction(renameAction);
if (selectedBoardIndex > -1)
{
QAction *deleteAction = new QAction(tr("Delete from the board"), this); QAction *deleteAction = new QAction(tr("Delete from the board"), this);
connect(deleteAction, &QAction::triggered, this, &MainWindow::onRemoveTaskMenu); connect(deleteAction, &QAction::triggered, this, &MainWindow::onRemoveTaskMenu);
menu.addAction(deleteAction); menu.addAction(deleteAction);
}
menu.addSeparator(); menu.addSeparator();
} }
@@ -145,7 +156,7 @@ void MainWindow::onNewTaskClick()
{ {
if (selectedBoardIndex > -1) if (selectedBoardIndex > -1)
{ {
TaskDialog dialog(status, priorities, this); TaskDialog dialog(this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
Task t = dialog.getTask(); Task t = dialog.getTask();
@@ -161,7 +172,7 @@ void MainWindow::onNewTaskClick()
void MainWindow::onNewFilterClick() void MainWindow::onNewFilterClick()
{ {
FilterDialog dialog("New filter", boards, status, priorities, this); FilterDialog dialog("New filter", boards, this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
Filter f = dialog.getFilter(); Filter f = dialog.getFilter();
@@ -187,7 +198,16 @@ void MainWindow::onBoardSelected(int i)
{ {
Board *b = boards[selectedBoardIndex]; Board *b = boards[selectedBoardIndex];
ui->label->setText(b->getName()); ui->label->setText(b->getName());
if (b->getDescription().length() > 0)
{
ui->boardDescription->setText(b->getDescription()); ui->boardDescription->setText(b->getDescription());
ui->boardDescription->setEnabled(true);
}
else
{
ui->boardDescription->setText("No description");
ui->boardDescription->setEnabled(false);
}
ui->actionNew_task->setDisabled(false); ui->actionNew_task->setDisabled(false);
} }
else else
@@ -214,7 +234,16 @@ void MainWindow::onFilterSelected(int i)
{ {
Filter f = filters[selectedFilterIndex]; Filter f = filters[selectedFilterIndex];
ui->label->setText(f.getName()); ui->label->setText(f.getName());
if (f.getDescription().length() > 0)
{
ui->boardDescription->setText(f.getDescription()); ui->boardDescription->setText(f.getDescription());
ui->boardDescription->setEnabled(true);
}
else
{
ui->boardDescription->setText("No description");
ui->boardDescription->setEnabled(false);
}
} }
else else
{ {
@@ -229,13 +258,14 @@ void MainWindow::onEditTask(QTreeWidgetItem *item)
Task *t = getSelectedTask(); Task *t = getSelectedTask();
if (t != nullptr) if (t != nullptr)
{ {
TaskDialog dialog(t, status, priorities, this); TaskDialog dialog(t, this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
Task editedTask = dialog.getTask(); Task editedTask = dialog.getTask();
t->update(editedTask); t->update(editedTask);
updateTaskRow(item, editedTask); updateTaskRow(item, editedTask);
save(); save();
redrawBoardStatus();
if (selectedFilterIndex > -1) if (selectedFilterIndex > -1)
{ {
redrawTaskTree(); redrawTaskTree();
@@ -246,14 +276,22 @@ void MainWindow::onEditTask(QTreeWidgetItem *item)
void MainWindow::onRemoveBoardMenu() void MainWindow::onRemoveBoardMenu()
{ {
if (selectedBoardIndex > -1) if (menuSelectedBoardItem != nullptr)
{ {
int i = ui->boardList->indexFromItem(menuSelectedBoardItem).row();
if (i == -1)
{
return;
}
QMessageBox::StandardButton result = QMessageBox::question(this, "Delete a board", "Do you want to delete this board?"); QMessageBox::StandardButton result = QMessageBox::question(this, "Delete a board", "Do you want to delete this board?");
if (result == QMessageBox::Yes) if (result == QMessageBox::Yes)
{ {
boards.removeAt(selectedBoardIndex); boards.removeAt(i);
delete ui->boardList->takeItem(selectedBoardIndex); delete ui->boardList->takeItem(i);
if (selectedBoardIndex == i)
{
selectedBoardIndex = -1; selectedBoardIndex = -1;
}
redrawTaskTree(); redrawTaskTree();
save(); save();
} }
@@ -278,14 +316,22 @@ void MainWindow::onRemoveTaskMenu()
void MainWindow::onRemoveFilterMenu() void MainWindow::onRemoveFilterMenu()
{ {
if (selectedFilterIndex > -1) if (menuSelectedFilterItem != nullptr)
{ {
int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row();
if (i == -1)
{
return;
}
QMessageBox::StandardButton result = QMessageBox::question(this, "Delete a filter", "Do you want to delete this filter?"); QMessageBox::StandardButton result = QMessageBox::question(this, "Delete a filter", "Do you want to delete this filter?");
if (result == QMessageBox::Yes) if (result == QMessageBox::Yes)
{ {
filters.removeAt(selectedFilterIndex); filters.removeAt(i);
delete ui->filterListWidget->takeItem(selectedFilterIndex); delete ui->filterListWidget->takeItem(i);
if (selectedFilterIndex == i)
{
selectedFilterIndex = -1; selectedFilterIndex = -1;
}
redrawTaskTree(); redrawTaskTree();
save(); save();
} }
@@ -294,21 +340,42 @@ void MainWindow::onRemoveFilterMenu()
void MainWindow::onEditNameBoardMenu() void MainWindow::onEditNameBoardMenu()
{ {
if (selectedBoardIndex > -1) if (menuSelectedBoardItem != nullptr)
{ {
Board *b = boards.at(selectedBoardIndex); int i = ui->boardList->indexFromItem(menuSelectedBoardItem).row();
NameDialog dialog("Edit board name", b->getName(), b->getDescription(), this); if (i == -1)
{
return;
}
Board *b = boards.at(i);
BoardConfigDialog dialog(b, this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
QString newName = dialog.getChoosenName(); QString newName = dialog.getName();
QString newDesc = dialog.getDescription(); QString newDesc = dialog.getDescription();
b->setName(newName); b->setName(newName);
b->setDescription(newDesc); b->setDescription(newDesc);
QListWidgetItem *item = ui->boardList->item(selectedBoardIndex); std::optional<Status> status = TaskStateService::getInstance()->getStatusByUUID(dialog.getStatus());
if (status.has_value())
{
b->setStatus(status.value());
}
b->setStatusMode(dialog.getBoardStatusMode());
QListWidgetItem *item = ui->boardList->item(i);
item->setText(newName); item->setText(newName);
item->setToolTip(newDesc); item->setToolTip(newDesc);
ui->label->setText(newName); ui->label->setText(newName);
if (newDesc.length() > 0)
{
ui->boardDescription->setText(newDesc); ui->boardDescription->setText(newDesc);
ui->boardDescription->setEnabled(true);
}
else
{
ui->boardDescription->setText("No description");
ui->boardDescription->setEnabled(false);
}
redrawBoardStatus();
save(); save();
} }
} }
@@ -325,10 +392,11 @@ void MainWindow::onEditNameTaskMenu()
void MainWindow::onEditFilterMenu() void MainWindow::onEditFilterMenu()
{ {
if (selectedFilterIndex > -1) if (menuSelectedFilterItem != nullptr)
{ {
Filter f = filters[selectedFilterIndex]; int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row();
FilterDialog dialog("Edit the filter", f, boards, status, priorities, this); Filter f = filters[i];
FilterDialog dialog("Edit the filter", f, boards, this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
Filter f = dialog.getFilter(); Filter f = dialog.getFilter();
@@ -337,7 +405,16 @@ void MainWindow::onEditFilterMenu()
item->setText(f.getName()); item->setText(f.getName());
item->setToolTip(f.getDescription()); item->setToolTip(f.getDescription());
ui->label->setText(f.getName()); ui->label->setText(f.getName());
if (f.getDescription().length() > 0)
{
ui->boardDescription->setText(f.getDescription()); ui->boardDescription->setText(f.getDescription());
ui->boardDescription->setEnabled(true);
}
else
{
ui->boardDescription->setText("No description");
ui->boardDescription->setEnabled(false);
}
redrawTaskTree(); redrawTaskTree();
save(); save();
} }
@@ -347,7 +424,8 @@ void MainWindow::onEditFilterMenu()
void MainWindow::prepareFilterMenu(const QPoint &pos) void MainWindow::prepareFilterMenu(const QPoint &pos)
{ {
QMenu menu(this); QMenu menu(this);
if (ui->filterListWidget->selectedItems().length() == 1) { this->menuSelectedFilterItem = ui->filterListWidget->itemAt(pos);
if (this->menuSelectedFilterItem != nullptr) {
QAction *renameAction = new QAction(tr("Edit the filter"), this); QAction *renameAction = new QAction(tr("Edit the filter"), this);
connect(renameAction, &QAction::triggered, this, &MainWindow::onEditFilterMenu); connect(renameAction, &QAction::triggered, this, &MainWindow::onEditFilterMenu);
menu.addAction(renameAction); menu.addAction(renameAction);
@@ -377,13 +455,15 @@ void MainWindow::init()
QJsonArray jsonStatus = save[STATUS_KEY].toArray(); QJsonArray jsonStatus = save[STATUS_KEY].toArray();
QJsonArray jsonBoards = save[BOARDS_KEY].toArray(); QJsonArray jsonBoards = save[BOARDS_KEY].toArray();
QJsonArray jsonFilters = save[FILTERS_KEY].toArray(); QJsonArray jsonFilters = save[FILTERS_KEY].toArray();
QVector<Priority> priorities;
QVector<Status> statuses;
for (QJsonValueRef value : jsonPriorities) for (QJsonValueRef value : jsonPriorities)
{ {
priorities.append(Priority(value.toObject())); priorities.append(Priority(value.toObject()));
} }
for (QJsonValueRef value : jsonStatus) for (QJsonValueRef value : jsonStatus)
{ {
status.append(Status(value.toObject())); statuses.append(Status(value.toObject()));
} }
for (QJsonValueRef value : jsonBoards) for (QJsonValueRef value : jsonBoards)
{ {
@@ -393,35 +473,16 @@ void MainWindow::init()
{ {
filters.append(Filter(value.toObject())); filters.append(Filter(value.toObject()));
} }
TaskStateService::getInstance()->updatePriorities(priorities);
TaskStateService::getInstance()->updateStatuses(statuses);
redrawFilterList(); redrawFilterList();
redrawBoardList(); redrawBoardList();
return; return;
} }
} }
this->priorities = defaultPriorities();
this->status = defaultStatus();
save(); save();
} }
QVector<Priority> MainWindow::defaultPriorities()
{
QVector<Priority> res;
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "None", QColor(217, 217, 217)));
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Low", QColor(48, 157, 176)));
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Medium", QColor(176, 142, 48)));
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "High", QColor(176, 67, 48)));
return res;
}
QVector<Status> MainWindow::defaultStatus()
{
QVector<Status> res;
res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "To Do", QColor(143, 143, 143)));
res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Working on", QColor(95, 48, 176)));
res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Completed", QColor(48, 176, 73)));
return res;
}
QVector<Filter> MainWindow::defaultFilters() QVector<Filter> MainWindow::defaultFilters()
{ {
QVector<Filter> res; QVector<Filter> res;
@@ -430,54 +491,42 @@ QVector<Filter> MainWindow::defaultFilters()
const QString MainWindow::getPriorityLabel(QString uuid) const QString MainWindow::getPriorityLabel(QString uuid)
{ {
QString res = ""; std::optional<Priority> p = TaskStateService::getInstance()->getPriorityByUUID(uuid);
foreach (Priority p, priorities) if (p.has_value())
{ {
if (p.getUUID() == uuid) return p.value().getName();
{
res = p.getName();
} }
} return "";
return res;
} }
const QString MainWindow::getStatusLabel(QString uuid) const QString MainWindow::getStatusLabel(QString uuid)
{ {
QString res = ""; std::optional<Status> s = TaskStateService::getInstance()->getStatusByUUID(uuid);
foreach (Status s, status) if (s.has_value())
{ {
if (s.getUUID() == uuid) return s.value().getName();
{
res = s.getName();
} }
} return "";
return res;
} }
const QColor MainWindow::getPriorityColor(QString uuid, QColor defaultColor) const QColor MainWindow::getPriorityColor(QString uuid, QColor defaultColor)
{ {
QColor color = defaultColor; std::optional<Priority> p = TaskStateService::getInstance()->getPriorityByUUID(uuid);
foreach (Priority p, priorities) if (p.has_value())
{ {
if (p.getUUID() == uuid) return p.value().getColor();
{
color = p.getColor();
} }
} return defaultColor;
return color;
} }
const QColor MainWindow::getStatusColor(QString uuid, QColor defaultColor) const QColor MainWindow::getStatusColor(QString uuid, QColor defaultColor)
{ {
QColor color = defaultColor; std::optional<Status> s = TaskStateService::getInstance()->getStatusByUUID(uuid);
foreach (Status s, status) if (s.has_value())
{ {
if (s.getUUID() == uuid) return s.value().getColor();
{
color = s.getColor();
} }
} return defaultColor;
return color;
} }
const QJsonDocument MainWindow::getJsonSave() const QJsonDocument MainWindow::getJsonSave()
@@ -485,18 +534,24 @@ const QJsonDocument MainWindow::getJsonSave()
QJsonDocument doc; QJsonDocument doc;
QJsonObject obj; QJsonObject obj;
QJsonArray jsonPriorities; QJsonArray jsonPriorities;
foreach (Priority p, this->priorities) { QJsonArray jsonStatus;
QJsonArray jsonBoards;
QJsonArray jsonFilters;
QVector<Priority> priorities = TaskStateService::getInstance()->getPriorities();
foreach (Priority p, priorities) {
jsonPriorities.append(p.toJson()); jsonPriorities.append(p.toJson());
} }
QJsonArray jsonStatus;
foreach (Status s, this->status) { QVector<Status> statuses = TaskStateService::getInstance()->getStatuses();
foreach (Status s, statuses) {
jsonStatus.append(s.toJson()); jsonStatus.append(s.toJson());
} }
QJsonArray jsonBoards;
foreach (Board *b, this->boards) { foreach (Board *b, this->boards) {
jsonBoards.append(b->toJson()); jsonBoards.append(b->toJson());
} }
QJsonArray jsonFilters;
foreach (Filter f, this->filters) foreach (Filter f, this->filters)
{ {
jsonFilters.append(f.toJson()); jsonFilters.append(f.toJson());
@@ -511,28 +566,26 @@ const QJsonDocument MainWindow::getJsonSave()
Task *MainWindow::getSelectedTask() Task *MainWindow::getSelectedTask()
{ {
QList<QTreeWidgetItem*> items = ui->taskList->selectedItems();
if (items.count() != 1)
{
return nullptr;
}
if (selectedBoardIndex > -1) if (selectedBoardIndex > -1)
{ {
Board *b = boards[selectedBoardIndex]; Board *b = boards[selectedBoardIndex];
QList<QTreeWidgetItem*> items = ui->taskList->selectedItems();
if (items.count() == 1)
{
int16_t i = ui->taskList->indexOfTopLevelItem(items[0]); int16_t i = ui->taskList->indexOfTopLevelItem(items[0]);
return b->taskAt(i); return b->taskAt(i);
} }
}
else if (selectedFilterIndex > -1) else if (selectedFilterIndex > -1)
{ {
if (!filterResult.empty()) if (!filterResult.empty())
{
QList<QTreeWidgetItem*> items = ui->taskList->selectedItems();
if (items.count() == 1)
{ {
int16_t i = ui->taskList->indexOfTopLevelItem(items[0]); int16_t i = ui->taskList->indexOfTopLevelItem(items[0]);
return filterResult[i]; return filterResult[i];
} }
} }
}
return nullptr; return nullptr;
} }
@@ -556,6 +609,12 @@ void MainWindow::updateTaskRow(QTreeWidgetItem *item, Task t)
fgColor.setStyle(Qt::BrushStyle::SolidPattern); fgColor.setStyle(Qt::BrushStyle::SolidPattern);
item->setForeground(3, fgColor); item->setForeground(3, fgColor);
} }
else
{
QBrush fgColor = item->foreground(3);
fgColor.setStyle(Qt::BrushStyle::NoBrush);
item->setForeground(3, fgColor);
}
if (!t.getStatusUUID().isEmpty()) if (!t.getStatusUUID().isEmpty())
{ {
@@ -628,6 +687,13 @@ void MainWindow::redrawTaskTree()
if (selectedBoardIndex > -1) if (selectedBoardIndex > -1)
{ {
Board *b = boards[selectedBoardIndex]; Board *b = boards[selectedBoardIndex];
std::optional<Status> boardStatus = TaskStateService::getInstance()->getStatusByUUID(b->getStatus());
if (boardStatus.has_value())
{
ui->boardStatus->setStyleSheet(Tools::getStatusLabelStylesheet(boardStatus.value()));
ui->boardStatus->setText(boardStatus.value().getName());
ui->boardStatus->setVisible(true);
}
foreach (Task *t, b->getTasks()) foreach (Task *t, b->getTasks())
{ {
QTreeWidgetItem *item = new QTreeWidgetItem(); QTreeWidgetItem *item = new QTreeWidgetItem();
@@ -646,6 +712,23 @@ void MainWindow::redrawTaskTree()
ui->taskList->addTopLevelItem(item); ui->taskList->addTopLevelItem(item);
} }
} }
redrawBoardStatus();
}
void MainWindow::redrawBoardStatus()
{
ui->boardStatus->setVisible(false);
if (selectedBoardIndex > -1)
{
Board *b = boards[selectedBoardIndex];
std::optional<Status> boardStatus = TaskStateService::getInstance()->getStatusByUUID(b->getStatus());
if (boardStatus.has_value())
{
ui->boardStatus->setStyleSheet(Tools::getStatusLabelStylesheet(boardStatus.value()));
ui->boardStatus->setText(boardStatus.value().getName());
ui->boardStatus->setVisible(true);
}
}
} }
void MainWindow::save() void MainWindow::save()

View File

@@ -3,6 +3,7 @@
#include <QMainWindow> #include <QMainWindow>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
#include <QListWidgetItem>
#include <QBrush> #include <QBrush>
#include <QJsonDocument> #include <QJsonDocument>
@@ -50,10 +51,12 @@ private:
int16_t selectedBoardIndex; int16_t selectedBoardIndex;
int16_t selectedFilterIndex; int16_t selectedFilterIndex;
QListWidgetItem *menuSelectedFilterItem;
QListWidgetItem *menuSelectedBoardItem;
QTreeWidgetItem *menuSelectedTaskItem;
QVector<Task*> filterResult; QVector<Task*> filterResult;
QVector<Priority> priorities;
QVector<Status> status;
QVector<Board*> boards; QVector<Board*> boards;
QVector<Filter> filters; QVector<Filter> filters;
@@ -75,6 +78,7 @@ private:
void redrawBoardList(); void redrawBoardList();
void redrawFilterList(); void redrawFilterList();
void redrawTaskTree(); void redrawTaskTree();
void redrawBoardStatus();
void save(); void save();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@@ -24,7 +24,7 @@
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
@@ -52,6 +52,9 @@
<height>250</height> <height>250</height>
</size> </size>
</property> </property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@@ -87,6 +90,10 @@
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum> <enum>QLayout::SetMaximumSize</enum>
</property> </property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="font"> <property name="font">
@@ -106,6 +113,39 @@
</property> </property>
</widget> </widget>
</item> </item>
</layout>
</item>
<item>
<widget class="QLabel" name="boardStatus">
<property name="minimumSize">
<size>
<width>100</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>24</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">border-color: rgb(87, 227, 137);
border: solid;
background-color: rgb(87, 227, 137);
border-radius: 4px;
color: white;</string>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QTreeWidget" name="taskList"> <widget class="QTreeWidget" name="taskList">
<property name="alternatingRowColors"> <property name="alternatingRowColors">
@@ -164,6 +204,7 @@
<string>Board</string> <string>Board</string>
</property> </property>
<addaction name="actionNew"/> <addaction name="actionNew"/>
<addaction name="actionNew_filter"/>
</widget> </widget>
<widget class="QMenu" name="menuTask"> <widget class="QMenu" name="menuTask">
<property name="title"> <property name="title">

View File

@@ -5,13 +5,15 @@
#include <QUuid> #include <QUuid>
#include "../tools.h" #include "../tools.h"
#include "../services/taskstateservice.h"
PrefDialog::PrefDialog(QVector<Status> status, QVector<Priority> priorities, QWidget *parent) : PrefDialog::PrefDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::PrefDialog) ui(new Ui::PrefDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
QVector<Status> status = TaskStateService::getInstance()->getStatuses();
foreach (Status s, status) foreach (Status s, status)
{ {
QListWidgetItem *item = new QListWidgetItem(s.getName()); QListWidgetItem *item = new QListWidgetItem(s.getName());
@@ -20,6 +22,7 @@ PrefDialog::PrefDialog(QVector<Status> status, QVector<Priority> priorities, QWi
ui->statusListWidget->addItem(item); ui->statusListWidget->addItem(item);
} }
QVector<Priority> priorities = TaskStateService::getInstance()->getPriorities();
foreach (Priority p, priorities) foreach (Priority p, priorities)
{ {
QListWidgetItem *item = new QListWidgetItem(p.getName()); QListWidgetItem *item = new QListWidgetItem(p.getName());
@@ -38,6 +41,8 @@ PrefDialog::PrefDialog(QVector<Status> status, QVector<Priority> priorities, QWi
connect(ui->namePriorityEdit, &QLineEdit::textEdited, this, &PrefDialog::onNameChange); connect(ui->namePriorityEdit, &QLineEdit::textEdited, this, &PrefDialog::onNameChange);
connect(ui->removeStatusButton, &QPushButton::clicked, this, &PrefDialog::onRemoveStatusButtonClick); connect(ui->removeStatusButton, &QPushButton::clicked, this, &PrefDialog::onRemoveStatusButtonClick);
connect(ui->removePriorityButton, &QPushButton::clicked, this, &PrefDialog::onRemovePriorityButtonClick); connect(ui->removePriorityButton, &QPushButton::clicked, this, &PrefDialog::onRemovePriorityButtonClick);
connect(ui->upStatus, &QPushButton::clicked, this, &PrefDialog::onUpStatusButtonClick);
connect(ui->downStatus, &QPushButton::clicked, this, &PrefDialog::onDownStatusButtonClick);
} }
PrefDialog::~PrefDialog() PrefDialog::~PrefDialog()
@@ -113,6 +118,16 @@ void PrefDialog::onItemSelectionChange(int index)
colorBtn = ui->colorStatusButton; colorBtn = ui->colorStatusButton;
nameEdit = ui->nameStatusEdit; nameEdit = ui->nameStatusEdit;
colorEdit = ui->colorStatusEdit; colorEdit = ui->colorStatusEdit;
if (index > -1)
{
ui->downStatus->setEnabled((index > 0));
ui->upStatus->setEnabled((index < statusUUIDRef.size()-1));
}
else
{
ui->downStatus->setEnabled(false);
ui->upStatus->setEnabled(false);
}
} }
else else
{ {
@@ -208,6 +223,46 @@ void PrefDialog::onRemovePriorityButtonClick()
priorityUUIDRef.removeAt(index); priorityUUIDRef.removeAt(index);
} }
void PrefDialog::onUpStatusButtonClick()
{
if (ui->statusListWidget->selectedItems().size() != 1)
{
return;
}
int i = ui->statusListWidget->indexFromItem(ui->statusListWidget->selectedItems()[0]).row();
if (i < statusUUIDRef.size())
{
QListWidgetItem *item = ui->statusListWidget->takeItem(i);
i++;
ui->statusListWidget->insertItem(i, item);
statusUUIDRef.move(i-1, i);
ui->downStatus->setEnabled((i > 0));
ui->upStatus->setEnabled((i < statusUUIDRef.size()-1));
ui->statusListWidget->setCurrentRow(i);
}
}
void PrefDialog::onDownStatusButtonClick()
{
if (ui->statusListWidget->selectedItems().size() != 1)
{
return;
}
int i = ui->statusListWidget->indexFromItem(ui->statusListWidget->selectedItems()[0]).row();
if (i > 0)
{
QListWidgetItem *item = ui->statusListWidget->takeItem(i);
i--;
ui->statusListWidget->insertItem(i, item);
statusUUIDRef.move(i+1, i);
ui->downStatus->setEnabled((i > 0));
ui->upStatus->setEnabled((i < statusUUIDRef.size()-1));
ui->statusListWidget->setCurrentRow(i);
}
}
void PrefDialog::setItemColor(QListWidgetItem *item, QColor bgColor) void PrefDialog::setItemColor(QListWidgetItem *item, QColor bgColor)
{ {
QColor fgColor = Tools::getForegroundColor(bgColor); QColor fgColor = Tools::getForegroundColor(bgColor);

View File

@@ -17,7 +17,7 @@ class PrefDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit PrefDialog(QVector<Status> status, QVector<Priority> priorities, QWidget *parent = nullptr); explicit PrefDialog(QWidget *parent = nullptr);
~PrefDialog(); ~PrefDialog();
QVector<Priority> getPriorities(); QVector<Priority> getPriorities();
@@ -31,7 +31,8 @@ private slots:
void onNameChange(); void onNameChange();
void onRemoveStatusButtonClick(); void onRemoveStatusButtonClick();
void onRemovePriorityButtonClick(); void onRemovePriorityButtonClick();
void onUpStatusButtonClick();
void onDownStatusButtonClick();
private: private:
Ui::PrefDialog *ui; Ui::PrefDialog *ui;

View File

@@ -59,6 +59,52 @@
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>General</string>
</attribute>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>161</width>
<height>18</height>
</rect>
</property>
<property name="font">
<font>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>At startup</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>81</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Open...</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>100</x>
<y>35</y>
<width>521</width>
<height>26</height>
</rect>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="title"> <attribute name="title">
<string>Status</string> <string>Status</string>
@@ -150,7 +196,7 @@
<x>570</x> <x>570</x>
<y>310</y> <y>310</y>
<width>41</width> <width>41</width>
<height>32</height> <height>21</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
@@ -166,13 +212,45 @@
<x>520</x> <x>520</x>
<y>310</y> <y>310</y>
<width>41</width> <width>41</width>
<height>31</height> <height>21</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>-</string> <string>-</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="downStatus">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>20</x>
<y>310</y>
<width>41</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Down</string>
</property>
</widget>
<widget class="QPushButton" name="upStatus">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>70</x>
<y>310</y>
<width>41</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Up</string>
</property>
</widget>
</widget> </widget>
<widget class="QWidget" name="tab_2"> <widget class="QWidget" name="tab_2">
<attribute name="title"> <attribute name="title">

View File

@@ -3,48 +3,28 @@
#include <QDate> #include <QDate>
TaskDialog::TaskDialog(QVector<Status> status, QVector<Priority> priorities, QWidget *parent) : #include "../services/taskstateservice.h"
TaskDialog::TaskDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::TaskDialog) ui(new Ui::TaskDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
init();
this->setWindowTitle("New task"); this->setWindowTitle("New task");
this->status = status;
this->priorities = priorities;
foreach (Status s, this->status)
{
ui->statusCombo->addItem(s.getName());
}
foreach (Priority p, this->priorities)
{
ui->priorityCombo->addItem(p.getName());
}
QDate expectedFor = QDate::currentDate(); QDate expectedFor = QDate::currentDate();
expectedFor = expectedFor.addDays(10); expectedFor = expectedFor.addDays(10);
ui->expectedForEdit->setDate(expectedFor); ui->expectedForEdit->setDate(expectedFor);
} }
TaskDialog::TaskDialog(Task *t, QVector<Status> status, QVector<Priority> priorities, QWidget *parent) : TaskDialog::TaskDialog(Task *t, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::TaskDialog) ui(new Ui::TaskDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
init();
this->setWindowTitle("Edit task"); this->setWindowTitle("Edit task");
this->status = status;
this->priorities = priorities;
foreach (Status s, this->status)
{
ui->statusCombo->addItem(s.getName());
}
foreach (Priority p, this->priorities)
{
ui->priorityCombo->addItem(p.getName());
}
// set fields // set fields
ui->nameEdit->setText(t->getTitle()); ui->nameEdit->setText(t->getTitle());
@@ -53,34 +33,12 @@ TaskDialog::TaskDialog(Task *t, QVector<Status> status, QVector<Priority> priori
if (t->getPriorityUUID().length() > 0) if (t->getPriorityUUID().length() > 0)
{ {
int16_t refindex = -1; initSelectionCombobox(t->getPriorityUUID(), ui->priorityCombo);
for (uint16_t i = 0; i < this->priorities.count(); i++)
{
if (this->priorities[i].getUUID() == t->getPriorityUUID())
{
refindex = i;
}
}
if (refindex > -1)
{
ui->priorityCombo->setCurrentIndex(refindex);
}
} }
if (t->getStatusUUID().length() > 0) if (t->getStatusUUID().length() > 0)
{ {
int16_t refindex = -1; initSelectionCombobox(t->getStatusUUID(), ui->statusCombo);
for (uint16_t i = 0; i < this->status.count(); i++)
{
if (this->status[i].getUUID() == t->getStatusUUID())
{
refindex = i;
}
}
if (refindex > -1)
{
ui->statusCombo->setCurrentIndex(refindex);
}
} }
} }
@@ -96,16 +54,42 @@ Task TaskDialog::getTask()
QString description = ui->descriptionEdit->toMarkdown(QTextDocument::MarkdownFeature::MarkdownDialectCommonMark); QString description = ui->descriptionEdit->toMarkdown(QTextDocument::MarkdownFeature::MarkdownDialectCommonMark);
QDate expectedFor = ui->expectedForEdit->date(); QDate expectedFor = ui->expectedForEdit->date();
QString priorityUUID = ""; QString priorityUUID = "";
if (ui->priorityCombo->currentIndex() > -1) if (!ui->priorityCombo->currentData().isNull())
{ {
Priority priority = priorities[ui->priorityCombo->currentIndex()]; priorityUUID = ui->priorityCombo->currentData().toString();
priorityUUID = priority.getUUID();
} }
QString statusUUID = ""; QString statusUUID = "";
if (ui->statusCombo->currentIndex() > -1) if (!ui->statusCombo->currentData().isNull())
{ {
Status s = status[ui->statusCombo->currentIndex()]; statusUUID = ui->statusCombo->currentData().toString();
statusUUID = s.getUUID();
} }
return Task(title, description, expectedFor, priorityUUID, statusUUID); return Task(title, description, expectedFor, priorityUUID, statusUUID);
} }
void TaskDialog::init()
{
QVector<Status> statuses = TaskStateService::getInstance()->getStatuses();
QVector<Priority> priorities = TaskStateService::getInstance()->getPriorities();
foreach (Status s, statuses)
{
ui->statusCombo->addItem(s.getName(), s.getUUID());
}
foreach (Priority p, priorities)
{
ui->priorityCombo->addItem(p.getName(), p.getUUID());
}
}
void TaskDialog::initSelectionCombobox(QString uuid, QComboBox *cbx)
{
for (uint16_t i = 0; i < cbx->count(); i++)
{
if (cbx->itemData(i).toString() == uuid)
{
cbx->setCurrentIndex(i);
break;
}
}
}

View File

@@ -3,6 +3,7 @@
#include <QDialog> #include <QDialog>
#include <QVector> #include <QVector>
#include <QComboBox>
#include "../models/status.h" #include "../models/status.h"
#include "../models/priority.h" #include "../models/priority.h"
@@ -17,8 +18,8 @@ class TaskDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit TaskDialog(QVector<Status>, QVector<Priority>, QWidget *parent = nullptr); explicit TaskDialog(QWidget *parent = nullptr);
TaskDialog(Task*, QVector<Status>, QVector<Priority>, QWidget *parent = nullptr); TaskDialog(Task *t, QWidget *parent = nullptr);
~TaskDialog(); ~TaskDialog();
Task getTask(); Task getTask();
@@ -26,8 +27,8 @@ public:
private: private:
Ui::TaskDialog *ui; Ui::TaskDialog *ui;
QVector<Status> status; void init();
QVector<Priority> priorities; void initSelectionCombobox(QString uuid, QComboBox *cbx);
}; };
#endif // TASKDIALOG_H #endif // TASKDIALOG_H

View File

@@ -4,17 +4,23 @@
#define TASKS_KEY "tasks" #define TASKS_KEY "tasks"
#define UUID_KEY "uuid" #define UUID_KEY "uuid"
#define DESCRIPTION_KEY "description" #define DESCRIPTION_KEY "description"
#define AUTOSTATUS_KEY "auto_status"
#define STATUSMODE_KEY "status_mode"
#define STATUS_KEY "status"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonValue> #include <QJsonValue>
#include <QUuid> #include <QUuid>
#include "../services/taskstateservice.h"
Board::Board(QString name, QString description) Board::Board(QString name, QString description)
{ {
QUuid uuid = QUuid::createUuid(); QUuid uuid = QUuid::createUuid();
this->uuid = uuid.toString(QUuid::WithoutBraces); this->uuid = uuid.toString(QUuid::WithoutBraces);
this->name = name; this->name = name;
this->description = description; this->description = description;
this->statusMode = NO_STATUS_MODE;
} }
Board::Board(QJsonObject obj) Board::Board(QJsonObject obj)
@@ -23,6 +29,20 @@ Board::Board(QJsonObject obj)
this->uuid = obj[UUID_KEY].toString(uuid.toString(QUuid::WithoutBraces)); this->uuid = obj[UUID_KEY].toString(uuid.toString(QUuid::WithoutBraces));
this->name = obj[NAME_KEY].toString("!Missing name!"); this->name = obj[NAME_KEY].toString("!Missing name!");
this->description = obj[DESCRIPTION_KEY].toString(""); this->description = obj[DESCRIPTION_KEY].toString("");
if (obj.contains(AUTOSTATUS_KEY))
{
this->statusMode = obj[AUTOSTATUS_KEY].toBool(true) ? AUTO_STATUS_MODE : CUSTOM_STATUS_MODE;
}
else
{
int val = obj[STATUSMODE_KEY].toInt(NO_STATUS_MODE);
if (val > std::numeric_limits<uint8_t>::max() || val < 0)
{
val = AUTO_STATUS_MODE;
}
this->statusMode = val;
}
this->statusUUID = obj[STATUS_KEY].toString();
QJsonArray jsonTasks = obj[TASKS_KEY].toArray(); QJsonArray jsonTasks = obj[TASKS_KEY].toArray();
foreach (QJsonValue value, jsonTasks) { foreach (QJsonValue value, jsonTasks) {
Task *t = new Task(value.toObject()); Task *t = new Task(value.toObject());
@@ -54,6 +74,36 @@ const QString Board::getDescription()
return description; return description;
} }
const QString Board::getStatus()
{
if (statusMode == AUTO_STATUS_MODE)
{
TaskStateService *tss = TaskStateService::getInstance();
int16_t h = -1;
QString suuid = "";
for (Task *t : tasks)
{
int16_t w = tss->getStatusWeight(t->getStatusUUID());
if (w > -1 && h < w)
{
h = w;
suuid = t->getStatusUUID();
}
}
return suuid;
}
else if (statusMode == NO_STATUS_MODE)
{
return "";
}
return statusUUID;
}
uint8_t Board::getStatusMode()
{
return statusMode;
}
void Board::setName(const QString name) void Board::setName(const QString name)
{ {
this->name = name; this->name = name;
@@ -64,6 +114,22 @@ void Board::setDescription(const QString description)
this->description = description; this->description = description;
} }
void Board::setStatus(Status s)
{
this->statusMode = CUSTOM_STATUS_MODE;
this->statusUUID = s.getUUID();
}
void Board::setStatusMode(uint8_t mode)
{
this->statusMode = mode;
if (mode != CUSTOM_STATUS_MODE)
{
this->statusUUID = "";
}
}
void Board::add(Task t) void Board::add(Task t)
{ {
tasks.append(new Task(t)); tasks.append(new Task(t));
@@ -99,6 +165,9 @@ const QJsonObject Board::toJson()
} }
QJsonObject obj; QJsonObject obj;
obj[NAME_KEY] = this->name; obj[NAME_KEY] = this->name;
obj[UUID_KEY] = this->uuid;
obj[STATUS_KEY] = this->statusUUID;
obj[STATUSMODE_KEY] = this->statusMode;
obj[TASKS_KEY] = array; obj[TASKS_KEY] = array;
obj[DESCRIPTION_KEY] = description; obj[DESCRIPTION_KEY] = description;
return obj; return obj;

View File

@@ -6,6 +6,11 @@
#include <QJsonObject> #include <QJsonObject>
#include "task.h" #include "task.h"
#include "status.h"
#define AUTO_STATUS_MODE 0
#define CUSTOM_STATUS_MODE 1
#define NO_STATUS_MODE 2
class Board class Board
{ {
@@ -17,10 +22,17 @@ public:
const QString getUuid(); const QString getUuid();
const QString getName(); const QString getName();
const QString getDescription(); const QString getDescription();
const QString getStatus();
uint8_t getStatusMode();
void setName(const QString name); void setName(const QString name);
void setDescription(const QString description); void setDescription(const QString description);
void setStatus(Status s);
void setStatusMode(uint8_t mode);
void add(Task); void add(Task);
void remove(uint16_t index); void remove(uint16_t index);
Task *taskAt(uint16_t); Task *taskAt(uint16_t);
const QVector<Task*> getTasks(); const QVector<Task*> getTasks();
@@ -32,6 +44,8 @@ private:
QString name; QString name;
QString description; QString description;
QString statusUUID;
uint8_t statusMode;
}; };
#endif // BOARD_H #endif // BOARD_H

View File

@@ -0,0 +1,55 @@
#include "generalpreferences.h"
#define PRELOAD_TYPE_KEY "preload_type"
#define PRELOAD_FACE_UUID_KEY "pr_face_uuid"
GeneralPreferences::GeneralPreferences()
{
this->preloadType = NO_PRELOAD_TYPE;
this->preloadUUID = "";
}
GeneralPreferences::GeneralPreferences(QJsonObject obj)
{
int val = obj[PRELOAD_TYPE_KEY].toInt(NO_PRELOAD_TYPE);
if (val > std::numeric_limits<uint8_t>::max() || val < 0)
{
val = NO_PRELOAD_TYPE;
}
this->preloadType = val;
this->preloadUUID = obj[PRELOAD_FACE_UUID_KEY].toString("");
}
uint8_t GeneralPreferences::getPreloadType()
{
return this->preloadType;
}
std::optional<QString> GeneralPreferences::getPreloadUUID()
{
if (this->preloadType == NO_PRELOAD_TYPE || this->preloadUUID.isEmpty())
{
return std::nullopt;
}
return std::optional<QString> {this->preloadUUID};
}
void GeneralPreferences::setPreloadType(uint8_t type)
{
this->preloadType = type;
}
void GeneralPreferences::setPreloadUUID(QString uuid)
{
this->preloadUUID = uuid;
}
const QJsonObject GeneralPreferences::toJson()
{
QJsonObject obj;
obj[PRELOAD_TYPE_KEY] = this->preloadType;
obj[PRELOAD_FACE_UUID_KEY] = this->preloadUUID;
return obj;
}

View File

@@ -0,0 +1,31 @@
#ifndef GENERALPREFERENCES_H
#define GENERALPREFERENCES_H
#include <QObject>
#include <QString>
#include <QJsonObject>
#define NO_PRELOAD_TYPE 0
#define FILTER_PRELOAD_TYPE 1
#define BOARD_PRELOAD_TYPE 2
class GeneralPreferences
{
public:
GeneralPreferences();
GeneralPreferences(QJsonObject);
uint8_t getPreloadType();
std::optional<QString> getPreloadUUID();
void setPreloadType(uint8_t type);
void setPreloadUUID(QString uuid);
const QJsonObject toJson();
private:
uint8_t preloadType;
QString preloadUUID;
};
#endif // GENERALPREFERENCES_H

View File

@@ -0,0 +1,33 @@
#include "configservice.h"
ConfigService *ConfigService::instance = nullptr;
ConfigService::~ConfigService()
{
delete data;
}
ConfigService *ConfigService::getInstance()
{
if (instance == nullptr)
{
instance = new ConfigService();
}
return instance;
}
void ConfigService::loadConfig(GeneralPreferences data)
{
delete this->data;
this->data = new GeneralPreferences(data);
}
GeneralPreferences *ConfigService::getConfig()
{
return data;
}
ConfigService::ConfigService()
{
data = new GeneralPreferences();
}

View File

@@ -0,0 +1,22 @@
#ifndef CONFIGSERVICE_H
#define CONFIGSERVICE_H
#include "../models/generalpreferences.h"
class ConfigService
{
public:
~ConfigService();
static ConfigService *getInstance();
void loadConfig(GeneralPreferences);
GeneralPreferences *getConfig();
private:
static ConfigService *instance;
ConfigService();
GeneralPreferences *data;
};
#endif // CONFIGSERVICE_H

View File

@@ -0,0 +1,80 @@
#include "taskstateservice.h"
TaskStateService *TaskStateService::instance = nullptr;
TaskStateService *TaskStateService::getInstance()
{
if (instance == nullptr)
{
instance = new TaskStateService();
}
return instance;
}
void TaskStateService::updateStatuses(QVector<Status> statuses)
{
this->statuses = statuses;
}
void TaskStateService::updatePriorities(QVector<Priority> priorities)
{
this->priorities = priorities;
}
QVector<Status> TaskStateService::getStatuses()
{
return statuses;
}
QVector<Priority> TaskStateService::getPriorities()
{
return priorities;
}
std::optional<Status> TaskStateService::getStatusByUUID(QString uuid)
{
foreach (Status s, statuses) {
if (s.getUUID() == uuid)
{
return std::optional{s};
}
}
return std::nullopt;
}
std::optional<Priority> TaskStateService::getPriorityByUUID(QString uuid)
{
foreach (Priority p, priorities) {
if (p.getUUID() == uuid)
{
return std::optional{p};
}
}
return std::nullopt;
}
int16_t TaskStateService::getStatusWeight(QString uuid)
{
int16_t weight = -1;
for (uint16_t i = 0; i < statuses.count(); i++)
{
if (statuses[i].getUUID() == uuid)
{
weight = i;
break;
}
}
return weight;
}
TaskStateService::TaskStateService()
{
priorities.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "None", QColor(217, 217, 217)));
priorities.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Low", QColor(48, 157, 176)));
priorities.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Medium", QColor(176, 142, 48)));
priorities.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "High", QColor(176, 67, 48)));
statuses.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "To Do", QColor(143, 143, 143)));
statuses.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Working on", QColor(95, 48, 176)));
statuses.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Completed", QColor(48, 176, 73)));
}

View File

@@ -0,0 +1,33 @@
#ifndef TASKSTATESERVICE_H
#define TASKSTATESERVICE_H
#include <QVector>
#include "../models/priority.h"
#include "../models/status.h"
class TaskStateService
{
public:
static TaskStateService *getInstance();
void updateStatuses(QVector<Status>);
void updatePriorities(QVector<Priority>);
QVector<Status> getStatuses();
QVector<Priority> getPriorities();
std::optional<Status> getStatusByUUID(QString);
std::optional<Priority> getPriorityByUUID(QString);
int16_t getStatusWeight(QString uuid);
private:
TaskStateService();
static TaskStateService *instance;
QVector<Priority> priorities;
QVector<Status> statuses;
};
#endif // TASKSTATESERVICE_H

View File

@@ -8,6 +8,8 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QDir> #include <QDir>
#include "services/taskstateservice.h"
Tools::Tools() Tools::Tools()
{ {
@@ -95,3 +97,14 @@ bool Tools::readSaveFile(QJsonDocument &doc) {
doc = QJsonDocument::fromJson(json.toUtf8()); doc = QJsonDocument::fromJson(json.toUtf8());
return true; return true;
} }
const QString Tools::getStatusLabelStylesheet(Status status)
{
QColor bg = status.getColor();
QColor fg = Tools::getForegroundColor(bg);
return QString("border-color: %1; \
border: solid; \
background-color: %1; \
border-radius: 4px; \
color: %2;").arg(bg.name(QColor::HexRgb), fg.name(QColor::HexRgb));
}

View File

@@ -4,6 +4,8 @@
#include <QColor> #include <QColor>
#include <QJsonDocument> #include <QJsonDocument>
#include "models/status.h"
class Tools class Tools
{ {
public: public:
@@ -14,6 +16,7 @@ public:
static bool isSaveFileExist(); static bool isSaveFileExist();
static bool writeSaveToFile(QJsonDocument doc); static bool writeSaveToFile(QJsonDocument doc);
static bool readSaveFile(QJsonDocument &doc); static bool readSaveFile(QJsonDocument &doc);
static const QString getStatusLabelStylesheet(Status);
private: private:
static const QString getSaveFilePath(); static const QString getSaveFilePath();