File indexing completed on 2024-05-19 04:56:08

0001 /**
0002  * \file standardtablemodel.h
0003  * Table model with containing values for multiple roles.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 12 Jul 2019
0008  *
0009  * Copyright (C) 2019-2024  Urs Fleisch
0010  *
0011  * This file is part of Kid3.
0012  *
0013  * Kid3 is free software; you can redistribute it and/or modify
0014  * it under the terms of the GNU General Public License as published by
0015  * the Free Software Foundation; either version 2 of the License, or
0016  * (at your option) any later version.
0017  *
0018  * Kid3 is distributed in the hope that it will be useful,
0019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0021  * GNU General Public License for more details.
0022  *
0023  * You should have received a copy of the GNU General Public License
0024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0025  */
0026 
0027 #include "standardtablemodel.h"
0028 
0029 StandardTableModel::StandardTableModel(QObject* parent)
0030   : QAbstractTableModel(parent),
0031     m_numColumns(1)
0032 {
0033 }
0034 
0035 Qt::ItemFlags StandardTableModel::flags(const QModelIndex& index) const
0036 {
0037   if (!index.isValid())
0038     return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled;
0039 
0040   return QAbstractItemModel::flags(index) | Qt::ItemIsEditable |
0041       Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
0042 }
0043 
0044 QVariant StandardTableModel::headerData(
0045     int section, Qt::Orientation orientation, int role) const
0046 {
0047   if (orientation == Qt::Horizontal && role == Qt::DisplayRole &&
0048       section >= 0 && section < m_horizontalHeaderLabels.size()) {
0049     return m_horizontalHeaderLabels.at(section);
0050   }
0051   return QAbstractTableModel::headerData(section, orientation, role);
0052 }
0053 
0054 bool StandardTableModel::setHeaderData(
0055     int section, Qt::Orientation orientation, const QVariant& value, int role)
0056 {
0057   if (orientation == Qt::Horizontal &&
0058       (role == Qt::DisplayRole || role == Qt::EditRole) &&
0059       section >= 0 && section < columnCount()) {
0060     if (section >= m_horizontalHeaderLabels.size()) {
0061       m_horizontalHeaderLabels.resize(section + 1);
0062     }
0063     m_horizontalHeaderLabels[section] = value.toString();
0064     return true;
0065   }
0066   return false;
0067 }
0068 
0069 Qt::DropActions StandardTableModel::supportedDropActions() const
0070 {
0071   return QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
0072 }
0073 
0074 int StandardTableModel::rowCount(const QModelIndex& parent) const
0075 {
0076   return parent.isValid() ? 0 : m_cont.size();
0077 }
0078 
0079 int StandardTableModel::columnCount(const QModelIndex& parent) const
0080 {
0081   return parent.isValid() ? 0 : m_numColumns;
0082 }
0083 
0084 QVariant StandardTableModel::data(const QModelIndex& index, int role) const
0085 {
0086   const int row = index.row(), column = index.column();
0087   if (row < 0 || row >= m_cont.size() ||
0088       column < 0 || column >= m_numColumns)
0089     return QVariant();
0090 
0091   if (role == Qt::EditRole)
0092     role = Qt::DisplayRole;
0093 
0094   const auto& r = m_cont.at(row);
0095   return column < r.size() ? r.at(column).value(role) : QVariant();
0096 }
0097 
0098 bool StandardTableModel::setData(const QModelIndex& index,
0099                                       const QVariant& value, int role)
0100 {
0101   const int row = index.row(), column = index.column();
0102   if (row < 0 || row >= m_cont.size() ||
0103       column < 0 || column >= m_numColumns)
0104     return false;
0105 
0106   if (role == Qt::EditRole)
0107     role = Qt::DisplayRole;
0108 
0109   auto& r = m_cont[row];
0110   if (column >= r.size())
0111     r.resize(m_numColumns);
0112 
0113   auto& c = r[column];
0114   if (auto it = c.find(role); it != c.end()) {
0115     if (*it != value) {
0116       *it = value;
0117       emit dataChanged(index, index);
0118     }
0119   } else {
0120     c.insert(role, value);
0121   }
0122   return true;
0123 }
0124 
0125 bool StandardTableModel::insertRows(int row, int count,
0126                                    const QModelIndex& parent)
0127 {
0128   if (count < 1 || row < 0 || row > rowCount(parent))
0129     return false;
0130   beginInsertRows(QModelIndex(), row, row + count - 1);
0131   m_cont.insert(row, count, {});
0132   endInsertRows();
0133   return true;
0134 }
0135 
0136 bool StandardTableModel::removeRows(int row, int count,
0137                                    const QModelIndex& parent)
0138 {
0139   if (count <= 0 || row < 0 || row + count > rowCount(parent))
0140     return false;
0141   beginRemoveRows(QModelIndex(), row, row + count - 1);
0142   m_cont.remove(row, count);
0143   endRemoveRows();
0144   return true;
0145 }
0146 
0147 void StandardTableModel::setColumnCount(int columns)
0148 {
0149   if (m_numColumns < columns) {
0150     beginInsertColumns(QModelIndex(), m_numColumns, columns - 1);
0151     m_numColumns = columns;
0152     endInsertColumns();
0153   } else if (m_numColumns > columns) {
0154     beginRemoveColumns(QModelIndex(), columns, m_numColumns - 1);
0155     m_numColumns = columns;
0156     endRemoveColumns();
0157   }
0158 }
0159 
0160 void StandardTableModel::setHorizontalHeaderLabels(
0161     const QStringList& labels)
0162 {
0163   if (labels.size() <= columnCount()) {
0164     m_horizontalHeaderLabels = labels.toVector();
0165   }
0166 }
0167 
0168 void StandardTableModel::clear()
0169 {
0170   if (m_cont.size() > 0) {
0171     beginRemoveRows(QModelIndex(), 0, m_cont.size() - 1);
0172     m_cont.clear();
0173     endRemoveRows();
0174   }
0175 }