File indexing completed on 2024-06-16 04:16:27

0001 /*
0002  * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #include "TableModel.h"
0007 
0008 #include <QApplication>
0009 
0010 TableDelegate::TableDelegate(QObject *parent)
0011     : QSqlRelationalDelegate(parent)
0012 {}
0013 
0014 QRect getNewRect(const QStyleOptionViewItem &option)
0015 {
0016     // get the rectangle in the middle of the field
0017     const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
0018     QRect newRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
0019                                         QSize(option.decorationSize.width() +
0020                                               5,option.decorationSize.height()),
0021                                         QRect(option.rect.x() + textMargin, option.rect.y(),
0022                                               option.rect.width() -
0023                                               (2 * textMargin), option.rect.height()));
0024     return newRect;
0025 }
0026 
0027 void TableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0028 {
0029     QStyleOptionViewItem viewItemOption(option);
0030     // Only do this if we are accessing the column with boolean variables.
0031     if (m_booleanColumns.contains(index.column())) {
0032         // This basically changes the rectangle in which the check box is drawn.
0033         viewItemOption.rect = getNewRect(option);
0034     }
0035     // Draw the check box using the new rectangle.
0036     QSqlRelationalDelegate::paint(painter, viewItemOption, index);
0037 }
0038 
0039 QSize TableDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0040 {
0041     return QSqlRelationalDelegate::sizeHint(option, index);
0042 }
0043 
0044 bool TableDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
0045 {
0046     if (m_editable) {
0047         if (m_booleanColumns.contains(index.column())) {
0048             QStyleOptionViewItem optionCheckable = option;
0049             optionCheckable.rect = getNewRect(option);
0050             optionCheckable.features |= QStyleOptionViewItem::HasCheckIndicator;
0051             return QSqlRelationalDelegate::editorEvent(event, model, optionCheckable, index);
0052         } else {
0053             return QSqlRelationalDelegate::editorEvent(event, model, option, index);
0054         }
0055     }
0056     return false;
0057 }
0058 
0059 QWidget *TableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
0060 {
0061     if (m_editable) {
0062         if (m_booleanColumns.contains(index.column())) {
0063             QStyleOptionViewItem optionCheckable = option;
0064             optionCheckable.features |= QStyleOptionViewItem::HasCheckIndicator;
0065             optionCheckable.rect = getNewRect(option);
0066             return QSqlRelationalDelegate::createEditor(parent, optionCheckable, index);
0067         } else {
0068             return QSqlRelationalDelegate::createEditor(parent, option, index);
0069         }
0070     }
0071     return 0;
0072 }
0073 
0074 void TableDelegate::addDateTimeColumn(int column)
0075 {
0076     m_dateTimeColumns << column;
0077 }
0078 
0079 void TableDelegate::addBooleanColumn(int column)
0080 {
0081     m_booleanColumns << column;
0082 }
0083 
0084 void TableDelegate::setEditable(bool editable)
0085 {
0086     m_editable = editable;
0087 }
0088 
0089 
0090 TableModel::TableModel(QObject *parent, QSqlDatabase db)
0091     : QSqlRelationalTableModel(parent, db)
0092 {
0093     this->setEditStrategy(QSqlTableModel::OnFieldChange);
0094 }
0095 
0096 TableModel::~TableModel()
0097 {
0098 
0099 }
0100 
0101 QVariant TableModel::data(const QModelIndex &index, int role) const
0102 {
0103     QVariant d = QSqlRelationalTableModel::data(index, role);
0104     if (role == Qt::DisplayRole) {
0105         if (m_dateTimeColumns.contains(index.column())) {
0106             return QDateTime::fromSecsSinceEpoch(d.toInt()).toString();
0107         } else if (m_booleanColumns.contains(index.column())) {
0108             return {};
0109         }
0110     }
0111     else if (role == Qt::CheckStateRole) {
0112         if (m_booleanColumns.contains(index.column())) {
0113             if (d.toInt() == 0) {
0114                 return Qt::Unchecked;
0115             }
0116             else {
0117                 return Qt::Checked;
0118             }
0119         }
0120         return {};
0121     }
0122     return d;
0123 }
0124 
0125 bool TableModel::setData(const QModelIndex & index, const QVariant & value, int role)
0126 {
0127     if (m_booleanColumns.contains(index.column()) && role == Qt::CheckStateRole) {
0128         // Writing the data when the check box is set to checked.
0129         if (value == Qt::Checked) {
0130             // Let's write the new value
0131             return QSqlTableModel::setData(index, 1, Qt::EditRole);
0132             // Writing the data when the check box is set to unchecked
0133         } else if (value == Qt::Unchecked) {
0134             // Let's write the new value
0135             return QSqlTableModel::setData(index, 0, Qt::EditRole);
0136         }
0137     }
0138 
0139     bool response = QSqlTableModel::setData(index, value, role);
0140     return response;
0141 }
0142 
0143 Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
0144 {
0145     Qt::ItemFlags f = QSqlRelationalTableModel::flags((index));
0146     if (m_booleanColumns.contains(index.column())) {
0147         f |= Qt::ItemIsUserCheckable;
0148     }
0149     return f;
0150 
0151 }
0152 
0153 void TableModel::addDateTimeColumn(int column)
0154 {
0155     m_dateTimeColumns << column;
0156 }
0157 
0158 void TableModel::addBooleanColumn(int column)
0159 {
0160     m_booleanColumns << column;
0161 }