Warning, file /office/calligra/libs/flake/KoSnapProxy.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2008-2009 Jan Hambrecht <jaham@gmx.net>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #include "KoSnapProxy.h"
0021 #include "KoSnapGuide.h"
0022 #include "KoCanvasBase.h"
0023 #include "KoShapeManager.h"
0024 #include "KoPathShape.h"
0025 #include "KoPathPoint.h"
0026 #include <KoSnapData.h>
0027 
0028 KoSnapProxy::KoSnapProxy(KoSnapGuide * snapGuide)
0029         : m_snapGuide(snapGuide)
0030 {
0031 }
0032 
0033 QVector<QPointF> KoSnapProxy::pointsInRect(const QRectF &rect) const
0034 {
0035     QVector<QPointF> result;
0036     QList<KoShape*> shapes = shapesInRect(rect);
0037     for (KoShape * shape : shapes) {
0038         // There exists a problem on msvc with for(each) and QVector<QPointF>
0039         QVector<QPointF> points(pointsFromShape(shape));
0040         for (int i = 0; i < points.count(); ++i) {
0041             const QPointF point(points[i]);
0042             if (rect.contains(point))
0043                 result.append(point);
0044         }
0045     }
0046 
0047     return result;
0048 }
0049 
0050 QList<KoShape*> KoSnapProxy::shapesInRect(const QRectF &rect, bool omitEditedShape) const
0051 {
0052     QList<KoShape*> shapes = m_snapGuide->canvas()->shapeManager()->shapesAt(rect);
0053     for (KoShape * shape : m_snapGuide->ignoredShapes()) {
0054         int index = shapes.indexOf(shape);
0055         if (index >= 0)
0056             shapes.removeAt(index);
0057     }
0058     if (! omitEditedShape && m_snapGuide->editedShape()) {
0059         QRectF bound = m_snapGuide->editedShape()->boundingRect();
0060         if (rect.intersects(bound) || rect.contains(bound))
0061             shapes.append(m_snapGuide->editedShape());
0062     }
0063     return shapes;
0064 }
0065 
0066 QVector<QPointF> KoSnapProxy::pointsFromShape(KoShape * shape) const
0067 {
0068     QVector<QPointF> snapPoints;
0069     // no snapping to hidden shapes
0070     if (! shape->isVisible(true))
0071         return snapPoints;
0072 
0073     // return the special snap points of the shape
0074     snapPoints += shape->snapData().snapPoints();
0075 
0076     KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
0077     if (path) {
0078         QTransform m = path->absoluteTransformation(0);
0079 
0080         QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
0081 
0082         int subpathCount = path->subpathCount();
0083         for (int subpathIndex = 0; subpathIndex < subpathCount; ++subpathIndex) {
0084             int pointCount = path->subpathPointCount(subpathIndex);
0085             for (int pointIndex = 0; pointIndex < pointCount; ++pointIndex) {
0086                 KoPathPoint * p = path->pointByIndex(KoPathPointIndex(subpathIndex, pointIndex));
0087                 if (! p || ignoredPoints.contains(p))
0088                     continue;
0089 
0090                 snapPoints.append(m.map(p->point()));
0091             }
0092         }
0093     }
0094     else
0095     {
0096         // add the bounding box corners as default snap points
0097         QRectF bbox = shape->boundingRect();
0098         snapPoints.append(bbox.topLeft());
0099         snapPoints.append(bbox.topRight());
0100         snapPoints.append(bbox.bottomRight());
0101         snapPoints.append(bbox.bottomLeft());
0102     }
0103 
0104     return snapPoints;
0105 }
0106 
0107 QList<KoPathSegment> KoSnapProxy::segmentsInRect(const QRectF &rect) const
0108 {
0109     
0110     QList<KoShape*> shapes = shapesInRect(rect, true);
0111     QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
0112 
0113     QList<KoPathSegment> segments;
0114     for (KoShape * shape : shapes) {
0115         QList<KoPathSegment> shapeSegments;
0116         QRectF rectOnShape = shape->documentToShape(rect);
0117         KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
0118         if (path) {
0119             shapeSegments = path->segmentsAt(rectOnShape);
0120         } else {
0121             for (const KoPathSegment & s : shape->snapData().snapSegments()) {
0122                 QRectF controlRect = s.controlPointRect();
0123                 if (! rect.intersects(controlRect) && ! controlRect.contains(rect))
0124                     continue;
0125                 QRectF bound = s.boundingRect();
0126                 if (! rect.intersects(bound) && ! bound.contains(rect))
0127                     continue;
0128                 shapeSegments.append(s);
0129             }
0130         }
0131 
0132         QTransform m = shape->absoluteTransformation(0);
0133         // transform segments to document coordinates
0134         for (const KoPathSegment & s : shapeSegments) {
0135             if (ignoredPoints.contains(s.first()) || ignoredPoints.contains(s.second()))
0136                 continue;
0137             segments.append(s.mapped(m));
0138         }
0139     }
0140     return segments;
0141 }
0142 
0143 QList<KoShape*> KoSnapProxy::shapes(bool omitEditedShape) const
0144 {
0145     QList<KoShape*> allShapes = m_snapGuide->canvas()->shapeManager()->shapes();
0146     QList<KoShape*> filteredShapes;
0147     QList<KoShape*> ignoredShapes = m_snapGuide->ignoredShapes();
0148 
0149     // filter all hidden and ignored shapes
0150     for (KoShape * shape : allShapes) {
0151         if (! shape->isVisible(true))
0152             continue;
0153         if (ignoredShapes.contains(shape))
0154             continue;
0155 
0156         filteredShapes.append(shape);
0157     }
0158     if (! omitEditedShape && m_snapGuide->editedShape())
0159         filteredShapes.append(m_snapGuide->editedShape());
0160 
0161     return filteredShapes;
0162 }
0163 
0164 KoCanvasBase * KoSnapProxy::canvas() const
0165 {
0166     return m_snapGuide->canvas();
0167 }
0168