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

« back to all changes in this revision

Viewing changes to libs/flake/KoSnapGuide.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:
18
18
 */
19
19
 
20
20
#include "KoSnapGuide.h"
 
21
#include "KoSnapProxy.h"
21
22
#include "KoSnapStrategy.h"
22
23
 
23
24
#include <KoPathShape.h>
30
31
 
31
32
#include <math.h>
32
33
 
 
34
 
33
35
class KoSnapGuide::Private
34
36
{
35
37
public:
36
38
    Private(KoCanvasBase *parentCanvas)
37
 
    : canvas(parentCanvas), editedShape(0), currentStrategy(0)
38
 
    , usedStrategies(0), active(true), snapDistance(10)
 
39
        : canvas(parentCanvas), editedShape(0), currentStrategy(0),
 
40
        active(true),
 
41
        snapDistance(10)
39
42
    {
40
43
    }
41
44
 
42
45
    ~Private()
43
46
    {
44
 
        qDeleteAll( strategies );
 
47
        qDeleteAll(strategies);
45
48
        strategies.clear();
46
49
    }
47
50
 
48
 
    KoCanvasBase * canvas;
49
 
    KoShape * editedShape;
 
51
    KoCanvasBase *canvas;
 
52
    KoShape *editedShape;
50
53
 
51
54
    QList<KoSnapStrategy*> strategies;
52
 
    KoSnapStrategy * currentStrategy;
 
55
    KoSnapStrategy *currentStrategy;
53
56
 
54
 
    int usedStrategies;
 
57
    KoSnapGuide::Strategies usedStrategies;
55
58
    bool active;
56
59
    int snapDistance;
57
60
    QList<KoPathPoint*> ignoredPoints;
58
61
    QList<KoShape*> ignoredShapes;
59
62
};
60
63
 
61
 
KoSnapGuide::KoSnapGuide(KoCanvasBase * canvas)
62
 
: d(new Private(canvas))
 
64
KoSnapGuide::KoSnapGuide(KoCanvasBase *canvas)
 
65
    : d(new Private(canvas))
63
66
{
64
67
    d->strategies.append(new GridSnapStrategy());
65
68
    d->strategies.append(new NodeSnapStrategy());
75
78
    delete d;
76
79
}
77
80
 
78
 
void KoSnapGuide::setEditedShape(KoShape * shape)
 
81
void KoSnapGuide::setEditedShape(KoShape *shape)
79
82
{
80
83
    d->editedShape = shape;
81
84
}
82
85
 
83
 
KoShape * KoSnapGuide::editedShape() const
 
86
KoShape *KoSnapGuide::editedShape() const
84
87
{
85
88
    return d->editedShape;
86
89
}
87
90
 
88
 
void KoSnapGuide::enableSnapStrategies(int strategies)
 
91
void KoSnapGuide::enableSnapStrategies(Strategies strategies)
89
92
{
90
93
    d->usedStrategies = strategies;
91
94
}
92
95
 
93
 
int KoSnapGuide::enabledSnapStrategies() const
 
96
KoSnapGuide::Strategies KoSnapGuide::enabledSnapStrategies() const
94
97
{
95
98
    return d->usedStrategies;
96
99
}
97
100
 
98
 
bool KoSnapGuide::addCustomSnapStrategy(KoSnapStrategy * customStrategy)
 
