12 Commits

Author SHA1 Message Date
Aurélie Delhaie
4c95000b8f compiler version 2023-02-13 08:25:58 +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
Aurélie Delhaie
693532a802 Fix '-D' char on os version Windows 2023-01-15 21:24:29 +01:00
Aurélie Delhaie
ba1a5f94f3 Change version in aboutbox 2023-01-15 22:12:55 +01:00
Aurélie Delhaie
43ecd2601e Adding filters 2023-01-15 12:39:03 +01:00
Aurélie Delhaie
6206a16c9d Create filter dialog, board description 2023-01-14 18:15:41 +01:00
Aurélie
36c752694f Update Ubuntu command in README.md 2023-01-13 12:06:15 +01:00
Aurelie Delhaie
a86ece9c9a Expected for color, add filter model 2023-01-08 20:43:24 +01:00
Aurélie
32a25f9b55 Update README.md 2022-12-27 12:31:41 +01:00
Aurélie Delhaie
361dda51ba Fix task priority/status color, fix editable field in config, Fix column
length, Fix redraw after updating config
2022-12-25 10:59:15 +01:00
27 changed files with 1239 additions and 183 deletions

View File

@@ -1 +1,15 @@
# TaskBoard # TaskBoard
Wrote with Qt 6 Open Source : [Download](https://www.qt.io/download-open-source)
## Prepare to use on linux
You need to install Qt 6.2.4 dependencies
```sh
sudo apt install libxcb1 libxcb-xinerama0 libqt6widgets6 libqt6gui6 libqt6core5compat6 libqt6core5compat6 libqt6core6 libqt6dbus6 qt6-qpa-plugins
```
### To run on Wayland
```sh
sudo apt install qt6-wayland
```

View File

@@ -1,11 +1,11 @@
QT += core gui QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 5): QT += widgets
CONFIG += c++17 CONFIG += c++17
win32:VERSION = 0.1.0.0 # major.minor.patch.build win32:VERSION = 0.2.1.0 # major.minor.patch.build
else:VERSION = 0.1.0 # major.minor.patch else:VERSION = 0.2.1 # major.minor.patch
DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\" DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\"
DEFINES += APP_NAME=\"\\\"TaskBoard\\\"\" DEFINES += APP_NAME=\"\\\"TaskBoard\\\"\"
@@ -68,12 +68,14 @@ 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/filterdialog.cpp \
src/frames/aboutdialog.cpp \ src/frames/aboutdialog.cpp \
src/models/board.cpp \ src/models/board.cpp \
src/main.cpp \ src/main.cpp \
src/frames/mainwindow.cpp \ src/frames/mainwindow.cpp \
src/frames/namedialog.cpp \ src/frames/namedialog.cpp \
src/frames/prefdialog.cpp \ src/frames/prefdialog.cpp \
src/models/filter.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 \
@@ -81,11 +83,13 @@ SOURCES += \
src/tools.cpp src/tools.cpp
HEADERS += \ HEADERS += \
src/frames/filterdialog.h \
src/frames/aboutdialog.h \ src/frames/aboutdialog.h \
src/models/board.h \ src/models/board.h \
src/frames/mainwindow.h \ src/frames/mainwindow.h \
src/frames/namedialog.h \ src/frames/namedialog.h \
src/frames/prefdialog.h \ src/frames/prefdialog.h \
src/models/filter.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 \
@@ -93,6 +97,7 @@ HEADERS += \
src/tools.h src/tools.h
FORMS += \ FORMS += \
src/frames/filterdialog.ui \
src/frames/aboutdialog.ui \ src/frames/aboutdialog.ui \
src/frames/mainwindow.ui \ src/frames/mainwindow.ui \
src/frames/namedialog.ui \ src/frames/namedialog.ui \

View File

@@ -1,5 +1,8 @@
<RCC> <RCC>
<qresource prefix="/images"> <qresource prefix="/images">
<file>resources/logo.png</file> <file>resources/logo.png</file>
<file>resources/board_add.png</file>
<file>resources/task_add.png</file>
<file>resources/add_filter.png</file>
</qresource> </qresource>
</RCC> </RCC>

BIN
resources/add_filter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
resources/board_add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
resources/task_add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,17 +1,43 @@
#include "aboutdialog.h" #include "aboutdialog.h"
#include "ui_aboutdialog.h" #include "ui_aboutdialog.h"
#ifdef unix
#include <gnu/libc-version.h>
#endif
AboutDialog::AboutDialog(QWidget *parent) : AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent), QDialog(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));
ui->version->setText(QString("v%1").arg(APP_VERSION)); #else
ui->textEdit_2->append(QString("Built with Qt %1").arg(QT_VERSION_STR)); ui->appName->setText(APP_NAME);
#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));
} }
AboutDialog::~AboutDialog() 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").arg(gnu_get_libc_version());
#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

@@ -77,9 +77,15 @@
<property name="text"> <property name="text">
<string>TextLabel</string> <string>TextLabel</string>
</property> </property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@@ -111,8 +117,7 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; } &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Menlo'; font-size:13pt;&quot;&gt;Copyright 2022 Aurélie Delhaie&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Menlo'; font-size:13pt;&quot;&gt;Copyright 2022 Aurélie Delhaie&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Menlo'; font-size:13pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Menlo'; font-size:13pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Menlo'; font-size:13pt;&quot;&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Menlo'; font-size:13pt;&quot;&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;/span&gt;&lt;/p&gt;
@@ -139,9 +144,8 @@ hr { height: 1px; border-width: 0; }
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; } &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Noto Sans'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>

146
src/frames/filterdialog.cpp Normal file
View File

