00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KoSelection.h"
00023 #include "KoShapeContainer.h"
00024 #include "KoShapeGroup.h"
00025 #include "KoPointerEvent.h"
00026
00027 #include <QPainter>
00028 #include <QTimer>
00029
00030 KoSelection::KoSelection()
00031 {
00032 m_eventTriggered = false;
00033 }
00034
00035 KoSelection::~KoSelection()
00036 {
00037 }
00038
00039 void KoSelection::paint( QPainter &painter, const KoViewConverter &converter)
00040 {
00041
00042
00043
00044
00045
00046
00047
00048
00049 }
00050
00051 void KoSelection::selectGroupChilds( KoShapeGroup *group )
00052 {
00053 if( ! group )
00054 return;
00055
00056 foreach(KoShape *shape, group->iterator()) {
00057 if( m_selectedObjects.contains(shape))
00058 continue;
00059 m_selectedObjects << shape;
00060
00061 KoShapeGroup* childGroup = dynamic_cast<KoShapeGroup*>( shape );
00062 if( childGroup )
00063 selectGroupChilds( childGroup );
00064 }
00065 }
00066
00067 void KoSelection::select(KoShape * object)
00068 {
00069 Q_ASSERT(object != this);
00070 Q_ASSERT(object);
00071 if(! object->isSelectable())
00072 return;
00073 if(!m_selectedObjects.contains(object))
00074 m_selectedObjects << object;
00075
00076 KoShapeGroup* group = dynamic_cast<KoShapeGroup*>(object);
00077 if( group )
00078 selectGroupChilds( group );
00079
00080 KoShapeContainer *parent = object->parent();
00081 while( parent ) {
00082 KoShapeGroup *parentGroup = dynamic_cast<KoShapeGroup*>(parent);
00083 if( ! parentGroup ) break;
00084 if( ! m_selectedObjects.contains(parentGroup) ) {
00085 m_selectedObjects << parentGroup;
00086 selectGroupChilds( parentGroup );
00087 }
00088 parent = parentGroup->parent();
00089 }
00090
00091 if(m_selectedObjects.count() == 1)
00092 {
00093 rotate(object->rotation());
00094 shear(object->shearX(), object->shearY());
00095 }
00096 else
00097 {
00098 rotate(0);
00099 shear(0, 0);
00100 }
00101 requestSelectionChangedEvent();
00102 }
00103
00104 void KoSelection::deselect(KoShape * object)
00105 {
00106 if(! m_selectedObjects.contains(object))
00107 return;
00108 KoShapeGroup *group = dynamic_cast<KoShapeGroup*>(object->parent());
00109 if(group) {
00110 m_selectedObjects.remove(group);
00111 foreach(KoShape *shape, group->iterator())
00112 m_selectedObjects.remove(shape);
00113 }
00114 else
00115 m_selectedObjects.remove( object );
00116
00117 if(m_selectedObjects.count() == 1)
00118 {
00119 rotate(firstSelectedShape()->rotation());
00120 shear(firstSelectedShape()->shearX(), firstSelectedShape()->shearY());
00121 }
00122 requestSelectionChangedEvent();
00123 }
00124
00125 void KoSelection::deselectAll()
00126 {
00127 if(m_selectedObjects.count() == 0)
00128 return;
00129 m_selectedObjects.clear();
00130 requestSelectionChangedEvent();
00131 }
00132
00133 void KoSelection::requestSelectionChangedEvent() {
00134 if(m_eventTriggered)
00135 return;
00136 m_eventTriggered = true;
00137 QTimer::singleShot(0, this, SLOT(selectionChangedEvent()));
00138 }
00139
00140 void KoSelection::selectionChangedEvent() {
00141 m_eventTriggered = false;
00142 scale(1,1);
00143 boundingRect();
00144 emit selectionChanged();
00145 }
00146
00147 int KoSelection::count() const
00148 {
00149 return m_selectedObjects.count();
00150 }
00151
00152 bool KoSelection::hitTest( const QPointF &position ) const
00153 {
00154 if ( count() > 1 )
00155 {
00156 QRectF bb( boundingRect() );
00157 return bb.contains( position );
00158 }
00159 else if ( count() == 1 )
00160 return ( *m_selectedObjects.begin() )->hitTest( position );
00161 else
00162 return false;
00163 }
00164
00165 QRectF KoSelection::boundingRect() const
00166 {
00167 bool first=true;
00168 QRectF bb;
00169
00170 QMatrix tmat = transformationMatrix(0);
00171 QMatrix itmat = tmat.inverted();
00172
00173 if ( count() > 0 )
00174 {
00175 KoSelectionSet::const_iterator it = m_selectedObjects.begin();
00176 for ( ; it != m_selectedObjects.end(); ++it ) {
00177 if( dynamic_cast<KoShapeGroup*>( *it ))
00178 continue;
00179 if(first) {
00180 bb = ((*it)->transformationMatrix(0) * itmat).mapRect(QRectF(QPointF(),(*it)->size()));
00181 first = false;
00182 }
00183 else
00184 bb = bb.unite(
00185 ((*it)->transformationMatrix(0) * itmat).mapRect(QRectF(QPointF(),(*it)->size())) );
00186 }
00187 }
00188
00189
00190 (const_cast <KoSelection *>(this))->resize( bb.size() );
00191 QPointF p = tmat.map(bb.topLeft() + itmat.map(position()));
00192 (const_cast <KoSelection *>(this))->setPosition( p );
00193
00194 return tmat.mapRect(bb);
00195 }
00196
00197 const KoSelectionSet KoSelection::selectedShapes(KoFlake::SelectionType strip) const {
00198 KoSelectionSet answer;
00199
00200 bool doStripping = strip == KoFlake::StrippedSelection;
00201 foreach (KoShape *shape, m_selectedObjects) {
00202 KoShapeContainer *container = shape->parent();
00203 if(strip != KoFlake::TopLevelSelection && dynamic_cast<KoShapeGroup*>(shape))
00204
00205
00206
00207 continue;
00208 bool add = true;
00209 while(doStripping && add && container) {
00210 if(dynamic_cast<KoShapeGroup*>(container) == 0 && m_selectedObjects.contains(container))
00211 add = false;
00212 container = container->parent();
00213 }
00214 if(strip == KoFlake::TopLevelSelection && container && m_selectedObjects.contains(container))
00215 add = false;
00216 if(add)
00217 answer << shape;
00218 }
00219 return answer;
00220 }
00221
00222 bool KoSelection::isSelected(const KoShape *object) const {
00223 if(object == this)
00224 return true;
00225
00226 QSetIterator<KoShape*> iter (m_selectedObjects);
00227 while(iter.hasNext()) {
00228 if(iter.next() == object)
00229 return true;
00230 }
00231
00232 return false;
00233 }
00234
00235 KoShape *KoSelection::firstSelectedShape(KoFlake::SelectionType strip) const {
00236 KoSelectionSet set = selectedShapes(strip);
00237 if(set.isEmpty())
00238 return 0;
00239 return *(set.begin());
00240 }
00241
00242 #include "KoSelection.moc"