diff options
Diffstat (limited to 'karbon/commands')
43 files changed, 4409 insertions, 0 deletions
diff --git a/karbon/commands/Makefile.am b/karbon/commands/Makefile.am new file mode 100644 index 00000000..fb5ac24a --- /dev/null +++ b/karbon/commands/Makefile.am @@ -0,0 +1,55 @@ +INCLUDES = $(KOFFICE_INCLUDES) $(KOFFICECORE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../core \ + -I$(srcdir)/../visitors \ + $(all_includes) + +noinst_LTLIBRARIES = libkarboncommands.la + +noinst_HEADERS = \ + valigncmd.h \ + vbooleancmd.h \ + vcleanupcmd.h \ + vclipartcmd.h \ + vclosepathcmd.h \ + vcommand.h \ + vdeletecmd.h \ + vdistributecmd.h \ + vfillcmd.h \ + vflattencmd.h \ + vgroupcmd.h \ + vdeletenodescmd.h \ + vlayercmd.h \ + vreplacingcmd.h \ + vshapecmd.h \ + vstrokecmd.h \ + vtransformcmd.h \ + vinsertcmd.h \ + vungroupcmd.h \ + vzordercmd.h + +libkarboncommands_la_SOURCES = \ + valigncmd.cc \ + vbooleancmd.cc \ + vcleanupcmd.cc \ + vclipartcmd.cc \ + vclosepathcmd.cc \ + vcommand.cc \ + vdeletecmd.cc \ + vdistributecmd.cc \ + vfillcmd.cc \ + vflattencmd.cc \ + vgroupcmd.cc \ + vdeletenodescmd.cc \ + vlayercmd.cc \ + vreplacingcmd.cc \ + vshapecmd.cc \ + vstrokecmd.cc \ + vtransformcmd.cc \ + vinsertcmd.cc \ + vungroupcmd.cc \ + vzordercmd.cc + +libkarboncommands_la_METASOURCES = \ + AUTO + diff --git a/karbon/commands/valigncmd.cc b/karbon/commands/valigncmd.cc new file mode 100644 index 00000000..9e6392a1 --- /dev/null +++ b/karbon/commands/valigncmd.cc @@ -0,0 +1,87 @@ +/* This file is doc of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <klocale.h> + +#include "valigncmd.h" +#include "vtransformcmd.h" +#include "vdocument.h" +#include "vselection.h" + +#include <kdebug.h> + +VAlignCmd::VAlignCmd( VDocument *doc, Align align ) + : VCommand( doc, i18n( "Align Objects" ) ), m_align( align ) +{ + m_trafoCmds.setAutoDelete( true ); +} + +VAlignCmd::~VAlignCmd() +{ +} + +void +VAlignCmd::execute() +{ + if( document()->selection()->objects().count() == 0 ) + return; + double dx, dy; + KoRect bbox; + KoRect r; + if( document()->selection()->objects().count() == 1 ) + r = document()->boundingBox(); + else + r = document()->selection()->boundingBox(); + VObjectList objs = document()->selection()->objects(); + VObjectListIterator itr( objs ); + VTranslateCmd *trafoCmd = 0L; + for( ; itr.current() ; ++itr ) + { + document()->selection()->clear(); + bbox = itr.current()->boundingBox(); + switch( m_align ) + { + case ALIGN_HORIZONTAL_LEFT : dx = r.topLeft().x() - bbox.topLeft().x(); dy = 0; break; + case ALIGN_HORIZONTAL_CENTER: dx = r.center().x() - bbox.center().x(); dy = 0; break; + case ALIGN_HORIZONTAL_RIGHT : dx = r.topRight().x() - bbox.topRight().x(); dy = 0; break; + case ALIGN_VERTICAL_TOP : dx = 0; dy = r.bottomRight().y() - bbox.bottomRight().y(); break; + case ALIGN_VERTICAL_CENTER : dx = 0; dy = r.center().y() - bbox.center().y(); break; + case ALIGN_VERTICAL_BOTTOM : dx = 0; dy = r.topLeft().y() - bbox.topLeft().y(); break; + }; + document()->selection()->append( itr.current() ); + trafoCmd = new VTranslateCmd( document(), dx, dy ); + m_trafoCmds.append( trafoCmd ); + trafoCmd->execute(); + } + itr.toFirst(); + for( ; itr.current() ; ++itr ) + document()->selection()->append( itr.current() ); + setSuccess( true ); +} + +void +VAlignCmd::unexecute() +{ + QPtrListIterator<VTranslateCmd> itr( m_trafoCmds ); + for( ; itr.current() ; ++itr ) + itr.current()->unexecute(); + setSuccess( false ); +} + diff --git a/karbon/commands/valigncmd.h b/karbon/commands/valigncmd.h new file mode 100644 index 00000000..9fd8bf09 --- /dev/null +++ b/karbon/commands/valigncmd.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project � + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VALIGNCMD_H__ +#define __VALIGNCMD_H__ + +#include "vcommand.h" + +class VTranslateCmd; + +// Align objects... + +class VAlignCmd : public VCommand +{ +public: + enum Align + { + ALIGN_HORIZONTAL_LEFT, + ALIGN_HORIZONTAL_CENTER, + ALIGN_HORIZONTAL_RIGHT, + ALIGN_VERTICAL_BOTTOM, + ALIGN_VERTICAL_CENTER, + ALIGN_VERTICAL_TOP + }; + VAlignCmd( VDocument *doc, Align align ); + virtual ~VAlignCmd(); + + virtual void execute(); + virtual void unexecute(); + +protected: + Align m_align; + QPtrList<VTranslateCmd> m_trafoCmds; +}; + +#endif + diff --git a/karbon/commands/vbooleancmd.cc b/karbon/commands/vbooleancmd.cc new file mode 100644 index 00000000..a97fefe9 --- /dev/null +++ b/karbon/commands/vbooleancmd.cc @@ -0,0 +1,240 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <qptrlist.h> +#include <qvaluelist.h> + +#include <klocale.h> + +#include "vbooleancmd.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vdocument.h" + +VBooleanCmd::VBooleanCmd( VDocument *doc, VBooleanType type ) + : VCommand( doc, i18n( "Boolean Operation" ) ) +{ + m_selection = document()->selection()->clone(); + m_type = type; +} + +VBooleanCmd::~VBooleanCmd() +{ + delete( m_selection ); +} + +void +VBooleanCmd::execute() +{ + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { +// TODO: pair wise visiting. + } + +// document()->append( ); + document()->selection()->clear(); +} + +void +VBooleanCmd::unexecute() +{ +} + +bool +VBooleanCmd::visit( VObject& object1, VObject& object2 ) +{ + m_path1 = 0L; + m_path2 = 0L; + object1.accept( *this ); + object2.accept( *this ); + + return success(); +} + +void +VBooleanCmd::visitVSubpath( VSubpath& path ) +{ + if( m_path1 == 0L ) + m_path1 = &path; + else if( m_path2 == 0L ) + { + m_path2 = &path; + + // intersection parameters (t): + VParamList params1; + VParamList params2; + VParamList::iterator pItr; + + double prevParam; + + m_path1->first(); + + // ommit "begin" segment: + while( m_path1->next() ) + { + params1.clear(); + + m_path2->first(); + + // ommit "begin" segment: + while( m_path2->next() ) + { + params2.clear(); + + recursiveSubdivision( + *m_path1->current(), 0.0, 1.0, + *m_path2->current(), 0.0, 1.0, + params1, params2 ); + + qHeapSort( params2 ); + + prevParam = 0.0; + + // walk down all intersection params and insert knots: + for( pItr = params2.begin(); pItr != params2.end(); ++pItr ) + { + m_path2->insert( + m_path2->current()->splitAt( + ( *pItr - prevParam )/( 1.0 - prevParam ) ) ); + + m_path2->next(); + prevParam = *pItr; + } + } + + qHeapSort( params1 ); + + prevParam = 0.0; + + // walk down all intersection params and insert knots: + for( pItr = params1.begin(); pItr != params1.end(); ++pItr ) + { + m_path1->insert( + m_path1->current()->splitAt( + ( *pItr - prevParam )/( 1.0 - prevParam ) ) ); + + m_path1->next(); + prevParam = *pItr; + } + } + } +} + +void +VBooleanCmd::recursiveSubdivision( + const VSegment& segment1, double t0_1, double t1_1, + const VSegment& segment2, double t0_2, double t1_2, + VParamList& params1, VParamList& params2 ) +{ + if( + !segment1.boundingBox().intersects( + segment2.boundingBox() ) ) + { + return; + } + + if( segment1.isFlat() ) + { + // calculate intersection of line segments: + if( segment2.isFlat() ) + { + KoPoint v1 = segment1.knot() - segment1.prev()->knot(); + KoPoint v2 = segment2.knot() - segment2.prev()->knot(); + + double det = v2.x() * v1.y() - v2.y() * v1.x(); + + if( 1.0 + det == 1.0 ) + return; + else + { + KoPoint v = segment2.prev()->knot() - segment1.prev()->knot(); + const double one_det = 1.0 / det; + + double t1 = one_det * ( v2.x() * v.y() - v2.y() * v.x() ); + double t2 = one_det * ( v1.x() * v.y() - v1.y() * v.x() ); + + if ( t1 < 0.0 || t1 > 1.0 || t2 < 0.0 || t2 > 1.0 ) + return; + + params1.append( t0_1 + t1 * ( t1_1 - t0_1 ) ); + params2.append( t0_2 + t2 * ( t1_2 - t0_2 ) ); + } + } + else + { + // "copy segment" and split it at midpoint: + VSubpath path2( segment2 ); + path2.insert( path2.current()->splitAt( 0.5 ) ); + + double mid2 = 0.5 * ( t0_2 + t1_2 ); + + recursiveSubdivision( + *path2.current(), t0_2, mid2, + segment1, t0_1, t1_1, params2, params1 ); + recursiveSubdivision( + *path2.next(), mid2, t1_2, + segment1, t0_1, t1_1, params2, params1 ); + } + } + else + { + // "copy segment" and split it at midpoint: + VSubpath path1( segment1 ); + path1.insert( path1.current()->splitAt( 0.5 ) ); + + double mid1 = 0.5 * ( t0_1 + t1_1 ); + + if( segment2.isFlat() ) + { + recursiveSubdivision( + *path1.current(), t0_1, mid1, + segment2, t0_2, t1_2, params1, params2 ); + recursiveSubdivision( + *path1.next(), mid1, t1_1, + segment2, t0_2, t1_2, params1, params2 ); + } + else + { + // "copy segment" and split it at midpoint: + VSubpath path2( segment2 ); + path2.insert( path2.current()->splitAt( 0.5 ) ); + + double mid2 = 0.5 * ( t0_2 + t1_2 ); + + recursiveSubdivision( + *path1.current(), t0_1, mid1, + *path2.current(), t0_2, mid2, params1, params2 ); + recursiveSubdivision( + *path1.next(), mid1, t1_1, + *path2.current(), t0_2, mid2, params1, params2 ); + + recursiveSubdivision( + *path1.prev(), t0_1, mid1, + *path2.next(), mid2, t1_2, params1, params2 ); + recursiveSubdivision( + *path1.next(), mid1, t1_1, + *path2.current(), mid2, t1_2, params1, params2 ); + } + } +} + diff --git a/karbon/commands/vbooleancmd.h b/karbon/commands/vbooleancmd.h new file mode 100644 index 00000000..4320f0d2 --- /dev/null +++ b/karbon/commands/vbooleancmd.h @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VBOOLEANCMD_H__ +#define __VBOOLEANCMD_H__ + + +#include <qvaluelist.h> + +#include "vcommand.h" + +class VSubpath; +class VSegment; +class VSelection; + + +class VBooleanCmd : public VCommand +{ +public: + enum VBooleanType + { + intersect, + shape_union, + shape_xor, + substract + }; + + VBooleanCmd( VDocument* doc, VBooleanType type = intersect ); + virtual ~VBooleanCmd(); + + virtual void execute(); + virtual void unexecute(); + + + // We can only visit object pairs. + virtual bool visit( VObject& /*object*/ ) + { + return false; + } + + // A pair visit() function. + bool visit( VObject& object1, VObject& object2 ); + + + virtual void visitVSubpath( VSubpath& path ); + +protected: + typedef QValueList<double> VParamList; + + void recursiveSubdivision( + const VSegment& segment1, double t0_1, double t1_1, + const VSegment& segment2, double t0_2, double t1_2, + VParamList& params1, VParamList& params2 ); + + + VSelection* m_selection; + + VBooleanType m_type; + + VSubpath* m_path1; + VSubpath* m_path2; +}; + +#endif + diff --git a/karbon/commands/vcleanupcmd.cc b/karbon/commands/vcleanupcmd.cc new file mode 100644 index 00000000..6df53601 --- /dev/null +++ b/karbon/commands/vcleanupcmd.cc @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vcleanupcmd.h" +#include "vlayer.h" +#include "vdocument.h" + +VCleanUpCmd::VCleanUpCmd( VDocument *doc ) + : VCommand( doc, i18n( "Clean Up" ) ) +{ +} + +VCleanUpCmd::~VCleanUpCmd() +{ +} + +void +VCleanUpCmd::execute() +{ + visit( *document() ); +} + +void +VCleanUpCmd::unexecute() +{ +} + +void +VCleanUpCmd::visitVLayer( VLayer& layer ) +{ + VObjectListIterator itr( layer.objects() ); + for( ; itr.current(); ++itr ) + { + if( itr.current()->state() == VObject::deleted ) + { + delete( itr.current() ); + layer.take( *itr.current() ); + } + } +} diff --git a/karbon/commands/vcleanupcmd.h b/karbon/commands/vcleanupcmd.h new file mode 100644 index 00000000..9acce3d3 --- /dev/null +++ b/karbon/commands/vcleanupcmd.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VCLEANUPCMD_H__ +#define __VCLEANUPCMD_H__ + +#include "vcommand.h" + +class VLayer; + +/* + * This visitor visits all layers and destroys all objects + * that are in a deleted state. Note that this operation + * is permanent! + */ +class VCleanUpCmd : public VCommand +{ +public: + VCleanUpCmd( VDocument *doc ); + virtual ~VCleanUpCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual void visitVLayer( VLayer& layer ); +}; + +#endif + diff --git a/karbon/commands/vclipartcmd.cc b/karbon/commands/vclipartcmd.cc new file mode 100644 index 00000000..42ce3a1d --- /dev/null +++ b/karbon/commands/vclipartcmd.cc @@ -0,0 +1,65 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include "vclipartcmd.h" +#include "vdocument.h" +#include "vselection.h" + +VClipartCmd::VClipartCmd( VDocument* doc, const QString& name, VObject* clipart ) + : VCommand( doc, name ), m_clipart( clipart->clone() ), m_executed( false ) +{ +} + +void +VClipartCmd::execute() +{ + if( !m_clipart ) + return; + + if( m_clipart->state() == VObject::deleted ) + m_clipart->setState( VObject::normal ); + else + { + m_clipart->setState( VObject::normal ); + document()->append( m_clipart ); + document()->selection()->clear(); + document()->selection()->append( m_clipart ); + } + + m_executed = true; + + setSuccess( true ); +} + +void +VClipartCmd::unexecute() +{ + if( !m_clipart ) + return; + + document()->selection()->take( *m_clipart ); + + m_clipart->setState( VObject::deleted ); + + m_executed = false; + + setSuccess( false ); +} + diff --git a/karbon/commands/vclipartcmd.h b/karbon/commands/vclipartcmd.h new file mode 100644 index 00000000..37e809a2 --- /dev/null +++ b/karbon/commands/vclipartcmd.h @@ -0,0 +1,43 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VCLIPARTCMD_H__ +#define __VCLIPARTCMD_H__ + +#include "vcommand.h" + +class VClipartCmd : public VCommand +{ +public: + VClipartCmd( VDocument* doc, const QString& name, VObject* clipart ); + virtual ~VClipartCmd() {} + + virtual void execute(); + virtual void unexecute(); + virtual bool isExecuted() { return m_executed; } + + virtual bool changesSelection() const { return true; } + +private: + VObject* m_clipart; + bool m_executed; +}; + +#endif + diff --git a/karbon/commands/vclosepathcmd.cc b/karbon/commands/vclosepathcmd.cc new file mode 100644 index 00000000..3afe6195 --- /dev/null +++ b/karbon/commands/vclosepathcmd.cc @@ -0,0 +1,36 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003, 2004 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "vclosepathcmd.h" +#include <klocale.h> + +#include <core/vpath.h> + +VClosePathCmd::VClosePathCmd( VDocument *doc ) + : VReplacingCmd( doc, i18n( "Close Path" ) ) +{ +} + +void +VClosePathCmd::visitVSubpath( VSubpath& path ) +{ + path.close(); + setSuccess(); +} + diff --git a/karbon/commands/vclosepathcmd.h b/karbon/commands/vclosepathcmd.h new file mode 100644 index 00000000..a7e02363 --- /dev/null +++ b/karbon/commands/vclosepathcmd.h @@ -0,0 +1,37 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003, 2004 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __CLOSEPATHCMD_H__ +#define __CLOSEPATHCMD_H__ + +#include <commands/vreplacingcmd.h> + +class VSubpath; + +class VClosePathCmd : public VReplacingCmd +{ +public: + VClosePathCmd( VDocument *doc ); + virtual ~VClosePathCmd() {} + + virtual void visitVSubpath( VSubpath& path ); +}; + +#endif + diff --git a/karbon/commands/vcommand.cc b/karbon/commands/vcommand.cc new file mode 100644 index 00000000..7ba4c4be --- /dev/null +++ b/karbon/commands/vcommand.cc @@ -0,0 +1,384 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include "kaction.h" +#include "klocale.h" + +#include "vcommand.h" +#include "karbon_part.h" + + +VCommandHistory::VCommandHistory( KarbonPart* part ) + : m_part( part ), m_undoLimit( 50 ), m_redoLimit( 30 ), m_savedPos( 0 ) +{ + m_commands.setAutoDelete( true ); + + m_undo = KStdAction::undo( this, SLOT( undo() ), m_part->actionCollection(), "koffice_undo" ); + m_redo = KStdAction::redo( this, SLOT( redo() ), m_part->actionCollection(), "koffice_redo" ); + + clear(); +} + +VCommandHistory::~VCommandHistory() +{ +} + +void +VCommandHistory::clear() +{ + if( m_savedPos != int( m_commands.count() - 1 ) ) + m_savedPos = -1; + else + m_savedPos = 0; + + m_commands.clear(); + + emit historyCleared(); + + if( m_undo != 0 ) + { + m_undo->setEnabled( false ); + m_undo->setText( i18n( "&Undo" ) ); + } + + if( m_redo != 0 ) + { + m_redo->setEnabled( false ); + m_redo->setText( i18n( "&Redo" ) ); + } +} + +void +VCommandHistory::addCommand( VCommand* command, bool execute ) +{ + if( command == 0L ) + return; + + if( !m_commands.isEmpty() ) + { + while( m_commands.last() && !m_commands.last()->success() ) + { + m_commands.removeLast(); + emit lastCommandRemoved(); + } + } + + m_commands.append( command ); + kdDebug(38000) << "History: new command: " << m_commands.findRef( command ) << endl; + + if( execute ) + { + command->execute(); + emit commandExecuted( command ); + } + + updateActions(); + + emit commandAdded( command ); +} + +void +VCommandHistory::setUndoLimit( unsigned int limit ) +{ + m_undoLimit = limit; + clipCommands(); +} + +void +VCommandHistory::setRedoLimit( unsigned int limit ) +{ + m_redoLimit = limit; + clipCommands(); +} + +void +VCommandHistory::undo() +{ + int i = m_commands.count() - 1; + + if( i == -1 ) + return; + + while( ( i >= 0 ) && !( m_commands.at( i )->success() ) ) + { + i--; + } + + if( i < 0 ) + return; + + VCommand* cmd = m_commands.at( i ); + + cmd->unexecute(); + + emit commandExecuted( cmd ); + + emit commandExecuted(); + + clipCommands(); + + updateActions(); + + m_part->repaintAllViews(); +} + +void +VCommandHistory::redo() +{ + int i = m_commands.count() - 1; + + if( i == -1 ) + return; + + while( ( i >= 0 ) && !( m_commands.at( i )->success() ) ) + { + i--; + } + + i++; + + if( i >= int( m_commands.count() ) ) + return; + + VCommand* cmd; + + if( ( cmd = m_commands.at( i ) ) == 0L ) + return; + + cmd->execute(); + + emit commandExecuted( cmd ); + emit commandExecuted(); + + updateActions(); + + m_part->repaintAllViews(); +} + +void +VCommandHistory::undo( VCommand* command ) +{ + if( ( m_commands.findRef( command ) == -1 ) || ( !command->success() ) ) + return; + + command->unexecute(); + + emit commandExecuted( command ); + emit commandExecuted(); + + updateActions(); + + m_part->repaintAllViews(); +} + +void +VCommandHistory::redo( VCommand* command ) +{ + if( ( m_commands.findRef( command ) == -1 ) || ( command->success() ) ) + return; + + command->execute(); + + emit commandExecuted( command ); + emit commandExecuted(); + + updateActions(); + + m_part->repaintAllViews(); +} + +void +VCommandHistory::undoAllTo( VCommand* command ) +{ + int to; + + if( ( to = m_commands.findRef( command ) ) == -1 ) + return; + + int i = m_commands.count() - 1; + + VCommand* cmd; + + while( i > to ) + { + cmd = m_commands.at( i-- ); + + if( cmd->success() ) + { + cmd->unexecute(); + emit commandExecuted( cmd ); + } + } + + emit commandExecuted(); + updateActions(); + + m_part->repaintAllViews(); +} + +void +VCommandHistory::redoAllTo( VCommand* command ) +{ + int to; + + if( ( to = m_commands.findRef( command ) ) == -1 ) + return; + + int i = 0; + + VCommand* cmd; + + while( i <= to ) + { + cmd = m_commands.at( i++ ); + + if( !cmd->success() ) + { + cmd->execute(); + emit commandExecuted( cmd ); + } + } + + emit commandExecuted(); + updateActions(); + + m_part->repaintAllViews(); +} + +void +VCommandHistory::documentSaved() +{ + // I don't know how to make this work... This is a temporary hack... + // Maybe remove all undone commands before the current one ? + int i = m_commands.count() - 1; + + while( ( i >= 0 ) && !( m_commands.at( i )->success() ) ) + { + i--; + } + + i++; + + m_savedPos = i; +} + +void +VCommandHistory::clipCommands() +{ + while( m_commands.count() > m_undoLimit ) + { + if( m_commands.removeFirst() ) + m_savedPos--, emit firstCommandRemoved(); + } + + int i = 0; + + int c = m_commands.count(); + + while( ( i < c ) && ( !m_commands.at( c - 1 - i )->success() ) ) + { + i++; + } + + i = i - m_redoLimit; + + for( int j = 0; j < i; j++ ) + { + if( m_commands.removeLast() ) + emit lastCommandRemoved(); + } +} + +void +VCommandHistory::updateActions() +{ + if( m_commands.count() == 0 ) + { + if( m_undo != 0 ) + { + m_undo->setEnabled( false ); + m_undo->setText( i18n( "&Undo" ) ); + } + + if( m_redo != 0 ) + { + m_redo->setEnabled( false ); + m_redo->setText( i18n( "&Redo" ) ); + } + + return; + } + + int i = m_commands.count() - 1; + + while( ( i >= 0 ) && !( m_commands.at( i )->success() ) ) + { + i--; + } + + if( m_undo != 0 ) + { + if( i < 0 ) + { + m_undo->setEnabled( false ); + m_undo->setText( i18n( "&Undo" ) ); + } + else + { + m_undo->setEnabled( true ); + m_undo->setText( i18n( "&Undo: " ) + m_commands.at( i )->name() ); + } + } + + if( m_redo != 0 ) + { + if( ++i == int( m_commands.count() ) ) + { + m_redo->setEnabled( false ); + m_redo->setText( i18n( "&Redo" ) ); + } + else + { + m_redo->setEnabled( true ); + m_redo->setText( i18n( "&Redo: " ) + m_commands.at( i )->name() ); + } + } + + if( m_savedPos >= 0 ) + { + for( i = 0; i < m_savedPos; i++ ) + { + if( !m_commands.at( i )->success() ) + return; + } + + for( i = m_savedPos; i < int( m_commands.count() ); i++ ) + { + if( m_commands.at( i )->success() ) + return; + } + + emit documentRestored(); + } +} + +#include "vcommand.moc" + diff --git a/karbon/commands/vcommand.h b/karbon/commands/vcommand.h new file mode 100644 index 00000000..254e27eb --- /dev/null +++ b/karbon/commands/vcommand.h @@ -0,0 +1,318 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VCOMMAND_H__ +#define __VCOMMAND_H__ + + +//#include <assert.h> + +#include <qobject.h> +#include <qptrlist.h> + +#include "vvisitor.h" + +class VDocument; +class KarbonPart; +class KAction; + +/** + * The base class for all karbon commands. + * + * It basically defines the common interface that all commands should implement. + */ +class VCommand : public VVisitor +{ +public: + /** + * Constructs a new command. + * + * @param doc the document the command should work on + * @param name the name of the command (appears in command history) + * @param icon the icon of the command (appears in command history) + */ + VCommand( VDocument* doc, const QString& name, const QString& icon = "14_action" ) + : m_document( doc ), m_name( name ), m_icon( icon ) + { +// A crash because of an assert() is not much better than an crash because of a null +// pointer. Allowing null pointers allows the usage of the vitors ascpect of a VCommand. +// assert( doc ); + } + + /** Destroys the command */ + virtual ~VCommand() {} + + /** + * Executes the command. + * + * All the changes to the document are done here. + * All commands have to implement this function. + */ + virtual void execute() = 0; + + /** + * Unexecutes the command. + * + * All changes to the document have to be undone here. + */ + virtual void unexecute() {} + + /** + * Returns if the command changes the actual document selection. + * + * This flag is checked to determine if the document has to be redrawn. + * + * @return true if the selection is changed, else false + */ + virtual bool changesSelection() const { return false; } + + /** + * Returns the name of the command. + * + * @return the command name + */ + QString name() const + { + return m_name; + } + + /** + * Sets the name of the command. + * + * @param name the new command name + */ + void setName( const QString& name ) + { + m_name = name; + } + + /** + * Returns the icon of the command. + * + * @return the command icon + */ + QString icon() const + { + return m_icon; + } + + /** + * Returns the document the command works on. + * + * @return the command's document + */ + VDocument* document() const + { + return m_document; + } + +private: + VDocument* m_document; + + QString m_name; + QString m_icon; +}; + +/** + * Manages a set of commands. + * + * It keeps the commands in a list, commands higher in the list are older + * than lower commands. + * All commands in the list can be undone, beginning from the latest command + * at the end of the list. Undone commands can be redone, beginning at the + * oldest undone command. That makes it possible to go back and forth to a + * specific document state. + */ +class VCommandHistory : public QObject +{ + Q_OBJECT + +public: + /** + * Constructs a command history. + * + * @param part the part the commands are managed for + */ + VCommandHistory( KarbonPart* part ); + + /** Destroys the command history. */ + ~VCommandHistory(); + + /** + * Clears the command history by removing all commands. + * + * Emits the historyCleared signal + */ + void clear(); + + /** + * Adds a new command to the history. + * + * @param command the new command to add + * @param execute controls if the new command should be executed + */ + void addCommand( VCommand* command, bool execute = true ); + + + // limits + /** + * Returns the actual undo limit. + * + * @return the undo limit + */ + unsigned int undoLimit() const + { + return m_undoLimit; + } + + /** + * Sets a new undo limit. + * + * The undo limit controls how many commands are stored in the history. + * If the new limit is lower than the actual history size, the oldest + * commands are removed unitl the size matches the undo limit. + * + * @param limit the new undo limit + */ + void setUndoLimit( unsigned int limit ); + + /** + * Returns the actual redo limit. + * + * @return the redo limit + */ + unsigned int redoLimit() const + { + return m_redoLimit; + } + + /** + * Sets a new redo limit. + * + * The redo limit controls how many undone commands are stored in history. + * If the new limit is lower than the actual number of undone commands, + * the newest commands are removed until the number matches the redo limit. + * + * @param limit the new redo limit + */ + void setRedoLimit( unsigned int limit ); + + /** + * Read only access to the command history list. + * + * @return pointer to the list of commands + */ + const QPtrList<VCommand>* commands() const + { + return & m_commands; + } + +public slots: + /** Undoes the last command not already undone. */ + void undo(); + + /** Redoes the last command not already undone. */ + void redo(); + + /** + * Undoes the specified command. + * + * @param command the command to undo + */ + void undo( VCommand* command ); + + /** + * Redoes the specified command. + * + * @param command the command to redo + */ + void redo( VCommand* command ); + + /** + * Undoes all command up to the specified command. + * + * @param command the command up to which all later commands should be undone + */ + void undoAllTo( VCommand* command ); + + /** + * Redoes all command up to the specified command. + * + * @param command the command up to which all former commands should be redone + */ + void redoAllTo( VCommand* command ); + + /** + * Marks the actual document state as saved. + * + * The position within the list corresponding to the actual document state is saved. + */ + void documentSaved(); + +signals: + /** This signal is emitted when the command history gets cleared. */ + void historyCleared(); + + /** + * This signal is emitted when a command is executed. + * + * The executed command is given as the argument. + */ + void commandExecuted( VCommand* ); + + /** This signal is emitted when a command is executed. */ + void commandExecuted(); + + /** + * This signal is emitted when a command is added to the history. + * + * The added command is given as the argument. + */ + void commandAdded( VCommand* ); + + /** This signal is emitted when the first (oldest) command is removed. */ + void firstCommandRemoved(); + + /** This signal is emitted when the last (latest) command is removed. */ + void lastCommandRemoved(); + + /** + * This signal is emitted when the actual document state matches the last saved one. + * + * Use documentSaved to set the last saved document state. + */ + void documentRestored(); + +private: + // helpers + void clipCommands(); + void updateActions(); + + KarbonPart *m_part; + unsigned int m_undoLimit; + unsigned int m_redoLimit; + KAction *m_undo; + KAction *m_redo; + QPtrList<VCommand> m_commands; + int m_savedPos; +}; + +#endif + diff --git a/karbon/commands/vdeletecmd.cc b/karbon/commands/vdeletecmd.cc new file mode 100644 index 00000000..d94723c0 --- /dev/null +++ b/karbon/commands/vdeletecmd.cc @@ -0,0 +1,74 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vdeletecmd.h" +#include "vselection.h" +#include "vdocument.h" + +VDeleteCmd::VDeleteCmd( VDocument* doc ) + : VCommand( doc, i18n( "Delete Objects" ), "editdelete" ) +{ + m_selection = document()->selection()->clone(); + + if( m_selection->objects().count() == 1 ) + setName( i18n( "Delete Object" ) ); +} + +VDeleteCmd::VDeleteCmd( VDocument* doc, VObject* object ) + : VCommand( doc, i18n( "Delete Object" ), "editdelete" ) +{ + m_selection = new VSelection(); + m_selection->append( object ); +} + +VDeleteCmd::~VDeleteCmd() +{ + delete( m_selection ); +} + +void +VDeleteCmd::execute() +{ + document()->selection()->clear(); + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { + itr.current()->setState( VObject::deleted ); + } + + setSuccess( true ); +} + +void +VDeleteCmd::unexecute() +{ + document()->selection()->clear(); + + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { + itr.current()->setState( VObject::selected ); + document()->selection()->append( itr.current() ); + } + + setSuccess( false ); +} + diff --git a/karbon/commands/vdeletecmd.h b/karbon/commands/vdeletecmd.h new file mode 100644 index 00000000..4e4b4333 --- /dev/null +++ b/karbon/commands/vdeletecmd.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VDELETECMD_H__ +#define __VDELETECMD_H__ + +#include "vcommand.h" + +class VSelection; + +/** + * A class to provide undo/redoable deletion of VObjects. + */ + +class VDeleteCmd : public VCommand +{ +public: + VDeleteCmd( VDocument *part ); + VDeleteCmd( VDocument *part, VObject *object ); + virtual ~VDeleteCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual bool changesSelection() const { return true; } + +protected: + VSelection *m_selection; +}; + +#endif + diff --git a/karbon/commands/vdeletenodescmd.cc b/karbon/commands/vdeletenodescmd.cc new file mode 100644 index 00000000..cde7d2a5 --- /dev/null +++ b/karbon/commands/vdeletenodescmd.cc @@ -0,0 +1,77 @@ +/* This file is doc of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <klocale.h> + +#include "vdeletenodescmd.h" +#include "vselection.h" +#include "vsegment.h" +#include "vpath.h" +#include "vdocument.h" + +VDeleteNodeCmd::VDeleteNodeCmd( VDocument *doc ) + : VCommand( doc, i18n( "Delete Node" ) ) +{ +} + +VDeleteNodeCmd::~VDeleteNodeCmd() +{ +} + +void +VDeleteNodeCmd::visitVSubpath( VSubpath& path ) +{ + VSegment* segment = path.first(); + + path.next(); // skip begin segment + while( segment ) + { + if( segment->state() != VSegment::deleted && segment->knotIsSelected() ) + { + segment->setState( VSegment::deleted ); + m_segments.append( segment ); + } + segment = segment->next(); + } + if( m_segments.count() > 0 ) + path.invalidateBoundingBox(); +} + +void +VDeleteNodeCmd::execute() +{ + VObjectListIterator itr( document()->selection()->objects() ); + + for( ; itr.current() ; ++itr ) + visit( *itr.current() ); + + setSuccess( m_segments.count() > 0 ); +} + +void +VDeleteNodeCmd::unexecute() +{ + QPtrListIterator<VSegment> itr( m_segments ); + for( ; itr.current() ; ++itr ) + itr.current()->setState( VSegment::normal ); + setSuccess( false ); +} + diff --git a/karbon/commands/vdeletenodescmd.h b/karbon/commands/vdeletenodescmd.h new file mode 100644 index 00000000..28e26226 --- /dev/null +++ b/karbon/commands/vdeletenodescmd.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project � + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VNODECMD_H__ +#define __VNODECMD_H__ + +#include "vcommand.h" +#include <koffice_export.h> + +class VSegment; +class VSubpath; + +class KARBONCOMMAND_EXPORT VDeleteNodeCmd : public VCommand +{ +public: + VDeleteNodeCmd( VDocument *doc ); + virtual ~VDeleteNodeCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual void visitVSubpath( VSubpath& path ); + +protected: + QPtrList<VSegment> m_segments; +}; + +#endif + diff --git a/karbon/commands/vdistributecmd.cc b/karbon/commands/vdistributecmd.cc new file mode 100644 index 00000000..d6ceb200 --- /dev/null +++ b/karbon/commands/vdistributecmd.cc @@ -0,0 +1,198 @@ +/* This file is doc of the KDE project + Copyright (C) 2005 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <klocale.h> + +#include "vdistributecmd.h" +#include "vtransformcmd.h" +#include "vdocument.h" +#include "vselection.h" + +VDistributeCmd::VDistributeCmd( VDocument *doc, Distribute distribute ) + : VCommand( doc, i18n( "Distribute Objects" ) ), m_distribute( distribute ) +{ + m_trafoCmds.setAutoDelete( true ); +} + +VDistributeCmd::~VDistributeCmd() +{ +} + +void +VDistributeCmd::execute() +{ + if( document()->selection()->objects().count() <= 2 ) + return; + + KoRect bbox; + double extent = 0.0; + double dx, dy; + + VObjectList objs = document()->selection()->objects(); + VObjectListIterator itr( objs ); + + QMap<double,VObject*> sortedPos; + + // sort by position and calculate sum of objects widht/height + for( ; itr.current(); ++itr ) + { + bbox = itr.current()->boundingBox(); + switch( m_distribute ) + { + case DISTRIBUTE_HORIZONTAL_CENTER: + sortedPos[bbox.center().x()] = itr.current(); + break; + case DISTRIBUTE_HORIZONTAL_GAP: + case DISTRIBUTE_HORIZONTAL_LEFT: + sortedPos[bbox.left()] = itr.current(); + extent += bbox.width(); + break; + case DISTRIBUTE_HORIZONTAL_RIGHT: + sortedPos[bbox.right()] = itr.current(); + break; + case DISTRIBUTE_VERTICAL_CENTER: + sortedPos[bbox.center().y()] = itr.current(); + break; + case DISTRIBUTE_VERTICAL_GAP: + case DISTRIBUTE_VERTICAL_BOTTOM: + sortedPos[bbox.bottom()] = itr.current(); + extent += bbox.height(); + break; + case DISTRIBUTE_VERTICAL_TOP: + sortedPos[bbox.top()] = itr.current(); + break; + } + } + + VObject* first = sortedPos.begin().data(); + VObject* last = (--sortedPos.end()).data(); + + // determine the available space to distribute + double space = getAvailableSpace( first, last, extent ); + double pos = 0.0, step = space / double(objs.count() - 1); + + VTranslateCmd *trafoCmd = 0L; + QMapIterator<double,VObject*> it = sortedPos.begin(), et = sortedPos.end(); + + for( ; it != et; ++it ) + { + if( it.data() == first || it.data() == last ) + continue; + + pos += step; + + document()->selection()->clear(); + + bbox = it.data()->boundingBox(); + + switch( m_distribute ) + { + case DISTRIBUTE_HORIZONTAL_CENTER: + dx = first->boundingBox().center().x() + pos - bbox.center().x(); + dy = 0.0; + break; + case DISTRIBUTE_HORIZONTAL_GAP: + dx = first->boundingBox().right() + pos + 0.5 * bbox.width() - bbox.center().x(); + dy = 0.0; + pos += bbox.width(); + break; + case DISTRIBUTE_HORIZONTAL_LEFT: + dx = first->boundingBox().left() + pos - bbox.left(); + dy = 0.0; + break; + case DISTRIBUTE_HORIZONTAL_RIGHT: + dx = first->boundingBox().right() + pos - bbox.right(); + dy = 0.0; + break; + case DISTRIBUTE_VERTICAL_CENTER: + dx = 0.0; + dy = first->boundingBox().center().y() + pos - bbox.center().y(); + break; + case DISTRIBUTE_VERTICAL_GAP: + dx = 0.0; + dy = first->boundingBox().bottom() + pos + 0.5 * bbox.height() - bbox.center().y(); + pos += bbox.height(); + break; + case DISTRIBUTE_VERTICAL_BOTTOM: + dx = 0.0; + dy = first->boundingBox().bottom() + pos - bbox.bottom(); + break; + case DISTRIBUTE_VERTICAL_TOP: + dx = 0.0; + dy = first->boundingBox().top() + pos - bbox.top(); + break; + }; + document()->selection()->append( it.data() ); + trafoCmd = new VTranslateCmd( document(), dx, dy ); + m_trafoCmds.append( trafoCmd ); + trafoCmd->execute(); + } + + // re-add object to selection + itr.toFirst(); + for( ; itr.current() ; ++itr ) + document()->selection()->append( itr.current() ); + setSuccess( true ); +} + +void +VDistributeCmd::unexecute() +{ + QPtrListIterator<VTranslateCmd> itr( m_trafoCmds ); + for( ; itr.current() ; ++itr ) + itr.current()->unexecute(); + setSuccess( false ); +} + +double +VDistributeCmd::getAvailableSpace( VObject *first, VObject *last, double extent ) +{ + switch( m_distribute ) + { + case DISTRIBUTE_HORIZONTAL_CENTER: + return last->boundingBox().center().x() - first->boundingBox().center().x(); + break; + case DISTRIBUTE_HORIZONTAL_GAP: + extent -= first->boundingBox().width() + last->boundingBox().width(); + return last->boundingBox().left() - first->boundingBox().right() - extent; + break; + case DISTRIBUTE_HORIZONTAL_LEFT: + return last->boundingBox().left() - first->boundingBox().left(); + break; + case DISTRIBUTE_HORIZONTAL_RIGHT: + return last->boundingBox().right() - first->boundingBox().right(); + break; + case DISTRIBUTE_VERTICAL_CENTER: + return last->boundingBox().center().y() - first->boundingBox().center().y(); + break; + case DISTRIBUTE_VERTICAL_GAP: + extent -= first->boundingBox().height() + last->boundingBox().height(); + return last->boundingBox().top() - first->boundingBox().bottom() - extent; + break; + case DISTRIBUTE_VERTICAL_BOTTOM: + return last->boundingBox().bottom() - first->boundingBox().bottom(); + break; + case DISTRIBUTE_VERTICAL_TOP: + return last->boundingBox().top() - first->boundingBox().top(); + break; + } + + return 0.0; +} diff --git a/karbon/commands/vdistributecmd.h b/karbon/commands/vdistributecmd.h new file mode 100644 index 00000000..2f0cffe3 --- /dev/null +++ b/karbon/commands/vdistributecmd.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2005, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VDISTRIBUTECMD_H__ +#define __VDISTRIBUTECMD_H__ + +#include "vcommand.h" + +class VTranslateCmd; + +/** A command for distributing objects */ + +class VDistributeCmd : public VCommand +{ +public: + enum Distribute + { + DISTRIBUTE_HORIZONTAL_CENTER, + DISTRIBUTE_HORIZONTAL_GAP, + DISTRIBUTE_HORIZONTAL_LEFT, + DISTRIBUTE_HORIZONTAL_RIGHT, + DISTRIBUTE_VERTICAL_CENTER, + DISTRIBUTE_VERTICAL_GAP, + DISTRIBUTE_VERTICAL_BOTTOM, + DISTRIBUTE_VERTICAL_TOP + }; + VDistributeCmd( VDocument *doc, Distribute distribute ); + virtual ~VDistributeCmd(); + + virtual void execute(); + virtual void unexecute(); + virtual bool changesSelection() const { return true; } + +protected: + double getAvailableSpace( VObject *first, VObject *last, double extent ); + + Distribute m_distribute; + QPtrList<VTranslateCmd> m_trafoCmds; +}; + +#endif + diff --git a/karbon/commands/vfillcmd.cc b/karbon/commands/vfillcmd.cc new file mode 100644 index 00000000..48572ade --- /dev/null +++ b/karbon/commands/vfillcmd.cc @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vfill.h" +#include "vfillcmd.h" +#include "vselection.h" +#include "vdocument.h" +#include "vcomposite.h" +#include "vgroup.h" +#include "vtext.h" + +VFillCmd::VFillCmd( VDocument *doc, const VFill &fill, const QString &icon ) + : VCommand( doc, i18n( "Fill Objects" ), icon ), m_fill( fill ) +{ + m_selection = document()->selection()->clone(); + + if( m_selection->objects().count() == 1 ) + setName( i18n( "Fill Object" ) ); +} + +VFillCmd::~VFillCmd() +{ + m_objects.clear(); + delete m_selection; + m_selection = 0L; +} + +void +VFillCmd::changeFill( const VFill &fill ) +{ + m_fill = fill; + + if( !m_selection ) + m_selection = document()->selection()->clone(); + + VObjectListIterator itr( m_selection->objects() ); + + for( ; itr.current() ; ++itr ) + { + visit( *itr.current() ); + } + + setSuccess( true ); +} + +void +VFillCmd::visitVGroup( VGroup& group ) +{ + VObjectListIterator itr( group.objects() ); + + for( ; itr.current() ; ++itr ) + { + m_oldfills.push_back( VFill( *( itr.current()->fill() ) ) ); + itr.current()->setFill( m_fill ); + m_objects.append(itr.current() ); + } +} + +void +VFillCmd::visitVPath( VPath& composite ) +{ + m_oldfills.push_back( VFill( *( composite.fill() ) ) ); + composite.setFill( m_fill ); + m_objects.append( &composite ); +} + +void +VFillCmd::visitVText( VText& text ) +{ + m_oldfills.push_back( VFill( *( text.fill() ) ) ); + text.setFill( m_fill ); + m_objects.append( &text ); +} + +void +VFillCmd::execute() +{ + if( !m_selection ) + m_selection = document()->selection()->clone(); + VObjectListIterator itr( m_selection->objects() ); + + for( ; itr.current() ; ++itr ) + { + visit( *itr.current() ); + } + + setSuccess( true ); +} + +void +VFillCmd::unexecute() +{ + VObjectListIterator itr( m_objects ); + + int i = 0; + + for( ; itr.current() ; ++itr ) + { + itr.current()->setFill( m_oldfills[ i++ ] ); + } + + setSuccess( false ); +} + diff --git a/karbon/commands/vfillcmd.h b/karbon/commands/vfillcmd.h new file mode 100644 index 00000000..41661290 --- /dev/null +++ b/karbon/commands/vfillcmd.h @@ -0,0 +1,62 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VFILLCMD_H__ +#define __VFILLCMD_H__ + +#include "vcommand.h" +#include "vfill.h" +#include "vgroup.h" + +#include <qvaluevector.h> +#include <koffice_export.h> +class VSelection; + +// Fill object(s) + +class KARBONCOMMAND_EXPORT VFillCmd : public VCommand +{ +public: + VFillCmd( VDocument *doc, const VFill &, const QString& icon = "14_action" ); + virtual ~VFillCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual bool changesSelection() const { return true; } + + virtual void visitVGroup( VGroup& group ); + virtual void visitVPath( VPath& composite ); + virtual void visitVText( VText& text ); + + virtual void changeFill( const VFill & ); + virtual VSelection* getSelection() const { return m_selection; } + +protected: + VObjectList m_objects; + VSelection *m_selection; + + VFill m_fill; + + QValueVector<VFill> m_oldfills; +}; + +#endif + diff --git a/karbon/commands/vflattencmd.cc b/karbon/commands/vflattencmd.cc new file mode 100644 index 00000000..0cab021a --- /dev/null +++ b/karbon/commands/vflattencmd.cc @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "vflattencmd.h" +#include <klocale.h> + +#include <core/vpath.h> +#include <core/vsegment.h> + +// TODO: Think about if we want to adapt this: + +/* + * <cite from GNU ghostscript's gxpflat.c> + * + * To calculate how many points to sample along a path in order to + * approximate it to the desired degree of flatness, we define + * dist((x,y)) = abs(x) + abs(y); + * then the number of points we need is + * N = 1 + sqrt(3/4 * D / flatness), + * where + * D = max(dist(p0 - 2*p1 + p2), dist(p1 - 2*p2 + p3)). + * Since we are going to use a power of 2 for the number of intervals, + * we can avoid the square root by letting + * N = 1 + 2^(ceiling(log2(3/4 * D / flatness) / 2)). + * (Reference: DEC Paris Research Laboratory report #1, May 1989.) + * + * We treat two cases specially. First, if the curve is very + * short, we halve the flatness, to avoid turning short shallow curves + * into short straight lines. Second, if the curve forms part of a + * character (indicated by flatness = 0), we let + * N = 1 + 2 * max(abs(x3-x0), abs(y3-y0)). + * This is probably too conservative, but it produces good results. + * + * </cite from GNU ghostscript's gxpflat.c> + */ + + +VFlattenCmd::VFlattenCmd( VDocument *doc, double flatness ) + : VReplacingCmd( doc, i18n( "Flatten Curves" ) ) +{ + m_flatness = flatness > 0.0 ? flatness : 1.0; +} + +void +VFlattenCmd::visitVSubpath( VSubpath& path ) +{ + path.first(); + + // Ommit first segment. + while( path.next() ) + { + while( !path.current()->isFlat( m_flatness ) ) + { + // Split at midpoint. + path.insert( + path.current()->splitAt( 0.5 ) ); + } + + // Convert to line. + path.current()->setDegree( 1 ); + + if( !success() ) + setSuccess(); + } +} + diff --git a/karbon/commands/vflattencmd.h b/karbon/commands/vflattencmd.h new file mode 100644 index 00000000..6e150ba3 --- /dev/null +++ b/karbon/commands/vflattencmd.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __FLATTENCMD_H__ +#define __FLATTENCMD_H__ + +#include <commands/vreplacingcmd.h> +#include <koffice_export.h> +class VSubpath; + +class KARBONCOMMAND_EXPORT VFlattenCmd : public VReplacingCmd +{ +public: + VFlattenCmd( VDocument *doc, double flatness ); + virtual ~VFlattenCmd() {} + + virtual void visitVSubpath( VSubpath& path ); + +protected: + double m_flatness; +}; + +#endif + diff --git a/karbon/commands/vgroupcmd.cc b/karbon/commands/vgroupcmd.cc new file mode 100644 index 00000000..bcad4d93 --- /dev/null +++ b/karbon/commands/vgroupcmd.cc @@ -0,0 +1,100 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vgroup.h" +#include "vgroupcmd.h" +#include "vselection.h" +#include "vdocument.h" +#include "vlayer.h" + +VGroupCmd::VGroupCmd( VDocument *doc ) + : VCommand( doc, i18n( "Group Objects" ), "14_group" ) +{ + m_selection = document()->selection()->clone(); + + m_group = 0L; +} + +VGroupCmd::~VGroupCmd() +{ + delete( m_selection ); +} + +void +VGroupCmd::execute() +{ + m_group = new VGroup( document()->activeLayer() ); + + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { + // remove from corresponding parent + VGroup *parent = dynamic_cast<VGroup*>( itr.current()->parent() ); + if( parent ) + parent->take( *itr.current() ); + + m_group->append( itr.current() ); + } + + document()->append( m_group ); + document()->selection()->clear(); + document()->selection()->append( m_group ); + + setSuccess( true ); +} + +void +VGroupCmd::unexecute() +{ + if( ! m_group ) + return; + + document()->selection()->clear(); + + VObjectListIterator itr( m_group->objects() ); + for ( ; itr.current() ; ++itr ) + { + // TODO : remove from corresponding VLayer + document()->selection()->append( itr.current() ); + } + + VGroup* parent; + if( ( parent = dynamic_cast<VGroup*>( m_group->parent() ) ) ) + { + // unregister from parent: + parent->take( *m_group ); + + // inform all objects in this group about their new parent + VObjectListIterator itr = m_selection->objects(); + + for ( ; itr.current() ; ++itr ) + { + parent->append( itr.current() ); + } + + m_group->clear(); + m_group->setState( VObject::deleted ); + } + + setSuccess( false ); +} + diff --git a/karbon/commands/vgroupcmd.h b/karbon/commands/vgroupcmd.h new file mode 100644 index 00000000..4dad4028 --- /dev/null +++ b/karbon/commands/vgroupcmd.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VGROUPCMD_H__ +#define __VGROUPCMD_H__ + +#include "vcommand.h" + + +class VSelection; + + +// Group object(s) + +class VGroup; + +class VGroupCmd : public VCommand +{ +public: + VGroupCmd( VDocument *doc ); + virtual ~VGroupCmd(); + + virtual void execute(); + virtual void unexecute(); + +protected: + VSelection* m_selection; + + VGroup* m_group; +}; + +#endif + diff --git a/karbon/commands/vinsertcmd.cc b/karbon/commands/vinsertcmd.cc new file mode 100644 index 00000000..2ec628c8 --- /dev/null +++ b/karbon/commands/vinsertcmd.cc @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2005, Inge Wallin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> + +#include "vdocument.h" +#include "vlayer.h" +#include "vselection.h" +#include "vinsertcmd.h" +#include "vtransformcmd.h" + + +VInsertCmd::VInsertCmd( VDocument *doc, const QString& name, + VObjectList *objects, + double offset ) + : VCommand( doc, name, "14_insert" ), + m_objects( *objects ), + m_offset( offset ) +{ +} + +VInsertCmd::~VInsertCmd() +{ +} + + +void +VInsertCmd::execute() +{ + VObjectListIterator itr( m_objects ); + + document()->selection()->clear(); + for ( ; itr.current() ; ++itr ) { + VObject *object = itr.current(); + + if ( object->state() == VObject::deleted ) { + object->setState( VObject::normal ); + } + else { + document()->append( object ); + + if ( m_offset != 0.0 ) { + VTranslateCmd cmd( 0L, m_offset, -m_offset ); + cmd.visit( *object ); + } + } + + document()->selection()->append( object ); + } + + setSuccess( true ); +} + + +void +VInsertCmd::unexecute() +{ + document()->selection()->clear(); + + VObjectListIterator itr( m_objects ); + for ( ; itr.current() ; ++itr ) { + itr.current()->setState( VObject::deleted ); + } + + setSuccess( false ); +} + diff --git a/karbon/commands/vinsertcmd.h b/karbon/commands/vinsertcmd.h new file mode 100644 index 00000000..7cc948a9 --- /dev/null +++ b/karbon/commands/vinsertcmd.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2004, Inge Wallin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VINSERTCMD_H__ +#define __VINSERTCMD_H__ + +#include "vcommand.h" +#include "vgroup.h" + + + + +// Insert object(s) + +class VInsert; + +class VInsertCmd : public VCommand +{ +public: + VInsertCmd( VDocument *doc, const QString& name, + VObjectList *objects, double offset ); + virtual ~VInsertCmd(); + + virtual void execute(); + virtual void unexecute(); + +protected: + VObjectList m_objects; + double m_offset; +}; + +#endif + diff --git a/karbon/commands/vlayercmd.cc b/karbon/commands/vlayercmd.cc new file mode 100644 index 00000000..d53155cd --- /dev/null +++ b/karbon/commands/vlayercmd.cc @@ -0,0 +1,86 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "vlayer.h" +#include "vlayercmd.h" +#include "vdocument.h" + +VLayerCmd::VLayerCmd( VDocument* doc, const QString& name, VLayer* layer, VLayerCmdType order ) + : VCommand( doc, name, "14_layers" ), m_layer( layer ), m_cmdType( order ) +{ + if( order == addLayer ) + { + layer->setState( VObject::deleted ); + document()->insertLayer( layer ); + } + + m_oldState = layer->state(); +} + +void +VLayerCmd::execute() +{ + switch( m_cmdType ) + { + case addLayer: + m_layer->setState( VObject::normal ); + break; + + case deleteLayer: + m_layer->setState( VObject::deleted ); + break; + + case raiseLayer: + document()->raiseLayer( m_layer ); + break; + + case lowerLayer: + document()->lowerLayer( m_layer ); + break; + } + + setSuccess( true ); +} + +void +VLayerCmd::unexecute() +{ + switch ( m_cmdType ) + { + case addLayer: + m_layer->setState( VObject::deleted ); + break; + + case deleteLayer: + m_layer->setState( m_oldState ); + break; + + case raiseLayer: + document()->lowerLayer( m_layer ); + break; + + case lowerLayer: + document()->raiseLayer( m_layer ); + break; + } + + setSuccess( false ); +} + diff --git a/karbon/commands/vlayercmd.h b/karbon/commands/vlayercmd.h new file mode 100644 index 00000000..b2771202 --- /dev/null +++ b/karbon/commands/vlayercmd.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VLAYERCMD_H__ +#define __VLAYERCMD_H__ + +#include "vcommand.h" +#include "vobject.h" + + +class VDocument; +class VLayer; + + +class VLayerCmd : public VCommand +{ +public: + /** + * The different types of layer commands. + */ + enum VLayerCmdType + { + addLayer, + raiseLayer, + lowerLayer, + deleteLayer + }; + + VLayerCmd( VDocument* doc, const QString& name, VLayer* layer, VLayerCmdType order ); + virtual ~VLayerCmd() {} + + virtual void execute(); + virtual void unexecute(); + +protected: + VLayer* m_layer; + VLayerCmdType m_cmdType; + VObject::VState m_oldState; +}; + +#endif + diff --git a/karbon/commands/vreplacingcmd.cc b/karbon/commands/vreplacingcmd.cc new file mode 100644 index 00000000..c14ffa1d --- /dev/null +++ b/karbon/commands/vreplacingcmd.cc @@ -0,0 +1,145 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include "vreplacingcmd.h" +#include "vselection.h" +#include "vdocument.h" + +VReplacingCmd::VReplacingCmd( VDocument* doc, const QString& name ) + : VCommand( doc, name ) +{ + // Set members. + m_oldObjects = doc ? document()->selection()->clone() : 0L; + m_newObjects = 0L; +} + +VReplacingCmd::~VReplacingCmd() +{ + delete( m_oldObjects ); + delete( m_newObjects ); +} + +void +VReplacingCmd::execute() +{ + // Did we have at least once a success? Otherwise we don't get inserted + // into the command history. + bool successful = false; + + + // Create new shapes if they don't exist yet. + if( !m_newObjects ) + { + m_newObjects = new VSelection(); + + // Pointer to temporary object. + VObject* newObject; + + VObjectListIterator itr( m_oldObjects->objects() ); + VObjectList rejects; + + for( ; itr.current(); ++itr ) + { + // Clone object and visit the clone. + newObject = itr.current()->clone(); + + // Success. + if( visit( *newObject ) ) + { + successful = true; + + // Insert new shape right before old shape. + itr.current()->parent()->insertInfrontOf( + newObject, itr.current() ); + + // Add new shape to list of new objects. + m_newObjects->append( newObject ); + } + // No success. + else + { + rejects.append( itr.current() ); + // Delete temporary object. + delete( newObject ); + } + } + VObjectListIterator jtr( rejects ); + for( ; jtr.current(); ++jtr ) + { + // Don't consider this object in the future anymore. + m_oldObjects->take( *jtr.current() ); + } + } + + // Nothing to do. + if( m_newObjects->objects().count() == 0 ) + return; + + + VObjectListIterator itr( m_oldObjects->objects() ); + + // Hide old objects. + for( ; itr.current(); ++itr ) + { + document()->selection()->take( *itr.current() ); + itr.current()->setState( VObject::deleted ); + } + + // Show new objects. + for( itr = m_newObjects->objects(); itr.current(); ++itr ) + { + itr.current()->setState( VObject::normal ); + document()->selection()->append( itr.current() ); + } + + + // Tell command history wether we had success at least once. + setSuccess( successful ); +} + +void +VReplacingCmd::unexecute() +{ + // Nothing to do. + if( m_newObjects->objects().count() == 0 ) + return; + + + VObjectListIterator itr( m_oldObjects->objects() ); + + // Show old objects. + for( ; itr.current(); ++itr ) + { + itr.current()->setState( VObject::normal ); + document()->selection()->append( itr.current() ); + } + + // Hide new objects. + for( itr = m_newObjects->objects(); itr.current(); ++itr ) + { + document()->selection()->take( *itr.current() ); + itr.current()->setState( VObject::deleted ); + } + + + // Reset success for command history. + setSuccess( false ); +} + diff --git a/karbon/commands/vreplacingcmd.h b/karbon/commands/vreplacingcmd.h new file mode 100644 index 00000000..54a14aac --- /dev/null +++ b/karbon/commands/vreplacingcmd.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VREPLACINGCMD_H__ +#define __VREPLACINGCMD_H__ + + +#include "vcommand.h" +#include <koffice_export.h> +class QString; +class VSelection; + + +/** + * VReplacingCmd is a generic command. Derive from it if you plan to do complex + * transformations upon selected objects which make it necessary to replace + * each object as a whole with a new object. + */ + +class KARBONCOMMAND_EXPORT VReplacingCmd : public VCommand +{ +public: + virtual void execute(); + virtual void unexecute(); + +protected: + /** + * Make it "abstract". + */ + VReplacingCmd( VDocument* doc, const QString& name ); + virtual ~VReplacingCmd(); + +private: + VSelection* m_oldObjects; + VSelection* m_newObjects; +}; + +#endif + diff --git a/karbon/commands/vshapecmd.cc b/karbon/commands/vshapecmd.cc new file mode 100644 index 00000000..59ea841a --- /dev/null +++ b/karbon/commands/vshapecmd.cc @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include "vcomposite.h" +#include "vdocument.h" +#include "vselection.h" +#include "vshapecmd.h" + + +VShapeCmd::VShapeCmd( VDocument* doc, const QString& name, VPath* shape, const QString& icon ) + : VCommand( doc, name, icon ), m_shape( shape ) +{ +} + +void +VShapeCmd::execute() +{ + if( !m_shape ) + return; + + if( m_shape->state() == VObject::deleted ) + { + document()->selection()->clear(); + m_shape->setState( VObject::normal ); + document()->selection()->append( m_shape ); + } + else + { + m_shape->setState( VObject::normal ); + m_shape->setFill( *( document()->selection()->fill() ) ); + m_shape->setStroke( *( document()->selection()->stroke() ) ); + + // Add path: + document()->append( m_shape ); + document()->selection()->clear(); + document()->selection()->append( m_shape ); + } + + setSuccess( true ); +} + +void +VShapeCmd::unexecute() +{ + if( !m_shape ) + return; + + document()->selection()->take( *m_shape ); + m_shape->setState( VObject::deleted ); + + setSuccess( false ); +} + diff --git a/karbon/commands/vshapecmd.h b/karbon/commands/vshapecmd.h new file mode 100644 index 00000000..dc033dbe --- /dev/null +++ b/karbon/commands/vshapecmd.h @@ -0,0 +1,51 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VSHAPECMD_H__ +#define __VSHAPECMD_H__ + +#include "vcommand.h" +#include <koffice_export.h> +class VPath; + +/* + * Provides a common base class for creation commands since they all have + * a similar execute / unexecute behaviour and all build a VPath. Upon + * execution() the shape will be added to the document and selected, upon undoing + * it will be set to the deleted state. + */ +class KARBONCOMMAND_EXPORT VShapeCmd : public VCommand +{ +public: + VShapeCmd( VDocument* doc, const QString& name, VPath* shape, const QString& icon = "14_polygon" ); + virtual ~VShapeCmd() {} + + virtual void execute(); + virtual void unexecute(); + + virtual bool changesSelection() const { return true; } + +protected: + /// Pointer to the created shape. + VPath *m_shape; +}; + +#endif + diff --git a/karbon/commands/vstrokecmd.cc b/karbon/commands/vstrokecmd.cc new file mode 100644 index 00000000..26a9a1a7 --- /dev/null +++ b/karbon/commands/vstrokecmd.cc @@ -0,0 +1,193 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vselection.h" +#include "vstroke.h" +#include "vgradient.h" +#include "vstrokecmd.h" +#include "vdocument.h" + +VStrokeCmd::VStrokeCmd( VDocument *doc, const VStroke *stroke, const QString& icon ) + : VCommand( doc, i18n( "Stroke Objects" ), icon ), m_stroke( *stroke ) +{ + m_selection = document()->selection()->clone(); + m_state = Stroke; + + if( m_selection->objects().count() == 1 ) + setName( i18n( "Stroke Object" ) ); +} + +VStrokeCmd::VStrokeCmd( VDocument *doc, VGradient *gradient ) + : VCommand( doc, i18n( "Stroke Objects" ), "14_gradient" ) +{ + m_selection = document()->selection()->clone(); + m_state = Gradient; + m_stroke.gradient() = *gradient; + + if( m_selection->objects().count() == 1 ) + setName( i18n( "Stroke Object" ) ); +} + +VStrokeCmd::VStrokeCmd( VDocument *doc, VPattern *pattern ) + : VCommand( doc, i18n( "Stroke Objects" ), "14_pattern" ) +{ + m_selection = document()->selection()->clone(); + m_state = Pattern; + m_stroke.pattern() = *pattern; + + if( m_selection->objects().count() == 1 ) + setName( i18n( "Stroke Object" ) ); +} + +VStrokeCmd::VStrokeCmd( VDocument *doc, double width ) + : VCommand( doc, i18n( "Stroke Width" ), "linewidth" ) +{ + m_selection = document()->selection()->clone(); + m_state = LineWidth; + m_stroke.setLineWidth( width ); +} + +VStrokeCmd::VStrokeCmd( VDocument *doc, const VColor &color ) + : VCommand( doc, i18n( "Stroke Color" ), "linewidth" ) +{ + m_selection = document()->selection()->clone(); + m_state = Color; + m_stroke.setColor( color ); +} + +VStrokeCmd::VStrokeCmd( VDocument *doc, const QValueList<float>& array ) + : VCommand( doc, i18n( "Dash Pattern" ), "linewidth" ) +{ + m_selection = document()->selection()->clone(); + m_state = Dash; + m_stroke.dashPattern().setArray( array ); +} + +VStrokeCmd::~VStrokeCmd() +{ + delete( m_selection ); +} + +void +VStrokeCmd::changeStroke( const VColor &color ) +{ + m_state = Color; + m_stroke.setColor( color ); + + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { + //if( m_opacity == -1 ) + // m_color.setOpacity( itr.current()->stroke()->color().opacity() ); + + m_oldstrokes.push_back( *itr.current()->stroke() ); + + VStroke stroke( *itr.current()->stroke() ); + stroke.setParent( itr.current() ); + + stroke.setColor( m_stroke.color() ); + stroke.setType( VStroke::solid ); + + itr.current()->setStroke( stroke ); + } + + setSuccess( true ); +} + +void +VStrokeCmd::execute() +{ + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { + //if( m_opacity == -1 ) + // m_color.setOpacity( itr.current()->stroke()->color().opacity() ); + + m_oldstrokes.push_back( *itr.current()->stroke() ); + + VStroke stroke( *itr.current()->stroke() ); + stroke.setParent( itr.current() ); + if( m_state == LineWidth ) + stroke.setLineWidth( m_stroke.lineWidth() ); + else if( m_state == Color ) + { + stroke.setColor( m_stroke.color() ); + stroke.setType( VStroke::solid ); + } + else if( m_state == Gradient ) + { + stroke.gradient() = m_stroke.gradient(); + stroke.setType( VStroke::grad ); + } + else if( m_state == Pattern ) + { + stroke.pattern() = m_stroke.pattern(); + stroke.setType( VStroke::patt ); + } + else if( m_state == Stroke ) + { + stroke.setLineCap( m_stroke.lineCap() ); + stroke.setLineJoin( m_stroke.lineJoin() ); + stroke.setLineWidth( m_stroke.lineWidth() ); + if( m_stroke.type() == VStroke::none ) + { + stroke.setType( VStroke::none ); + } + else if( m_stroke.type() == VStroke::solid ) + { + stroke.setColor( m_stroke.color() ); + stroke.setType( VStroke::solid ); + } + else if( m_stroke.type() == VStroke::grad ) + { + stroke.gradient() = m_stroke.gradient(); + stroke.setType( VStroke::grad ); + } + else if( m_stroke.type() == VStroke::patt ) + { + stroke.pattern() = m_stroke.pattern(); + stroke.setType( VStroke::patt ); + } + } + else if( m_state == Dash ) + { + stroke.dashPattern() = m_stroke.dashPattern(); + } + itr.current()->setStroke( stroke ); + } + + setSuccess( true ); +} + +void +VStrokeCmd::unexecute() +{ + VObjectListIterator itr( m_selection->objects() ); + int i = 0; + for ( ; itr.current() ; ++itr ) + { + itr.current()->setStroke( m_oldstrokes[ i++ ] ); + } + + setSuccess( false ); +} + diff --git a/karbon/commands/vstrokecmd.h b/karbon/commands/vstrokecmd.h new file mode 100644 index 00000000..71adb334 --- /dev/null +++ b/karbon/commands/vstrokecmd.h @@ -0,0 +1,69 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VSTROKECMD_H__ +#define __VSTROKECMD_H__ + +#include "vcommand.h" +#include "vcolor.h" +#include "vstroke.h" + +#include <qvaluevector.h> +#include <koffice_export.h> +// Stroke object(s) + +class KARBONCOMMAND_EXPORT VStrokeCmd : public VCommand +{ +public: + VStrokeCmd( VDocument *doc, const VStroke *, const QString& icon = "14_action" ); + VStrokeCmd( VDocument *doc, VGradient * ); + VStrokeCmd( VDocument *doc, VPattern * ); + VStrokeCmd( VDocument *doc, const VColor & ); + VStrokeCmd( VDocument *doc, double ); + VStrokeCmd( VDocument *doc, const QValueList<float>& ); + virtual ~VStrokeCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual bool changesSelection() const { return true; } + + virtual void changeStroke( const VColor & ); + virtual VSelection* getSelection() const { return m_selection; } + +protected: + typedef enum + { + LineWidth, + Color, + Gradient, + Pattern, + Stroke, + Dash + } State; + + State m_state; + VSelection *m_selection; + VStroke m_stroke; + QValueVector<VStroke> m_oldstrokes; +}; + +#endif + diff --git a/karbon/commands/vtextcmd.cc b/karbon/commands/vtextcmd.cc new file mode 100644 index 00000000..5bab728d --- /dev/null +++ b/karbon/commands/vtextcmd.cc @@ -0,0 +1,40 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "karbon_view.h" + +#include "vpath.h" +#include "vtext.h" +#include "vtextcmd.h" + +VTextCmd::VTextCmd( KarbonPart* part, const QFont& font, const QString& text ) + : VShapeCmd( part, i18n( "Insert Text" ) ), m_font( font ), m_text( text ) +{ +} + +VObject* +VTextCmd::createPath() +{ + return + new VText( static_cast<KarbonView*>( m_part->views().getFirst() ), m_font, m_text ); +} + diff --git a/karbon/commands/vtextcmd.h b/karbon/commands/vtextcmd.h new file mode 100644 index 00000000..3e0f310e --- /dev/null +++ b/karbon/commands/vtextcmd.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VTEXTCMD_H__ +#define __VTEXTCMD_H__ + +#include <qfont.h> + +#include "vshapecmd.h" + +// create a text-object. + +class VObject; + +class VTextCmd : public VShapeCmd +{ +public: + VTextCmd( KarbonPart* part, const QFont& font, const QString& m_text ); + virtual ~VTextCmd() {} + + virtual VObject* createPath(); + +protected: + QFont m_font; + QString m_text; +}; + +#endif + diff --git a/karbon/commands/vtransformcmd.cc b/karbon/commands/vtransformcmd.cc new file mode 100644 index 00000000..5feacac5 --- /dev/null +++ b/karbon/commands/vtransformcmd.cc @@ -0,0 +1,491 @@ +/* This file is doc of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <klocale.h> + +#include "vcomposite.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vtext.h" +#include "vimage.h" +#include "vtransformcmd.h" +#include "vstroke.h" +#include "vfill.h" +#include "vdocument.h" + +#include <kdebug.h> + +VTransformCmd::VTransformCmd( VDocument *doc, const QWMatrix& mat, bool duplicate ) + : VCommand( doc, i18n( "Transform Objects" ) ), m_mat( mat ), m_duplicate( duplicate ) +{ + m_selection = ( document() && document()->selection() ) + ? document()->selection()->clone() + : new VSelection(); + + if( m_duplicate ) + { + if( !m_selection || m_selection->objects().count() == 1 ) + setName( i18n( "Duplicate Object" ) ); + else + setName( i18n( "Duplicate Objects" ) ); + } + else if( !m_selection || m_selection->objects().count() == 1 ) + setName( i18n( "Transform Object" ) ); +} + +VTransformCmd::VTransformCmd( VDocument *doc, const QString& name, const QString& icon, bool duplicate ) + : VCommand( doc, name, icon ), m_duplicate( duplicate ) +{ + m_selection = ( document() && document()->selection() ) + ? document()->selection()->clone() + : new VSelection(); + + if( m_duplicate ) + { + if( !m_selection || m_selection->objects().count() == 1 ) + setName( i18n( "Duplicate Object" ) ); + else + setName( i18n( "Duplicate Objects" ) ); + } +} + +VTransformCmd::~VTransformCmd() +{ + delete( m_selection ); + m_selection = 0L; +} + +void +VTransformCmd::execute() +{ + VObjectListIterator itr( m_selection->objects() ); + + if( m_duplicate ) + { + // clone original objects, add duplicates to document, transform and select them + VObject *copy = 0L; + for( ; itr.current() ; ++itr ) + { + copy = itr.current()->clone(); + visit( *copy ); + document()->append( copy ); + document()->selection()->take( *itr.current() ); + document()->selection()->append( copy ); + m_duplicates.append( copy ); + } + } + else + { + // clear selection ... + document()->selection()->clear(); + // transform objects + for( ; itr.current() ; ++itr ) + { + visit( *itr.current() ); + } + // ... and re-add all objects incase we are re-executing the command + document()->selection()->append( m_selection->objects() ); + } + + setSuccess( true ); +} + +void +VTransformCmd::unexecute() +{ + // inverting the matrix should undo the affine transformation + m_mat = m_mat.invert(); + + if( m_duplicate ) + { + // remove duplicated objects + VObjectListIterator itr( m_duplicates ); + for( ; itr.current() ; ++itr ) + { + document()->selection()->take( *itr.current() ); + itr.current()->setState( VObject::deleted ); + } + VObjectListIterator jtr( m_selection->objects() ); + + // add original selection objects to new selection + for( ; jtr.current() ; ++jtr ) + { + document()->selection()->append( jtr.current() ); + } + } + else + { + document()->selection()->clear(); + // move objects back to original position + visit( *m_selection ); + document()->selection()->append( m_selection->objects() ); + } + // reset + m_mat = m_mat.invert(); + setSuccess( false ); +} + +void +VTransformCmd::visitVObject( VObject& object ) +{ + // Apply transformation to gradients. + VStroke* stroke = object.stroke(); + if( stroke && stroke->type() == VStroke::grad ) + stroke->gradient().transform( m_mat ); + else if( stroke && stroke->type() == VStroke::patt ) + stroke->pattern().transform( m_mat ); + + VFill* fill = object.fill(); + if( fill && fill->type() == VFill::grad ) + fill->gradient().transform( m_mat ); + else if( fill && fill->type() == VFill::patt ) + fill->pattern().transform( m_mat ); +} + +void +VTransformCmd::visitVPath( VPath& composite ) +{ + if( composite.state() == VObject::hidden || + composite.state() == VObject::normal_locked || + composite.state() == VObject::hidden_locked ) + return; + + visitVObject( composite ); + + composite.transform( m_mat ); + + VVisitor::visitVPath( composite ); +} + +void +VTransformCmd::visitVSubpath( VSubpath& path ) +{ + if( path.state() == VObject::hidden || + path.state() == VObject::normal_locked || + path.state() == VObject::hidden_locked ) + return; + + VSegment* segment = path.first(); + + while( segment ) + { + for( unsigned short i = 0; i < segment->degree(); ++i ) + { + segment->setPoint( i, segment->point( i ).transform( m_mat ) ); + } + + segment = segment->next(); + } + + path.invalidateBoundingBox(); +} + +void +VTransformCmd::visitVText( VText& text ) +{ + if( text.state() == VObject::hidden || + text.state() == VObject::normal_locked || + text.state() == VObject::hidden_locked ) + return; + + visitVObject( text ); + + visit( text.basePath() ); + + VPathListIterator itr( text.glyphs() ); + + for( ; itr.current() ; ++itr ) + { + visit( *itr.current() ); + } + + text.invalidateBoundingBox(); +} + +void +VTransformCmd::visitVImage( VImage &img ) +{ + if( img.state() == VObject::hidden || + img.state() == VObject::normal_locked || + img.state() == VObject::hidden_locked ) + return; + + img.transform( m_mat ); +} + +VTranslateCmd::VTranslateCmd( VDocument *doc, double d1, double d2, bool duplicate ) + : VTransformCmd( doc, i18n( "Translate Objects" ), "translate", duplicate ) +{ + if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) ) + setName( i18n( "Translate Object" ) ); + + m_mat.translate( d1, d2 ); +} + + +VScaleCmd::VScaleCmd( VDocument *doc, const KoPoint& p, double s1, double s2, bool duplicate ) + : VTransformCmd( doc, i18n( "Scale Objects" ), "14_select", duplicate ) +{ + if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) ) + setName( i18n( "Scale Object" ) ); + + m_mat.translate( p.x(), p.y() ); + m_mat.scale( s1, s2 ); + m_mat.translate( -p.x(), -p.y() ); +} + + +VShearCmd::VShearCmd( VDocument *doc, const KoPoint& p, double s1, double s2, bool duplicate ) + : VTransformCmd( doc, i18n( "Shear Objects" ), "14_shear", duplicate ) +{ + if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) ) + setName( i18n( "Shear Object" ) ); + + m_mat.translate( p.x(), p.y() ); + m_mat.shear( s1, s2 ); + m_mat.translate( -p.x(), -p.y() ); +} + +VRotateCmd::VRotateCmd( VDocument *doc, const KoPoint& p, double angle, bool duplicate ) + : VTransformCmd( doc, i18n( "Rotate Objects" ), "14_rotate", duplicate ) +{ + if( !duplicate && ( !m_selection || m_selection->objects().count() == 1 ) ) + setName( i18n( "Rotate Object" ) ); + + m_mat.translate( p.x(), p.y() ); + m_mat.rotate( angle ); + m_mat.translate( -p.x(), -p.y() ); +} + +VTranslateBezierCmd::VTranslateBezierCmd( VDocument *doc, VSegment *segment, double d1, double d2, bool firstControl ) + : VCommand( doc, i18n( "Translate Bezier" ) ), m_segment( segment ), m_firstControl( firstControl ) + , m_subpath(0L) +{ + m_mat.translate( d1, d2 ); + m_segmenttwo = 0L; + + if( document() && document()->selection() ) + { + VObjectListIterator itr( document()->selection()->objects() ); + + // find subpath containing the segment + for( ; itr.current() ; ++itr ) + visit( *itr.current() ); + } +} + +VTranslateBezierCmd::~VTranslateBezierCmd() +{ +} + +void +VTranslateBezierCmd::execute() +{ + if( m_segment->degree() == 3 ) + { + QWMatrix m2( m_mat.m11(), m_mat.m12(), m_mat.m21(), m_mat.m22(), -m_mat.dx(), -m_mat.dy() ); + if( m_firstControl ) + { + if( m_segment->prev() && + m_segment->prev()->degree() == 3 && + m_segment->prev()->isSmooth() ) + { + m_segmenttwo = m_segment->prev(); + for( uint i = 0;i < m_segmenttwo->degree();i++ ) + { + m_segmenttwo->selectPoint( i, i == 1 ); + + if( i == 1 ) + m_segmenttwo->setPoint( i, m_segmenttwo->point( i ).transform( m2 ) ); + } + } + } + else + { + m_segmenttwo = ( m_segment->isSmooth() && m_segment->next()->degree() == 3 ) ? m_segment->next() : 0L; + if( m_segmenttwo ) + { + for( uint i = 0;i < m_segmenttwo->degree();i++ ) + { + m_segmenttwo->selectPoint( i, i == 0 ); + + if( i == 0 ) + m_segmenttwo->setPoint( i, m_segmenttwo->point( i ).transform( m2 ) ); + } + } + } + + for( uint i = 0;i < m_segment->degree();i++ ) + { + m_segment->selectPoint( i, i == uint( m_firstControl ? 0 : 1 ) ); + + if( i == uint( m_firstControl ? 0 : 1 ) ) + m_segment->setPoint( i, m_segment->point( i ).transform( m_mat ) ); + } + } + + if( m_subpath ) + m_subpath->invalidateBoundingBox(); + + setSuccess( true ); +} + +void +VTranslateBezierCmd::unexecute() +{ + QWMatrix m2( m_mat.m11(), m_mat.m12(), m_mat.m21(), m_mat.m22(), -m_mat.dx(), -m_mat.dy() ); + if( m_segment ) + { + for( uint i = 0;i < m_segment->degree();i++ ) + { + m_segment->selectPoint( i, i == uint( m_firstControl ? 0 : 1 ) ); + + if( i == uint( m_firstControl ? 0 : 1 ) ) + m_segment->setPoint( i, m_segment->point( i ).transform( m_mat.invert() ) ); + } + + if( m_segmenttwo ) + { + uint index = m_firstControl ? 1 : 0; + for( uint i = 0;i < m_segmenttwo->degree();i++ ) + { + m_segmenttwo->selectPoint( i, i == index ); + + if( i == index ) + m_segmenttwo->setPoint( i, m_segmenttwo->point( i ).transform( m2.invert() ) ); + } + } + } + setSuccess( false ); +} + +void +VTranslateBezierCmd::visitVSubpath( VSubpath& path ) +{ + if( m_subpath ) + return; + + VSegment* segment = path.first(); + + // check all segments of the path + while( segment ) + { + if( segment == m_segment ) + { + m_subpath = &path; + break; + } + segment = segment->next(); + } +} + +VTranslatePointCmd::VTranslatePointCmd( VDocument *doc, double d1, double d2 ) + : VCommand( doc, i18n( "Translate Points" ), "translate" ) +{ + m_mat.translate( d1, d2 ); + + if( document() && document()->selection() ) + { + VObjectListIterator itr( document()->selection()->objects() ); + + // collect all points to translate + for( ; itr.current() ; ++itr ) + visit( *itr.current() ); + + if( m_segPnts.size() > 1 || ( m_segPnts.size() == 0 && m_segPnts.begin().data().size() > 1 ) ) + setName( i18n( "Translate Point" ) ); + } +} + +VTranslatePointCmd::~VTranslatePointCmd() +{ +} + +void +VTranslatePointCmd::execute() +{ + translatePoints(); + setSuccess( true ); +} + +void +VTranslatePointCmd::unexecute() +{ + m_mat = m_mat.invert(); + translatePoints(); + m_mat = m_mat.invert(); + setSuccess( false ); +} + +void +VTranslatePointCmd::visitVSubpath( VSubpath& path ) +{ + if( path.state() == VObject::hidden || + path.state() == VObject::normal_locked || + path.state() == VObject::hidden_locked ) + return; + + VSegment* segment = path.first(); + + uint segCnt = m_segPnts.size(); + + // save indices of selected points for all segments + while( segment ) + { + QValueVector<int> pnts; + + for( unsigned short i = 0; i < segment->degree(); ++i ) + { + if( segment->pointIsSelected( i ) ) + pnts.push_back( i ); + } + if( pnts.size() ) + m_segPnts[segment] = pnts; + + segment = segment->next(); + } + + // save subpaths which have selected points + if( segCnt != m_segPnts.size() ) + m_subpaths.append( &path ); +} + +void +VTranslatePointCmd::translatePoints() +{ + QMap<VSegment*, QValueVector<int> >::iterator it, et = m_segPnts.end(); + + // iterate over the segments and transform all selected points + for( it = m_segPnts.begin(); it != et; ++it ) + { + VSegment *segment = it.key(); + QValueVector<int> &pnts = it.data(); + + int pntCnt = pnts.size(); + for( int i = 0; i < pntCnt; ++i ) + segment->setPoint( pnts[i], segment->point( pnts[i] ).transform( m_mat ) ); + } + + // invalidate all changed subpaths + VObjectListIterator itr( m_subpaths ); + for( ; itr.current(); ++itr ) + itr.current()->invalidateBoundingBox(); +} diff --git a/karbon/commands/vtransformcmd.h b/karbon/commands/vtransformcmd.h new file mode 100644 index 00000000..daa26950 --- /dev/null +++ b/karbon/commands/vtransformcmd.h @@ -0,0 +1,136 @@ +/* This file is part of the KDE project � + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VTRANSFORMCMD_H__ +#define __VTRANSFORMCMD_H__ + +#include <qvaluevector.h> +#include "vcommand.h" +#include "vgroup.h" +#include <koffice_export.h> +// Transform object(s) with a specified matrix and allow undo. + + +class QWMatrix; +class VPath; +class VSubpath; +class VSegment; +class VSelection; + + +class KARBONCOMMAND_EXPORT VTransformCmd : public VCommand +{ +public: + VTransformCmd( VDocument *doc, const QWMatrix& mat, bool duplicate = false ); + virtual ~VTransformCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual void visitVPath( VPath& composite ); + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVText( VText& text ); + virtual void visitVImage( VImage& img ); + virtual void visitVObject( VObject& object ); + + void setMatrix( const QWMatrix& m ) + { + m_mat = m; + } + +protected: + VTransformCmd( VDocument *doc, const QString& name, const QString& icon, bool duplicate = false ); + + VSelection* m_selection; + VObjectList m_duplicates; + + QWMatrix m_mat; + + bool m_duplicate; +}; + + +class KARBONCOMMAND_EXPORT VTranslateCmd : public VTransformCmd +{ +public: + VTranslateCmd( VDocument *doc, double d1, double d2, bool duplicate = false ); +}; + + +class KARBONCOMMAND_EXPORT VScaleCmd : public VTransformCmd +{ +public: + VScaleCmd( VDocument *doc, const KoPoint& p, double s1, double s2, bool duplicate = false ); +}; + + +class KARBONCOMMAND_EXPORT VShearCmd : public VTransformCmd +{ +public: + VShearCmd( VDocument *doc, const KoPoint& p, double s1, double s2, bool duplicate = false ); +}; + + +class KARBONCOMMAND_EXPORT VRotateCmd : public VTransformCmd +{ +public: + VRotateCmd( VDocument *doc, const KoPoint& p, double angle, bool duplicate = false ); +}; + +class KARBONCOMMAND_EXPORT VTranslateBezierCmd : public VCommand +{ +public: + VTranslateBezierCmd( VDocument *doc, VSegment *segment, double d1, double d2, bool firstControl ); + virtual ~VTranslateBezierCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual void visitVSubpath( VSubpath& path ); + +protected: + QWMatrix m_mat; + VSegment *m_segment; + VSegment *m_segmenttwo; + bool m_firstControl; + VSubpath *m_subpath; +}; + +class KARBONCOMMAND_EXPORT VTranslatePointCmd : public VCommand +{ +public: + VTranslatePointCmd( VDocument *doc, double d1, double d2 ); + virtual ~VTranslatePointCmd(); + + virtual void execute(); + virtual void unexecute(); + + virtual void visitVSubpath( VSubpath& path ); + +protected: + void translatePoints(); + + QWMatrix m_mat; + QMap<VSegment*, QValueVector<int> > m_segPnts; + VObjectList m_subpaths; +}; + +#endif + diff --git a/karbon/commands/vungroupcmd.cc b/karbon/commands/vungroupcmd.cc new file mode 100644 index 00000000..314a873e --- /dev/null +++ b/karbon/commands/vungroupcmd.cc @@ -0,0 +1,99 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vgroup.h" +#include "vungroupcmd.h" +#include "vselection.h" +#include "vdocument.h" +#include "vlayer.h" + +VUnGroupCmd::VUnGroupCmd( VDocument *doc ) + : VCommand( doc, i18n( "Ungroup Objects" ), "14_ungroup" ) +{ + m_group = dynamic_cast<VGroup *>( document()->selection()->objects().getFirst() ); + if( m_group ) + m_objects = m_group->objects(); +} + +VUnGroupCmd::~VUnGroupCmd() +{ +} + +void +VUnGroupCmd::execute() +{ + if( !m_group ) + return; + + document()->selection()->clear(); + + VObjectListIterator itr( m_group->objects() ); + for ( ; itr.current() ; ++itr ) + { + // TODO : remove from corresponding VLayer + document()->selection()->append( itr.current() ); + } + + VGroup* parent; + if( ( parent = dynamic_cast<VGroup*>( m_group->parent() ) ) ) + { + // unregister from parent: + parent->take( *m_group ); + + // inform all objects in this group about their new parent + VObjectListIterator itr = m_group->objects(); + + for ( ; itr.current() ; ++itr ) + { + itr.current()->invalidateBoundingBox(); + parent->append( itr.current() ); + } + + m_group->clear(); + m_group->setState( VObject::deleted ); + } + + setSuccess( true ); +} + +void +VUnGroupCmd::unexecute() +{ + if( !m_group ) + return; + + VObjectListIterator itr( m_objects ); + for ( ; itr.current() ; ++itr ) + { + // TODO : remove from corresponding VLayer + document()->activeLayer()->take( *itr.current() ); + m_group->append( itr.current() ); + } + + m_group->setState( VObject::normal ); + document()->append( m_group ); + document()->selection()->clear(); + document()->selection()->append( m_group ); + + setSuccess( false ); +} + diff --git a/karbon/commands/vungroupcmd.h b/karbon/commands/vungroupcmd.h new file mode 100644 index 00000000..5fb5a40c --- /dev/null +++ b/karbon/commands/vungroupcmd.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VUNGROUPCMD_H__ +#define __VUNGROUPCMD_H__ + +#include "vcommand.h" + +// Group object(s) + +class VGroup; + +class VUnGroupCmd : public VCommand +{ +public: + VUnGroupCmd( VDocument *doc ); + virtual ~VUnGroupCmd(); + + virtual void execute(); + virtual void unexecute(); + +protected: + VObjectList m_objects; + + VGroup* m_group; +}; + +#endif + diff --git a/karbon/commands/vzordercmd.cc b/karbon/commands/vzordercmd.cc new file mode 100644 index 00000000..2839120f --- /dev/null +++ b/karbon/commands/vzordercmd.cc @@ -0,0 +1,172 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> + +#include "vzordercmd.h" +#include "vselection.h" +#include "vdocument.h" +#include "vlayer.h" + +VZOrderCmd::VZOrderCmd( VDocument *doc, VOrder state ) + : VCommand( doc, i18n( "Order Selection" ) ), m_state( state ) +{ + m_selection = document()->selection()->clone(); +} + +VZOrderCmd::VZOrderCmd( VDocument *doc, VObject *obj, VOrder state ) + : VCommand( doc, i18n( "Order Selection" ) ), m_state( state ) +{ + m_selection = new VSelection(); + m_selection->append( obj ); +} + +VZOrderCmd::~VZOrderCmd() +{ + delete( m_selection ); +} + +void +VZOrderCmd::execute() +{ + if( m_state == sendToBack ) + { + VObjectListIterator itr( document()->selection()->objects() ); + for ( itr.toLast() ; itr.current() ; --itr ) + { + // remove from old layer + VObjectList objects; + VLayerListIterator litr( document()->layers() ); + + for ( ; litr.current(); ++litr ) + { + objects = litr.current()->objects(); + VObjectListIterator itr2( objects ); + for ( ; itr2.current(); ++itr2 ) + if( itr2.current() == itr.current() ) + { + litr.current()->sendToBack( *itr2.current() ); + itr2.current()->setState( VObject::selected ); + } + } + } + } + else if( m_state == bringToFront ) + { + VObjectListIterator itr( document()->selection()->objects() ); + for ( ; itr.current() ; ++itr ) + { + // remove from old layer + VObjectList objects; + VLayerListIterator litr( document()->layers() ); + + for ( ; litr.current(); ++litr ) + { + objects = litr.current()->objects(); + VObjectListIterator itr2( objects ); + for ( ; itr2.current(); ++itr2 ) + if( itr2.current() == itr.current() ) + { + litr.current()->bringToFront( *itr2.current() ); + itr2.current()->setState( VObject::selected ); + } + } + } + } + else if( m_state == up || m_state == down ) + { + VSelection selection = *m_selection; + // TODO : this doesn't work for objects inside groups! + VLayerListIterator litr( document()->layers() ); + while( !selection.objects().isEmpty() && litr.current() ) + { + for ( ; litr.current(); ++litr ) + { + if( litr.current()->state() == VObject::deleted ) + continue; + VObjectList objects = litr.current()->objects(); + VObjectList todo; + VObjectListIterator objectItr( objects ); + // find all selected VObjects that are in the current layer + for ( ; objectItr.current(); ++objectItr ) + { + VObjectListIterator selectionItr( selection.objects() ); + for ( ; selectionItr.current() ; ++selectionItr ) + { + if( objectItr.current() == selectionItr.current() ) + { + if( m_state == up ) + todo.prepend( objectItr.current() ); + else + todo.append( objectItr.current() ); + } + } + } + + kdDebug(38000) << "todo.count() : " << todo.count() << endl; + + // we have found the affected vobjects in this vlayer + VObjectListIterator todoItr( todo ); + for ( ; todoItr.current(); ++todoItr ) + { + if( m_state == up ) + litr.current()->upwards( *todoItr.current() ); + else + litr.current()->downwards( *todoItr.current() ); + // remove from selection + selection.take( *todoItr.current() ); + // make sure object stays selected + todoItr.current()->setState( VObject::selected ); + } + } + } + } + setSuccess( true ); +} + +void +VZOrderCmd::unexecute() +{ + if( m_state == sendToBack ) + { + m_state = bringToFront; + execute(); + m_state = sendToBack; + } + else if( m_state == bringToFront ) + { + m_state = sendToBack; + execute(); + m_state = bringToFront; + } + else if( m_state == up ) + { + m_state = down; + execute(); + m_state = up; + } + else if( m_state == down ) + { + m_state = up; + execute(); + m_state = down; + } + setSuccess( false ); +} + diff --git a/karbon/commands/vzordercmd.h b/karbon/commands/vzordercmd.h new file mode 100644 index 00000000..b2ca9a94 --- /dev/null +++ b/karbon/commands/vzordercmd.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VZORDERCMD_H__ +#define __VZORDERCMD_H__ + +#include "vcommand.h" + +class VSelection; + +/** + * Command that changes the z-order of the selection within a layer + * to front, back, one step up, or one step down. + */ +class VZOrderCmd : public VCommand +{ +public: + enum VOrder + { + bringToFront = 0, + up = 1, + down = 2, + sendToBack = 3 + }; + + VZOrderCmd( VDocument* doc, VOrder ); + VZOrderCmd( VDocument* doc, VObject *obj, VOrder ); + virtual ~VZOrderCmd(); + + virtual void execute(); + virtual void unexecute(); + virtual bool isExecuted() { return true; } + +protected: + VSelection *m_selection; + VOrder m_state; +}; + +#endif + |