Skip to content

Commit

Permalink
Bugfix for SF#131: matrices processing are now fast upon undoing a fo…
Browse files Browse the repository at this point in the history
…rmula.
  • Loading branch information
Suthiro committed Mar 16, 2021
1 parent df6b7fd commit 7ef2e3c
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 1 deletion.
7 changes: 6 additions & 1 deletion libscidavis/src/Matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,10 @@ bool Matrix::recalculate()
saveCellsToMemory();
double dx = fabs(xEnd() - xStart()) / (double)(numRows() - 1);
double dy = fabs(yEnd() - yStart()) / (double)(numCols() - 1);
std::pair<double, bool> invalidValue(std::numeric_limits<double>::quiet_NaN(), false);
std::vector<std::vector<std::pair<double, bool>>> calculatedValues(
endRow - startRow + 1,
std::vector<std::pair<double, bool>>(endCol - startCol + 1, invalidValue));
for (int row = startRow; row <= endRow; row++)
for (int col = startCol; col <= endCol; col++) {
if (!isCellSelected(row, col))
Expand All @@ -431,8 +435,9 @@ bool Matrix::recalculate()
QApplication::restoreOverrideCursor();
return false;
}
setCell(row, col, ret.toDouble());
calculatedValues[row - startRow][col - startCol] = std::pair(ret.toDouble(), true);
}
d_future_matrix->setCells(startRow, startCol, calculatedValues);
forgetSavedCells();

blockSignals(false);
Expand Down
66 changes: 66 additions & 0 deletions libscidavis/src/future/matrix/future_Matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,30 @@ void Matrix::transpose()
RESET_CURSOR;
}

std::vector<std::vector<std::pair<double, bool>>>
Matrix::getCells(const int startRow, const int endRow, const int startCol, const int endCol) const
{
return d_matrix_private->getCells(startRow, endRow, startCol, endCol);
}

void Matrix::setCells(
const int startRow, const int startCol,
const std::vector<std::vector<std::pair<double, bool>>> &values)
{
WAIT_CURSOR;
auto lastRow = startRow + values.size() - 1;
auto lastCol = startCol
+ std::max_element(values.cbegin(), values.cend(),
[](const std::vector<std::pair<double, bool>> &a,
const std::vector<std::pair<double, bool>> &b) {
return a.size() > b.size();
})
->size() - 1;
exec(new MatrixSetCellsCmd(d_matrix_private, startRow, lastRow, startCol, lastCol, values));
RESET_CURSOR;

}

void Matrix::mirrorHorizontally()
{
WAIT_CURSOR;
Expand Down Expand Up @@ -1781,4 +1805,46 @@ void Matrix::Private::setFormula(const QString &formula)
emit d_owner->formulaChanged();
}

std::vector<std::vector<std::pair<double, bool>>> Matrix::Private::getCells(const int startRow,
const int endRow,
const int startCol,
const int endCol) const
{
if (startRow > endRow || startCol > endCol || startCol < 0 || endCol > columnCount()
|| startRow < 0 || endRow > rowCount())
return std::vector<std::vector<std::pair<double, bool>>>();

std::pair<double, bool> invalidValue(std::numeric_limits<double>::quiet_NaN(), false);
std::vector<std::vector<std::pair<double, bool>>> values(
endRow - startRow + 1,
std::vector<std::pair<double, bool>>(endCol - startCol + 1, invalidValue));
for (int row = startRow; row <= endRow; row++)
for (int col = startCol; col <= endCol; col++)
values[row - startRow][col - startCol] = std::pair(cell(row, col), true);
return values;
}

