159
161
* default object.
160
162
* \return the data at the given coordinate
162
T lookup(int col, int row) const {
164
T lookup(int col, int row, const T& defaultVal = T()) const {
163
165
Q_ASSERT(1 <= col && col <= KS_colMax);
164
166
Q_ASSERT(1 <= row && row <= KS_rowMax);
165
167
// is the row not present?
166
168
if (row > m_rows.count())
168
170
const QVector<int>::const_iterator cstart(m_cols.begin() + m_rows.value(row - 1));
169
171
const QVector<int>::const_iterator cend((row < m_rows.count()) ? (m_cols.begin() + m_rows.value(row)) : m_cols.end());
170
172
const QVector<int>::const_iterator cit = qBinaryFind(cstart, cend, col);
171
173
// is the col not present?
174
176
return m_data.value(m_rows.value(row - 1) + (cit - cstart));
178
180
* Removes data at \p col , \p row .
179
181
* \return the removed data (default data, if none)
181
T take(int col, int row) {
183
T take(int col, int row, const T& defaultVal = T()) {
182
184
Q_ASSERT(1 <= col && col <= KS_colMax);
183
185
Q_ASSERT(1 <= row && row <= KS_rowMax);
184
186
// row's missing?
185
187
if (row > m_rows.count())
187
189
const int rowStart = (row - 1 < m_rows.count()) ? m_rows.value(row - 1) : m_data.count();
188
190
const int rowLength = (row < m_rows.count()) ? m_rows.value(row) - rowStart : -1;
189
191
const QVector<int> cols = m_cols.mid(rowStart, rowLength);
190
192
QVector<int>::const_iterator cit = qBinaryFind(cols, col);
191
193
// column's missing?
192
194
if (cit == cols.constEnd())
194
196
const int index = rowStart + (cit - cols.constBegin());
195
197
// save the old data
196
198
const T oldData = m_data[ index ];
407
409
const QVector<T> data = m_data.mid(rowStart, rowLength);
408
410
// first, iterate over the destination row
409
411
for (int col = cols.count() - 1; col >= 0; --col) {
410
if (cols.value(col) >= rect.left() && cols.value(col) <= rect.right()) {
412
const int column = cols.value(col); // real column value (1...KS_colMax)
413
if (column >= rect.left() && column <= rect.right()) {
411
414
// save the old data
412
415
if (row <= rect.bottom())
413
oldData.append(qMakePair(QPoint(cols.value(col), row), data.value(col)));
416
oldData.append(qMakePair(QPoint(column, row), data.value(col)));
415
const QVector<int>::const_iterator cstart2((row + rect.height() - 1 < m_rows.count()) ? m_cols.begin() + m_rows.value(row + rect.height() - 1) : m_cols.end());
416
const QVector<int>::const_iterator cend2(((row + rect.height() < m_rows.count())) ? (m_cols.begin() + m_rows.value(row + rect.height())) : m_cols.end());
417
const QVector<int>::const_iterator cit2 = qBinaryFind(cstart2, cend2, cols.value(col));
418
const int srcRow = row + rect.height();
419
const QVector<int>::const_iterator cstart2((srcRow - 1 < m_rows.count()) ? m_cols.begin() + m_rows.value(srcRow - 1) : m_cols.end());
420
const QVector<int>::const_iterator cend2((srcRow < m_rows.count()) ? (m_cols.begin() + m_rows.value(srcRow)) : m_cols.end());
421
const QVector<int>::const_iterator cit2 = qBinaryFind(cstart2, cend2, column);
418
422
// column's missing?
419
423
if (cit2 == cend2) {
420
424
m_cols.remove(rowStart + col);
439
443
// last, iterate over the source row
440
const int rowStart2 = (row + rect.height() - 1 < m_rows.count()) ? m_rows.value(row + rect.height() - 1) : m_data.count();
441
const int rowLength2 = (row + rect.height() < m_rows.count()) ? m_rows.value(row + rect.height()) - rowStart2 : -1;
444
const int srcRow = row + rect.height();
445
const int rowStart2 = (srcRow - 1 < m_rows.count()) ? m_rows.value(srcRow - 1) : m_data.count();
446
const int rowLength2 = (srcRow < m_rows.count()) ? m_rows.value(srcRow) - rowStart2 : -1;
442
447
const QVector<int> cols2 = m_cols.mid(rowStart2, rowLength2);
443
448
const QVector<T> data2 = m_data.mid(rowStart2, rowLength2);
444
450
for (int col = cols2.count() - 1; col >= 0; --col) {
445
if (cols2.value(col) >= rect.left() && cols2.value(col) <= rect.right()) {
451
const int column = cols2.value(col); // real column value (1...KS_colMax)
452
if (column >= rect.left() && column <= rect.right()) {
446
453
// find the insertion position
447
454
const QVector<int>::const_iterator cstart((row - 1 < m_rows.count()) ? m_cols.begin() + m_rows.value(row - 1) : m_cols.end());
448
455
const QVector<int>::const_iterator cend(((row < m_rows.count())) ? (m_cols.begin() + m_rows.value(row)) : m_cols.end());
449
456
const QVector<int>::const_iterator cit = qUpperBound(cstart, cend, cols2.value(col));
450
// copy it to its new position
451
m_data.insert(cit - m_cols.constBegin(), m_data.value(rowStart2 + col));
452
m_cols.insert(cit - m_cols.constBegin(), m_cols.value(rowStart2 + col));
453
// remove it from its old position
454
m_data.remove(rowStart2 + col + 1);
455
m_cols.remove(rowStart2 + col + 1);
456
// adjust the offsets of the following rows
457
for (int r = row; r < row + rect.height(); ++r)
457
// Destination column:
458
const QVector<int>::const_iterator dstcit = qBinaryFind(cols.begin(), cols.end(), column);
459
if (dstcit != cols.end()) { // destination column exists
460
// replace the existing destination value
461
const int dstCol = (dstcit - cols.constBegin());
462
m_data[rowStart + dstCol] = m_data.value(rowStart2 + col);
463
// remove it from its old position
464
m_data.remove(rowStart2 + col + 1);
465
m_cols.remove(rowStart2 + col + 1);
466
// The amount of values in the range from the
467
// destination row to the source row have not changed.
468
// adjust the offsets of the following rows
469
for (int r = srcRow; r < m_rows.count(); ++r) {
472
} else { // destination column does not exist yet
473
// copy it to its new position
474
const int dstCol = cit - m_cols.constBegin();
475
m_data.insert(dstCol, data2.value(col));
476
m_cols.insert(dstCol, cols2.value(col));
477
// remove it from its old position
478
m_data.remove(rowStart2 + col + 1 + offset);
479
m_cols.remove(rowStart2 + col + 1 + offset);
481
// adjust the offsets of the following rows
482
for (int r = row; r < srcRow; ++r) {