@@ -0,0 +1,146 @@
#include "filterdialog.h"
#include "ui_filterdialog.h"
#include <QMessageBox>
FilterDialog::FilterDialog(QString dialogTitle, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent) :
QDialog(parent),
ui(new Ui::FilterDialog)
{
ui->setupUi(this);
this->setWindowTitle(dialogTitle);
init(boards, status, priorities);
}
FilterDialog::FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent) :
QDialog(parent),
ui(new Ui::FilterDialog)
{
ui->setupUi(this);
this->setWindowTitle(dialogTitle);
init(boards, status, priorities);
ui->nameEdit->setText(f.getName());
ui->descriptionEdit->setPlainText(f.getDescription());
ui->dateComparationCombobox->setCurrentIndex(f.getExpectedForComparator());
foreach (QString uuid, f.getBoards())
{
for (int i = 0; i < ui->boardListWidget->count(); ++i)
{
QListWidgetItem *item = ui->boardListWidget->item(i);
if (item->data(1).toString() == uuid)
{
item->setCheckState(Qt::Checked);
}
}
}
foreach (QString uuid, f.getStatus())
{
for (int i = 0; i < ui->statusListWidget->count(); ++i)
{
QListWidgetItem *item = ui->statusListWidget->item(i);
if (item->data(1).toString() == uuid)
{
item->setCheckState(Qt::Checked);
}
}
}
foreach (QString uuid, f.getPriorities())
{
for (int i = 0; i < ui->priorityListWidget->count(); ++i)
{
QListWidgetItem *item = ui->priorityListWidget->item(i);
if (item->data(1).toString() == uuid)
{
item->setCheckState(Qt::Checked);
}
}
}
}
void FilterDialog::init(QVector<Board *> boards, QVector<Status> status, QVector<Priority> priorities)
{
for (Board *b : boards)
{
QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Unchecked);
item->setText(b->getName());
item->setData(1, b->getUuid());
ui->boardListWidget->addItem(item);
}
for (Status s : status)
{
QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Unchecked);
item->setText(s.getName());
item->setData(1, s.getUUID());
ui->statusListWidget->addItem(item);
}
for (Priority p : priorities)
{
QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Unchecked);
item->setText(p.getName());
item->setData(1, p.getUUID());
ui->priorityListWidget->addItem(item);
}
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &FilterDialog::validateAndAccept);
}
FilterDialog::~FilterDialog()
{
delete ui;
}
const Filter FilterDialog::getFilter()
{
QString name = ui->nameEdit->text();
QString description = ui->descriptionEdit->toPlainText();
uint8_t dateComparation = 0;
if (ui->dateComparationCombobox->currentIndex() > -1)
{
dateComparation = ui->dateComparationCombobox->currentIndex();
}
QVector<QString> boards;
for (int i = 0; i < ui->boardListWidget->count(); ++i) {
QListWidgetItem *item = ui->boardListWidget->item(i);
if (item->checkState() == Qt::Checked)
{
boards.append(item->data(1).toString());
}
}
QVector<QString> status;
for (int i = 0; i < ui->statusListWidget->count(); ++i) {
QListWidgetItem *item = ui->statusListWidget->item(i);
if (item->checkState() == Qt::Checked)
{
status.append(item->data(1).toString());
}
}
QVector<QString> priorities;
for (int i = 0; i < ui->priorityListWidget->count(); ++i) {
QListWidgetItem *item = ui->priorityListWidget->item(i);
if (item->checkState() == Qt::Checked)
{
priorities.append(item->data(1).toString());
}
}
return Filter(name, description, dateComparation, boards, status, priorities);
}
void FilterDialog::validateAndAccept()
{
if (ui->nameEdit->text().length() == 0)
{
QMessageBox::critical(this, "This filter needs a name", "You need to enter a name to save this filter");
return;
}
accept();
}

34
src/frames/filterdialog.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef FILTERDIALOG_H
#define FILTERDIALOG_H
#include <QDialog>
#include "../models/board.h"
#include "../models/priority.h"
#include "../models/status.h"
#include "../models/filter.h"
namespace Ui {
class FilterDialog;
}
class FilterDialog : public QDialog
{
Q_OBJECT
public:
explicit FilterDialog(QString dialogTitle, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent = nullptr);
FilterDialog(QString dialogTitle, Filter f, QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities, QWidget *parent = nullptr);
~FilterDialog();
const Filter getFilter();
private slots:
void validateAndAccept();
private:
Ui::FilterDialog *ui;
void init(QVector<Board*> boards, QVector<Status> status, QVector<Priority> priorities);
};
#endif // FILTERDIALOG_H

163
src/frames/filterdialog.ui Normal file
View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FilterDialog</class>
<widget class="QDialog" name="FilterDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>449</width>
<height>656</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Filter name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nameEdit"/>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="descriptionEdit"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Date comparation</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="dateComparationCombobox">
<item>
<property name="text">
<string>Ignore date</string>
</property>
</item>
<item>
<property name="text">
<string>On time</string>
</property>
</item>
<item>
<property name="text">
<string>End today</string>
</property>
</item>
<item>
<property name="text">
<string>Ended</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Boards (None = all)</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="boardListWidget">
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="selectionRectVisible">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Status (None = all)</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="statusListWidget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Priority (None = all)</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="priorityListWidget"/>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FilterDialog</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