void Matrix::Private::setCells(const int startRow, const int startCol,
const std::vector<std::vector<std::pair<double, bool>>> &values)
{
blockChangeSignals(true);
for (size_t ii = 0u; values.size() > ii; ++ii) {
const auto &column = values[ii];
for (size_t jj = 0u; column.size() > jj; ++jj) {
const auto &pair = column[jj];
if (!pair.second)
continue;
setCell(startRow + ii, startCol + jj, pair.first);
}
}
blockChangeSignals(false);
auto endRow = startRow + values.size() - 1;
auto endCol = startCol + std::max_element(
values.cbegin(), values.cend(),
[](const std::vector<std::pair<double, bool>> &a,
const std::vector<std::pair<double, bool>> &b)
{ return a.size() > b.size();})->size() - 1;
emit d_owner->dataChanged(startRow, startCol, endRow, endCol);
}

} // namespace
13 changes: 13 additions & 0 deletions libscidavis/src/future/matrix/future_Matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ public slots:
//! Clear the whole matrix (i.e. set all cells to 0.0)
void clear();
void transpose();

std::vector<std::vector<std::pair<double, bool>>>
getCells(const int startRow, const int endRow, const int startCol, const int endCol) const;

void setCells(const int startRow, const int startCol,
const std::vector<std::vector<std::pair<double, bool>>> &values);
void mirrorVertically();
void mirrorHorizontally();

Expand Down Expand Up @@ -438,6 +444,13 @@ class Matrix::Private
double yEnd() const;
QString formula() const;
void setFormula(const QString &formula);

std::vector<std::vector<std::pair<double, bool>>>
getCells(const int startRow, const int endRow, const int startCol, const int endCol) const;

void setCells(const int startRow, const int startCol,
const std::vector<std::vector<std::pair<double, bool>>> &values);

void setXStart(double x);
void setXEnd(double x);
void setYStart(double y);
Expand Down
25 changes: 25 additions & 0 deletions libscidavis/src/future/matrix/matrixcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,3 +532,28 @@ void MatrixMirrorVerticallyCmd::undo()
///////////////////////////////////////////////////////////////////////////
// end of class MatrixMirrorVerticallyCmd
///////////////////////////////////////////////////////////////////////////

MatrixSetCellsCmd::MatrixSetCellsCmd(
future::Matrix::Private *private_obj, int first_row, int last_row, int first_column,
int last_column, const std::vector<std::vector<std::pair<double, bool>>> &values,
QUndoCommand *parent)
: QUndoCommand(parent), d_private_obj{ private_obj },
d_first_row{ first_row },
d_last_row{ last_row },
d_first_column{ first_column },
d_last_column{ last_column },
d_values{ values },
d_old_values{ private_obj->getCells(first_row, last_row, first_column, last_column) }
{
setText(QObject::tr("%1: set values for multiple cells").arg(d_private_obj->name()));
}

void MatrixSetCellsCmd::redo()
{
d_private_obj->setCells(d_first_row, d_first_column, d_values);
}

void MatrixSetCellsCmd::undo()
{
d_private_obj->setCells(d_first_row, d_first_column, d_old_values);
}
36 changes: 36 additions & 0 deletions libscidavis/src/future/matrix/matrixcommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,42 @@ class MatrixSetRowCellsCmd : public QUndoCommand
// end of class MatrixSetRowCellsCmd
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
// class MatrixSetCellsCmd
///////////////////////////////////////////////////////////////////////////
//! Set cell values for multiple cells at once
class MatrixSetCellsCmd : public QUndoCommand
{
public:
MatrixSetCellsCmd(future::Matrix::Private *private_obj, int first_row, int last_row,
int first_column, int last_column,
const std::vector<std::vector<std::pair<double, bool>>> &values,
QUndoCommand *parent = 0);

void redo() override;
void undo() override;

private:
//! The private object to modify
future::Matrix::Private * const d_private_obj;
//! The index of the first row
const int d_first_row;
//! The index of the last row
const int d_last_row;
//! The index of the first column
const int d_first_column;
//! The index of the last column
const int d_last_column;
//! New cell values
const std::vector<std::vector<std::pair<double, bool>>> d_values;
//! Backup of the changed values
const std::vector<std::vector<std::pair<double, bool>>> d_old_values;
};

///////////////////////////////////////////////////////////////////////////
// end of class MatrixSetCellsCmd
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
// class MatrixTransposeCmd
///////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 7ef2e3c

Please sign in to comment.