Warning, file /utilities/daykountdown/src/kountdownmodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
0002 // SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
0003 //
0004 // SPDX-LicenseRef: GPL-3.0-or-later
0005 
0006 #include "kountdownmodel.h"
0007 #include "daykountdownconfig.h"
0008 
0009 #include <QCoreApplication>
0010 #include <QDateTime>
0011 #include <QDebug>
0012 #include <QDir>
0013 #include <QStandardPaths>
0014 #include <QSqlRecord>
0015 #include <QSqlError>
0016 
0017 KountdownModel::KountdownModel(QObject *parent)
0018     : QSqlTableModel(parent)
0019 {
0020     // If database does not contain KountdownModel table, then create it
0021     if (!QSqlDatabase::database().tables().contains(QStringLiteral("KountdownModel"))) {
0022         // Statement to be inputted into SQLite
0023         // This is a rawstring
0024         const auto statement = QStringLiteral(R"RAWSTRING(
0025             CREATE TABLE IF NOT EXISTS KountdownModel (
0026                 id INTEGER PRIMARY KEY AUTOINCREMENT,
0027                 name TEXT NOT NULL,
0028                 description TEXT NOT NULL,
0029                 date TEXT NOT NULL,
0030                 dateInMs INTEGER NOT NULL,
0031                 colour TEXT NOT NULL
0032             )
0033         )RAWSTRING");
0034         auto query = QSqlQuery(statement);
0035         // QSqlQuery returns false if query was unsuccessful
0036         if (!query.exec()) {
0037             qCritical() << query.lastError() << "while creating table";
0038         }
0039     }
0040     
0041     //QSqlQuery("DROP TABLE KountdownModel");
0042     
0043     // Sets data table on which the model is going to operate
0044     setTable(QStringLiteral("KountdownModel"));
0045     // All changed will be cached in the model until submitAll() ot revertAll() is called
0046     setEditStrategy(QSqlTableModel::OnManualSubmit);
0047     // Populates the model with data from the table set above
0048     select();
0049 }
0050 
0051 // Returns value for the specified item and role (important when accessed by QML)
0052 // Roles are integers. Feeding certain integer does certain action
0053 QVariant KountdownModel::data(const QModelIndex &index, int role) const
0054 {
0055     if (role == Qt::EditRole) {
0056         return QSqlTableModel::data(index, Qt::EditRole);
0057     }
0058     // ParentColumn defines the piece of data we will take from a record
0059     int parentColumn = 0;
0060     if (role == Qt::UserRole + 0 + 1) { // ID
0061         parentColumn = 0;
0062     } else if (role == Qt::UserRole + 1 + 1) { // Name
0063         parentColumn = 1;
0064     } else if (role == Qt::UserRole + 2 + 1) { // Description
0065         parentColumn = 2;
0066     } else if (role == Qt::UserRole + 3 + 1) { // Date
0067         parentColumn = 3;
0068         // QModelIndex class is used as an index into KountdownModel
0069         // These indexes refer to items in the model
0070         QModelIndex parentIndex = createIndex(index.row(), parentColumn);
0071         // We need to do some conversions for QDateTime class objects
0072         return QDateTime::fromString(QSqlTableModel::data(parentIndex, Qt::DisplayRole).toString(), Qt::ISODate);
0073     } else if (role == Qt::UserRole + 4 + 1) { //DateInMs
0074         parentColumn = 4;
0075     } else if (role == Qt::UserRole + 5 + 1) { // Colour
0076         parentColumn = 5;
0077     }
0078     QModelIndex parentIndex = createIndex(index.row(), parentColumn);
0079     // We return a piece of data at index.row, parentColumn
0080     return QSqlTableModel::data(parentIndex, Qt::DisplayRole);
0081 }
0082 
0083 QHash<int, QByteArray> KountdownModel::roleNames() const
0084 {
0085     QHash<int, QByteArray> roles;
0086     for (int i = 0; i < this->record().count(); i ++) {
0087         roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
0088     }
0089     return roles;
0090 }
0091 
0092 bool KountdownModel::addKountdown(const QString& name, const QString& description, const QDateTime& date, QString colour)
0093 {
0094     // Create new instance of QSqlRecord
0095     // this points towards newRecord itself
0096     // calls record(), which returns a QSqlRecord containing the field information
0097     QSqlRecord newRecord = this->record();
0098     // Set field values
0099     newRecord.setValue(QStringLiteral("Name"), name);
0100     newRecord.setValue(QStringLiteral("Description"), description);
0101     newRecord.setValue(QStringLiteral("Date"), date.toString(Qt::ISODate));
0102     newRecord.setValue(QStringLiteral("DateInMs"), date.toMSecsSinceEpoch());
0103     newRecord.setValue(QStringLiteral("Colour"), colour);
0104     
0105     // insertRecord returns bool
0106     // inserts in last location
0107     bool result = insertRecord(rowCount(), newRecord);
0108     // result = result & submitAll
0109     // submitAll also returns bool
0110     result &= submitAll();
0111     return result;
0112 }
0113 
0114 //Similar to previous function, except result = setRecord instead of insertRecord
0115 bool KountdownModel::editKountdown(int index, const QString& name, const QString& description, const QDateTime& date, QString colour)
0116 {
0117     QSqlRecord record = this->record();
0118     record.setValue(QStringLiteral("ID"), index);
0119     record.setValue(QStringLiteral("Name"), name);
0120     record.setValue(QStringLiteral("Description"), description);
0121     record.setValue(QStringLiteral("Date"), date.toString(Qt::ISODate));
0122     record.setValue(QStringLiteral("DateInMs"), date.toMSecsSinceEpoch());
0123     record.setValue(QStringLiteral("Colour"), colour);
0124     qDebug() << record;
0125     bool result = setRecord(index, record);
0126     qDebug() << result;
0127     result &= submitAll();
0128     qDebug() << result;
0129     qDebug() << KountdownModel::lastError();
0130     return result;
0131 }
0132 
0133 bool KountdownModel::removeKountdown(int index)
0134 {
0135     bool result = removeRow(index);
0136     result &= submitAll();
0137     return result;
0138 }
0139 
0140 bool KountdownModel::removeAllKountdowns()
0141 {
0142     QSqlQuery query;
0143     bool result = query.exec("DELETE FROM KountdownModel");
0144     result &= submitAll();
0145     return result;
0146 }
0147 
0148 void KountdownModel::sortModel(int sort_by) {
0149     // Switch based on enum defined in kountdownmodel.h
0150     switch(sort_by) {
0151         case (AlphabeticalAsc):
0152             // This points to KountdownModel
0153             this->setSort(1, Qt::AscendingOrder);
0154             break;
0155         case (AlphabeticalDesc):
0156             this->setSort(1, Qt::DescendingOrder);
0157             break;
0158         case (DateAsc):
0159             this->setSort(3, Qt::AscendingOrder);
0160             break;
0161         case (DateDesc):
0162             this->setSort(3, Qt::DescendingOrder);
0163             break;
0164         case (CreationDesc):
0165             this->setSort(0, Qt::DescendingOrder);
0166             break;
0167         case (CreationAsc):
0168         default:
0169             this->setSort(0, Qt::AscendingOrder);
0170             break;
0171     }
0172     // Required to update model
0173     select();
0174 
0175     auto config = DayKountdownConfig::self();
0176     config->setCurrentGroup("KountdownSorting");
0177     config->setSortMode(sort_by);
0178     config->save();
0179 }