~ubuntu-branches/ubuntu/oneiric/koffice/oneiric-updates

« back to all changes in this revision

Viewing changes to kspread/PointStorage.h

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <QVector>
26
26
 
27
27
#include "Region.h"
 
28
#include "kspread_limits.h"
28
29
 
29
30
// #define KSPREAD_POINT_STORAGE_HASH
30
31
 
32
33
{
33
34
 
34
35
/**
 
36
 * \ingroup Storage
35
37
 * A custom pointwise storage.
36
38
 * Based on a compressed sparse matrix data structure.
37
39
 * Usable for any kind of data attached to 2D coordinates.
159
161
     * default object.
160
162
     * \return the data at the given coordinate
161
163
     */
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())
167
 
            return T();
 
169
            return defaultVal;
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?
172
174
        if (cit == cend)
173
 
            return T();
 
175
            return defaultVal;
174
176
        return m_data.value(m_rows.value(row - 1) + (cit - cstart));
175
177
    }
176
178
 
178
180
     * Removes data at \p col , \p row .
179
181
     * \return the removed data (default data, if none)
180
182
     */
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())
186
 
            return T();
 
188
            return defaultVal;
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())
193
 
            return T();
 
195
            return defaultVal;
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)));
414
417
                    // search
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);
437
441
                }
438
442
            }
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);
 
449
            int offset = 0;
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)
458
 
                        ++m_rows[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) {
 
470
                            ++m_rows[r];
 
471
                        }
 
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);
 
480
                        ++offset;
 
481
                        // adjust the offsets of the following rows
 
482
                        for (int r = row; r < srcRow; ++r) {
 
483
                            ++m_rows[r];
 
484
                        }
 
485
                    }
459
486
                }
460
487
            }
461
488
        }