@@ -4,6 +4,7 @@
#define PRIORITIES_KEY "priorities" #define PRIORITIES_KEY "priorities"
#define STATUS_KEY "status" #define STATUS_KEY "status"
#define BOARDS_KEY "boards" #define BOARDS_KEY "boards"
#define FILTERS_KEY "filters"
#include <QUuid> #include <QUuid>
#include <QColor> #include <QColor>
@@ -15,6 +16,7 @@
#include "aboutdialog.h" #include "aboutdialog.h"
#include "namedialog.h" #include "namedialog.h"
#include "taskdialog.h" #include "taskdialog.h"
#include "filterdialog.h"
#include "../tools.h" #include "../tools.h"
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
@@ -22,18 +24,29 @@ MainWindow::MainWindow(QWidget *parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
this->menuSelectedBoardItem = nullptr;
this->menuSelectedFilterItem = nullptr;
this->menuSelectedTaskItem = nullptr;
init(); init();
this->selectedBoardIndex = -1; this->selectedBoardIndex = -1;
// Change "name" column size
ui->taskList->header()->resizeSection(0, 520);
// Change "status" column size
ui->taskList->header()->resizeSection(1, 150);
connect(ui->actionPreferences, &QAction::triggered, this, &MainWindow::openPreferences); connect(ui->actionPreferences, &QAction::triggered, this, &MainWindow::openPreferences);
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::openAbout); connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::openAbout);
connect(ui->actionNew, &QAction::triggered, this, &MainWindow::onNewBoardClick); connect(ui->actionNew, &QAction::triggered, this, &MainWindow::onNewBoardClick);
connect(ui->actionNew_task, &QAction::triggered, this, &MainWindow::onNewTaskClick); connect(ui->actionNew_task, &QAction::triggered, this, &MainWindow::onNewTaskClick);
connect(ui->actionNew_filter, &QAction::triggered, this, &MainWindow::onNewFilterClick);
connect(ui->boardList, &QListWidget::currentRowChanged, this, &MainWindow::onBoardSelected); connect(ui->boardList, &QListWidget::currentRowChanged, this, &MainWindow::onBoardSelected);
connect(ui->boardList, &QListWidget::customContextMenuRequested, this, &MainWindow::prepareBoardMenu); connect(ui->boardList, &QListWidget::customContextMenuRequested, this, &MainWindow::prepareBoardMenu);
connect(ui->filterListWidget, &QListWidget::currentRowChanged, this, &MainWindow::onFilterSelected);
connect(ui->filterListWidget, &QListWidget::customContextMenuRequested, this, &MainWindow::prepareFilterMenu);
connect(ui->taskList, &QTreeWidget::itemDoubleClicked, this, &MainWindow::onEditTask); connect(ui->taskList, &QTreeWidget::itemDoubleClicked, this, &MainWindow::onEditTask);
connect(ui->taskList, &QTreeWidget::customContextMenuRequested, this, &MainWindow::prepareTaskMenu); connect(ui->taskList, &QTreeWidget::customContextMenuRequested, this, &MainWindow::prepareTaskMenu);
ui->boardList->setContextMenuPolicy(Qt::CustomContextMenu); ui->boardList->setContextMenuPolicy(Qt::CustomContextMenu);
ui->taskList->setContextMenuPolicy(Qt::CustomContextMenu); ui->taskList->setContextMenuPolicy(Qt::CustomContextMenu);
ui->filterListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@@ -54,6 +67,7 @@ void MainWindow::openPreferences()
this->priorities = dialog.getPriorities(); this->priorities = dialog.getPriorities();
this->status = dialog.getStatus(); this->status = dialog.getStatus();
save(); save();
redrawTaskTree();
} }
} }
@@ -65,51 +79,71 @@ void MainWindow::openAbout()
void MainWindow::prepareBoardMenu(const QPoint &pos) void MainWindow::prepareBoardMenu(const QPoint &pos)
{ {
if (ui->boardList->selectedItems().length() == 1) {
QMenu menu(this); QMenu menu(this);
this->menuSelectedBoardItem = ui->boardList->itemAt(pos);
QAction *renameAction = new QAction(tr("Rename this board"), this); if (this->menuSelectedBoardItem != nullptr) {
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);
menu.addSeparator(); QAction *deleteAction = new QAction(tr("Delete the board and all the tasks"), this);
QAction *deleteAction = new QAction(tr("Delete this board"), this);
connect(deleteAction, &QAction::triggered, this, &MainWindow::onRemoveBoardMenu); connect(deleteAction, &QAction::triggered, this, &MainWindow::onRemoveBoardMenu);
menu.addAction(deleteAction); menu.addAction(deleteAction);
menu.exec(ui->boardList->mapToGlobal(pos)); menu.addSeparator();
} }
QAction *addAction = new QAction(tr("New board"), this);
connect(addAction, &QAction::triggered, this, &MainWindow::onNewBoardClick);
menu.addAction(addAction);
menu.exec(ui->boardList->mapToGlobal(pos));
} }
void MainWindow::prepareTaskMenu(const QPoint &pos) void MainWindow::prepareTaskMenu(const QPoint &pos)
{ {
if (ui->taskList->selectedItems().length() == 1) { bool show = false;
QMenu menu(this); QMenu menu(this);
this->menuSelectedTaskItem = ui->taskList->itemAt(pos);
if (menuSelectedTaskItem != nullptr) {
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);
menu.addSeparator(); 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();
}
if (selectedBoardIndex > -1)
{
show = true;
QAction *addAction = new QAction(tr("New task"), this);
connect(addAction, &QAction::triggered, this, &MainWindow::onNewTaskClick);
menu.addAction(addAction);
}
if (show)
{
menu.exec(ui->taskList->mapToGlobal(pos)); menu.exec(ui->taskList->mapToGlobal(pos));
} }
} }
void MainWindow::onNewBoardClick() void MainWindow::onNewBoardClick()
{ {
NameDialog dialog("Create a board", "New empty board", this); NameDialog dialog("Create a board", "New empty board", "", this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
QString name = dialog.getChoosenName(); QString name = dialog.getChoosenName();
Board *b = new Board(name); QString desc = dialog.getDescription();
Board *b = new Board(name, desc);
boards.append(b); boards.append(b);
QListWidgetItem *item = new QListWidgetItem(name); QListWidgetItem *item = new QListWidgetItem(name);
item->setStatusTip(desc);
ui->boardList->addItem(item); ui->boardList->addItem(item);
save(); save();
} }
@@ -126,63 +160,81 @@ void MainWindow::onNewTaskClick()
Board *b = boards[selectedBoardIndex]; Board *b = boards[selectedBoardIndex];
b->add(t); b->add(t);
QTreeWidgetItem *item = new QTreeWidgetItem(); QTreeWidgetItem *item = new QTreeWidgetItem();
item->setText(0, t.getTitle()); updateTaskRow(item, t);
item->setText(3, t.getExpectedFor().toString());
if (!t.getStatusUUID().isEmpty())
{
item->setText(1, getStatusLabel(t.getStatusUUID()));
QBrush bgColor = item->background(1);
QBrush fgColor = item->foreground(1);
bgColor.setColor(getStatusColor(t.getStatusUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
item->setBackground(1, bgColor);
item->setForeground(1, fgColor);
}
if (!t.getPriorityUUID().isEmpty())
{
item->setText(2, getPriorityLabel(t.getPriorityUUID()));
QBrush bgColor = item->background(2);
QBrush fgColor = item->foreground(2);
bgColor.setColor(getPriorityColor(t.getPriorityUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
item->setBackground(2, bgColor);
item->setForeground(2, fgColor);
}
ui->taskList->addTopLevelItem(item); ui->taskList->addTopLevelItem(item);
save(); save();
} }
} }
} }
void MainWindow::onNewFilterClick()
{
FilterDialog dialog("New filter", boards, status, priorities, this);
if (dialog.exec() == QDialog::DialogCode::Accepted)
{
Filter f = dialog.getFilter();
filters.append(f);
QListWidgetItem *item = new QListWidgetItem(f.getName());
item->setToolTip(f.getDescription());
ui->filterListWidget->addItem(item);
save();
}
}
void MainWindow::onBoardSelected(int i) void MainWindow::onBoardSelected(int i)
{ {
selectedBoardIndex = i; selectedBoardIndex = i;
selectedFilterIndex = -1;
ui->filterListWidget->blockSignals(true);
ui->filterListWidget->setCurrentIndex(ui->filterListWidget->currentIndex().sibling(-1, -1));
ui->filterListWidget->blockSignals(false);
filterResult.clear();
if (selectedBoardIndex > -1) if (selectedBoardIndex > -1)
{ {
Board *b = boards[selectedBoardIndex]; Board *b = boards[selectedBoardIndex];
ui->label->setText(b->getName()); ui->label->setText(b->getName());
ui->boardDescription->setText(b->getDescription());
ui->actionNew_task->setDisabled(false); ui->actionNew_task->setDisabled(false);
} }
else else
{ {
ui->label->setText("<- Select a board"); ui->label->setText("No board selected");
ui->boardDescription->clear();
ui->actionNew_task->setDisabled(true); ui->actionNew_task->setDisabled(true);
} }
redrawTaskTree(); redrawTaskTree();
} }
void MainWindow::onFilterSelected(int i)
{
selectedFilterIndex = i;
selectedBoardIndex = -1;
ui->boardList->blockSignals(true);
ui->boardList->setCurrentIndex(ui->boardList->currentIndex().sibling(-1, -1));
ui->boardList->blockSignals(false);
filterResult.clear();
ui->actionNew_task->setDisabled(true);
if (selectedFilterIndex > -1)
{
Filter f = filters[selectedFilterIndex];
ui->label->setText(f.getName());
ui->boardDescription->setText(f.getDescription());
}
else
{
ui->label->setText("No board selected");
ui->boardDescription->clear();
}
redrawTaskTree();
}
void MainWindow::onEditTask(QTreeWidgetItem *item) void MainWindow::onEditTask(QTreeWidgetItem *item)
{ {
if (item != nullptr && selectedBoardIndex > -1) Task *t = getSelectedTask();
{
Board *b = boards[selectedBoardIndex];
int row = ui->taskList->indexOfTopLevelItem(item);
Task *t = b->taskAt(row);
if (t != nullptr) if (t != nullptr)
{ {
TaskDialog dialog(t, status, priorities, this); TaskDialog dialog(t, status, priorities, this);
@@ -190,34 +242,11 @@ void MainWindow::onEditTask(QTreeWidgetItem *item)
{ {
Task editedTask = dialog.getTask(); Task editedTask = dialog.getTask();
t->update(editedTask); t->update(editedTask);
item->setText(0, editedTask.getTitle()); updateTaskRow(item, editedTask);
item->setText(3, editedTask.getExpectedFor().toString());
if (!editedTask.getStatusUUID().isEmpty())
{
item->setText(1, getStatusLabel(editedTask.getStatusUUID()));
QBrush bgColor = item->background(1);
QBrush fgColor = item->foreground(1);
bgColor.setColor(getStatusColor(editedTask.getStatusUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
item->setBackground(1, bgColor);
item->setForeground(1, fgColor);
}
if (!editedTask.getPriorityUUID().isEmpty())
{
item->setText(2, getPriorityLabel(editedTask.getPriorityUUID()));
QBrush bgColor = item->background(2);
QBrush fgColor = item->foreground(2);
bgColor.setColor(getPriorityColor(editedTask.getPriorityUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
item->setBackground(2, bgColor);
item->setForeground(2, fgColor);
}
save(); save();
if (selectedFilterIndex > -1)
{
redrawTaskTree();
} }
} }
} }
@@ -225,14 +254,18 @@ void MainWindow::onEditTask(QTreeWidgetItem *item)
void MainWindow::onRemoveBoardMenu() void MainWindow::onRemoveBoardMenu()
{ {
if (selectedBoardIndex > -1) if (menuSelectedBoardItem != nullptr)
{ {
int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row();
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();
} }
@@ -255,18 +288,44 @@ void MainWindow::onRemoveTaskMenu()
} }
} }
void MainWindow::onRemoveFilterMenu()
{
if (menuSelectedFilterItem != nullptr)
{
int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row();
QMessageBox::StandardButton result = QMessageBox::question(this, "Delete a filter", "Do you want to delete this filter?");
if (result == QMessageBox::Yes)
{
filters.removeAt(i);
delete ui->filterListWidget->takeItem(i);
if (selectedFilterIndex == i)
{
selectedFilterIndex = -1;
}
redrawTaskTree();
save();
}
}
}
void MainWindow::onEditNameBoardMenu() void MainWindow::onEditNameBoardMenu()
{ {
if (selectedBoardIndex > -1) if (menuSelectedBoardItem != nullptr)
{ {
Board *b = boards.at(selectedBoardIndex); int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row();
NameDialog dialog("Edit board name", b->getName(), this); Board *b = boards.at(i);
NameDialog dialog("Edit board name", b->getName(), b->getDescription(), this);
if (dialog.exec() == QDialog::DialogCode::Accepted) if (dialog.exec() == QDialog::DialogCode::Accepted)
{ {
QString newName= dialog.getChoosenName(); QString newName = dialog.getChoosenName();
QString newDesc = dialog.getDescription();
b->setName(newName); b->setName(newName);
ui->boardList->item(selectedBoardIndex)->setText(newName); b->setDescription(newDesc);
QListWidgetItem *item = ui->boardList->item(i);
item->setText(newName);
item->setToolTip(newDesc);
ui->label->setText(newName); ui->label->setText(newName);
ui->boardDescription->setText(newDesc);
save(); save();
} }
} }
@@ -274,12 +333,57 @@ void MainWindow::onEditNameBoardMenu()
void MainWindow::onEditNameTaskMenu() void MainWindow::onEditNameTaskMenu()
{ {
if (selectedBoardIndex > -1 && ui->taskList->selectedItems().length() == 1) Task *t = getSelectedTask();
if (t != nullptr)
{ {
onEditTask(ui->taskList->currentItem()); onEditTask(ui->taskList->currentItem());
} }
} }
void MainWindow::onEditFilterMenu()
{
if (menuSelectedFilterItem != nullptr)
{
int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row();
Filter f = filters[i];
FilterDialog dialog("Edit the filter", f, boards, status, priorities, this);
if (dialog.exec() == QDialog::DialogCode::Accepted)
{
Filter f = dialog.getFilter();
filters[selectedFilterIndex] = f;
QListWidgetItem *item = ui->filterListWidget->item(selectedFilterIndex);
item->setText(f.getName());
item->setToolTip(f.getDescription());
ui->label->setText(f.getName());
ui->boardDescription->setText(f.getDescription());
redrawTaskTree();
save();
}
}
}
void MainWindow::prepareFilterMenu(const QPoint &pos)
{
QMenu menu(this);
this->menuSelectedFilterItem = ui->filterListWidget->itemAt(pos);
if (this->menuSelectedFilterItem != nullptr) {
QAction *renameAction = new QAction(tr("Edit the filter"), this);
connect(renameAction, &QAction::triggered, this, &MainWindow::onEditFilterMenu);
menu.addAction(renameAction);
QAction *deleteAction = new QAction(tr("Delete"), this);
connect(deleteAction, &QAction::triggered, this, &MainWindow::onRemoveFilterMenu);
menu.addAction(deleteAction);
menu.addSeparator();
}
QAction *addAction = new QAction(tr("New filter"), this);
connect(addAction, &QAction::triggered, this, &MainWindow::onNewFilterClick);
menu.addAction(addAction);
menu.exec(ui->filterListWidget->mapToGlobal(pos));
}
void MainWindow::init() void MainWindow::init()
{ {
if (Tools::isSaveFileExist()) if (Tools::isSaveFileExist())
@@ -291,15 +395,24 @@ void MainWindow::init()
QJsonArray jsonPriorities = save[PRIORITIES_KEY].toArray(); QJsonArray jsonPriorities = save[PRIORITIES_KEY].toArray();
QJsonArray jsonStatus = save[STATUS_KEY].toArray(); QJsonArray jsonStatus = save[STATUS_KEY].toArray();
QJsonArray jsonBoards = save[BOARDS_KEY].toArray(); QJsonArray jsonBoards = save[BOARDS_KEY].toArray();
for (QJsonValueRef value : jsonPriorities) { QJsonArray jsonFilters = save[FILTERS_KEY].toArray();
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())); status.append(Status(value.toObject()));
} }
for (QJsonValueRef value : jsonBoards) { for (QJsonValueRef value : jsonBoards)
{
boards.append(new Board(value.toObject())); boards.append(new Board(value.toObject()));
} }
for (QJsonValueRef value : jsonFilters)
{
filters.append(Filter(value.toObject()));
}
redrawFilterList();
redrawBoardList(); redrawBoardList();
return; return;
} }
@@ -312,18 +425,25 @@ void MainWindow::init()
QVector<Priority> MainWindow::defaultPriorities() QVector<Priority> MainWindow::defaultPriorities()
{ {
QVector<Priority> res; QVector<Priority> res;
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Low", QColor("#309db0"))); res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "None", QColor(217, 217, 217)));
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Medium", QColor("#b08e30"))); res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "Low", QColor(48, 157, 176)));
res.append(Priority(QUuid::createUuid().toString(QUuid::WithoutBraces), "High", QColor("#b04330"))); 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; return res;
} }
QVector<Status> MainWindow::defaultStatus() QVector<Status> MainWindow::defaultStatus()
{ {
QVector<Status> res; QVector<Status> res;
res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "To Do", QColor("#8f8f8f"))); 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("#5f30b0"))); res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Working on", QColor(95, 48, 176)));
res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Completed", QColor("#30b049"))); res.append(Status(QUuid::createUuid().toString(QUuid::WithoutBraces), "Completed", QColor(48, 176, 73)));
return res;
}
QVector<Filter> MainWindow::defaultFilters()
{
QVector<Filter> res;
return res; return res;
} }
@@ -395,13 +515,99 @@ const QJsonDocument MainWindow::getJsonSave()
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)
{
jsonFilters.append(f.toJson());
}
obj[PRIORITIES_KEY] = jsonPriorities; obj[PRIORITIES_KEY] = jsonPriorities;
obj[STATUS_KEY] = jsonStatus; obj[STATUS_KEY] = jsonStatus;
obj[BOARDS_KEY] = jsonBoards; obj[BOARDS_KEY] = jsonBoards;
obj[FILTERS_KEY] = jsonFilters;
doc.setObject(obj); doc.setObject(obj);
return doc; return doc;
} }
Task *MainWindow::getSelectedTask()
{
QList<QTreeWidgetItem*> items = ui->taskList->selectedItems();
if (items.count() != 1)
{
return nullptr;
}
if (selectedBoardIndex > -1)
{
Board *b = boards[selectedBoardIndex];
int16_t i = ui->taskList->indexOfTopLevelItem(items[0]);
return b->taskAt(i);
}
else if (selectedFilterIndex > -1)
{
if (!filterResult.empty())
{
int16_t i = ui->taskList->indexOfTopLevelItem(items[0]);
return filterResult[i];
}
}
return nullptr;
}
void MainWindow::updateTaskRow(QTreeWidgetItem *item, Task t)
{
item->setText(0, t.getTitle());
item->setToolTip(0, t.getDescription());
item->setText(3, t.getExpectedFor().toString());
if (t.getExpectedFor() < QDate::currentDate())
{
QBrush fgColor = item->foreground(3);
fgColor.setColor(QColor(176, 67, 48));
fgColor.setStyle(Qt::BrushStyle::SolidPattern);
item->setForeground(3, fgColor);
}
else if (t.getExpectedFor() == QDate::currentDate())
{
QBrush fgColor = item->foreground(3);
fgColor.setColor(QColor(176, 142, 48));
fgColor.setStyle(Qt::BrushStyle::SolidPattern);
item->setForeground(3, fgColor);
}
else
{
QBrush fgColor = item->foreground(3);
fgColor.setStyle(Qt::BrushStyle::NoBrush);
item->setForeground(3, fgColor);
}
if (!t.getStatusUUID().isEmpty())
{
item->setText(1, getStatusLabel(t.getStatusUUID()));
QBrush bgColor = item->background(1);
QBrush fgColor = item->foreground(1);
bgColor.setColor(getStatusColor(t.getStatusUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
fgColor.setStyle(Qt::BrushStyle::SolidPattern);
item->setBackground(1, bgColor);
item->setForeground(1, fgColor);
}
if (!t.getPriorityUUID().isEmpty())
{
item->setText(2, getPriorityLabel(t.getPriorityUUID()));
QBrush bgColor = item->background(2);
QBrush fgColor = item->foreground(2);
bgColor.setColor(getPriorityColor(t.getPriorityUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
fgColor.setStyle(Qt::BrushStyle::SolidPattern);
item->setBackground(2, bgColor);
item->setForeground(2, fgColor);
}
}
void MainWindow::redrawBoardList() void MainWindow::redrawBoardList()
{ {
QListWidget *l = ui->boardList; QListWidget *l = ui->boardList;
@@ -413,6 +619,23 @@ void MainWindow::redrawBoardList()
foreach (Board *b, boards) foreach (Board *b, boards)
{ {
QListWidgetItem *item = new QListWidgetItem(b->getName()); QListWidgetItem *item = new QListWidgetItem(b->getName());
item->setToolTip(b->getDescription());
l->addItem(item);
}
}
void MainWindow::redrawFilterList()
{
QListWidget *l = ui->filterListWidget;
uint16_t itemCount = l->count();
for (int16_t i = itemCount; i >= 0; i--)
{
delete l->takeItem(i);
}
foreach (Filter f, filters)
{
QListWidgetItem *item = new QListWidgetItem(f.getName());
item->setToolTip(f.getDescription());
l->addItem(item); l->addItem(item);
} }
} }
@@ -431,37 +654,21 @@ void MainWindow::redrawTaskTree()
foreach (Task *t, b->getTasks()) foreach (Task *t, b->getTasks())
{ {
QTreeWidgetItem *item = new QTreeWidgetItem(); QTreeWidgetItem *item = new QTreeWidgetItem();
item->setText(0, t->getTitle()); updateTaskRow(item, *t);
item->setText(3, t->getExpectedFor().toString()); ui->taskList->addTopLevelItem(item);
}
if (!t->getStatusUUID().isEmpty()) }
{ else if (selectedFilterIndex > -1)
item->setText(1, getStatusLabel(t->getStatusUUID())); {
QBrush bgColor = item->background(1); Filter f = filters[selectedFilterIndex];
QBrush fgColor = item->foreground(1); filterResult = f.filter(boards);
bgColor.setColor(getStatusColor(t->getStatusUUID(), bgColor.color())); foreach (Task *t, filterResult)
bgColor.setStyle(Qt::BrushStyle::SolidPattern); {
fgColor.setColor(Tools::getForegroundColor(bgColor.color())); QTreeWidgetItem *item = new QTreeWidgetItem();
item->setBackground(1, bgColor); updateTaskRow(item, *t);
item->setForeground(1, fgColor);
}
if (!t->getPriorityUUID().isEmpty())
{
item->setText(2, getPriorityLabel(t->getPriorityUUID()));
QBrush bgColor = item->background(2);
QBrush fgColor = item->foreground(2);
bgColor.setColor(getPriorityColor(t->getPriorityUUID(), bgColor.color()));
bgColor.setStyle(Qt::BrushStyle::SolidPattern);
fgColor.setColor(Tools::getForegroundColor(bgColor.color()));
item->setBackground(2, bgColor);
item->setForeground(2, fgColor);
}
ui->taskList->addTopLevelItem(item); ui->taskList->addTopLevelItem(item);
} }
} }
} }
void MainWindow::save() void MainWindow::save()

