33
35
class KoSnapGuide::Private
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),
44
qDeleteAll( strategies );
47
qDeleteAll(strategies);
45
48
strategies.clear();
48
KoCanvasBase * canvas;
49
KoShape * editedShape;
51
54
QList<KoSnapStrategy*> strategies;
52
KoSnapStrategy * currentStrategy;
55
KoSnapStrategy *currentStrategy;
57
KoSnapGuide::Strategies usedStrategies;
57
60
QList<KoPathPoint*> ignoredPoints;
58
61
QList<KoShape*> ignoredShapes;
61
KoSnapGuide::KoSnapGuide(KoCanvasBase * canvas)
62
: d(new Private(canvas))
64
KoSnapGuide::KoSnapGuide(KoCanvasBase *canvas)
65
: d(new Private(canvas))
64
67
d->strategies.append(new GridSnapStrategy());
65
68
d->strategies.append(new NodeSnapStrategy());
78
void KoSnapGuide::setEditedShape(KoShape * shape)
81
void KoSnapGuide::setEditedShape(KoShape *shape)
80
83
d->editedShape = shape;
83
KoShape * KoSnapGuide::editedShape() const
86
KoShape *KoSnapGuide::editedShape() const
85
88
return d->editedShape;
88
void KoSnapGuide::enableSnapStrategies(int strategies)
91
void KoSnapGuide::enableSnapStrategies(Strategies strategies)
90
93
d->usedStrategies = strategies;
93
int KoSnapGuide::enabledSnapStrategies() const
96
KoSnapGuide::Strategies KoSnapGuide::enabledSnapStrategies() const
95
98
return d->usedStrategies;
98
bool KoSnapGuide::addCustomSnapStrategy(KoSnapStrategy * customStrategy)
101
bool KoSnapGuide::addCustomSnapStrategy(KoSnapStrategy *customStrategy)
100
if (!customStrategy || customStrategy->type() != KoSnapStrategy::Custom)
103
if (!customStrategy || customStrategy->type() != CustomSnapping)
103
106
d->strategies.append(customStrategy);
136
139
qreal minDistance = HUGE_VAL;
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();
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))
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);
235
/////////////////////////////////////////////////////////
237
/////////////////////////////////////////////////////////
239
KoSnapProxy::KoSnapProxy(KoSnapGuide * snapGuide)
240
: m_snapGuide(snapGuide)
244
QList<QPointF> KoSnapProxy::pointsInRect(const QRectF &rect)
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);
258
QList<KoShape*> KoSnapProxy::shapesInRect(const QRectF &rect, bool omitEditedShape)
260
QList<KoShape*> shapes = m_snapGuide->canvas()->shapeManager()->shapesAt(rect);
261
foreach(KoShape * shape, m_snapGuide->ignoredShapes()) {
262
int index = shapes.indexOf(shape);
264
shapes.removeAt(index);
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());
274
QList<QPointF> KoSnapProxy::pointsFromShape(KoShape * shape)
276
QList<QPointF> snapPoints;
277
// no snapping to hidden shapes
278
if (! shape->isVisible(true))
281
// return the special snap points of the shape
282
snapPoints += shape->snapData().snapPoints();
284
KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
286
QMatrix m = path->absoluteTransformation(0);
288
QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
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))
298
snapPoints.append(m.map(p->point()));
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());
315
QList<KoPathSegment> KoSnapProxy::segmentsInRect(const QRectF &rect)
317
QList<KoShape*> shapes = shapesInRect(rect, true);
318
QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
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);
326
shapeSegments = path->segmentsAt(rectOnShape);
328
foreach(const KoPathSegment & s, shape->snapData().snapSegments()) {
329
QRectF controlRect = s.controlPointRect();
330
if (! rect.intersects(controlRect) && ! controlRect.contains(rect))
332
QRectF bound = s.boundingRect();
333
if (! rect.intersects(bound) && ! bound.contains(rect))
335
shapeSegments.append(s);
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()))
344
segments.append(s.mapped(m));
350
QList<KoShape*> KoSnapProxy::shapes(bool omitEditedShape)
352
QList<KoShape*> allShapes = m_snapGuide->canvas()->shapeManager()->shapes();
353
QList<KoShape*> filteredShapes;
354
QList<KoShape*> ignoredShapes = m_snapGuide->ignoredShapes();
356
// filter all hidden and ignored shapes
357
foreach(KoShape * shape, allShapes) {
358
if (! shape->isVisible(true))
360
if (ignoredShapes.contains(shape))
363
filteredShapes.append(shape);
365
if (! omitEditedShape && m_snapGuide->editedShape())
366
filteredShapes.append(m_snapGuide->editedShape());
368
return filteredShapes;
371
KoCanvasBase * KoSnapProxy::canvas()
373
return m_snapGuide->canvas();