summaryrefslogtreecommitdiffstats
path: root/karbon/commands
diff options
context:
space:
mode:
Diffstat (limited to 'karbon/commands')
-rw-r--r--karbon/commands/Makefile.am55
-rw-r--r--karbon/commands/valigncmd.cc87
-rw-r--r--karbon/commands/valigncmd.h54
-rw-r--r--karbon/commands/vbooleancmd.cc240
-rw-r--r--karbon/commands/vbooleancmd.h82
-rw-r--r--karbon/commands/vcleanupcmd.cc58
-rw-r--r--karbon/commands/vcleanupcmd.h45
-rw-r--r--karbon/commands/vclipartcmd.cc65
-rw-r--r--karbon/commands/vclipartcmd.h43
-rw-r--r--karbon/commands/vclosepathcmd.cc36
-rw-r--r--karbon/commands/vclosepathcmd.h37
-rw-r--r--karbon/commands/vcommand.cc384
-rw-r--r--karbon/commands/vcommand.h318
-rw-r--r--karbon/commands/vdeletecmd.cc74
-rw-r--r--karbon/commands/vdeletecmd.h48
-rw-r--r--karbon/commands/vdeletenodescmd.cc77
-rw-r--r--karbon/commands/vdeletenodescmd.h46
-rw-r--r--karbon/commands/vdistributecmd.cc198
-rw-r--r--karbon/commands/vdistributecmd.h58
-rw-r--r--karbon/commands/vfillcmd.cc123
-rw-r--r--karbon/commands/vfillcmd.h62
-rw-r--r--karbon/commands/vflattencmd.cc82
-rw-r--r--karbon/commands/vflattencmd.h40
-rw-r--r--karbon/commands/vgroupcmd.cc100
-rw-r--r--karbon/commands/vgroupcmd.h50
-rw-r--r--karbon/commands/vinsertcmd.cc83
-rw-r--r--karbon/commands/vinsertcmd.h49
-rw-r--r--karbon/commands/vlayercmd.cc86
-rw-r--r--karbon/commands/vlayercmd.h59
-rw-r--r--karbon/commands/vreplacingcmd.cc145
-rw-r--r--karbon/commands/vreplacingcmd.h55
-rw-r--r--karbon/commands/vshapecmd.cc71
-rw-r--r--karbon/commands/vshapecmd.h51
-rw-r--r--karbon/commands/vstrokecmd.cc193
-rw-r--r--karbon/commands/vstrokecmd.h69
-rw-r--r--karbon/commands/vtextcmd.cc40
-rw-r--r--karbon/commands/vtextcmd.h46
-rw-r--r--karbon/commands/vtransformcmd.cc491
-rw-r--r--karbon/commands/vtransformcmd.h136
-rw-r--r--karbon/commands/vungroupcmd.cc99
-rw-r--r--karbon/commands/vungroupcmd.h46
-rw-r--r--karbon/commands/vzordercmd.cc172
-rw-r--r--karbon/commands/vzordercmd.h56
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
+