View File

@@ -3,12 +3,14 @@
#include <QMainWindow> #include <QMainWindow>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
#include <QListWidgetItem>
#include <QBrush> #include <QBrush>
#include <QJsonDocument> #include <QJsonDocument>
#include "../models/priority.h" #include "../models/priority.h"
#include "../models/status.h" #include "../models/status.h"
#include "../models/board.h" #include "../models/board.h"
#include "../models/filter.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }
@@ -27,12 +29,17 @@ private slots:
void openAbout(); void openAbout();
void onNewBoardClick(); void onNewBoardClick();
void onNewTaskClick(); void onNewTaskClick();
void onNewFilterClick();
void onBoardSelected(int i); void onBoardSelected(int i);
void onFilterSelected(int i);
void onEditTask(QTreeWidgetItem*); void onEditTask(QTreeWidgetItem*);
void onRemoveBoardMenu(); void onRemoveBoardMenu();
void onRemoveTaskMenu(); void onRemoveTaskMenu();
void onRemoveFilterMenu();
void onEditNameBoardMenu(); void onEditNameBoardMenu();
void onEditNameTaskMenu(); void onEditNameTaskMenu();
void onEditFilterMenu();
void prepareFilterMenu(const QPoint &pos);
void prepareBoardMenu(const QPoint &pos); void prepareBoardMenu(const QPoint &pos);
void prepareTaskMenu(const QPoint &pos); void prepareTaskMenu(const QPoint &pos);
@@ -42,12 +49,22 @@ private:
void init(); void init();
int16_t selectedBoardIndex; int16_t selectedBoardIndex;
int16_t selectedFilterIndex;
QListWidgetItem *menuSelectedFilterItem;
QListWidgetItem *menuSelectedBoardItem;
QTreeWidgetItem *menuSelectedTaskItem;
QVector<Task*> filterResult;
QVector<Priority> priorities; QVector<Priority> priorities;
QVector<Status> status; QVector<Status> status;
QVector<Board*> boards; QVector<Board*> boards;
QVector<Filter> filters;
QVector<Priority> defaultPriorities(); QVector<Priority> defaultPriorities();
QVector<Status> defaultStatus(); QVector<Status> defaultStatus();
QVector<Filter> defaultFilters();
const QString getPriorityLabel(QString uuid); const QString getPriorityLabel(QString uuid);
const QString getStatusLabel(QString uuid); const QString getStatusLabel(QString uuid);
@@ -57,7 +74,11 @@ private:
const QJsonDocument getJsonSave(); const QJsonDocument getJsonSave();
Task *getSelectedTask();
void updateTaskRow(QTreeWidgetItem *item, Task t);
void redrawBoardList(); void redrawBoardList();
void redrawFilterList();
void redrawTaskTree(); void redrawTaskTree();
void save(); void save();
}; };

