~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to kspread/StyleStorage.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
    QMap<int, bool> usedRows;
46
46
    QRegion usedArea;
47
47
    QHash<Style::Key, QList<SharedSubStyle> > subStyles;
48
 
    QMap<int, QPair<QRectF,SharedSubStyle> > possibleGarbage;
 
48
    QMap<int, QPair<QRectF, SharedSubStyle> > possibleGarbage;
49
49
    QCache<QPoint, Style> cache;
50
50
    QRegion cachedArea;
51
51
};
52
52
 
53
53
StyleStorage::StyleStorage(Map* map)
54
 
    : QObject(map)
55
 
    , d(new Private)
 
54
        : QObject(map)
 
55
        , d(new Private)
56
56
{
57
57
    d->map = map;
58
 
    d->cache.setMaxCost( g_maximumCachedStyles );
 
58
    d->cache.setMaxCost(g_maximumCachedStyles);
59
59
}
60
60
 
61
61
StyleStorage::StyleStorage(const StyleStorage& other)
62
 
    : QObject(other.d->map)
63
 
    , d(new Private)
 
62
        : QObject(other.d->map)
 
63
        , d(new Private)
64
64
{
65
65
    d->map = other.d->map;
66
66
    d->tree = other.d->tree;
81
81
    if (!d->usedArea.contains(point) && !d->usedColumns.contains(point.x()) && !d->usedRows.contains(point.y()))
82
82
        return *styleManager()->defaultStyle();
83
83
    // first, lookup point in the cache
84
 
    if ( d->cache.contains( point ) )
85
 
    {
 
84
    if (d->cache.contains(point)) {
86
85
//         kDebug(36006) <<"StyleStorage: Using cached style for" << cellName;
87
 
        return *d->cache.object( point );
 
86
        return *d->cache.object(point);
88
87
    }
89
88
    // not found, lookup in the tree
90
89
    QList<SharedSubStyle> subStyles = d->tree.contains(point);
91
 
    if ( subStyles.isEmpty() )
 
90
    if (subStyles.isEmpty())
92
91
        return *styleManager()->defaultStyle();
93
92
    Style* style = new Style();
94
 
    (*style) = composeStyle( subStyles );
 
93
    (*style) = composeStyle(subStyles);
95
94
    // insert style into the cache
96
 
    d->cache.insert( point, style );
97
 
    d->cachedArea += QRect( point, point );
 
95
    d->cache.insert(point, style);
 
96
    d->cachedArea += QRect(point, point);
98
97
    return *style;
99
98
}
100
99
 
101
100
Style StyleStorage::contains(const QRect& rect) const
102
101
{
103
102
    QList<SharedSubStyle> subStyles = d->tree.contains(rect);
104
 
    return composeStyle( subStyles );
 
103
    return composeStyle(subStyles);
105
104
}
106
105
 
107
106
Style StyleStorage::intersects(const QRect& rect) const
108
107
{
109
108
    QList<SharedSubStyle> subStyles = d->tree.intersects(rect);
110
 
    return composeStyle( subStyles );
 
109
    return composeStyle(subStyles);
111
110
}
112
111
 
113
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::undoData(const Region& region) const
 
112
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::undoData(const Region& region) const
114
113
{
115
 
    QList< QPair<QRectF,SharedSubStyle> > result;
 
114
    QList< QPair<QRectF, SharedSubStyle> > result;
116
115
    Region::ConstIterator end = region.constEnd();
117
 
    for ( Region::ConstIterator it = region.constBegin(); it != end; ++it )
118
 
    {
 
116
    for (Region::ConstIterator it = region.constBegin(); it != end; ++it) {
119
117
        const QRect rect = (*it)->rect();
120
 
        QList< QPair<QRectF,SharedSubStyle> > pairs = d->tree.intersectingPairs(rect).values();
121
 
        for ( int i = 0; i < pairs.count(); ++i )
122
 
        {
 
118
        QList< QPair<QRectF, SharedSubStyle> > pairs = d->tree.intersectingPairs(rect).values();
 
119
        for (int i = 0; i < pairs.count(); ++i) {
123
120
            // trim the rects
124
 
            pairs[i].first = pairs[i].first.intersected( rect );
 
121
            pairs[i].first = pairs[i].first.intersected(rect);
125
122
        }
126
123
        result << pairs;
127
124
    }
139
136
{
140
137
#if 0 // TODO
141
138
    // If we have both, column and row styles, we can take the short route.
142
 
    if (!d->usedColumns.isEmpty() && !d->usedRows.isEmpty())
143
 
    {
144
 
        for (int i = 0; i < d->usedColumns.count(); ++i)
145
 
        {
 
139
    if (!d->usedColumns.isEmpty() && !d->usedRows.isEmpty()) {
 
140
        for (int i = 0; i < d->usedColumns.count(); ++i) {
146
141
            const int col = d->usedColumns[i];
147
142
            tableContext.columnDefaultStyles[col].insertSubStyle(contains(QRect(col, 1, 1, KS_rowMax)));
148
143
        }
149
 
        for (int i = 0; i < d->usedColumns.count(); ++i)
150
 
        {
 
144
        for (int i = 0; i < d->usedColumns.count(); ++i) {
151
145
            const int row = d->usedRow[i];
152
146
            tableContext.rowDefaultStyles[row].insertSubStyle(contains(QRect(1, row, KS_colMax, 1)));
153
147
        }
155
149
    }
156
150
#endif
157
151
    const QRect sheetRect(QPoint(1, 1), QPoint(KS_colMax, KS_rowMax));
158
 
    if (d->usedColumns.count() != 0)
159
 
    {
 
152
    if (d->usedColumns.count() != 0) {
160
153
        maxCols = qMax(maxCols, (--d->usedColumns.constEnd()).key());
161
154
        maxRows = KS_rowMax;
162
155
    }
163
 
    if (d->usedRows.count() != 0)
164
 
    {
 
156
    if (d->usedRows.count() != 0) {
165
157
        maxCols = KS_colMax;
166
158
        maxRows = qMax(maxRows, (--d->usedRows.constEnd()).key());
167
159
    }
168
 
    const QList< QPair<QRectF,SharedSubStyle> > pairs = d->tree.intersectingPairs(sheetRect).values();
169
 
    for (int i = 0; i < pairs.count(); ++i)
170
 
    {
 
160
    const QList< QPair<QRectF, SharedSubStyle> > pairs = d->tree.intersectingPairs(sheetRect).values();
 
161
    for (int i = 0; i < pairs.count(); ++i) {
171
162
        const QRect rect = pairs[i].first.toRect();
172
163
        // column default cell styles
173
164
        // Columns have no content. Prefer them over rows for the default cell styles.
174
 
        if (rect.top() == 1 && rect.bottom() == maxRows)
175
 
        {
176
 
            for (int col = rect.left(); col <= rect.right(); ++col)
177
 
            {
 
165
        if (rect.top() == 1 && rect.bottom() == maxRows) {
 
166
            for (int col = rect.left(); col <= rect.right(); ++col) {
178
167
                if (pairs[i].second.data()->type() == Style::DefaultStyleKey)
179
168
                    tableContext.columnDefaultStyles.remove(col);
180
169
                else
182
171
            }
183
172
        }
184
173
        // row default cell styles
185
 
        else if (rect.left() == 1 && rect.right() == maxCols)
186
 
        {
187
 
            for (int row = rect.top(); row <= rect.bottom(); ++row)
188
 
            {
 
174
        else if (rect.left() == 1 && rect.right() == maxCols) {
 
175
            for (int row = rect.top(); row <= rect.bottom(); ++row) {
189
176
                if (pairs[i].second.data()->type() == Style::DefaultStyleKey)
190
177
                    tableContext.rowDefaultStyles.remove(row);
191
178
                else
195
182
    }
196
183
}
197
184
 
198
 
int StyleStorage::nextColumnStyleIndex( int column ) const
 
185
int StyleStorage::nextColumnStyleIndex(int column) const
199
186
{
200
187
    QMap<int, bool>::iterator it = d->usedColumns.upperBound(column + 1);
201
188
    return (it == d->usedColumns.end()) ? 0 : it.key();
224
211
//     kDebug(36006) <<"StyleStorage: inserting" << SubStyle::name(subStyle->type()) <<" into" << rect;
225
212
    // keep track of the used area
226
213
    const bool isDefault = subStyle->type() == Style::DefaultStyleKey;
227
 
    if (rect.top() == 1 && rect.bottom() == KS_colMax)
228
 
    {
229
 
        for (int i = rect.left(); i <= rect.right(); ++i)
230
 
        {
 
214
    if (rect.top() == 1 && rect.bottom() == KS_colMax) {
 
215
        for (int i = rect.left(); i <= rect.right(); ++i) {
231
216
            if (isDefault)
232
217
                d->usedColumns.remove(i);
233
218
            else
235
220
        }
236
221
        if (isDefault)
237
222
            d->usedArea -= rect;
238
 
    }
239
 
    else if (rect.left() == 1 && rect.right() == KS_rowMax)
240
 
    {
241
 
        for (int i = rect.top(); i <= rect.bottom(); ++i)
242
 
        {
 
223
    } else if (rect.left() == 1 && rect.right() == KS_rowMax) {
 
224
        for (int i = rect.top(); i <= rect.bottom(); ++i) {
243
225
            if (isDefault)
244
226
                d->usedRows.remove(i);
245
227
            else
247
229
        }
248
230
        if (isDefault)
249
231
            d->usedArea -= rect;
250
 
    }
251
 
    else
252
 
    {
 
232
    } else {
253
233
        if (isDefault)
254
234
            d->usedArea -= rect;
255
235
        else
258
238
 
259
239
    // lookup already used substyles
260
240
    typedef const QList< SharedSubStyle> StoredSubStyleList;
261
 
    StoredSubStyleList& storedSubStyles( d->subStyles.value(subStyle->type()) );
 
241
    StoredSubStyleList& storedSubStyles(d->subStyles.value(subStyle->type()));
262
242
    StoredSubStyleList::ConstIterator end(storedSubStyles.end());
263
 
    for ( StoredSubStyleList::ConstIterator it(storedSubStyles.begin()); it != end; ++it )
264
 
    {
265
 
        if ( Style::compare( subStyle.data(), (*it).data() ) )
266
 
        {
 
243
    for (StoredSubStyleList::ConstIterator it(storedSubStyles.begin()); it != end; ++it) {
 
244
        if (Style::compare(subStyle.data(), (*it).data())) {
267
245
//             kDebug(36006) <<"[REUSING EXISTING SUBSTYLE]";
268
246
            d->tree.insert(rect, *it);
269
 
            regionChanged( rect );
 
247
            regionChanged(rect);
270
248
            return;
271
249
        }
272
250
    }
273
251
    // insert substyle and add to the used substyle list
274
252
    d->tree.insert(rect, subStyle);
275
253
    d->subStyles[subStyle->type()].append(subStyle);
276
 
    regionChanged( rect );
 
254
    regionChanged(rect);
277
255
}
278
256
 
279
257
void StyleStorage::insert(const Region& region, const Style& style)
280
258
{
281
 
    if ( style.isEmpty() )
 
259
    if (style.isEmpty())
282
260
        return;
283
 
    foreach ( const SharedSubStyle& subStyle, style.subStyles() )
284
 
    {
 
261
    foreach(const SharedSubStyle& subStyle, style.subStyles()) {
285
262
        Region::ConstIterator end(region.constEnd());
286
 
        for (Region::ConstIterator it(region.constBegin()); it != end; ++it)
287
 
        {
 
263
        for (Region::ConstIterator it(region.constBegin()); it != end; ++it) {
288
264
            // insert substyle
289
265
            insert((*it)->rect(), subStyle);
290
 
            regionChanged( (*it)->rect() );
 
266
            regionChanged((*it)->rect());
291
267
        }
292
268
    }
293
269
}
294
270
 
295
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::insertRows(int position, int number)
 
271
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::insertRows(int position, int number)
296
272
{
297
 
    const QRect invalidRect(1,position,KS_colMax,KS_rowMax);
 
273
    const QRect invalidRect(1, position, KS_colMax, KS_rowMax);
298
274
    // invalidate the affected, cached styles
299
 
    invalidateCache( invalidRect );
 
275
    invalidateCache(invalidRect);
300
276
    // update the used area
301
277
    const QRegion usedArea = d->usedArea & invalidRect;
302
278
    d->usedArea -= invalidRect;
303
279
    d->usedArea += usedArea.translated(0, number);
304
 
    const QVector<QRect> rects = (d->usedArea & QRect(1, position-1, KS_colMax, 1)).rects();
 
280
    const QVector<QRect> rects = (d->usedArea & QRect(1, position - 1, KS_colMax, 1)).rects();
305
281
    for (int i = 0; i < rects.count(); ++i)
306
282
        d->usedArea += rects[i].adjusted(0, 1, 0, number + 1);
307
283
    // update the used rows
308
284
    QMap<int, bool> map;
309
285
    QMap<int, bool>::iterator begin = d->usedRows.upperBound(position);
310
286
    QMap<int, bool>::iterator end = d->usedRows.end();
311
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
312
 
    {
 
287
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
313
288
        if (it.key() + number <= KS_rowMax)
314
289
            map.insert(it.key() + number, true);
315
290
    }
317
292
        d->usedRows.remove(it.key());
318
293
    d->usedRows.unite(map);
319
294
    // process the tree
320
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.insertRows(position, number);
 
295
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.insertRows(position, number);
321
296
    return undoData;
322
297
}
323
298
 
324
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::insertColumns(int position, int number)
 
299
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::insertColumns(int position, int number)
325
300
{
326
 
    const QRect invalidRect(position,1,KS_colMax,KS_rowMax);
 
301
    const QRect invalidRect(position, 1, KS_colMax, KS_rowMax);
327
302
    // invalidate the affected, cached styles
328
 
    invalidateCache( invalidRect );
 
303
    invalidateCache(invalidRect);
329
304
    // update the used area
330
305
    const QRegion usedArea = d->usedArea & invalidRect;
331
306
    d->usedArea -= invalidRect;
332
307
    d->usedArea += usedArea.translated(number, 0);
333
 
    const QVector<QRect> rects = (d->usedArea & QRect(position-1, 0, 1, KS_rowMax)).rects();
 
308
    const QVector<QRect> rects = (d->usedArea & QRect(position - 1, 0, 1, KS_rowMax)).rects();
334
309
    for (int i = 0; i < rects.count(); ++i)
335
310
        d->usedArea += rects[i].adjusted(1, 0, number + 1, 0);
336
311
    // update the used columns
337
312
    QMap<int, bool> map;
338
313
    QMap<int, bool>::iterator begin = d->usedColumns.upperBound(position);
339
314
    QMap<int, bool>::iterator end = d->usedColumns.end();
340
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
341
 
    {
 
315
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
342
316
        if (it.key() + number <= KS_colMax)
343
317
            map.insert(it.key() + number, true);
344
318
    }
346
320
        d->usedColumns.remove(it.key());
347
321
    d->usedColumns.unite(map);
348
322
    // process the tree
349
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.insertColumns(position, number);
 
323
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.insertColumns(position, number);
350
324
    return undoData;
351
325
}
352
326
 
353
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::removeRows(int position, int number)
 
327
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::removeRows(int position, int number)
354
328
{
355
 
    const QRect invalidRect(1,position,KS_colMax,KS_rowMax);
 
329
    const QRect invalidRect(1, position, KS_colMax, KS_rowMax);
356
330
    // invalidate the affected, cached styles
357
 
    invalidateCache( invalidRect );
 
331
    invalidateCache(invalidRect);
358
332
    // update the used area
359
333
    const QRegion usedArea = d->usedArea & QRect(1, position + number, KS_colMax, KS_rowMax);
360
334
    d->usedArea -= invalidRect;
363
337
    QMap<int, bool> map;
364
338
    QMap<int, bool>::iterator begin = d->usedRows.upperBound(position);
365
339
    QMap<int, bool>::iterator end = d->usedRows.end();
366
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
367
 
    {
 
340
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
368
341
        if (it.key() - number >= position)
369
342
            map.insert(it.key() - number, true);
370
343
    }
372
345
        d->usedRows.remove(it.key());
373
346
    d->usedRows.unite(map);
374
347
    // process the tree
375
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.removeRows(position, number);
 
348
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.removeRows(position, number);
376
349
    return undoData;
377
350
}
378
351
 
379
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::removeColumns(int position, int number)
 
352
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::removeColumns(int position, int number)
380
353
{
381
 
    const QRect invalidRect(position,1,KS_colMax,KS_rowMax);
 
354
    const QRect invalidRect(position, 1, KS_colMax, KS_rowMax);
382
355
    // invalidate the affected, cached styles
383
 
    invalidateCache( invalidRect );
 
356
    invalidateCache(invalidRect);
384
357
    // update the used area
385
358
    const QRegion usedArea = d->usedArea & QRect(position + number, 1, KS_colMax, KS_rowMax);
386
359
    d->usedArea -= invalidRect;
389
362
    QMap<int, bool> map;
390
363
    QMap<int, bool>::iterator begin = d->usedColumns.upperBound(position);
391
364
    QMap<int, bool>::iterator end = d->usedColumns.end();
392
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
393
 
    {
 
365
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
394
366
        if (it.key() - number >= position)
395
367
            map.insert(it.key() - number, true);
396
368
    }
398
370
        d->usedColumns.remove(it.key());
399
371
    d->usedColumns.unite(map);
400
372
    // process the tree
401
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.removeColumns(position, number);
 
373
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.removeColumns(position, number);
402
374
    return undoData;
403
375
}
404
376
 
405
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::insertShiftRight( const QRect& rect )
 
377
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::insertShiftRight(const QRect& rect)
406
378
{
407
 
    const QRect invalidRect( rect.topLeft(), QPoint(KS_colMax, rect.bottom()) );
408
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.insertShiftRight( rect );
409
 
    regionChanged( invalidRect );
 
379
    const QRect invalidRect(rect.topLeft(), QPoint(KS_colMax, rect.bottom()));
 
380
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.insertShiftRight(rect);
 
381
    regionChanged(invalidRect);
410
382
    // update the used area
411
383
    const QRegion usedArea = d->usedArea & invalidRect;
412
384
    d->usedArea -= invalidRect;
413
385
    d->usedArea += usedArea.translated(rect.width(), 0);
414
 
    const QVector<QRect> rects = (d->usedArea & QRect(rect.left()-1, rect.top(), 1, rect.height())).rects();
 
386
    const QVector<QRect> rects = (d->usedArea & QRect(rect.left() - 1, rect.top(), 1, rect.height())).rects();
415
387
    for (int i = 0; i < rects.count(); ++i)
416
388
        d->usedArea += rects[i].adjusted(1, 0, rect.width() + 1, 0);
417
389
    // update the used columns
418
390
    QMap<int, bool>::iterator begin = d->usedColumns.upperBound(rect.left());
419
391
    QMap<int, bool>::iterator end = d->usedColumns.end();
420
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
421
 
    {
 
392
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
422
393
        if (it.key() + rect.width() <= KS_colMax)
423
394
            d->usedArea += QRect(it.key() + rect.width(), rect.top(), rect.width(), rect.height());
424
395
    }
427
398
    return undoData;
428
399
}
429
400
 
430
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::insertShiftDown( const QRect& rect )
 
401
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::insertShiftDown(const QRect& rect)
431
402
{
432
 
    const QRect invalidRect( rect.topLeft(), QPoint(rect.right(), KS_rowMax) );
433
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.insertShiftDown( rect );
434
 
    regionChanged( invalidRect );
 
403
    const QRect invalidRect(rect.topLeft(), QPoint(rect.right(), KS_rowMax));
 
404
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.insertShiftDown(rect);
 
405
    regionChanged(invalidRect);
435
406
    // update the used area
436
407
    const QRegion usedArea = d->usedArea & invalidRect;
437
408
    d->usedArea -= invalidRect;
438
409
    d->usedArea += usedArea.translated(0, rect.height());
439
 
    const QVector<QRect> rects = (d->usedArea & QRect(rect.left(), rect.top()-1, rect.width(), 1)).rects();
 
410
    const QVector<QRect> rects = (d->usedArea & QRect(rect.left(), rect.top() - 1, rect.width(), 1)).rects();
440
411
    for (int i = 0; i < rects.count(); ++i)
441
412
        d->usedArea += rects[i].adjusted(0, 1, 0, rect.height() + 1);
442
413
    // update the used rows
443
414
    QMap<int, bool>::iterator begin = d->usedRows.upperBound(rect.top());
444
415
    QMap<int, bool>::iterator end = d->usedRows.end();
445
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
446
 
    {
 
416
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
447
417
        if (it.key() + rect.height() <= KS_rowMax)
448
418
            d->usedArea += QRect(rect.left(), it.key() + rect.height(), rect.width(), rect.height());
449
419
    }
452
422
    return undoData;
453
423
}
454
424
 
455
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::removeShiftLeft( const QRect& rect )
 
425
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::removeShiftLeft(const QRect& rect)
456
426
{
457
 
    const QRect invalidRect( rect.topLeft(), QPoint(KS_colMax, rect.bottom()) );
458
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.removeShiftLeft( rect );
459
 
    regionChanged( invalidRect );
 
427
    const QRect invalidRect(rect.topLeft(), QPoint(KS_colMax, rect.bottom()));
 
428
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.removeShiftLeft(rect);
 
429
    regionChanged(invalidRect);
460
430
    // update the used area
461
431
    const QRegion usedArea = d->usedArea & QRect(rect.right() + 1, rect.top(), KS_colMax, rect.height());
462
432
    d->usedArea -= invalidRect;
464
434
    // update the used columns
465
435
    QMap<int, bool>::iterator begin = d->usedColumns.upperBound(rect.right() + 1);
466
436
    QMap<int, bool>::iterator end = d->usedColumns.end();
467
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
468
 
    {
 
437
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
469
438
        if (it.key() - rect.width() >= rect.left())
470
439
            d->usedArea += QRect(it.key() - rect.width(), rect.top(), rect.width(), rect.height());
471
440
    }
472
441
    return undoData;
473
442
}
474
443
 
475
 
QList< QPair<QRectF,SharedSubStyle> > StyleStorage::removeShiftUp( const QRect& rect )
 
444
QList< QPair<QRectF, SharedSubStyle> > StyleStorage::removeShiftUp(const QRect& rect)
476
445
{
477
 
    const QRect invalidRect( rect.topLeft(), QPoint(rect.right(), KS_rowMax) );
478
 
    QList< QPair<QRectF,SharedSubStyle> > undoData = d->tree.removeShiftUp( rect );
479
 
    regionChanged( invalidRect );
 
446
    const QRect invalidRect(rect.topLeft(), QPoint(rect.right(), KS_rowMax));
 
447
    QList< QPair<QRectF, SharedSubStyle> > undoData = d->tree.removeShiftUp(rect);
 
448
    regionChanged(invalidRect);
480
449
    // update the used area
481
 
    const QRegion usedArea = d->usedArea & QRect(rect.left(), rect.bottom()+1, rect.width(), KS_rowMax);
 
450
    const QRegion usedArea = d->usedArea & QRect(rect.left(), rect.bottom() + 1, rect.width(), KS_rowMax);
482
451
    d->usedArea -= invalidRect;
483
452
    d->usedArea += usedArea.translated(0, -rect.height());
484
453
    // update the used rows
485
454
    QMap<int, bool>::iterator begin = d->usedRows.upperBound(rect.bottom() + 1);
486
455
    QMap<int, bool>::iterator end = d->usedRows.end();
487
 
    for (QMap<int, bool>::iterator it = begin; it != end; ++it)
488
 
    {
 
456
    for (QMap<int, bool>::iterator it = begin; it != end; ++it) {
489
457
        if (it.key() - rect.height() >= rect.top())
490
458
            d->usedArea += QRect(rect.left(), it.key() - rect.height(), rect.width(), rect.height());
491
459
    }
501
469
void StyleStorage::garbageCollection()
502
470
{
503
471
    // any possible garbage left?
504
 
    if ( d->possibleGarbage.isEmpty() )
 
472
    if (d->possibleGarbage.isEmpty())
505
473
        return;
506
474
 
507
475
    const int currentZIndex = d->possibleGarbage.constBegin().key();
508
476
    const QPair<QRectF, SharedSubStyle> currentPair = d->possibleGarbage.take(currentZIndex);
509
477
 
510
478
    // check whether the named style still exists
511
 
    if ( currentPair.second->type() == Style::NamedStyleKey &&
512
 
         !styleManager()->style( static_cast<const NamedStyle*>(currentPair.second.data())->name ) )
513
 
    {
 
479
    if (currentPair.second->type() == Style::NamedStyleKey &&
 
480
            !styleManager()->style(static_cast<const NamedStyle*>(currentPair.second.data())->name)) {
514
481
        kDebug(36006) << "removing" << currentPair.second->debugData()
515
 
                      << "at" << Region(currentPair.first.toRect()).name()
516
 
                      << "used" << currentPair.second->ref << "times" << endl;
 
482
        << "at" << Region(currentPair.first.toRect()).name()
 
483
        << "used" << currentPair.second->ref << "times" << endl;
517
484
        d->tree.remove(currentPair.first.toRect(), currentPair.second);
518
 
        d->subStyles[currentPair.second->type()].removeAll( currentPair.second );
519
 
        QTimer::singleShot( g_garbageCollectionTimeOut, this, SLOT( garbageCollection() ) );
 
485
        d->subStyles[currentPair.second->type()].removeAll(currentPair.second);
 
486
        QTimer::singleShot(g_garbageCollectionTimeOut, this, SLOT(garbageCollection()));
520
487
        return; // already done
521
488
    }
522
489
 
523
 
    typedef QPair<QRectF,SharedSubStyle> SharedSubStylePair;
 
490
    typedef QPair<QRectF, SharedSubStyle> SharedSubStylePair;
524
491
    QMap<int, SharedSubStylePair> pairs = d->tree.intersectingPairs(currentPair.first.toRect());
525
 
    if ( pairs.isEmpty() ) // actually never true, just for sanity
526
 
         return;
 
492
    if (pairs.isEmpty())   // actually never true, just for sanity
 
493
        return;
527
494
    int zIndex = pairs.constBegin().key();
528
495
    SharedSubStylePair pair = pairs[zIndex];
529
496
 
530
497
    // check whether the default style is placed first
531
 
    if ( zIndex == currentZIndex &&
532
 
         currentPair.second->type() == Style::DefaultStyleKey &&
533
 
         pair.second->type() == Style::DefaultStyleKey &&
534
 
         pair.first == currentPair.first )
535
 
    {
 
498
    if (zIndex == currentZIndex &&
 
499
            currentPair.second->type() == Style::DefaultStyleKey &&
 
500
            pair.second->type() == Style::DefaultStyleKey &&
 
501
            pair.first == currentPair.first) {
536
502
        kDebug(36006) << "removing default style"
537
 
                      << "at" << Region(currentPair.first.toRect()).name()
538
 
                      << "used" << currentPair.second->ref << "times" << endl;
 
503
        << "at" << Region(currentPair.first.toRect()).name()
 
504
        << "used" << currentPair.second->ref << "times" << endl;
539
505
        d->tree.remove(currentPair.first.toRect(), currentPair.second);
540
 
        QTimer::singleShot( g_garbageCollectionTimeOut, this, SLOT( garbageCollection() ) );
 
506
        QTimer::singleShot(g_garbageCollectionTimeOut, this, SLOT(garbageCollection()));
541
507
        return; // already done
542
508
    }
543
509
 
544
510
    // special handling for indentation:
545
511
    // check whether the default indentation is placed first
546
 
    if ( zIndex == currentZIndex &&
547
 
         currentPair.second->type() == Style::Indentation &&
548
 
         static_cast<const SubStyleOne<Style::Indentation, int>*>(currentPair.second.data())->value1 == 0 &&
549
 
         pair.first == currentPair.first )
550
 
    {
 
512
    if (zIndex == currentZIndex &&
 
513
            currentPair.second->type() == Style::Indentation &&
 
514
            static_cast<const SubStyleOne<Style::Indentation, int>*>(currentPair.second.data())->value1 == 0 &&
 
515
            pair.first == currentPair.first) {
551
516
        kDebug(36006) << "removing default indentation"
552
 
                      << "at" << Region(currentPair.first.toRect()).name()
553
 
                      << "used" << currentPair.second->ref << "times" << endl;
 
517
        << "at" << Region(currentPair.first.toRect()).name()
 
518
        << "used" << currentPair.second->ref << "times" << endl;
554
519
        d->tree.remove(currentPair.first.toRect(), currentPair.second);
555
 
        QTimer::singleShot( g_garbageCollectionTimeOut, this, SLOT( garbageCollection() ) );
 
520
        QTimer::singleShot(g_garbageCollectionTimeOut, this, SLOT(garbageCollection()));
556
521
        return; // already done
557
522
    }
558
523
 
559
524
    // special handling for precision:
560
525
    // check whether the storage default precision is placed first
561
 
    if ( zIndex == currentZIndex &&
562
 
         currentPair.second->type() == Style::Precision &&
563
 
         static_cast<const SubStyleOne<Style::Precision, int>*>(currentPair.second.data())->value1 == 0 &&
564
 
         pair.first == currentPair.first )
565
 
    {
 
526
    if (zIndex == currentZIndex &&
 
527
            currentPair.second->type() == Style::Precision &&
 
528
            static_cast<const SubStyleOne<Style::Precision, int>*>(currentPair.second.data())->value1 == 0 &&
 
529
            pair.first == currentPair.first) {
566
530
        kDebug(36006) << "removing default precision"
567
 
                      << "at" << Region(currentPair.first.toRect()).name()
568
 
                      << "used" << currentPair.second->ref << "times" << endl;
 
531
        << "at" << Region(currentPair.first.toRect()).name()
 
532
        << "used" << currentPair.second->ref << "times" << endl;
569
533
        d->tree.remove(currentPair.first.toRect(), currentPair.second);
570
 
        QTimer::singleShot( g_garbageCollectionTimeOut, this, SLOT( garbageCollection() ) );
 
534
        QTimer::singleShot(g_garbageCollectionTimeOut, this, SLOT(garbageCollection()));
571
535
        return; // already done
572
536
    }
573
537
 
574
538
    // check, if the current substyle is covered by others added after it
575
539
    bool found = false;
576
540
    QMap<int, SharedSubStylePair>::ConstIterator end = pairs.constEnd();
577
 
    for (QMap<int, SharedSubStylePair>::ConstIterator it = pairs.constFind(currentZIndex); it != end; ++it)
578
 
    {
 
541
    for (QMap<int, SharedSubStylePair>::ConstIterator it = pairs.constFind(currentZIndex); it != end; ++it) {
579
542
        zIndex = it.key();
580
543
        pair = it.value();
581
544
 
582
545
        // as long as the substyle in question was not found, skip the substyle
583
 
        if ( !found )
584
 
        {
585
 
            if ( pair.first == currentPair.first &&
586
 
                 Style::compare( pair.second.data(), currentPair.second.data() ) &&
587
 
                 zIndex == currentZIndex)
588
 
            {
 
546
        if (!found) {
 
547
            if (pair.first == currentPair.first &&
 
548
                    Style::compare(pair.second.data(), currentPair.second.data()) &&
 
549
                    zIndex == currentZIndex) {
589
550
                found = true;
590
551
            }
591
552
            continue;
594
555
        // remove the current pair, if another substyle of the same type,
595
556
        // the default style or a named style follows and the rectangle
596
557
        // is completely covered
597
 
        if ( zIndex != currentZIndex &&
598
 
             ( pair.second->type() == currentPair.second->type() ||
599
 
               pair.second->type() == Style::DefaultStyleKey ||
600
 
               pair.second->type() == Style::NamedStyleKey ) &&
601
 
            pair.first.toRect().contains(currentPair.first.toRect()))
602
 
        {
 
558
        if (zIndex != currentZIndex &&
 
559
                (pair.second->type() == currentPair.second->type() ||
 
560
                 pair.second->type() == Style::DefaultStyleKey ||
 
561
                 pair.second->type() == Style::NamedStyleKey) &&
 
562
                pair.first.toRect().contains(currentPair.first.toRect())) {
603
563
            // special handling for indentation
604
564
            // only remove, if covered by default
605
 
            if ( pair.second->type() == Style::Indentation &&
606
 
                 static_cast<const SubStyleOne<Style::Indentation, int>*>(pair.second.data())->value1 != 0 )
607
 
            {
 
565
            if (pair.second->type() == Style::Indentation &&
 
566
                    static_cast<const SubStyleOne<Style::Indentation, int>*>(pair.second.data())->value1 != 0) {
608
567
                continue;
609
568
            }
610
569
 
611
570
            // special handling for precision
612
571
            // only remove, if covered by default
613
 
            if ( pair.second->type() == Style::Precision &&
614
 
                 static_cast<const SubStyleOne<Style::Precision, int>*>(pair.second.data())->value1 != 0 )
615
 
            {
 
572
            if (pair.second->type() == Style::Precision &&
 
573
                    static_cast<const SubStyleOne<Style::Precision, int>*>(pair.second.data())->value1 != 0) {
616
574
                continue;
617
575
            }
618
576
 
619
577
            kDebug(36006) << "removing" << currentPair.second->debugData()
620
 
                          << "at" << Region(currentPair.first.toRect()).name()
621
 
                          << "used" << currentPair.second->ref << "times" << endl;
 
578
            << "at" << Region(currentPair.first.toRect()).name()
 
579
            << "used" << currentPair.second->ref << "times" << endl;
622
580
            d->tree.remove(currentPair.first.toRect(), currentPair.second);
623
581
#if 0
624
 
            kDebug(36006) <<"StyleStorage: usage of" << currentPair.second->debugData() <<" is" << currentPair.second->ref;
 
582
            kDebug(36006) << "StyleStorage: usage of" << currentPair.second->debugData() << " is" << currentPair.second->ref;
625
583
            // FIXME Stefan: The usage of substyles used once should be
626
584
            //               two (?) here, not more. Why is this not the case?
627
585
            //               The shared pointers are used by:
629
587
            //               b) the reusage list (where it should be removed)
630
588
            //               c) the cached styles (!)
631
589
            //               d) the undo data of operations (!)
632
 
            if ( currentPair.second->ref == 2 )
633
 
            {
634
 
                kDebug(36006) <<"StyleStorage: removing" << currentPair.second <<" from the used subStyles";
635
 
                d->subStyles[currentPair.second->type()].removeAll( currentPair.second );
 
590
            if (currentPair.second->ref == 2) {
 
591
                kDebug(36006) << "StyleStorage: removing" << currentPair.second << " from the used subStyles";
 
592
                d->subStyles[currentPair.second->type()].removeAll(currentPair.second);
636
593
            }
637
594
#endif
638
595
            break;
639
596
        }
640
597
    }
641
 
    QTimer::singleShot( g_garbageCollectionTimeOut, this, SLOT( garbageCollection() ) );
 
598
    QTimer::singleShot(g_garbageCollectionTimeOut, this, SLOT(garbageCollection()));
642
599
}
643
600
 
644
 
void StyleStorage::regionChanged( const QRect& rect )
 
601
void StyleStorage::regionChanged(const QRect& rect)
645
602
{
646
 
    if ( d->map->isLoading() )
647
 
         return;
 
603
    if (d->map->isLoading())
 
604
        return;
648
605
    // mark the possible garbage
649
606
    // NOTE Stefan: The map may contain multiple indices. The already existing possible garbage has
650
607
    // has to be inserted most recently, because it should be accessed first.
651
608
    d->possibleGarbage = d->tree.intersectingPairs(rect).unite(d->possibleGarbage);
652
 
    QTimer::singleShot( g_garbageCollectionTimeOut, this, SLOT( garbageCollection() ) );
 
609
    QTimer::singleShot(g_garbageCollectionTimeOut, this, SLOT(garbageCollection()));
653
610
    // invalidate cache
654
 
    invalidateCache( rect );
 
611
    invalidateCache(rect);
655
612
}
656
613
 
657
 
void StyleStorage::invalidateCache( const QRect& rect )
 
614
void StyleStorage::invalidateCache(const QRect& rect)
658
615
{
659
616
//     kDebug(36006) <<"StyleStorage: Invalidating" << rect;
660
 
    const QRegion region = d->cachedArea.intersected( rect );
661
 
    d->cachedArea = d->cachedArea.subtracted( rect );
662
 
    foreach ( const QRect& rect, region.rects() )
663
 
    {
664
 
        for ( int col = rect.left(); col <= rect.right(); ++col )
665
 
        {
666
 
            for ( int row = rect.top(); row <= rect.bottom(); ++row )
667
 
            {
 
617
    const QRegion region = d->cachedArea.intersected(rect);
 
618
    d->cachedArea = d->cachedArea.subtracted(rect);
 
619
    foreach(const QRect& rect, region.rects()) {
 
620
        for (int col = rect.left(); col <= rect.right(); ++col) {
 
621
            for (int row = rect.top(); row <= rect.bottom(); ++row) {
668
622
//                 kDebug(36006) <<"StyleStorage: Removing cached style for" << Cell::name( col, row );
669
 
                d->cache.remove( QPoint( col, row ) ); // also deletes it
 
623
                d->cache.remove(QPoint(col, row));     // also deletes it
670
624
            }
671
625
        }
672
626
    }
673
627
}
674
628
 
675
 
Style StyleStorage::composeStyle( const QList<SharedSubStyle>& subStyles ) const
 
629
Style StyleStorage::composeStyle(const QList<SharedSubStyle>& subStyles) const
676
630
{
677
 
    if ( subStyles.isEmpty() )
 
631
    if (subStyles.isEmpty())
678
632
        return *styleManager()->defaultStyle();
679
633
 
680
634
    Style style;
681
 
    for ( int i = 0; i < subStyles.count(); ++i )
682
 
    {
683
 
        if ( subStyles[i]->type() == Style::DefaultStyleKey )
 
635
    for (int i = 0; i < subStyles.count(); ++i) {
 
636
        if (subStyles[i]->type() == Style::DefaultStyleKey)
684
637
            style = *styleManager()->defaultStyle();
685
 
        else if ( subStyles[i]->type() == Style::NamedStyleKey )
686
 
        {
 
638
        else if (subStyles[i]->type() == Style::NamedStyleKey) {
687
639
            style.clear();
688
 
            const CustomStyle* namedStyle = styleManager()->style( static_cast<const NamedStyle*>(subStyles[i].data())->name );
689
 
            if ( namedStyle )
690
 
            {
 
640
            const CustomStyle* namedStyle = styleManager()->style(static_cast<const NamedStyle*>(subStyles[i].data())->name);
 
641
            if (namedStyle) {
691
642
                // first, load the attributes of the parent style(s)
692
643
                QList<CustomStyle*> parentStyles;
693
 
                CustomStyle* parentStyle = styleManager()->style( namedStyle->parentName() );
 
644
                CustomStyle* parentStyle = styleManager()->style(namedStyle->parentName());
694
645
//                 kDebug(36006) <<"StyleStorage:" << namedStyle->name() <<"'s parent =" << namedStyle->parentName();
695
 
                while ( parentStyle )
696
 
                {
 
646
                while (parentStyle) {
697
647
//                     kDebug(36006) <<"StyleStorage:" << parentStyle->name() <<"'s parent =" << parentStyle->parentName();
698
 
                    parentStyles.prepend( parentStyle );
699
 
                    parentStyle = styleManager()->style( parentStyle->parentName() );
 
648
                    parentStyles.prepend(parentStyle);
 
649
                    parentStyle = styleManager()->style(parentStyle->parentName());
700
650
                }
701
651
                Style tmpStyle;
702
 
                for ( int i = 0; i < parentStyles.count(); ++i )
703
 
                {
 
652
                for (int i = 0; i < parentStyles.count(); ++i) {
704
653
//                     kDebug(36006) <<"StyleStorage: merging" << parentStyles[i]->name() <<" in.";
705
654
                    tmpStyle = *parentStyles[i];
706
655
                    tmpStyle.merge(style);
712
661
                tmpStyle.merge(style);
713
662
                style = tmpStyle;
714
663
                // not the default anymore
715
 
                style.clearAttribute( Style::DefaultStyleKey );
 
664
                style.clearAttribute(Style::DefaultStyleKey);
716
665
                // reset the parent name
717
 
                style.setParentName( namedStyle->name() );
 
666
                style.setParentName(namedStyle->name());
718
667
//                 kDebug(36006) <<"StyleStorage: merging done";
719
668
            }
720
 
        }
721
 
        else if ( subStyles[i]->type() == Style::Indentation )
722
 
        {
 
669
        } else if (subStyles[i]->type() == Style::Indentation) {
723
670
            // special handling for indentation
724
671
            const int indentation = static_cast<const SubStyleOne<Style::Indentation, int>*>(subStyles[i].data())->value1;
725
 
            if ( indentation == 0 || ( style.indentation() + indentation <= 0 ) )
726
 
                style.clearAttribute( Style::Indentation ); // reset
 
672
            if (indentation == 0 || (style.indentation() + indentation <= 0))
 
673
                style.clearAttribute(Style::Indentation);   // reset
727
674
            else
728
 
                style.setIndentation( style.indentation() + indentation ); // increase/decrease
729
 
        }
730
 
        else if ( subStyles[i]->type() == Style::Precision )
731
 
        {
 
675
                style.setIndentation(style.indentation() + indentation);   // increase/decrease
 
676
        } else if (subStyles[i]->type() == Style::Precision) {
732
677
            // special handling for precision
733
678
            // The Style default (-1) and the storage default (0) differ.
734
679
            const int precision = static_cast<const SubStyleOne<Style::Precision, int>*>(subStyles[i].data())->value1;
735
 
            if ( precision == 0 ) // storage default
736
 
                style.clearAttribute( Style::Precision ); // reset
737
 
            else
738
 
            {
739
 
                if ( style.precision() == -1 ) // Style default
740
 
                    style.setPrecision( qMax( 0, precision)  ); // positive initial value
741
 
                else if ( style.precision() + precision <= 0 )
742
 
                    style.setPrecision( 0 );
743
 
                else if ( style.precision() + precision >= 10 )
744
 
                    style.setPrecision( 10 );
 
680
            if (precision == 0)   // storage default
 
681
                style.clearAttribute(Style::Precision);   // reset
 
682
            else {
 
683
                if (style.precision() == -1)   // Style default
 
684
                    style.setPrecision(qMax(0, precision));     // positive initial value
 
685
                else if (style.precision() + precision <= 0)
 
686
                    style.setPrecision(0);
 
687
                else if (style.precision() + precision >= 10)
 
688
                    style.setPrecision(10);
745
689
                else
746
 
                    style.setPrecision( style.precision() + precision ); // increase/decrease
 
690
                    style.setPrecision(style.precision() + precision);   // increase/decrease
747
691
            }
748
 
        }
749
 
        else
750
 
        {
 
692
        } else {
751
693
            // insert the substyle
752
694
//             kDebug(36006) <<"StyleStorage: inserting" << subStyles[i]->debugData();
753
 
            style.insertSubStyle( subStyles[i] );
 
695
            style.insertSubStyle(subStyles[i]);
754
696
            // not the default anymore
755
 
            style.clearAttribute( Style::DefaultStyleKey );
 
697
            style.clearAttribute(Style::DefaultStyleKey);
756
698
        }
757
699
    }
758
700
    return style;