diff --git a/src/backend/matrix/MatrixModel.cpp b/src/backend/matrix/MatrixModel.cpp index 0f051c029..506068a59 100644 --- a/src/backend/matrix/MatrixModel.cpp +++ b/src/backend/matrix/MatrixModel.cpp @@ -1,304 +1,303 @@ /*************************************************************************** File : MatrixModel.cpp Project : LabPlot Description : Matrix data model -------------------------------------------------------------------- Copyright : (C) 2015-2016 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2008-2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "backend/matrix/MatrixModel.h" #include "backend/matrix/Matrix.h" #include #include /*! \class MatrixModel \brief Model for the access to data of a Matrix-object. This is a model in the sense of Qt4 model/view framework which is used to access a Matrix object from any of Qt4s view classes, typically a QMatrixView. Its main purposes are translating Matrix signals into QAbstractItemModel signals and translating calls to the QAbstractItemModel read/write API into calls in the public API of Matrix. \ingroup backend */ MatrixModel::MatrixModel(Matrix* matrix) : QAbstractItemModel(nullptr), m_matrix(matrix), m_suppressDataChangedSignal(false) { connect(m_matrix, &Matrix::columnsAboutToBeInserted, this, &MatrixModel::handleColumnsAboutToBeInserted); connect(m_matrix, &Matrix::columnsInserted, this, &MatrixModel::handleColumnsInserted); connect(m_matrix, &Matrix::columnsAboutToBeRemoved, this, &MatrixModel::handleColumnsAboutToBeRemoved); connect(m_matrix, &Matrix::columnsRemoved, this, &MatrixModel::handleColumnsRemoved); connect(m_matrix, &Matrix::rowsAboutToBeInserted, this, &MatrixModel::handleRowsAboutToBeInserted); connect(m_matrix, &Matrix::rowsInserted, this, &MatrixModel::handleRowsInserted); connect(m_matrix, &Matrix::rowsAboutToBeRemoved, this, &MatrixModel::handleRowsAboutToBeRemoved); connect(m_matrix, &Matrix::rowsRemoved, this, &MatrixModel::handleRowsRemoved); connect(m_matrix, &Matrix::dataChanged, this, &MatrixModel::handleDataChanged); connect(m_matrix, &Matrix::coordinatesChanged, this, &MatrixModel::handleCoordinatesChanged); connect(m_matrix, &Matrix::numericFormatChanged, this, &MatrixModel::handleFormatChanged); connect(m_matrix, &Matrix::precisionChanged, this, &MatrixModel::handleFormatChanged); } void MatrixModel::setSuppressDataChangedSignal(bool b) { m_suppressDataChangedSignal = b; } void MatrixModel::setChanged() { emit changed(); } Qt::ItemFlags MatrixModel::flags(const QModelIndex& index) const { if (index.isValid()) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; else return Qt::ItemIsEnabled; } QVariant MatrixModel::data(const QModelIndex& index, int role) const { if( !index.isValid() ) return QVariant(); int row = index.row(); int col = index.column(); switch(role) { case Qt::ToolTipRole: case Qt::EditRole: case Qt::DisplayRole: { AbstractColumn::ColumnMode mode = m_matrix->mode(); //DEBUG("MatrixModel::data() DisplayRole, mode = " << mode); switch (mode) { case AbstractColumn::Numeric: return QVariant(m_matrix->text(row, col)); case AbstractColumn::Integer: return QVariant(m_matrix->text(row, col)); case AbstractColumn::DateTime: case AbstractColumn::Month: case AbstractColumn::Day: return QVariant(m_matrix->text(row, col)); case AbstractColumn::Text: // should not happen return QVariant(m_matrix->text(row, col)); default: DEBUG(" unknown column mode " << mode << " found"); break; } break; } case Qt::BackgroundRole: //use bluish background color to distinguish Matrix from Spreadsheet return QVariant(QBrush(QColor(192,255,255))); case Qt::ForegroundRole: //ignore current theme settings and always use black foreground color so Matrix is usable with dark themes, too. return QVariant(QBrush(QColor(Qt::black))); } return QVariant(); } QVariant MatrixModel::headerData(int section, Qt::Orientation orientation, int role) const { QString result; Matrix::HeaderFormat headerFormat = m_matrix->headerFormat(); switch(orientation) { case Qt::Horizontal: switch(role) { case Qt::DisplayRole: case Qt::ToolTipRole: if (headerFormat==Matrix::HeaderRowsColumns) { result = QString::number(section+1); } else if (headerFormat == Matrix::HeaderValues) { double diff = m_matrix->xEnd() - m_matrix->xStart(); double step = 0.0; if (m_matrix->columnCount() > 1) step = diff/double(m_matrix->columnCount()-1); result = QLocale().toString(m_matrix->xStart()+double(section)*step, m_matrix->numericFormat(), m_matrix->precision()); } else { result = QString::number(section+1) + QLatin1String(" ("); double diff = m_matrix->xEnd() - m_matrix->xStart(); double step = 0.0; if (m_matrix->columnCount() > 1) step = diff/double(m_matrix->columnCount()-1); result += QLocale().toString(m_matrix->xStart()+double(section)*step, m_matrix->numericFormat(), m_matrix->precision()); result += ')'; } return QVariant(result); } break; case Qt::Vertical: switch(role) { case Qt::DisplayRole: case Qt::ToolTipRole: if (headerFormat==Matrix::HeaderRowsColumns) { result = QString::number(section+1); } else if (headerFormat==Matrix::HeaderValues) { double diff = m_matrix->yEnd() - m_matrix->yStart(); double step = 0.0; if (m_matrix->rowCount() > 1) step = diff/double(m_matrix->rowCount()-1); // TODO: implement decent double == 0 check // if (diff < 1e-10) // result += QLocale().toString(m_matrix->yStart(), // m_matrix->numericFormat(), m_matrix->displayedDigits()); result += QLocale().toString(m_matrix->yStart()+double(section)*step, m_matrix->numericFormat(), m_matrix->precision()); } else { result = QString::number(section+1) + QString(" ("); double diff = m_matrix->yEnd() - m_matrix->yStart(); double step = 0.0; if (m_matrix->rowCount() > 1) step = diff/double(m_matrix->rowCount()-1); result += QLocale().toString(m_matrix->yStart()+double(section)*step, m_matrix->numericFormat(), m_matrix->precision()); result += ')'; } return QVariant(result); } } return QVariant(); } int MatrixModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return m_matrix->rowCount(); } int MatrixModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return m_matrix->columnCount(); } bool MatrixModel::setData(const QModelIndex& index, const QVariant& value, int role) { - //QDEBUG("MatrixModel::setData() value =" << value); if (!index.isValid()) return false; int row = index.row(); int column = index.column(); if(role == Qt::EditRole) { - AbstractColumn::ColumnMode mode = m_matrix->mode(); - //DEBUG(" mode = " << mode); + const AbstractColumn::ColumnMode mode = m_matrix->mode(); switch (mode) { case AbstractColumn::Numeric: m_matrix->setCell(row, column, value.toDouble()); break; case AbstractColumn::Integer: m_matrix->setCell(row, column, value.toInt()); break; case AbstractColumn::DateTime: case AbstractColumn::Month: case AbstractColumn::Day: + DEBUG(" WARNING: DateTime format not supported yet"); // should not happen //TODO: m_matrix->setCell(row, column, value.toDateTime()); break; case AbstractColumn::Text: - DEBUG(" WARNING: Text format not supported"); // should not happen + DEBUG(" WARNING: Text format not supported yet"); // should not happen m_matrix->setCell(row, column, value.toString()); break; default: - DEBUG(" unknown column mode " << mode << " found"); + DEBUG(" Unsupported column mode " << mode); break; } if (!m_suppressDataChangedSignal) emit changed(); return true; } return false; } QModelIndex MatrixModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent) return createIndex(row, column); } QModelIndex MatrixModel::parent(const QModelIndex& child) const { Q_UNUSED(child) return QModelIndex{}; } void MatrixModel::updateHeader() { emit headerDataChanged(Qt::Horizontal, 0, m_matrix->columnCount()); emit headerDataChanged(Qt::Vertical, 0, m_matrix->rowCount()); } void MatrixModel::handleColumnsAboutToBeInserted(int before, int count) { beginInsertColumns(QModelIndex(), before, before+count-1); } void MatrixModel::handleColumnsInserted(int first, int count) { Q_UNUSED(first) Q_UNUSED(count) endInsertColumns(); if (!m_suppressDataChangedSignal) emit changed(); } void MatrixModel::handleColumnsAboutToBeRemoved(int first, int count) { beginRemoveColumns(QModelIndex(), first, first+count-1); } void MatrixModel::handleColumnsRemoved(int first, int count) { Q_UNUSED(first) Q_UNUSED(count) endRemoveColumns(); if (!m_suppressDataChangedSignal) emit changed(); } void MatrixModel::handleRowsAboutToBeInserted(int before, int count) { beginInsertRows(QModelIndex(), before, before+count-1); } void MatrixModel::handleRowsInserted(int first, int count) { Q_UNUSED(first) Q_UNUSED(count) endInsertRows(); if (!m_suppressDataChangedSignal) emit changed(); } void MatrixModel::handleRowsAboutToBeRemoved(int first, int count) { beginRemoveRows(QModelIndex(), first, first+count-1); } void MatrixModel::handleRowsRemoved(int first, int count) { Q_UNUSED(first) Q_UNUSED(count) endRemoveRows(); if (!m_suppressDataChangedSignal) emit changed(); } void MatrixModel::handleDataChanged(int top, int left, int bottom, int right) { emit dataChanged(index(top, left), index(bottom, right)); if (!m_suppressDataChangedSignal) emit changed(); } void MatrixModel::handleCoordinatesChanged() { emit headerDataChanged(Qt::Horizontal, 0, columnCount()-1); emit headerDataChanged(Qt::Vertical, 0, rowCount()-1); } void MatrixModel::handleFormatChanged() { handleCoordinatesChanged(); handleDataChanged(0, 0, rowCount()-1, columnCount()-1); }