View File

@@ -26,6 +26,41 @@
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Filters</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="filterListWidget">
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>250</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Boards</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QListWidget" name="boardList"> <widget class="QListWidget" name="boardList">
<property name="minimumSize"> <property name="minimumSize">
@@ -45,17 +80,29 @@
</property> </property>
</widget> </widget>
</item> </item>
</layout>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="font"> <property name="font">
<font> <font>
<pointsize>26</pointsize> <pointsize>19</pointsize>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;- Select a board</string> <string>No board selected</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="boardDescription">
<property name="text">
<string>Create or select a board to start</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -101,7 +148,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1159</width> <width>1159</width>
<height>24</height> <height>23</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuAbout"> <widget class="QMenu" name="menuAbout">
@@ -117,6 +164,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">
@@ -128,15 +176,49 @@
<addaction name="menuTask"/> <addaction name="menuTask"/>
<addaction name="menuAbout"/> <addaction name="menuAbout"/>
</widget> </widget>
<widget class="QToolBar" name="toolBar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>toolBar</string>
</property>
<property name="movable">
<bool>false</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="floatable">
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionNew"/>
<addaction name="actionNew_task"/>
<addaction name="separator"/>
<addaction name="actionNew_filter"/>
</widget>
<action name="actionPreferences"> <action name="actionPreferences">
<property name="text"> <property name="text">
<string>Preferences</string> <string>Preferences</string>
</property> </property>
</action> </action>
<action name="actionNew"> <action name="actionNew">
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/images/resources/board_add.png</normaloff>:/images/resources/board_add.png</iconset>
</property>
<property name="text"> <property name="text">
<string>New Board</string> <string>New Board</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+N, Ctrl+B</string>
</property>
</action> </action>
<action name="actionAbout"> <action name="actionAbout">
<property name="text"> <property name="text">
@@ -147,11 +229,32 @@
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/images/resources/task_add.png</normaloff>:/images/resources/task_add.png</iconset>
</property>
<property name="text"> <property name="text">
<string>New task</string> <string>New task</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+N, Ctrl+T</string>
</property>
</action>
<action name="actionNew_filter">
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/images/resources/add_filter.png</normaloff>:/images/resources/add_filter.png</iconset>
</property>
<property name="text">
<string>New filter</string>
</property>
<property name="shortcut">
<string>Ctrl+N, Ctrl+F</string>
</property>
</action> </action>
</widget> </widget>
<resources/> <resources>
<include location="../../resources.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@@ -1,7 +1,7 @@
#include "namedialog.h" #include "namedialog.h"
#include "ui_namedialog.h" #include "ui_namedialog.h"
NameDialog::NameDialog(QString label, QString defaultName, QWidget *parent) : NameDialog::NameDialog(QString label, QString defaultName, QString description, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::NameDialog) ui(new Ui::NameDialog)
{ {
@@ -9,6 +9,7 @@ NameDialog::NameDialog(QString label, QString defaultName, QWidget *parent) :
this->setWindowTitle(label); this->setWindowTitle(label);
this->defaultName = defaultName; this->defaultName = defaultName;
ui->lineEdit->setText(defaultName); ui->lineEdit->setText(defaultName);
ui->descriptionTextEdit->setPlainText(description);
} }
NameDialog::~NameDialog() NameDialog::~NameDialog()
@@ -24,3 +25,10 @@ const QString NameDialog::getChoosenName()
} }
return defaultName; return defaultName;
} }
const QString NameDialog::getDescription()
{
return ui->descriptionTextEdit->toPlainText();
}

