libs/flake

KoPathToolSelection.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  * Copyright (C) 2006,2008 Jan Hambrecht <jaham@gmx.net>
00003  * Copyright (C) 2006,2007 Thorsten Zachmann <zachmann@kde.org>
00004  * Copyright (C) 2007 Thomas Zander <zander@kde.org>
00005  * Copyright (C) 2007 Boudewijn Rempt <boud@valdyas.org>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Library General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Library General Public License
00018  * along with this library; see the file COPYING.LIB.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #include "KoPathToolSelection.h"
00024 #include "KoPathTool.h"
00025 #include <KoParameterShape.h>
00026 #include <KoPathPoint.h>
00027 #include <KoPathPointData.h>
00028 #include <KoViewConverter.h>
00029 #include <KoCanvasBase.h>
00030 #include <KoCanvasResourceProvider.h>
00031 #include <QtGui/QPainter>
00032 
00033 KoPathToolSelection::KoPathToolSelection(KoPathTool * tool)
00034         : m_tool(tool)
00035 {
00036 }
00037 
00038 KoPathToolSelection::~KoPathToolSelection()
00039 {
00040 }
00041 
00042 void KoPathToolSelection::paint(QPainter &painter, const KoViewConverter &converter)
00043 {
00044     int handleRadius = m_tool->canvas()->resourceProvider()->handleRadius();
00045 
00046     PathShapePointMap::iterator it(m_shapePointMap.begin());
00047     for (; it != m_shapePointMap.end(); ++it) {
00048         painter.save();
00049 
00050         painter.setMatrix(it.key()->absoluteTransformation(&converter) * painter.matrix());
00051         KoShape::applyConversion(painter, converter);
00052 
00053         foreach(KoPathPoint *p, it.value())
00054             p->paint(painter, handleRadius, KoPathPoint::All);
00055 
00056         painter.restore();
00057     }
00058 }
00059 
00060 void KoPathToolSelection::add(KoPathPoint * point, bool clear)
00061 {
00062     if( ! point )
00063         return;
00064 
00065     bool allreadyIn = false;
00066     if (clear) {
00067         if (size() == 1 && m_selectedPoints.contains(point)) {
00068             allreadyIn = true;
00069         } else {
00070             this->clear();
00071         }
00072     } else {
00073         allreadyIn = m_selectedPoints.contains(point);
00074     }
00075 
00076     if (!allreadyIn) {
00077         m_selectedPoints.insert(point);
00078         KoPathShape * pathShape = point->parent();
00079         PathShapePointMap::iterator it(m_shapePointMap.find(pathShape));
00080         if (it == m_shapePointMap.end()) {
00081             it = m_shapePointMap.insert(pathShape, QSet<KoPathPoint *>());
00082         }
00083         it.value().insert(point);
00084         m_tool->repaint(point->boundingRect());
00085         emit selectionChanged();
00086     }
00087 }
00088 
00089 void KoPathToolSelection::remove(KoPathPoint * point)
00090 {
00091     if (m_selectedPoints.remove(point)) {
00092         KoPathShape * pathShape = point->parent();
00093         m_shapePointMap[pathShape].remove(point);
00094         if (m_shapePointMap[pathShape].size() == 0) {
00095             m_shapePointMap.remove(pathShape);
00096         }
00097         emit selectionChanged();
00098     }
00099     m_tool->repaint(point->boundingRect());
00100 }
00101 
00102 void KoPathToolSelection::clear()
00103 {
00104     repaint();
00105     m_selectedPoints.clear();
00106     m_shapePointMap.clear();
00107     emit selectionChanged();
00108 }
00109 
00110 void KoPathToolSelection::selectPoints(const QRectF &rect, bool clearSelection)
00111 {
00112     if (clearSelection) {
00113         clear();
00114     }
00115 
00116     blockSignals(true);
00117     foreach(KoPathShape* shape, m_selectedShapes) {
00118         KoParameterShape *parameterShape = dynamic_cast<KoParameterShape*>(shape);
00119         if (parameterShape && parameterShape->isParametricShape())
00120             continue;
00121         foreach(KoPathPoint* point, shape->pointsAt(shape->documentToShape(rect)))
00122             add(point, false);
00123     }
00124     blockSignals(false);
00125     emit selectionChanged();
00126 }
00127 
00128 int KoPathToolSelection::objectCount() const
00129 {
00130     return m_shapePointMap.size();
00131 }
00132 
00133 int KoPathToolSelection::size() const
00134 {
00135     return m_selectedPoints.size();
00136 }
00137 
00138 bool KoPathToolSelection::contains(KoPathPoint * point)
00139 {
00140     return m_selectedPoints.contains(point);
00141 }
00142 
00143 const QSet<KoPathPoint *> & KoPathToolSelection::selectedPoints() const
00144 {
00145     return m_selectedPoints;
00146 }
00147 
00148 QList<KoPathPointData> KoPathToolSelection::selectedPointsData() const
00149 {
00150     QList<KoPathPointData> pointData;
00151     foreach(KoPathPoint* p, m_selectedPoints) {
00152         KoPathShape * pathShape = p->parent();
00153         pointData.append(KoPathPointData(pathShape, pathShape->pathPointIndex(p)));
00154     }
00155     return pointData;
00156 }
00157 
00158 QList<KoPathPointData> KoPathToolSelection::selectedSegmentsData() const
00159 {
00160     QList<KoPathPointData> pointData;
00161 
00162     QList<KoPathPointData> pd(selectedPointsData());
00163     qSort(pd);
00164 
00165     KoPathPointData last(0, KoPathPointIndex(-1, -1));
00166     KoPathPointData lastSubpathStart(0, KoPathPointIndex(-1, -1));
00167 
00168     QList<KoPathPointData>::const_iterator it(pd.constBegin());
00169     for (; it != pd.constEnd(); ++it) {
00170         if (it->pointIndex.second == 0)
00171             lastSubpathStart = *it;
00172 
00173         if (last.pathShape == it->pathShape
00174                 && last.pointIndex.first == it->pointIndex.first
00175                 && last.pointIndex.second + 1 == it->pointIndex.second) {
00176             pointData.append(last);
00177         }
00178 
00179         if (lastSubpathStart.pathShape == it->pathShape
00180                 && it->pathShape->pointByIndex(it->pointIndex)->properties() & KoPathPoint::CloseSubpath
00181                 && (it->pathShape->pointByIndex(it->pointIndex)->properties() & KoPathPoint::StartSubpath) == 0) {
00182             pointData.append(*it);
00183         }
00184 
00185         last = *it;
00186     }
00187 
00188     return pointData;
00189 }
00190 
00191 QList<KoPathShape*> KoPathToolSelection::selectedShapes() const
00192 {
00193     return m_selectedShapes;
00194 }
00195 
00196 void KoPathToolSelection::setSelectedShapes(const QList<KoPathShape*> shapes)
00197 {
00198     m_selectedShapes = shapes;
00199 }
00200 
00201 void KoPathToolSelection::repaint()
00202 {
00203     update();
00204     foreach(KoPathPoint *p, m_selectedPoints) {
00205         m_tool->repaint(p->boundingRect(false));
00206     }
00207 }
00208 
00209 void KoPathToolSelection::update()
00210 {
00211     bool selectionHasChanged = false;
00212 
00213     PathShapePointMap::iterator it(m_shapePointMap.begin());
00214     while (it != m_shapePointMap.end()) {
00215         KoParameterShape *parameterShape = dynamic_cast<KoParameterShape*>(it.key());
00216         bool isParametricShape = parameterShape && parameterShape->isParametricShape();
00217         if (! m_selectedShapes.contains(it.key()) || isParametricShape) {
00218             QSet<KoPathPoint *>::iterator pointIt(it.value().begin());
00219             for (; pointIt != it.value().end(); ++pointIt) {
00220                 m_selectedPoints.remove( *pointIt );
00221             }
00222             it = m_shapePointMap.erase(it);
00223             selectionHasChanged = true;
00224         } else {
00225             QSet<KoPathPoint *>::iterator pointIt(it.value().begin());
00226             while (pointIt != it.value().end()) {
00227                 if ((*pointIt)->parent()->pathPointIndex(*pointIt) == KoPathPointIndex(-1, -1)) {
00228                     m_selectedPoints.remove(*pointIt);
00229                     pointIt = it.value().erase(pointIt);
00230                     selectionHasChanged = true;
00231                 } else {
00232                     ++pointIt;
00233                 }
00234             }
00235             ++it;
00236         }
00237     }
00238 
00239     if (selectionHasChanged)
00240         emit selectionChanged();
00241 }
00242 
00243 bool KoPathToolSelection::hasSelection()
00244 {
00245     return !m_selectedPoints.isEmpty();
00246 }
00247 
00248 #include "KoPathToolSelection.moc"