#include "sqmtablemodel.h" #include #include #include SQMTableModel::SQMTableModel(QObject *parent) : QAbstractTableModel(parent) { } int SQMTableModel::rowCount(const QModelIndex & /*parent*/) const { return binLen; } int SQMTableModel::columnCount(const QModelIndex & /*parent*/) const { return 3; } QVariant SQMTableModel::data(const QModelIndex &index, int role) const { int row = index.row(); int col = index.column(); QVariant result; switch (role) { case Qt::DisplayRole: try { result = QString::number(sqmMatrix.at(col).at(row)); } catch (...) { result = "x"; } break; case Qt::ForegroundRole: if (changedHere.isValid() && highlightChanged) { if ((row > changedHere.row() || (col >= changedHere.column() && row == changedHere.row())) && (col != 0 || changedHere.column() == 0)) { result = QColor(Qt::red); } } break; case Qt::TextAlignmentRole: result = Qt::AlignRight; break; } return result; } QVariant SQMTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return QString("BIN"); case 1: return QString("SQN"); case 2: return QString("MUL"); } } return QVariant(); } bool SQMTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::EditRole) { if (!checkIndex(index)) { return false; } int row = index.row(); int col = index.column(); if (col == 0 && value.toInt() != 0 && value.toInt() != 1) { return false; } // call calculateSqmMatrix sqmMatrix.at(col).at(row) = value.toInt(); changedHere = index; highlightChanged = true; UpdateSqmMatrix(index); return true; } return false; } Qt::ItemFlags SQMTableModel::flags(const QModelIndex &index) const { return Qt::ItemIsEditable | QAbstractTableModel::flags(index); } void SQMTableModel::SetStartValues(int pBase, int pExp, int pMod) { base = pBase; exp = pExp; mod = pMod; highlightChanged = false; //changedHere.model()->index(-1, -1, QModelIndex()); CalculateSqmMatrix(); } void SQMTableModel::CalculateSqmMatrix() { // Clear sqmMatrix sqmMatrix.clear(); binLen = 0; vector colBin; while ((1 << binLen) < exp) { colBin.push_back((exp >> binLen) & 1); binLen += 1; } // Add or remove rows beginResetModel(); sqmMatrix.push_back(colBin); endResetModel(); // Init SQN & MUL Column vector colSqn, colMul; colSqn.push_back(1); colMul.push_back(base); sqmMatrix.push_back(colSqn); sqmMatrix.push_back(colMul); // Calculate SQM for (int i = 1; i < binLen; i++) { sqmMatrix.at(1).push_back((sqmMatrix.at(2).at(i - 1) * sqmMatrix.at(2).at(i - 1)) % mod); if (sqmMatrix.at(0).at(i) == 0) { sqmMatrix.at(2).push_back(sqmMatrix.at(1).at(i)); } else { sqmMatrix.at(2).push_back((sqmMatrix.at(1).at(i) * base) % mod); } } } void SQMTableModel::UpdateSqmMatrix(QModelIndex startIndex) { int start_row = startIndex.row(); int start_col = startIndex.column(); // If change appeared in col 2, start in next row if (start_col == 2) { start_row++; } // Update sqmMatrix for (int i = start_row; i < binLen; i++) { if (start_row == 0 && start_col == 0) { sqmMatrix.at(1).at(i) = 1; start_row = 1; } else if (start_col != 1) { sqmMatrix.at(1).at(i) = (sqmMatrix.at(2).at(i - 1) * sqmMatrix.at(2).at(i - 1)) % mod; } start_col = 0; if (sqmMatrix.at(0).at(i) == 0) { sqmMatrix.at(2).at(i) = sqmMatrix.at(1).at(i); } else { sqmMatrix.at(2).at(i) = (sqmMatrix.at(1).at(i) * base) % mod; } } }