View File

@@ -12,9 +12,10 @@ class NameDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit NameDialog(QString label, QString defaultName, QWidget *parent = nullptr); explicit NameDialog(QString label, QString defaultName, QString description, QWidget *parent = nullptr);
~NameDialog(); ~NameDialog();
const QString getChoosenName(); const QString getChoosenName();
const QString getDescription();
private: private:
Ui::NameDialog *ui; Ui::NameDialog *ui;

View File

@@ -10,19 +10,19 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>400</width>
<height>133</height> <height>227</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>400</width> <width>400</width>
<height>133</height> <height>227</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>400</width> <width>400</width>
<height>133</height> <height>227</height>
</size> </size>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -34,8 +34,8 @@
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>40</x> <x>50</x>
<y>90</y> <y>190</y>
<width>341</width> <width>341</width>
<height>32</height> <height>32</height>
</rect> </rect>
@@ -51,7 +51,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>50</y> <y>33</y>
<width>381</width> <width>381</width>
<height>21</height> <height>21</height>
</rect> </rect>
@@ -61,7 +61,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>30</y> <y>13</y>
<width>58</width> <width>58</width>
<height>16</height> <height>16</height>
</rect> </rect>
@@ -70,6 +70,29 @@
<string>Name</string> <string>Name</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>181</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Description</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="descriptionTextEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>381</width>
<height>91</height>
</rect>
</property>
</widget>
</widget> </widget>
<resources/> <resources/>
<connections> <connections>