101
bool KoSnapGuide::addCustomSnapStrategy(KoSnapStrategy *customStrategy)
99
102
{
100
 
    if (!customStrategy || customStrategy->type() != KoSnapStrategy::Custom)
 
103
    if (!customStrategy || customStrategy->type() != CustomSnapping)
101
104
        return false;
102
105
 
103
106
    d->strategies.append(customStrategy);
135
138
 
136
139
    qreal minDistance = HUGE_VAL;
137
140
 
138
 
    qreal maxSnapDistance = d->canvas->viewConverter()->viewToDocument(QSizeF(d->snapDistance, d->snapDistance)).width();
 
141
    qreal maxSnapDistance = d->canvas->viewConverter()->viewToDocument(QSizeF(d->snapDistance,
 
142
                d->snapDistance)).width();
139
143
 
140
 
    foreach(KoSnapStrategy * strategy, d->strategies) {
 
144
    foreach (KoSnapStrategy *strategy, d->strategies) {
141
145
        if (d->usedStrategies & strategy->type()
142
 
            || strategy->type() == KoSnapStrategy::Grid
143
 
            || strategy->type() == KoSnapStrategy::Custom) {
 
146
                || strategy->type() == GridSnapping || strategy->type() == CustomSnapping) {
144
147
            if (! strategy->snap(mousePosition, &proxy, maxSnapDistance))
145
148
                continue;
146
149
 
168
171
        return rect.adjusted(-2, -2, 2, 2);
169
172
    } else {
170
173
        return rect;
171
 
    };
 
174
    }
172
175
}
173
176
 
174
177
void KoSnapGuide::paint(QPainter &painter, const KoViewConverter &converter)
191
194
    painter.drawPath(decoration);
192
195
}
193
196
 
194
 
KoCanvasBase * KoSnapGuide::canvas() const
 
197
KoCanvasBase *KoSnapGuide::canvas() const
195
198
{
196
199
    return d->canvas;
197
200
}
224
227
    d->ignoredShapes.clear();
225
228
    // remove all custom strategies
226
229
    int strategyCount = d->strategies.count();
