From 22ebe6eded9b24eb46f392986a344a60e7f2d68f Mon Sep 17 00:00:00 2001 From: Aurelie Delhaie Date: Mon, 20 Feb 2023 16:51:21 +0100 Subject: [PATCH] fix out of bound crash when edit or remove a board, add board config dialog, fix glibc version in about dialog --- TaskBoard.pro | 3 + src/frames/aboutdialog.cpp | 6 +- src/frames/boardconfigdialog.cpp | 75 +++++++++++++++++++ src/frames/boardconfigdialog.h | 32 +++++++++ src/frames/boardconfigdialog.ui | 119 +++++++++++++++++++++++++++++++ src/frames/mainwindow.cpp | 82 ++++++++++++++++++--- src/frames/mainwindow.ui | 3 + src/frames/taskdialog.cpp | 90 ++++++++++------------- src/frames/taskdialog.h | 5 +- src/models/board.cpp | 12 ++++ src/models/board.h | 6 ++ 11 files changed, 364 insertions(+), 69 deletions(-) create mode 100644 src/frames/boardconfigdialog.cpp create mode 100644 src/frames/boardconfigdialog.h create mode 100644 src/frames/boardconfigdialog.ui diff --git a/TaskBoard.pro b/TaskBoard.pro index 4dd8303..f00e34e 100644 --- a/TaskBoard.pro +++ b/TaskBoard.pro @@ -68,6 +68,7 @@ linux-* { #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + src/frames/boardconfigdialog.cpp \ src/frames/filterdialog.cpp \ src/frames/aboutdialog.cpp \ src/models/board.cpp \ @@ -84,6 +85,7 @@ SOURCES += \ src/tools.cpp HEADERS += \ + src/frames/boardconfigdialog.h \ src/frames/filterdialog.h \ src/frames/aboutdialog.h \ src/models/board.h \ @@ -99,6 +101,7 @@ HEADERS += \ src/tools.h FORMS += \ + src/frames/boardconfigdialog.ui \ src/frames/filterdialog.ui \ src/frames/aboutdialog.ui \ src/frames/mainwindow.ui \ diff --git a/src/frames/aboutdialog.cpp b/src/frames/aboutdialog.cpp index c5b303d..363eaf1 100644 --- a/src/frames/aboutdialog.cpp +++ b/src/frames/aboutdialog.cpp @@ -1,10 +1,6 @@ #include "aboutdialog.h" #include "ui_aboutdialog.h" -#ifdef unix -#include -#endif - AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) @@ -33,7 +29,7 @@ QString AboutDialog::getCompilerInfo() #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()); + return QString("GLIBC_%1.%2").arg(QString::number(__GLIBC__), QString::number(__GLIBC_MINOR__)); #endif #elif _MSC_VER return QString("MSVC_%1").arg(_MSC_VER); diff --git a/src/frames/boardconfigdialog.cpp b/src/frames/boardconfigdialog.cpp new file mode 100644 index 0000000..f2ebdd6 --- /dev/null +++ b/src/frames/boardconfigdialog.cpp @@ -0,0 +1,75 @@ +#include "boardconfigdialog.h" +#include "ui_boardconfigdialog.h" + +#include "../services/taskstateservice.h" +#include + +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()); + if (!b->isAutoStatus()) + { + QVector statuses = TaskStateService::getInstance()->getStatuses(); + foreach (Status s, statuses) + { + ui->statusCombobox->addItem(s.getName(), s.getUUID()); + } + ui->autoStatusCheckbox->setChecked(false); + ui->statusCombobox->setEnabled(true); + } + connect(ui->autoStatusCheckbox, &QCheckBox::stateChanged, this, &BoardConfigDialog::onAutoStatusCheckboxChange); +} + +BoardConfigDialog::~BoardConfigDialog() +{ + delete ui; +} + +const QString BoardConfigDialog::getName() +{ + return ui->nameField->text(); +} + +const QString BoardConfigDialog::getDescription() +{ + return ui->descriptionField->toPlainText(); +} + +bool BoardConfigDialog::isAutoStatus() +{ + return ui->autoStatusCheckbox->isChecked(); +} + +const QString BoardConfigDialog::getStatus() +{ + if (!ui->autoStatusCheckbox->isChecked()) + { + if (!ui->statusCombobox->currentData().isNull()) + { + return ui->statusCombobox->currentData().toString(); + } + } + return ""; +} + +void BoardConfigDialog::onAutoStatusCheckboxChange(int state) +{ + if (state == Qt::CheckState::Unchecked) + { + QVector 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(); + } +} diff --git a/src/frames/boardconfigdialog.h b/src/frames/boardconfigdialog.h new file mode 100644 index 0000000..fe2c88f --- /dev/null +++ b/src/frames/boardconfigdialog.h @@ -0,0 +1,32 @@ +#ifndef BOARDCONFIGDIALOG_H +#define BOARDCONFIGDIALOG_H + +#include + +#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(); + bool isAutoStatus(); + const QString getStatus(); + +private slots: + void onAutoStatusCheckboxChange(int); + +private: + Ui::BoardConfigDialog *ui; +}; + +#endif // BOARDCONFIGDIALOG_H diff --git a/src/frames/boardconfigdialog.ui b/src/frames/boardconfigdialog.ui new file mode 100644 index 0000000..4eab8d5 --- /dev/null +++ b/src/frames/boardconfigdialog.ui @@ -0,0 +1,119 @@ + + + BoardConfigDialog + + + + 0 + 0 + 400 + 379 + + + + Board Configuration + + + + + + Name + + + + + + + + + + Description + + + + + + + + + + Qt::Horizontal + + + + + + + Auto determine status + + + true + + + + + + + + + Status + + + + + + + false + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + BoardConfigDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + BoardConfigDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frames/mainwindow.cpp b/src/frames/mainwindow.cpp index eac6c84..eaec679 100644 --- a/src/frames/mainwindow.cpp +++ b/src/frames/mainwindow.cpp @@ -17,6 +17,7 @@ #include "namedialog.h" #include "taskdialog.h" #include "filterdialog.h" +#include "boardconfigdialog.h" #include "../tools.h" #include "../services/taskstateservice.h" @@ -197,7 +198,16 @@ void MainWindow::onBoardSelected(int i) { Board *b = boards[selectedBoardIndex]; ui->label->setText(b->getName()); - ui->boardDescription->setText(b->getDescription()); + if (b->getDescription().length() > 0) + { + ui->boardDescription->setText(b->getDescription()); + ui->boardDescription->setEnabled(true); + } + else + { + ui->boardDescription->setText("No description"); + ui->boardDescription->setEnabled(false); + } ui->actionNew_task->setDisabled(false); } else @@ -224,7 +234,16 @@ void MainWindow::onFilterSelected(int i) { Filter f = filters[selectedFilterIndex]; ui->label->setText(f.getName()); - ui->boardDescription->setText(f.getDescription()); + if (f.getDescription().length() > 0) + { + ui->boardDescription->setText(f.getDescription()); + ui->boardDescription->setEnabled(true); + } + else + { + ui->boardDescription->setText("No description"); + ui->boardDescription->setEnabled(false); + } } else { @@ -259,7 +278,11 @@ void MainWindow::onRemoveBoardMenu() { if (menuSelectedBoardItem != nullptr) { - int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row(); + 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?"); if (result == QMessageBox::Yes) { @@ -296,6 +319,10 @@ void MainWindow::onRemoveFilterMenu() 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?"); if (result == QMessageBox::Yes) { @@ -315,20 +342,50 @@ void MainWindow::onEditNameBoardMenu() { if (menuSelectedBoardItem != nullptr) { - int i = ui->filterListWidget->indexFromItem(menuSelectedFilterItem).row(); + int i = ui->boardList->indexFromItem(menuSelectedBoardItem).row(); + if (i == -1) + { + return; + } Board *b = boards.at(i); - NameDialog dialog("Edit board name", b->getName(), b->getDescription(), this); + BoardConfigDialog dialog(b, this); if (dialog.exec() == QDialog::DialogCode::Accepted) { - QString newName = dialog.getChoosenName(); + QString newName = dialog.getName(); QString newDesc = dialog.getDescription(); b->setName(newName); b->setDescription(newDesc); + if (!dialog.isAutoStatus()) + { + std::optional status = TaskStateService::getInstance()->getStatusByUUID(dialog.getStatus()); + if (status.has_value()) + { + b->setDirtyStatus(status.value()); + } + else + { + b->removeDirtyStatus(); + } + } + else + { + b->removeDirtyStatus(); + } QListWidgetItem *item = ui->boardList->item(i); item->setText(newName); item->setToolTip(newDesc); ui->label->setText(newName); - ui->boardDescription->setText(newDesc); + if (newDesc.length() > 0) + { + ui->boardDescription->setText(newDesc); + ui->boardDescription->setEnabled(true); + } + else + { + ui->boardDescription->setText("No description"); + ui->boardDescription->setEnabled(false); + } + redrawBoardStatus(); save(); } } @@ -358,7 +415,16 @@ void MainWindow::onEditFilterMenu() item->setText(f.getName()); item->setToolTip(f.getDescription()); ui->label->setText(f.getName()); - ui->boardDescription->setText(f.getDescription()); + if (f.getDescription().length() > 0) + { + ui->boardDescription->setText(f.getDescription()); + ui->boardDescription->setEnabled(true); + } + else + { + ui->boardDescription->setText("No description"); + ui->boardDescription->setEnabled(false); + } redrawTaskTree(); save(); } diff --git a/src/frames/mainwindow.ui b/src/frames/mainwindow.ui index f0702e0..2b74a66 100644 --- a/src/frames/mainwindow.ui +++ b/src/frames/mainwindow.ui @@ -52,6 +52,9 @@ 250 + + true + diff --git a/src/frames/taskdialog.cpp b/src/frames/taskdialog.cpp index 79db195..e5eb6a8 100644 --- a/src/frames/taskdialog.cpp +++ b/src/frames/taskdialog.cpp @@ -10,19 +10,8 @@ TaskDialog::TaskDialog(QWidget *parent) : ui(new Ui::TaskDialog) { ui->setupUi(this); + init(); this->setWindowTitle("New task"); - this->status = TaskStateService::getInstance()->getStatuses(); - this->priorities = TaskStateService::getInstance()->getPriorities(); - - foreach (Status s, this->status) - { - ui->statusCombo->addItem(s.getName()); - } - - foreach (Priority p, this->priorities) - { - ui->priorityCombo->addItem(p.getName()); - } QDate expectedFor = QDate::currentDate(); expectedFor = expectedFor.addDays(10); @@ -34,19 +23,8 @@ TaskDialog::TaskDialog(Task *t, QWidget *parent) : ui(new Ui::TaskDialog) { ui->setupUi(this); + init(); this->setWindowTitle("Edit task"); - this->status = TaskStateService::getInstance()->getStatuses(); - this->priorities = TaskStateService::getInstance()->getPriorities(); - - foreach (Status s, this->status) - { - ui->statusCombo->addItem(s.getName()); - } - - foreach (Priority p, this->priorities) - { - ui->priorityCombo->addItem(p.getName()); - } // set fields ui->nameEdit->setText(t->getTitle()); @@ -55,34 +33,12 @@ TaskDialog::TaskDialog(Task *t, QWidget *parent) : if (t->getPriorityUUID().length() > 0) { - int16_t refindex = -1; - 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); - } + initSelectionCombobox(t->getPriorityUUID(), ui->priorityCombo); } if (t->getStatusUUID().length() > 0) { - int16_t refindex = -1; - 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); - } + initSelectionCombobox(t->getStatusUUID(), ui->statusCombo); } } @@ -98,16 +54,42 @@ Task TaskDialog::getTask() QString description = ui->descriptionEdit->toMarkdown(QTextDocument::MarkdownFeature::MarkdownDialectCommonMark); QDate expectedFor = ui->expectedForEdit->date(); QString priorityUUID = ""; - if (ui->priorityCombo->currentIndex() > -1) + if (!ui->priorityCombo->currentData().isNull()) { - Priority priority = priorities[ui->priorityCombo->currentIndex()]; - priorityUUID = priority.getUUID(); + priorityUUID = ui->priorityCombo->currentData().toString(); } QString statusUUID = ""; - if (ui->statusCombo->currentIndex() > -1) + if (!ui->statusCombo->currentData().isNull()) { - Status s = status[ui->statusCombo->currentIndex()]; - statusUUID = s.getUUID(); + statusUUID = ui->statusCombo->currentData().toString(); } return Task(title, description, expectedFor, priorityUUID, statusUUID); } + +void TaskDialog::init() +{ + QVector statuses = TaskStateService::getInstance()->getStatuses(); + QVector 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; + } + } +} diff --git a/src/frames/taskdialog.h b/src/frames/taskdialog.h index 30e0953..64edb9b 100644 --- a/src/frames/taskdialog.h +++ b/src/frames/taskdialog.h @@ -3,6 +3,7 @@ #include #include +#include #include "../models/status.h" #include "../models/priority.h" @@ -26,8 +27,8 @@ public: private: Ui::TaskDialog *ui; - QVector status; - QVector priorities; + void init(); + void initSelectionCombobox(QString uuid, QComboBox *cbx); }; #endif // TASKDIALOG_H diff --git a/src/models/board.cpp b/src/models/board.cpp index b05365f..c6a61e5 100644 --- a/src/models/board.cpp +++ b/src/models/board.cpp @@ -96,6 +96,18 @@ void Board::setDescription(const QString description) this->description = description; } +void Board::setDirtyStatus(Status s) +{ + this->autoStatus = false; + this->statusUUID = s.getUUID(); +} + +void Board::removeDirtyStatus() +{ + this->autoStatus = true; + this->statusUUID = ""; +} + void Board::add(Task t) { tasks.append(new Task(t)); diff --git a/src/models/board.h b/src/models/board.h index 6dd6e0a..3f1343d 100644 --- a/src/models/board.h +++ b/src/models/board.h @@ -6,6 +6,7 @@ #include #include "task.h" +#include "status.h" class Board { @@ -19,10 +20,15 @@ public: const QString getDescription(); const QString getStatus(); bool isAutoStatus(); + void setName(const QString name); void setDescription(const QString description); + void setDirtyStatus(Status s); + void removeDirtyStatus(); + void add(Task); void remove(uint16_t index); + Task *taskAt(uint16_t); const QVector getTasks();