diff options
Diffstat (limited to 'karbon/visitors')
-rw-r--r-- | karbon/visitors/Makefile.am | 28 | ||||
-rw-r--r-- | karbon/visitors/vcomputeboundingbox.cc | 110 | ||||
-rw-r--r-- | karbon/visitors/vcomputeboundingbox.h | 58 | ||||
-rw-r--r-- | karbon/visitors/vdrawselection.cc | 174 | ||||
-rw-r--r-- | karbon/visitors/vdrawselection.h | 46 | ||||
-rw-r--r-- | karbon/visitors/vselectiondesc.cc | 62 | ||||
-rw-r--r-- | karbon/visitors/vselectiondesc.h | 54 | ||||
-rw-r--r-- | karbon/visitors/vselectnodes.cc | 153 | ||||
-rw-r--r-- | karbon/visitors/vselectnodes.h | 71 | ||||
-rw-r--r-- | karbon/visitors/vselectobjects.cc | 273 | ||||
-rw-r--r-- | karbon/visitors/vselectobjects.h | 71 | ||||
-rw-r--r-- | karbon/visitors/vtransformnodes.cc | 76 | ||||
-rw-r--r-- | karbon/visitors/vtransformnodes.h | 43 |
13 files changed, 1219 insertions, 0 deletions
diff --git a/karbon/visitors/Makefile.am b/karbon/visitors/Makefile.am new file mode 100644 index 00000000..60bc3caa --- /dev/null +++ b/karbon/visitors/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = \ + $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../core \ + -I$(srcdir)/../tools \ + -I$(srcdir)/../render \ + $(LIBFREETYPE_CFLAGS) $(all_includes) + +noinst_LTLIBRARIES = libkarbonvisitors.la + +noinst_HEADERS = \ + vselectnodes.h \ + vselectobjects.h \ + vdrawselection.h \ + vselectiondesc.h \ + vtransformnodes.h \ + vcomputeboundingbox.h + +libkarbonvisitors_la_SOURCES = \ + vselectnodes.cc \ + vselectobjects.cc \ + vdrawselection.cc \ + vselectiondesc.cc \ + vtransformnodes.cc \ + vcomputeboundingbox.cc + +libkarbonvisitors_la_METASOURCES = \ + AUTO diff --git a/karbon/visitors/vcomputeboundingbox.cc b/karbon/visitors/vcomputeboundingbox.cc new file mode 100644 index 00000000..e303a2f9 --- /dev/null +++ b/karbon/visitors/vcomputeboundingbox.cc @@ -0,0 +1,110 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Jan Hambrecht <jaham@gmx.net> + + 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 "vcomputeboundingbox.h" +#include "vdocument.h" +#include "vlayer.h" +#include "vgroup.h" +#include "vcomposite.h" +#include "vtext.h" +#include "vimage.h" + +VComputeBoundingBox::VComputeBoundingBox( bool omitHidden ) +: m_omitHidden( omitHidden ) +{ +} + +void +VComputeBoundingBox::visitVDocument( VDocument& document ) +{ + VLayerListIterator itr( document.layers() ); + + for( ; itr.current(); ++itr ) + { + if( itr.current()->state() == VObject::deleted ) + continue; + // do not use hidden layers + if( m_omitHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +VComputeBoundingBox::visitVLayer( VLayer& layer ) +{ + VObjectListIterator itr( layer.objects() ); + + for( ; itr.current(); ++itr ) + { + if( itr.current()->state() == VObject::deleted ) + continue; + // do not export hidden objects + if( m_omitHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +VComputeBoundingBox::visitVGroup( VGroup& group ) +{ + VObjectListIterator itr( group.objects() ); + + for( ; itr.current(); ++itr ) + { + if( itr.current()->state() == VObject::deleted ) + continue; + // do not use hidden child objects + if( m_omitHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +VComputeBoundingBox::visitVPath( VPath& composite ) +{ + m_boundingBox |= composite.boundingBox(); +} + +void +VComputeBoundingBox::visitVText( VText& text ) +{ + m_boundingBox |= text.boundingBox(); +} + +void +VComputeBoundingBox::visitVImage( VImage& img ) +{ + m_boundingBox |= img.boundingBox(); +} + +bool +VComputeBoundingBox::isVisible( const VObject* object ) const +{ + return object->state() != VObject::hidden && object->state() != VObject::hidden_locked; +} + +const KoRect& +VComputeBoundingBox::boundingRect() const +{ + return m_boundingBox; +} diff --git a/karbon/visitors/vcomputeboundingbox.h b/karbon/visitors/vcomputeboundingbox.h new file mode 100644 index 00000000..437b1125 --- /dev/null +++ b/karbon/visitors/vcomputeboundingbox.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Jan Hambrecht <jaham@gmx.net> + + 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 __VCOMPUTEBOUNDINGBOX_H__ +#define __VCOMPUTEBOUNDINGBOX_H__ + +#include "KoRect.h" +#include "vvisitor.h" + +class VDocument; +class VLayer; +class VGroup; +class VPath; +class VText; +class VImage; + +/** + * This visitor visits objects and calculates the combined bounding box of the + * objects and their child objects. + */ +class VComputeBoundingBox : public VVisitor +{ +public: + VComputeBoundingBox( bool omitHidden = false ); + + virtual void visitVDocument( VDocument& document ); + virtual void visitVLayer( VLayer& layer ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVPath( VPath& composite ); + virtual void visitVText( VText& text ); + virtual void visitVImage( VImage& img ); + + const KoRect& boundingRect() const; +private: + bool isVisible( const VObject* object ) const; + + KoRect m_boundingBox; + bool m_omitHidden; +}; + +#endif // __VCOMPUTEBOUNDINGBOX_H__ + diff --git a/karbon/visitors/vdrawselection.cc b/karbon/visitors/vdrawselection.cc new file mode 100644 index 00000000..ad597027 --- /dev/null +++ b/karbon/visitors/vdrawselection.cc @@ -0,0 +1,174 @@ +/* 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 "vdrawselection.h" +#include "vcomposite.h" +#include "vsegment.h" +#include "vcolor.h" +#include "vstroke.h" +#include "vpainter.h" +#include "vpath.h" + +void +VDrawSelection::visitVPath( VPath &composite ) +{ + if( + composite.state() == VObject::deleted || + composite.state() == VObject::hidden || + composite.state() == VObject::hidden_locked ) + { + return; + } + + + m_painter->save(); + m_painter->setPen( Qt::SolidLine ); + + const bool editnodes = composite.state() == VObject::edit && m_nodeediting; + + VSubpathListIterator itr( composite.paths() ); + + if( + composite.state() == VObject::selected || + editnodes ) + { + // paint fill: + m_painter->newPath(); + + if( editnodes ) + m_painter->setRasterOp( Qt::XorROP ); + + m_painter->setPen( editnodes ? Qt::yellow : Qt::blue ); + m_painter->setBrush( Qt::NoBrush ); + + for( itr.toFirst(); itr.current(); ++itr ) + { + VSubpathIterator jtr( *( itr.current() ) ); + + for( ; jtr.current(); ++jtr ) + { + jtr.current()->draw( m_painter ); + } + + m_painter->strokePath(); + } + } + + // Draw nodes and control lines. + if( + composite.state() == VObject::selected || + editnodes ) + { + itr.toFirst(); + //++itr; // Skip "begin". + + for( ; itr.current(); ++itr ) + { + if( (*itr)->isEmpty() ) + continue; + VSubpathIterator jtr( *( itr.current() ) ); + //++jtr; + + for( ; jtr.current(); ++jtr ) + { + if( editnodes ) + m_painter->setRasterOp( Qt::XorROP ); + + VColor color; + color.set( 0.5, 0.5, 1.0 ); + + VStroke stroke( color ); + stroke.setLineWidth( 1.0 ); + + if( !editnodes ) + { + m_painter->setPen( stroke ); + m_painter->setPen( Qt::blue ); + } + else + m_painter->setPen( Qt::yellow ); + + m_painter->setBrush( Qt::NoBrush ); + + if( ( editnodes || composite.state() == VObject::selected && m_nodeediting ) && + jtr.current()->isCurve() ) + { + VSegment* curr = jtr.current(); + VSegment* next = curr->next(); + VSegment* prev = curr->prev(); + + // Draw control lines. + if ( curr->pointIsSelected( curr->degree()-2 ) || curr->knotIsSelected() + || ( next && next->isCurve() && next->pointIsSelected( 0 ) && curr->isSmooth() ) ) + { + m_painter->newPath(); + m_painter->moveTo( curr->point( curr->degree()-2 ) ); + m_painter->lineTo( curr->knot() ); + m_painter->strokePath(); + // Draw control node2: + m_painter->newPath(); + m_painter->setBrush( editnodes ? Qt::yellow : Qt::blue ); + m_painter->drawNode( curr->point( curr->degree()-2 ), m_nodeSize ); + m_painter->strokePath(); + } + + if ( prev && ( ( prev->knotIsSelected() || curr->pointIsSelected( 0 ) ) + || ( prev->isCurve() && prev->pointIsSelected( prev->degree()-2 ) && prev->isSmooth() ) ) ) + { + m_painter->newPath(); + m_painter->moveTo( prev->knot() ); + m_painter->lineTo( curr->point( 0 ) ); + m_painter->strokePath(); + // Draw control node1: + m_painter->newPath(); + m_painter->setBrush( editnodes ? Qt::yellow : Qt::blue ); + m_painter->drawNode( curr->point( 0 ), m_nodeSize ); + m_painter->strokePath(); + } + } + + // Draw knot. + m_painter->setPen( editnodes ? Qt::yellow : Qt::blue ); + + if( !m_nodeediting ) + m_painter->setBrush( Qt::blue ); + else if( jtr.current()->knotIsSelected() ) + m_painter->setBrush( editnodes ? Qt::yellow : Qt::blue ); + else + m_painter->setBrush( Qt::white ); + + m_painter->drawNode( jtr.current()->knot(), m_nodeSize ); + } + } + } + + // Draw center node. + if( composite.drawCenterNode() && composite.state() == VObject::selected && !m_nodeediting ) + { + m_painter->setPen( Qt::NoPen ); + m_painter->setBrush( Qt::blue.light() ); + m_painter->drawNode( composite.boundingBox().center(), m_nodeSize ); + } + + m_painter->restore(); + + setSuccess(); +} + diff --git a/karbon/visitors/vdrawselection.h b/karbon/visitors/vdrawselection.h new file mode 100644 index 00000000..535d9184 --- /dev/null +++ b/karbon/visitors/vdrawselection.h @@ -0,0 +1,46 @@ +/* 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 __VDRAWSELECTION_H__ +#define __VDRAWSELECTION_H__ + +#include "vgroup.h" +#include "vvisitor.h" +#include <koffice_export.h> +/** + * Helper class to draw the outline of a composite path, including (?) + * optionally its bezier helper lines, depending on the state. + */ +class KARBONBASE_EXPORT VDrawSelection : public VVisitor +{ +public: + VDrawSelection( const VObjectList& selection, VPainter *painter, bool nodeediting = false, uint nodeSize = 2 ) + : m_selection( selection ), m_painter( painter ), m_nodeediting( nodeediting ), m_nodeSize( nodeSize ) {} + + virtual void visitVPath( VPath& composite ); + +private: + VObjectList m_selection; + VPainter *m_painter; + bool m_nodeediting; + uint m_nodeSize; +}; + +#endif + diff --git a/karbon/visitors/vselectiondesc.cc b/karbon/visitors/vselectiondesc.cc new file mode 100644 index 00000000..0036f31c --- /dev/null +++ b/karbon/visitors/vselectiondesc.cc @@ -0,0 +1,62 @@ +/* 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 "vselectiondesc.h" +#include "vselection.h" +#include "vgroup.h" +#include "vtext.h" +#include "vimage.h" +#include "vcomposite.h" +#include <kdebug.h> +#include <klocale.h> + +void +VSelectionDescription::visitVSelection( VSelection& selection ) +{ + if( selection.objects().count() == 1 ) + VVisitor::visitVSelection( selection ); + else + m_desc = i18n( "One object", "%n objects", selection.objects().count() ); +} + +void +VSelectionDescription::visitVPath( VPath& composite ) +{ + m_desc = m_shortdesc = !composite.name().isEmpty() ? composite.name() : i18n( "path" ); +} + +void +VSelectionDescription::visitVGroup( VGroup &group ) +{ + m_desc = i18n( "One group, containing one object", "One group, containing %n objects", group.objects().count() ); + m_shortdesc = !group.name().isEmpty() ? group.name() : i18n( "group" ); +} + +void +VSelectionDescription::visitVText( VText &text ) +{ + m_desc = m_shortdesc = !text.name().isEmpty() ? text.name() : i18n( "text" ); +} + +void +VSelectionDescription::visitVImage( VImage &img ) +{ + m_desc = m_shortdesc = !img.name().isEmpty() ? img.name() : i18n( "image" ); +} + diff --git a/karbon/visitors/vselectiondesc.h b/karbon/visitors/vselectiondesc.h new file mode 100644 index 00000000..c019c107 --- /dev/null +++ b/karbon/visitors/vselectiondesc.h @@ -0,0 +1,54 @@ +/* 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 __VSELECTIONDESC_H__ +#define __VSELECTIONDESC_H__ + +#include "vvisitor.h" +#include <qstring.h> +#include <koffice_export.h> +/** + * This visitors visits structures and tries to capture relevant object type info + * as text. There are two methods, one creates a large description like "(1 group, containing + * 2 objects)", and a short description giving object id, or if there is no object id just the + * object type, like group/path/text etc. + * + * These texts are primarily meant for statusbar messages and object trees. + */ +class KARBONBASE_EXPORT VSelectionDescription : public VVisitor +{ +public: + VSelectionDescription() { m_desc = ""; m_shortdesc = ""; } + + virtual void visitVSelection( VSelection& ); + virtual void visitVGroup( VGroup& ); + virtual void visitVPath( VPath& ); + virtual void visitVText( VText& ); + virtual void visitVImage( VImage& ); + + QString description() { return m_desc; } + QString shortDescription() { return m_shortdesc; } + +private: + QString m_desc; + QString m_shortdesc; +}; + +#endif + diff --git a/karbon/visitors/vselectnodes.cc b/karbon/visitors/vselectnodes.cc new file mode 100644 index 00000000..00f56de3 --- /dev/null +++ b/karbon/visitors/vselectnodes.cc @@ -0,0 +1,153 @@ +/* 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 "vpath.h" +#include "vsegment.h" +#include "vselectnodes.h" +#include "vlayer.h" +#include "vdocument.h" + +void +VSelectNodes::visitVSubpath( VSubpath& path ) +{ + path.first(); + + VSegment *curr = path.current(); + + while( curr ) + { + if( m_rect.isEmpty() ) + { + for( int i = 0; i < curr->degree(); i++ ) + curr->selectPoint( i, m_select ); + + setSuccess(); + } + else + { + if( m_exclusive ) + { + // we are in exclusive mode, so deselect all nodes first + for( int i = 0; i < curr->degree(); i++ ) + curr->selectPoint( i, false ); + } + + if( curr->isCurve() ) + { + // select all control points inside the selection rect + for( int i = 0; i < curr->degree()-1; ++i ) + { + if( m_rect.contains( curr->point( i ) ) ) + { + curr->selectPoint( i, m_select ); + setSuccess(); + } + } + VSegment* prev = curr->prev(); + // make sure the last control point of the previous segment and the first control point + // of the current segment are selected if: + // - both segments are curves with a smooth transition and + // - the previous segment's knot is selected or + // - one of the above mentioned control points is already selected + if( prev ) + { + if( curr->pointIsSelected( 0 ) == m_select ) + { + if( prev->isCurve() && prev->isSmooth() ) + prev->selectPoint( prev->degree()-2, m_select ); + } + else + { + if( prev->knotIsSelected() || ( prev->isCurve() && prev->isSmooth() && prev->pointIsSelected( prev->degree()-2 ) ) ) + curr->selectPoint( 0, m_select ); + } + } + } + + if( m_rect.contains( curr->knot() ) ) + { + curr->selectKnot( m_select ); + // select the last control point before the knot, if segment is curve + if( curr->isCurve() && m_select ) + curr->selectPoint( curr->degree()-2 ); + + setSuccess(); + } + } + curr = curr->next(); + } + // select first node as well + if( path.isClosed() && path.getLast()->knotIsSelected() ) + path.getFirst()->selectKnot( m_select ); +} + +void +VSelectNodes::visitVLayer( VLayer& layer ) +{ + VDocument* doc = (VDocument*)layer.parent(); + if ( ( layer.state() != VObject::deleted ) && + ( ( doc->selectionMode() == VDocument::AllLayers ) || + ( doc->selectionMode() == VDocument::VisibleLayers && ( layer.state() == VObject::normal || layer.state() == VObject::normal_locked ) ) || + ( doc->selectionMode() == VDocument::SelectedLayers && layer.selected() ) || + ( doc->selectionMode() == VDocument::ActiveLayer && doc->activeLayer() == &layer ) ) ) + { + VObjectListIterator itr( layer.objects() ); + for( ; itr.current(); ++itr ) + itr.current()->accept( *this ); + } +} + +void +VTestNodes::visitVSubpath( VSubpath& path ) +{ + path.first(); + + while( path.current() ) + { + for( int i = 0; i < path.current()->degree(); i++ ) + if( m_rect.contains( path.current()->point( i ) ) ) //&& + //path.current()->pointIsSelected( i ) ) + { + m_segments.append( path.current() ); + setSuccess(); + // only add a segment once + break; + } + + path.next(); + } +} + +void +VTestNodes::visitVLayer( VLayer& layer ) +{ + VDocument* doc = (VDocument*)layer.parent(); + if ( ( layer.state() != VObject::deleted ) && + ( ( doc->selectionMode() == VDocument::AllLayers ) || + ( doc->selectionMode() == VDocument::VisibleLayers && ( layer.state() == VObject::normal || layer.state() == VObject::normal_locked ) ) || + ( doc->selectionMode() == VDocument::SelectedLayers && layer.selected() ) || + ( doc->selectionMode() == VDocument::ActiveLayer && doc->activeLayer() == &layer ) ) ) + { + VObjectListIterator itr( layer.objects() ); + for( ; itr.current(); ++itr ) + itr.current()->accept( *this ); + } +} + diff --git a/karbon/visitors/vselectnodes.h b/karbon/visitors/vselectnodes.h new file mode 100644 index 00000000..c4efc93c --- /dev/null +++ b/karbon/visitors/vselectnodes.h @@ -0,0 +1,71 @@ +/* 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 __VSELECTNODES_H__ +#define __VSELECTNODES_H__ + + +#include "KoRect.h" + +#include "vvisitor.h" +#include "vsegment.h" + +class VSelectNodes : public VVisitor +{ +public: + VSelectNodes( bool select = true, bool exclusive = true ) + { + m_select = select; + m_exclusive = exclusive; + } + + VSelectNodes( const KoRect& rect, bool select = true, bool exclusive = true ) + { + m_select = select; + m_exclusive = exclusive; + m_rect = rect; + } + + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVLayer( VLayer& layer ); + +private: + bool m_select; + bool m_exclusive; + KoRect m_rect; +}; + +class VTestNodes : public VVisitor +{ +public: + VTestNodes( const KoRect& rect ) : m_rect( rect ) { m_segments.clear(); } + + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVLayer( VLayer& layer ); + + QPtrList<VSegment> &result() { return m_segments; } + +private: + KoRect m_rect; + QPtrList<VSegment> m_segments; +}; + +#endif + + diff --git a/karbon/visitors/vselectobjects.cc b/karbon/visitors/vselectobjects.cc new file mode 100644 index 00000000..060eeacb --- /dev/null +++ b/karbon/visitors/vselectobjects.cc @@ -0,0 +1,273 @@ +/* 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 "vselectobjects.h" +#include "vlayer.h" +#include "vdocument.h" +#include "vsegment.h" +#include <kdebug.h> + +void +VSelectObjects::visitVPath( VPath& composite ) +{ + // Never select a deleted, locked or hidden object. + if( composite.state() > VObject::normal && + composite.state() < VObject::selected ) + return; + + if( m_rectMode && m_rect.isEmpty() ) // in this mode everything is selected + { + visitVObject( composite ); + return; + } + + bool selected = false; + + if( m_rectMode ) + { + // Check if composite is completely inside the selection rectangle. + // This test should be the first test since it's the less expensive one. + if( m_rect.contains( composite.boundingBox() ) ) + { + selected = true; + } + + // Check if any of the rectangle corners is inside the composite. + // This test should be done before the intersect test since it covers many + // intersection cases. + if( !selected ) + { + if( + composite.pointIsInside( m_rect.topLeft() ) || + composite.pointIsInside( m_rect.topRight() ) || + composite.pointIsInside( m_rect.bottomRight() ) || + composite.pointIsInside( m_rect.bottomLeft() ) ) + { + selected = true; + } + } + + // Check if selection rectangle intersects the composite. + if( !selected ) + { + // Path for holding a helper segment. + VSubpath path( 0L ); + + path.moveTo( m_rect.topLeft() ); + path.lineTo( m_rect.topRight() ); + + if( composite.intersects( *path.getLast() ) ) + { + selected = true; + } + else + { + path.getFirst()->setKnot( m_rect.bottomRight() ); + + if( composite.intersects( *path.getLast() ) ) + { + selected = true; + } + else + { + path.getLast()->setKnot( m_rect.bottomLeft() ); + + if( composite.intersects( *path.getLast() ) ) + { + selected = true; + } + else + { + path.getFirst()->setKnot( m_rect.topLeft() ); + + if( composite.intersects( *path.getLast() ) ) + { + selected = true; + } + } + } + } + } + } + else + { + if( composite.pointIsInside( m_point ) ) + selected = true; + } + + if( selected ) + { + if( m_select ) + { + composite.setState( VObject::selected ); + if( ! m_selection.containsRef( &composite ) ) + m_selection.append( &composite ); + } + else + { + composite.setState( VObject::normal ); + m_selection.remove( &composite ); + } + + setSuccess(); + } +} + +void +VSelectObjects::visitVObject( VObject& object ) +{ + // Never select a deleted, locked or hidden object. + if( object.state() > VObject::normal && + object.state() < VObject::selected ) + return; + + // selection by selection rectangle + if( m_rectMode ) + { + if( !m_rect.isEmpty() ) + { + if( m_select ) + { + if( m_rect.intersects( object.boundingBox() ) ) + { + object.setState( VObject::selected ); + if( ! m_selection.containsRef( &object ) ) + m_selection.append( &object ); + setSuccess(); + } + } + else + { + if( m_rect.intersects( object.boundingBox() ) ) + { + object.setState( VObject::normal ); + m_selection.remove( &object ); + setSuccess(); + } + } + } + else + { + if( m_select ) + { + object.setState( VObject::selected ); + if( ! m_selection.containsRef( &object ) ) + m_selection.append( &object ); + setSuccess(); + } + else + { + object.setState( VObject::normal ); + m_selection.remove( &object ); + setSuccess(); + } + } + } + // selection by point + else + { + if( object.boundingBox().contains( m_point ) ) + { + if( m_select ) + { + object.setState( VObject::selected ); + if( ! m_selection.containsRef( &object ) ) + m_selection.append( &object ); + } + else + { + object.setState( VObject::normal ); + m_selection.remove( &object ); + } + setSuccess(); + } + } + +} + +void +VSelectObjects::visitVLayer( VLayer& layer ) +{ + VDocument* doc = (VDocument*)layer.parent(); + if ( ( layer.state() != VObject::deleted ) && + ( ( doc->selectionMode() == VDocument::AllLayers ) || + ( doc->selectionMode() == VDocument::VisibleLayers && ( layer.state() == VObject::normal || layer.state() == VObject::normal_locked ) ) || + ( doc->selectionMode() == VDocument::SelectedLayers && layer.selected() ) || + ( doc->selectionMode() == VDocument::ActiveLayer && doc->activeLayer() == &layer ) ) ) + { + VObjectListIterator itr( layer.objects() ); + for( ; itr.current(); ++itr ) + itr.current()->accept( *this ); + } +} + +void +VSelectObjects::visitVText( VText& text ) +{ + // Never select a deleted, locked or hidden object. + if( text.state() > VObject::normal && + text.state() < VObject::selected ) + return; + + int deselectedGlyphs = 0; + + VPathListIterator itr( text.glyphs() ); + for( ; itr.current(); ++itr ) + { + VPath c( 0L ); + c.combine( *itr.current() ); + visitVPath( c ); + if( m_select && c.state() == VObject::selected ) + { + kdDebug(38000) << "selected: " << itr.current() << endl; + m_selection.remove( &c ); + text.setState( VObject::selected ); + if( ! m_selection.containsRef( &text ) ) + m_selection.append( &text ); + return; + } + else if( c.state() == VObject::normal ) + { + kdDebug(38000) << "deselected: " << itr.current() << endl; + deselectedGlyphs++; + } + } + if( deselectedGlyphs >= 0 && uint( deselectedGlyphs ) == text.glyphs().count() ) + { + text.setState( VObject::normal ); + m_selection.remove( &text ); + } +} + +void +VSelectObjects::visitVGroup( VGroup& group ) +{ + // Never select a deleted, locked or hidden object. + if( group.state() > VObject::normal && + group.state() < VObject::selected ) + return; + + if( ! m_insideGroups ) + visitVObject( group ); + else + { + VVisitor::visitVGroup( group ); + } +} diff --git a/karbon/visitors/vselectobjects.h b/karbon/visitors/vselectobjects.h new file mode 100644 index 00000000..f42e0ad5 --- /dev/null +++ b/karbon/visitors/vselectobjects.h @@ -0,0 +1,71 @@ +/* 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 __VSELECTOBJECTS_H__ +#define __VSELECTOBJECTS_H__ + + +#include "KoRect.h" + +#include "vcomposite.h" +#include "vgroup.h" +#include "vtext.h" +#include "vimage.h" +#include "vvisitor.h" + +/** + * This visitor visits a selection and selects objects that are contained + * in a paramater selection rectangle. For composites it makes a more accurate test, if the + * selection rectangle intersects with any part of the composite, it is selected. + * Also this visitor can be used to deselect objects. + */ +class VSelectObjects : public VVisitor +{ +public: + VSelectObjects( VObjectList& selection, bool select = true ) + : m_selection( selection ), m_select( select ), m_rectMode( true ), m_insideGroups( false ) {} + + VSelectObjects( VObjectList& selection, const KoRect& rect, bool select = true ) + : m_selection( selection ), m_select( select ), m_rect( rect ), m_rectMode( true ), m_insideGroups( false ) { } + + VSelectObjects( VObjectList& selection, const KoPoint& point, bool select = true, bool insideGroups = false ) + : m_selection( selection ), m_select( select ), m_point( point ), m_rectMode( false ), m_insideGroups( insideGroups ) {} + + virtual void visitVGroup( VGroup& group ); + virtual void visitVPath( VPath& composite ); + virtual void visitVText( VText& text ); + virtual void visitVImage( VImage& img ) + { visitVObject( img ); } + virtual void visitVLayer( VLayer& layer ); + +private: + void visitVObject( VObject& object ); + + VObjectList& m_selection; + + bool m_select; + + KoRect m_rect; + KoPoint m_point; + bool m_rectMode; + bool m_insideGroups; +}; + +#endif + diff --git a/karbon/visitors/vtransformnodes.cc b/karbon/visitors/vtransformnodes.cc new file mode 100644 index 00000000..ed670538 --- /dev/null +++ b/karbon/visitors/vtransformnodes.cc @@ -0,0 +1,76 @@ +/* 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 "vpath.h" +#include "vsegment.h" +#include "vtransformnodes.h" + + +VTransformNodes::VTransformNodes( const QWMatrix& m ) + : m_matrix( m ) +{ +} + +void +VTransformNodes::visitVSubpath( VSubpath& path ) +{ + path.first(); + while( path.current() ) + { + if( path.current()->isCurve() ) + { + if( !path.current()->knotIsSelected() && + path.current()->pointIsSelected( 1 ) && + path.current()->next() && + path.current()->next()->isCurve() && + !path.current()->next()->pointIsSelected( 0 ) && + path.current()->isSmooth() ) + { + // Do extra reverse trafo for smooth beziers + QWMatrix m2( m_matrix.m11(), m_matrix.m12(), m_matrix.m21(), m_matrix.m22(), + -m_matrix.dx(), -m_matrix.dy() ); + path.current()->next()->setPoint( 0, path.current()->next()->point( 0 ).transform( m2 ) ); + } + if( path.current()->pointIsSelected( 0 ) && + path.current()->prev() && + path.current()->prev()->isCurve() && + !path.current()->prev()->knotIsSelected() && + !path.current()->prev()->pointIsSelected( 1 ) && + path.current()->prev()->isSmooth() ) + { + // Do extra reverse trafo for smooth beziers + QWMatrix m2( m_matrix.m11(), m_matrix.m12(), m_matrix.m21(), m_matrix.m22(), + -m_matrix.dx(), -m_matrix.dy() ); + path.current()->prev()->setPoint( 1, path.current()->prev()->point( 1 ).transform( m2 ) ); + } + } + + for( uint i = 0; i < path.current()->degree(); ++i ) + { + if( path.current()->pointIsSelected( i ) ) + path.current()->setPoint( i, path.current()->point( i ).transform( m_matrix ) ); + } + + if( !success() ) + setSuccess(); + path.next(); + } +} + diff --git a/karbon/visitors/vtransformnodes.h b/karbon/visitors/vtransformnodes.h new file mode 100644 index 00000000..5c384e61 --- /dev/null +++ b/karbon/visitors/vtransformnodes.h @@ -0,0 +1,43 @@ +/* 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 __VTRANSFORMNODES_H__ +#define __VTRANSFORMNODES_H__ + +#include <qwmatrix.h> +#include <koffice_export.h> +#include "vvisitor.h" + + +class VSegment; + + +class KARBONBASE_EXPORT VTransformNodes : public VVisitor +{ +public: + VTransformNodes( const QWMatrix& m ); + + virtual void visitVSubpath( VSubpath& path ); + +private: + QWMatrix m_matrix; +}; + +#endif + |