View File

@@ -124,6 +124,9 @@
<height>21</height> <height>21</height>
</rect> </rect>
</property> </property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget> </widget>
<widget class="QToolButton" name="colorStatusButton"> <widget class="QToolButton" name="colorStatusButton">
<property name="enabled"> <property name="enabled">
@@ -145,7 +148,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>570</x> <x>570</x>
<y>300</y> <y>310</y>
<width>41</width> <width>41</width>
<height>32</height> <height>32</height>
</rect> </rect>
@@ -161,9 +164,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>520</x> <x>520</x>
<y>300</y> <y>310</y>
<width>41</width> <width>41</width>
<height>32</height> <height>31</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
@@ -213,6 +216,9 @@
<height>21</height> <height>21</height>
</rect> </rect>
</property> </property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget> </widget>
<widget class="QListWidget" name="priorityListWidget"> <widget class="QListWidget" name="priorityListWidget">
<property name="geometry"> <property name="geometry">
@@ -257,7 +263,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>570</x> <x>570</x>
<y>300</y> <y>310</y>
<width>41</width> <width>41</width>
<height>32</height> <height>32</height>
</rect> </rect>
@@ -273,7 +279,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>520</x> <x>520</x>
<y>300</y> <y>310</y>
<width>41</width> <width>41</width>
<height>32</height> <height>32</height>
</rect> </rect>

View File

@@ -2,20 +2,29 @@
#define NAME_KEY "name" #define NAME_KEY "name"
#define TASKS_KEY "tasks" #define TASKS_KEY "tasks"
#define UUID_KEY "uuid"
#define DESCRIPTION_KEY "description"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonValue> #include <QJsonValue>
#include <QUuid>
Board::Board(QString name) Board::Board(QString name, QString description)
{ {
QUuid uuid = QUuid::createUuid();
this->uuid = uuid.toString(QUuid::WithoutBraces);
this->name = name; this->name = name;
this->description = description;
} }
Board::Board(QJsonObject obj) Board::Board(QJsonObject obj)
{ {
this->name = obj[NAME_KEY].toString(); QUuid uuid = QUuid::createUuid();
this->uuid = obj[UUID_KEY].toString(uuid.toString(QUuid::WithoutBraces));
this->name = obj[NAME_KEY].toString("!Missing name!");
this->description = obj[DESCRIPTION_KEY].toString("");
QJsonArray jsonTasks = obj[TASKS_KEY].toArray(); QJsonArray jsonTasks = obj[TASKS_KEY].toArray();
for (QJsonValue value : jsonTasks) { foreach (QJsonValue value, jsonTasks) {
Task *t = new Task(value.toObject()); Task *t = new Task(value.toObject());
this->tasks.append(t); this->tasks.append(t);
} }
@@ -30,16 +39,31 @@ Board::~Board()
} }
} }
const QString Board::getUuid()
{
return uuid;
}
const QString Board::getName() const QString Board::getName()
{ {
return name; return name;
} }
const QString Board::getDescription()
{
return description;
}
void Board::setName(const QString name) void Board::setName(const QString name)
{ {
this->name = name; this->name = name;
} }
void Board::setDescription(const QString description)
{
this->description = description;
}
void Board::add(Task t) void Board::add(Task t)
{ {
tasks.append(new Task(t)); tasks.append(new Task(t));
@@ -75,7 +99,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[TASKS_KEY] = array; obj[TASKS_KEY] = array;
obj[DESCRIPTION_KEY] = description;
return obj; return obj;
} }

View File

@@ -10,12 +10,15 @@
class Board class Board
{ {
public: public:
Board(QString name); Board(QString name, QString description);
Board(QJsonObject); Board(QJsonObject);
~Board(); ~Board();
const QString getUuid();
const QString getName(); const QString getName();
const QString getDescription();
void setName(const QString name); void setName(const QString name);
void setDescription(const QString description);
void add(Task); void add(Task);
void remove(uint16_t index); void remove(uint16_t index);
Task *taskAt(uint16_t); Task *taskAt(uint16_t);
@@ -25,7 +28,9 @@ public:
private: private:
QVector<Task*> tasks; QVector<Task*> tasks;
QString uuid;
QString name; QString name;
QString description;
}; };

196
src/models/filter.cpp Normal file
View File

@@ -0,0 +1,196 @@
#include "filter.h"
#include "qjsonarray.h"
#define NAME_KEY "name"
#define DESCRIPTION_KEY "description"
#define DATE_KEY "date"
#define BOARDS_KEY "boards"
#define STATUS_KEY "status"
#define PRIORITY_KEY "priority"
Filter::Filter(QString name, QString description, uint8_t expectedForComparator, QVector<QString> boards, QVector<QString> status, QVector<QString> priorities)
{
this->name = name;
this->description = description;
this->expectedForComparator = expectedForComparator;
this->boards = boards;
this->status = status;
this->priorities = priorities;
}
Filter::Filter(QJsonObject obj)
{
this->name = obj[NAME_KEY].toString("!Missing name!");
this->description = obj[DESCRIPTION_KEY].toString();
this->expectedForComparator = obj[DATE_KEY].toInt();
QJsonArray b = obj[BOARDS_KEY].toArray();
QJsonArray s = obj[STATUS_KEY].toArray();
QJsonArray p = obj[PRIORITY_KEY].toArray();
foreach (QJsonValue value, b)
{
if (value.isString())
{
boards.append(value.toString());
}
}
foreach (QJsonValue value, s)
{
if (value.isString())
{
status.append(value.toString());
}
}
foreach (QJsonValue value, p)
{
if (value.isString())
{
priorities.append(value.toString());
}
}
}
QVector<Task *> Filter::filter(QVector<Board *> allBoards)
{
QDate now = QDate::currentDate();
QVector<Board*> selectedBoards;
if (this->boards.count() > 0)
{
for (Board *b : allBoards)
{
foreach (QString boardUuid, this->boards)
{
if (b->getUuid() == boardUuid)
{
selectedBoards.append(b);
}
}
}
}
else
{
selectedBoards = allBoards;
}
bool fstatus, fpriority, fdate;
QVector<Task*> result;
for (Board *b : selectedBoards)
{
for (Task *t : b->getTasks())
{
fstatus = filterStatus(t);
fpriority = filterPriority(t);
fdate = filterDate(t, now);
if (fstatus && fpriority && fdate)
{
result.append(t);
}
}
}
return result;
}
bool Filter::filterStatus(Task *t)
{
if (status.count() == 0)
{
return true;
}
bool result = false;
foreach (QString s, status)
{
if (t->getStatusUUID() == s)
{
result = true;
}
}
return result;
}
bool Filter::filterPriority(Task *t)
{
if (priorities.count() == 0)
{
return true;
}
bool result = false;
foreach (QString p, priorities)
{
if (t->getPriorityUUID() == p)
{
result = true;
}
}
return result;
}
bool Filter::filterDate(Task *t, QDate now)
{
switch (expectedForComparator) {
case 0:
return true;
case 1:
return t->getExpectedFor() < now;
case 2:
return t->getExpectedFor() == now;
case 3:
return t->getExpectedFor() > now;
}
return false;
}
const QString Filter::getName()
{
return name;
}
const QString Filter::getDescription()
{
return description;
}
uint8_t Filter::getExpectedForComparator()
{
return expectedForComparator;
}
const QVector<QString> Filter::getBoards()
{
return boards;
}
const QVector<QString> Filter::getStatus()
{
return status;
}
const QVector<QString> Filter::getPriorities()
{
return priorities;
}
const QJsonObject Filter::toJson()
{
QJsonObject obj;
obj[NAME_KEY] = name;
obj[DESCRIPTION_KEY] = description;
obj[DATE_KEY] = expectedForComparator;
QJsonArray b;
foreach (QString uuid, boards)
{
b.append(uuid);
}
QJsonArray s;
foreach (QString uuid, status)
{
s.append(uuid);
}
QJsonArray p;
foreach (QString uuid, priorities)
{
p.append(uuid);
}
obj[BOARDS_KEY] = b;
obj[STATUS_KEY] = s;
obj[PRIORITY_KEY] = p;
return obj;
}

