File indexing completed on 2024-05-26 04:57:57

0001 /**
0002  * \file texttablemodel.cpp
0003  * Model to display a text with tabulators in a table.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 12 Aug 2011
0008  *
0009  * Copyright (C) 2011-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 "texttablemodel.h"
0028 #include <QRegularExpression>
0029 
0030 /**
0031  * Constructor.
0032  * @param parent parent widget
0033  */
0034 TextTableModel::TextTableModel(QObject* parent)
0035   : QAbstractTableModel(parent), m_hasHeaderLine(false)
0036 {
0037   setObjectName(QLatin1String("TextTableModel"));
0038 }
0039 
0040 /**
0041  * Get item flags for index.
0042  * @param index model index
0043  * @return item flags
0044  */
0045 Qt::ItemFlags TextTableModel::flags(const QModelIndex& index) const
0046 {
0047   if (index.isValid())
0048     return Qt::ItemIsEnabled;
0049   return QAbstractTableModel::flags(index);
0050 }
0051 
0052 /**
0053  * Get data for a given role.
0054  * @param index model index
0055  * @param role item data role
0056  * @return data for role
0057  */
0058 QVariant TextTableModel::data(const QModelIndex& index, int role) const
0059 {
0060   if (!index.isValid())
0061     return QVariant();
0062   int rowNr = index.row() + (m_hasHeaderLine ? 1 : 0);
0063   if (rowNr < 0 || rowNr >= m_cells.size() || index.column() < 0)
0064     return QVariant();
0065   if (const QStringList& row = m_cells.at(rowNr);
0066       index.column() < row.size() &&
0067       (role == Qt::DisplayRole || role == Qt::EditRole)) {
0068     return row.at(index.column());
0069   }
0070   return QVariant();
0071 }
0072 
0073 /**
0074  * Get data for header section.
0075  * @param section column or row
0076  * @param orientation horizontal or vertical
0077  * @param role item data role
0078  * @return header data for role
0079  */
0080 QVariant TextTableModel::headerData(
0081     int section, Qt::Orientation orientation, int role) const
0082 {
0083   if (role != Qt::DisplayRole)
0084     return QVariant();
0085   if (orientation == Qt::Horizontal && m_hasHeaderLine && !m_cells.isEmpty() &&
0086       section < m_cells.first().size()) {
0087     return m_cells.first().at(section);
0088   }
0089   return section + 1;
0090 }
0091 
0092 /**
0093  * Get number of rows.
0094  * @param parent parent model index, invalid for table models
0095  * @return number of rows,
0096  * if parent is valid number of children (0 for table models)
0097  */
0098 int TextTableModel::rowCount(const QModelIndex& parent) const
0099 {
0100   int numRows = m_cells.size();
0101   if (m_hasHeaderLine && numRows > 0)
0102     --numRows;
0103   return parent.isValid() ? 0 : numRows;
0104 }
0105 
0106 /**
0107  * Get number of columns.
0108  * @param parent parent model index, invalid for table models
0109  * @return number of columns,
0110  * if parent is valid number of children (0 for table models)
0111  */
0112 int TextTableModel::columnCount(const QModelIndex& parent) const
0113 {
0114   return parent.isValid() ? 0 : m_cells.isEmpty() ? 0 : m_cells.first().size();
0115 }
0116 
0117 /**
0118  * Set the text to be displayed in the table.
0119  * @param text text with tab-separated columns and newline-separated rows
0120  * @param hasHeaderLine true if the first line is the header
0121  * @return true if the first line of the text contains a tab character.
0122  */
0123 bool TextTableModel::setText(const QString& text, bool hasHeaderLine)
0124 {
0125   beginResetModel();
0126   m_hasHeaderLine = hasHeaderLine;
0127   m_cells.clear();
0128   QStringList lines = text.split(QRegularExpression(QLatin1String("[\\r\\n]+")));
0129   if (lines.isEmpty() || lines.first().indexOf(QLatin1Char('\t')) == -1) {
0130     endResetModel();
0131     return false;
0132   }
0133 
0134   for (int i = 0; i < lines.size(); ++i) {
0135     const QString& line = lines.at(i);
0136     if (i == lines.size() - 1 && line.isEmpty())
0137       break;
0138     m_cells.append(line.split(QLatin1Char('\t')));
0139   }
0140   endResetModel();
0141   return true;
0142 }