23#include "vcomposite.h"
26#include "vselection.h"
29#include "vtransformcmd.h"
36VTransformCmd::VTransformCmd(
VDocument *doc,
const TQWMatrix& mat,
bool duplicate )
37 :
VCommand( doc, i18n(
"Transform Objects" ) ), m_mat( mat ), m_duplicate( duplicate )
39 m_selection = ( document() && document()->selection() )
40 ? document()->selection()->clone()
45 if( !m_selection || m_selection->objects().count() == 1 )
46 setName( i18n(
"Duplicate Object" ) );
48 setName( i18n(
"Duplicate Objects" ) );
50 else if( !m_selection || m_selection->objects().count() == 1 )
51 setName( i18n(
"Transform Object" ) );
54VTransformCmd::VTransformCmd(
VDocument *doc,
const TQString& name,
const TQString& icon,
bool duplicate )
55 :
VCommand( doc, name, icon ), m_duplicate( duplicate )
57 m_selection = ( document() && document()->selection() )
58 ? document()->selection()->clone()
63 if( !m_selection || m_selection->objects().count() == 1 )
64 setName( i18n(
"Duplicate Object" ) );
66 setName( i18n(
"Duplicate Objects" ) );
70VTransformCmd::~VTransformCmd()
72 delete( m_selection );
79 VObjectListIterator itr( m_selection->objects() );
85 for( ; itr.current() ; ++itr )
87 copy = itr.current()->
clone();
92 m_duplicates.append( copy );
100 for( ; itr.current() ; ++itr )
102 visit( *itr.current() );
115 m_mat = m_mat.invert();
120 VObjectListIterator itr( m_duplicates );
121 for( ; itr.current() ; ++itr )
126 VObjectListIterator jtr( m_selection->objects() );
129 for( ; jtr.current() ; ++jtr )
138 visit( *m_selection );
142 m_mat = m_mat.invert();
147VTransformCmd::visitVObject(
VObject&
object )
150 VStroke* stroke =
object.stroke();
152 stroke->gradient().transform( m_mat );
154 stroke->pattern().transform( m_mat );
156 VFill* fill =
object.fill();
158 fill->gradient().transform( m_mat );
160 fill->pattern().transform( m_mat );
164VTransformCmd::visitVPath(
VPath& composite )
171 visitVObject( composite );
173 composite.transform( m_mat );
179VTransformCmd::visitVSubpath(
VSubpath& path )
186 VSegment* segment = path.first();
190 for(
unsigned short i = 0; i < segment->
degree(); ++i )
192 segment->
setPoint( i, segment->
point( i ).transform( m_mat ) );
195 segment = segment->
next();
202VTransformCmd::visitVText( VText& text )
209 visitVObject( text );
211 visit( text.basePath() );
213 VPathListIterator itr( text.glyphs() );
215 for( ; itr.current() ; ++itr )
217 visit( *itr.current() );
224VTransformCmd::visitVImage( VImage &img )
231 img.transform( m_mat );
234VTranslateCmd::VTranslateCmd(
VDocument *doc,
double d1,
double d2,
bool duplicate )
235 : VTransformCmd( doc, i18n(
"Translate Objects" ),
"translate", duplicate )
237 if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) )
238 setName( i18n(
"Translate Object" ) );
240 m_mat.translate( d1, d2 );
244VScaleCmd::VScaleCmd(
VDocument *doc,
const KoPoint& p,
double s1,
double s2,
bool duplicate )
245 : VTransformCmd( doc, i18n(
"Scale Objects" ),
"14_select", duplicate )
247 if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) )
248 setName( i18n(
"Scale Object" ) );
250 m_mat.translate( p.x(), p.y() );
251 m_mat.scale( s1, s2 );
252 m_mat.translate( -p.x(), -p.y() );
256VShearCmd::VShearCmd(
VDocument *doc,
const KoPoint& p,
double s1,
double s2,
bool duplicate )
257 : VTransformCmd( doc, i18n(
"Shear Objects" ),
"14_shear", duplicate )
259 if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) )
260 setName( i18n(
"Shear Object" ) );
262 m_mat.translate( p.x(), p.y() );
263 m_mat.shear( s1, s2 );
264 m_mat.translate( -p.x(), -p.y() );
267VRotateCmd::VRotateCmd(
VDocument *doc,
const KoPoint& p,
double angle,
bool duplicate )
268 : VTransformCmd( doc, i18n(
"Rotate Objects" ),
"14_rotate", duplicate )
270 if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) )
271 setName( i18n(
"Rotate Object" ) );
273 m_mat.translate( p.x(), p.y() );
274 m_mat.rotate( angle );
275 m_mat.translate( -p.x(), -p.y() );
278VTranslateBezierCmd::VTranslateBezierCmd(
VDocument *doc,
VSegment *segment,
double d1,
double d2,
bool firstControl )
279 :
VCommand( doc, i18n(
"Translate Bezier" ) ), m_segment( segment ), m_firstControl( firstControl )
282 m_mat.translate( d1, d2 );
285 if( document() && document()->selection() )
287 VObjectListIterator itr( document()->selection()->objects() );
290 for( ; itr.current() ; ++itr )
291 visit( *itr.current() );
295VTranslateBezierCmd::~VTranslateBezierCmd()
302 if( m_segment->degree() == 3 )
304 TQWMatrix m2( m_mat.m11(), m_mat.m12(), m_mat.m21(), m_mat.m22(), -m_mat.dx(), -m_mat.dy() );
307 if( m_segment->prev() &&
308 m_segment->prev()->degree() == 3 &&
309 m_segment->prev()->isSmooth() )
311 m_segmenttwo = m_segment->prev();
312 for( uint i = 0;i < m_segmenttwo->degree();i++ )
314 m_segmenttwo->selectPoint( i, i == 1 );
317 m_segmenttwo->setPoint( i, m_segmenttwo->point( i ).transform( m2 ) );
323 m_segmenttwo = ( m_segment->isSmooth() && m_segment->next()->degree() == 3 ) ? m_segment->next() : 0L;
326 for( uint i = 0;i < m_segmenttwo->degree();i++ )
328 m_segmenttwo->selectPoint( i, i == 0 );
331 m_segmenttwo->setPoint( i, m_segmenttwo->point( i ).transform( m2 ) );
336 for( uint i = 0;i < m_segment->degree();i++ )
338 m_segment->selectPoint( i, i == uint( m_firstControl ? 0 : 1 ) );
340 if( i == uint( m_firstControl ? 0 : 1 ) )
341 m_segment->setPoint( i, m_segment->point( i ).transform( m_mat ) );
346 m_subpath->invalidateBoundingBox();
354 TQWMatrix m2( m_mat.m11(), m_mat.m12(), m_mat.m21(), m_mat.m22(), -m_mat.dx(), -m_mat.dy() );
357 for( uint i = 0;i < m_segment->degree();i++ )
359 m_segment->selectPoint( i, i == uint( m_firstControl ? 0 : 1 ) );
361 if( i == uint( m_firstControl ? 0 : 1 ) )
362 m_segment->setPoint( i, m_segment->point( i ).transform( m_mat.invert() ) );
367 uint index = m_firstControl ? 1 : 0;
368 for( uint i = 0;i < m_segmenttwo->degree();i++ )
370 m_segmenttwo->selectPoint( i, i == index );
373 m_segmenttwo->setPoint( i, m_segmenttwo->point( i ).transform( m2.invert() ) );
381VTranslateBezierCmd::visitVSubpath(
VSubpath& path )
386 VSegment* segment = path.first();
391 if( segment == m_segment )
396 segment = segment->
next();
400VTranslatePointCmd::VTranslatePointCmd(
VDocument *doc,
double d1,
double d2 )
401 :
VCommand( doc, i18n(
"Translate Points" ),
"translate" )
403 m_mat.translate( d1, d2 );
405 if( document() && document()->selection() )
407 VObjectListIterator itr( document()->selection()->objects() );
410 for( ; itr.current() ; ++itr )
411 visit( *itr.current() );
413 if( m_segPnts.size() > 1 || ( m_segPnts.size() == 0 && m_segPnts.begin().data().size() > 1 ) )
414 setName( i18n(
"Translate Point" ) );
418VTranslatePointCmd::~VTranslatePointCmd()
432 m_mat = m_mat.invert();
434 m_mat = m_mat.invert();
439VTranslatePointCmd::visitVSubpath(
VSubpath& path )
446 VSegment* segment = path.first();
448 uint segCnt = m_segPnts.size();
453 TQValueVector<int> pnts;
455 for(
unsigned short i = 0; i < segment->
degree(); ++i )
461 m_segPnts[segment] = pnts;
463 segment = segment->
next();
467 if( segCnt != m_segPnts.size() )
468 m_subpaths.append( &path );
472VTranslatePointCmd::translatePoints()
474 TQMap<VSegment*, TQValueVector<int> >::iterator it, et = m_segPnts.end();
477 for( it = m_segPnts.begin(); it != et; ++it )
479 VSegment *segment = it.key();
480 TQValueVector<int> &pnts = it.data();
482 int pntCnt = pnts.size();
483 for(
int i = 0; i < pntCnt; ++i )
484 segment->
setPoint( pnts[i], segment->
point( pnts[i] ).transform( m_mat ) );
488 VObjectListIterator itr( m_subpaths );
489 for( ; itr.current(); ++itr )
490 itr.current()->invalidateBoundingBox();
The base class for all karbon commands.
virtual void unexecute()
Unexecutes the command.
VDocument * document() const
Returns the document the command works on.
virtual void execute()=0
Executes the command.
All non-visual, static doc info is in here.
VSelection * selection() const
Returns a pointer to the selection.
void append(VObject *object)
Appends a new object to the active layer.
The base class for all karbon objects.
virtual VObject * clone() const =0
Create an exact copy of this object.
@ normal_locked
visible, but locked (r/o)
@ hidden_locked
hidden and locked (r/o)
@ deleted
deleted, nearly dead
void invalidateBoundingBox()
Invalidates the bounding box, so it has to be recalculated.
VState state() const
Get the state the object is in.
A composite path consists of one or many subpaths.
A class representing lines and beziers.
bool pointIsSelected(int i) const
Returns true if the point with index 0 <= i < degree() is selected.
VSegment * next() const
Returns a pointer to the next not deleted segment, if stored in a VSubpath.
void setPoint(int i, const KoPoint &p)
Sets the segment's point with index 0 <= i < degree() to "p".
unsigned short degree() const
Returns the segment's degree, which is identical to the number of nodes.
const KoPoint & point(int i) const
Returns the segment's point with index 0 <= i < degree().
VSelection manages a set of selected vobjects.
void append()
Adds all objects to the selection.
void clear()
Removes the references to all objects, not the objects themselves.
void take(VObject &object)
Removes the reference to the object, not the object itself.
VSubpath provides a sophisticated list of VSegment.
virtual bool visit(VObject &object)
General visit method.
virtual void visitVPath(VPath &composite)
Visit method for a VPath.
void setSuccess(bool success=true)
Set the success property.