227
 
    for(int i = strategyCount-1; i >= 0; --i) {
228
 
        if (d->strategies[i]->type() == KoSnapStrategy::Custom) {
 
230
    for (int i = strategyCount-1; i >= 0; --i) {
 
231
        if (d->strategies[i]->type() == CustomSnapping) {
229
232
            delete d->strategies[i];
230
233
            d->strategies.removeAt(i);
231
234
        }
232
235
    }
233
236
}
234
237
 
235
 
/////////////////////////////////////////////////////////
236
 
// snap proxy
237
 
/////////////////////////////////////////////////////////
238
 
 
239
 
KoSnapProxy::KoSnapProxy(KoSnapGuide * snapGuide)
240
 
        : m_snapGuide(snapGuide)
241
 
{
242
 
}
243
 
 
244
 
QList<QPointF> KoSnapProxy::pointsInRect(const QRectF &rect)
245
 
{
246
 
    QList<QPointF> points;
247
 
    QList<KoShape*> shapes = shapesInRect(rect);
248
 
    foreach(KoShape * shape, shapes) {
249
 
        foreach(const QPointF & point, pointsFromShape(shape)) {
250
 
            if (rect.contains(point))
251
 
                points.append(point);
252
 
        }
253
 
    }
254
 
 
255
 
    return points;
256
 
}
257
 
 
258
 
QList<KoShape*> KoSnapProxy::shapesInRect(const QRectF &rect, bool omitEditedShape)
259
 
{
260
 
    QList<KoShape*> shapes = m_snapGuide->canvas()->shapeManager()->shapesAt(rect);
261
 
    foreach(KoShape * shape, m_snapGuide->ignoredShapes()) {
262
 
        int index = shapes.indexOf(shape);
263
 
        if (index >= 0)
264
 
            shapes.removeAt(index);
265
 
    }
266
 
    if (! omitEditedShape && m_snapGuide->editedShape()) {
267
 
        QRectF bound = m_snapGuide->editedShape()->boundingRect();
268
 
        if (rect.intersects(bound) || rect.contains(bound))
269
 
            shapes.append(m_snapGuide->editedShape());
270
 
    }
271
 
    return shapes;
272
 
}
273
 
 
274
 
QList<QPointF> KoSnapProxy::pointsFromShape(KoShape * shape)
275
 
{
276
 
    QList<QPointF> snapPoints;
277
 
    // no snapping to hidden shapes
278
 
    if (! shape->isVisible(true))
279
 
        return snapPoints;
280
 
 
281
 
    // return the special snap points of the shape
282
 
    snapPoints += shape->snapData().snapPoints();
283
 
 
284
 
    KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
285
 
    if (path) {
286
 
        QMatrix m = path->absoluteTransformation(0);
287
 
 
288
 
        QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
289
 
 
290
 
        int subpathCount = path->subpathCount();
291
 
        for (int subpathIndex = 0; subpathIndex < subpathCount; ++subpathIndex) {
292
 
            int pointCount = path->pointCountSubpath(subpathIndex);
293
 
            for (int pointIndex = 0; pointIndex < pointCount; ++pointIndex) {
294
 
                KoPathPoint * p = path->pointByIndex(KoPathPointIndex(subpathIndex, pointIndex));
295
 
                if (! p || ignoredPoints.contains(p))
296
 
                    continue;
297
 
 
298
 
                snapPoints.append(m.map(p->point()));
299
 
            }
300
 
        }
301
 
    }
302
 
    else
303
 
    {
304
 
        // add the bounding box corners as default snap points
305
 
        QRectF bbox = shape->boundingRect();
306
 
        snapPoints.append(bbox.topLeft());
307
 
        snapPoints.append(bbox.topRight());
308
 
        snapPoints.append(bbox.bottomRight());
309
 
        snapPoints.append(bbox.bottomLeft());
310
 
    }
311
 
 
312
 
    return snapPoints;
313
 
}
314
 
 
315
 
QList<KoPathSegment> KoSnapProxy::segmentsInRect(const QRectF &rect)
316
 
{
317
 
    QList<KoShape*> shapes = shapesInRect(rect, true);
318
 
    QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
319
 
 
320
 
    QList<KoPathSegment> segments;
321
 
    foreach(KoShape * shape, shapes) {
322
 
        QList<KoPathSegment> shapeSegments;
323
 
        QRectF rectOnShape = shape->documentToShape(rect);
324
 
        KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
325
 
        if (path) {
326
 
            shapeSegments = path->segmentsAt(rectOnShape);
327
 
        } else {
328
 
            foreach(const KoPathSegment & s, shape->snapData().snapSegments()) {
329
 
                QRectF controlRect = s.controlPointRect();
330
 
                if (! rect.intersects(controlRect) && ! controlRect.contains(rect))
331
 
                    continue;
332
 
                QRectF bound = s.boundingRect();
333
 
                if (! rect.intersects(bound) && ! bound.contains(rect))
334
 
                    continue;
335
 
                shapeSegments.append(s);
336
 
            }
337
 
        }
338
 
 
339
 
        QMatrix m = shape->absoluteTransformation(0);
340
 
        // transform segments to document coordinates
341
 
        foreach(const KoPathSegment & s, shapeSegments) {
342
 
            if (ignoredPoints.contains(s.first()) || ignoredPoints.contains(s.second()))
343
 
                continue;
344
 
            segments.append(s.mapped(m));
345
 
        }
346
 
    }
347
 
    return segments;
348
 
}
349
 
 
350
 
QList<KoShape*> KoSnapProxy::shapes(bool omitEditedShape)
351
 
{
352
 
    QList<KoShape*> allShapes = m_snapGuide->canvas()->shapeManager()->shapes();
353
 
    QList<KoShape*> filteredShapes;
354
 
    QList<KoShape*> ignoredShapes = m_snapGuide->ignoredShapes();
355
 
 
356
 
    // filter all hidden and ignored shapes
357
 
    foreach(KoShape * shape, allShapes) {
358
 
        if (! shape->isVisible(true))
359
 
            continue;
360
 
        if (ignoredShapes.contains(shape))
361
 
            continue;
362
 
 
363
 
        filteredShapes.append(shape);
364
 
    }
365
 
    if (! omitEditedShape && m_snapGuide->editedShape())
366
 
        filteredShapes.append(m_snapGuide->editedShape());
367
 
 
368
 
    return filteredShapes;
369
 
}
370
 
 
371
 
KoCanvasBase * KoSnapProxy::canvas()
372
 
{
373
 
    return m_snapGuide->canvas();
374
 
}