43
src/models/filter.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef FILTER_H
#define FILTER_H
#include <QVector>
#include <QString>
#include <QJsonObject>
#include "task.h"
#include "board.h"
class Filter
{
private:
QString name;
QString description;
// 0 none, 1 lower, 2 equal, 3 upper
uint8_t expectedForComparator;
// if empty => all
QVector<QString> boards;
QVector<QString> status;
QVector<QString> priorities;
bool filterStatus(Task *t);
bool filterPriority(Task *t);
bool filterDate(Task *t, QDate now);
public:
Filter(QString name, QString description, uint8_t expectedForComparator,QVector<QString> boards,QVector<QString> status,QVector<QString> priorities);
Filter(QJsonObject obj);
QVector<Task*> filter(QVector<Board*>);
const QString getName();
const QString getDescription();
uint8_t getExpectedForComparator();
const QVector<QString> getBoards();
const QVector<QString> getStatus();
const QVector<QString> getPriorities();
const QJsonObject toJson();
};
#endif // FILTER_H

View File

@@ -4,6 +4,8 @@
#define NAME_KEY "name" #define NAME_KEY "name"
#define COLOR_KEY "color" #define COLOR_KEY "color"
#include <QUuid>
Priority::Priority(QString uuid, QString name, QColor color) Priority::Priority(QString uuid, QString name, QColor color)
{ {
this->uuid = uuid; this->uuid = uuid;
@@ -13,9 +15,10 @@ Priority::Priority(QString uuid, QString name, QColor color)
Priority::Priority(QJsonObject obj) Priority::Priority(QJsonObject obj)
{ {
this->uuid = obj[UUID_KEY].toString(); QUuid uuid = QUuid::createUuid();
this->name = obj[NAME_KEY].toString(); this->uuid = obj[UUID_KEY].toString(uuid.toString(QUuid::WithoutBraces));
this->color = QColor(obj[COLOR_KEY].toString()); this->name = obj[NAME_KEY].toString("!Missing name!");
this->color = QColor(obj[COLOR_KEY].toString("#ffffff"));
} }
const QString Priority::getName() const QString Priority::getName()

View File

@@ -4,6 +4,8 @@
#define NAME_KEY "name" #define NAME_KEY "name"
#define COLOR_KEY "color" #define COLOR_KEY "color"
#include <QUuid>
Status::Status(QString uuid, QString name, QColor color) Status::Status(QString uuid, QString name, QColor color)
{ {
this->uuid = uuid; this->uuid = uuid;
@@ -13,9 +15,10 @@ Status::Status(QString uuid, QString name, QColor color)
Status::Status(QJsonObject obj) Status::Status(QJsonObject obj)
{ {
this->uuid = obj[UUID_KEY].toString(); QUuid uuid = QUuid::createUuid();
this->name = obj[NAME_KEY].toString(); this->uuid = obj[UUID_KEY].toString(uuid.toString(QUuid::WithoutBraces));
this->color = QColor(obj[COLOR_KEY].toString()); this->name = obj[NAME_KEY].toString("!Missing name!");
this->color = QColor(obj[COLOR_KEY].toString("#ffffff"));
} }
const QString Status::getName() const QString Status::getName()

View File

@@ -5,9 +5,14 @@
#define EXPECTEDFOR_KEY "expected_for" #define EXPECTEDFOR_KEY "expected_for"
#define PRIORITY_KEY "priority" #define PRIORITY_KEY "priority"
#define STATUS_KEY "status" #define STATUS_KEY "status"
#define UUID_KEY "uuid"
#include <QUuid>
Task::Task(QString title, QString description, QDate expectedFor, QString priorityUUID, QString statusUUID) Task::Task(QString title, QString description, QDate expectedFor, QString priorityUUID, QString statusUUID)
{ {
QUuid uuid = QUuid::createUuid();
this->uuid = uuid.toString(QUuid::WithoutBraces);
this->title = title; this->title = title;
this->description = description; this->description = description;
this->expectedFor = expectedFor; this->expectedFor = expectedFor;
@@ -17,6 +22,8 @@ Task::Task(QString title, QString description, QDate expectedFor, QString priori
Task::Task(QJsonObject obj) Task::Task(QJsonObject obj)
{ {
QUuid uuid = QUuid::createUuid();
this->uuid = obj[UUID_KEY].toString(uuid.toString(QUuid::WithoutBraces));
this->title = obj[TITLE_KEY].toString(); this->title = obj[TITLE_KEY].toString();
this->description = obj[DESCRIPTION_KEY].toString(); this->description = obj[DESCRIPTION_KEY].toString();
this->expectedFor = QDate::fromString(obj[EXPECTEDFOR_KEY].toString(), Qt::DateFormat::ISODate); this->expectedFor = QDate::fromString(obj[EXPECTEDFOR_KEY].toString(), Qt::DateFormat::ISODate);
@@ -24,6 +31,11 @@ Task::Task(QJsonObject obj)
this->statusUUID = obj[STATUS_KEY].toString(); this->statusUUID = obj[STATUS_KEY].toString();
} }
const QString Task::getUuid()
{
return this->uuid;
}
const QString Task::getTitle() const QString Task::getTitle()
{ {
return this->title; return this->title;

View File

@@ -11,6 +11,7 @@ public:
Task(QString title, QString description, QDate expectedFor, QString priorityUUID, QString statusUUID); Task(QString title, QString description, QDate expectedFor, QString priorityUUID, QString statusUUID);
Task(QJsonObject); Task(QJsonObject);
const QString getUuid();
const QString getTitle(); const QString getTitle();
const QString getDescription(); const QString getDescription();
const QDate getExpectedFor(); const QDate getExpectedFor();
@@ -21,6 +22,7 @@ public:
void update(Task); void update(Task);
private: private:
QString uuid;
QString title; QString title;
QString description; QString description;
QDate expectedFor; QDate expectedFor;