karbon

vgroup.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2001, 2002, 2003 The Karbon Developers
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 #include <qdom.h>
00025 
00026 #include <KoStore.h>
00027 #include <KoXmlWriter.h>
00028 #include <KoOasisLoadingContext.h>
00029 #include <KoStyleStack.h>
00030 #include <KoXmlNS.h>
00031 
00032 #include "vcomposite.h"
00033 #include "shapes/vellipse.h"
00034 #include "shapes/vrectangle.h"
00035 #include "shapes/vsinus.h"
00036 #include "shapes/vspiral.h"
00037 #include "shapes/vstar.h"
00038 #include "shapes/vpolyline.h"
00039 #include "shapes/vpolygon.h"
00040 #include "vfill.h"
00041 #include "vgroup.h"
00042 #include "vlayer.h"
00043 #include "vimage.h"
00044 #include "vstroke.h"
00045 #include "vvisitor.h"
00046 #include "vclipgroup.h"
00047 #ifdef HAVE_KARBONTEXT
00048 #include "vtext.h"
00049 #endif
00050 
00051 #include <kdebug.h>
00052 
00053 
00054 VGroup::VGroup( VObject* parent, VState state )
00055     : VObject( parent, state )
00056 {
00057     m_stroke = new VStroke( this );
00058     m_fill = new VFill();
00059 }
00060 
00061 VGroup::VGroup( const VGroup& group )
00062     : VObject( group )
00063 {
00064     m_stroke = new VStroke( *group.m_stroke );
00065     m_stroke->setParent( this );
00066     m_fill = new VFill( *group.m_fill );
00067 
00068     VObjectListIterator itr = group.m_objects;
00069     for ( ; itr.current() ; ++itr )
00070         append( itr.current()->clone() );
00071 }
00072 
00073 VGroup::~VGroup()
00074 {
00075     VObjectListIterator itr = m_objects;
00076     for ( ; itr.current(); ++itr )
00077     {
00078         delete( itr.current() );
00079     }
00080 }
00081 
00082 void
00083 VGroup::draw( VPainter* painter, const KoRect* rect ) const
00084 {
00085     if(
00086         state() == deleted ||
00087         state() == hidden ||
00088         state() == hidden_locked )
00089     {
00090         return;
00091     }
00092 
00093     VObjectListIterator itr = m_objects;
00094 
00095     for ( ; itr.current(); ++itr )
00096         itr.current()->draw( painter, rect );
00097 }
00098 
00099 const KoRect&
00100 VGroup::boundingBox() const
00101 {
00102     if( m_boundingBoxIsInvalid )
00103     {
00104         // clear:
00105         m_boundingBox = KoRect();
00106 
00107         VObjectListIterator itr = m_objects;
00108         for( ; itr.current(); ++itr )
00109         {
00110             m_boundingBox |= itr.current()->boundingBox();
00111         }
00112 
00113         m_boundingBoxIsInvalid = false;
00114     }
00115 
00116     return m_boundingBox;
00117 }
00118 
00119 VGroup*
00120 VGroup::clone() const
00121 {
00122     return new VGroup( *this );
00123 }
00124 
00125 void
00126 VGroup::setFill( const VFill& fill )
00127 {
00128     VObjectListIterator itr = m_objects;
00129 
00130     for ( ; itr.current() ; ++itr )
00131         itr.current()->setFill( fill );
00132 
00133     VObject::setFill( fill );
00134 }
00135 
00136 void
00137 VGroup::setStroke( const VStroke& stroke )
00138 {
00139     VObjectListIterator itr = m_objects;
00140 
00141     for ( ; itr.current() ; ++itr )
00142         itr.current()->setStroke( stroke );
00143 
00144     VObject::setStroke( stroke );
00145 }
00146 
00147 void
00148 VGroup::setState( const VState state )
00149 {
00150     VObjectListIterator itr = m_objects;
00151 
00152     for ( ; itr.current() ; ++itr )
00153         if( m_state == VObject::deleted || itr.current()->state() != VObject::deleted )
00154             itr.current()->setState( state );
00155 
00156     VObject::setState( state );
00157 }
00158 
00159 void
00160 VGroup::save( QDomElement& element ) const
00161 {
00162     if( state() != deleted )
00163     {
00164         QDomElement me = element.ownerDocument().createElement( "GROUP" );
00165         element.appendChild( me );
00166 
00167         // save objects:
00168         VObjectListIterator itr = m_objects;
00169 
00170         for ( ; itr.current(); ++itr )
00171             itr.current()->save( me );
00172 
00173         VObject::save( me );
00174     }
00175 }
00176 
00177 void
00178 VGroup::saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const
00179 {
00180     docWriter->startElement( "draw:g" );
00181 
00182     // save objects:
00183     VObjectListIterator itr = m_objects;
00184 
00185     for ( ; itr.current(); ++itr )
00186         itr.current()->saveOasis( store, docWriter, mainStyles, ++index );
00187 
00188     docWriter->endElement();
00189 }
00190 
00191 bool
00192 VGroup::loadOasis( const QDomElement &element, KoOasisLoadingContext &context )
00193 {
00194     m_objects.setAutoDelete( true );
00195     m_objects.clear();
00196     m_objects.setAutoDelete( false );
00197 
00198     QDomNodeList list = element.childNodes();
00199     for( uint i = 0; i < list.count(); ++i )
00200     {
00201         if( list.item( i ).isElement() )
00202         {
00203             QDomElement e = list.item( i ).toElement();
00204 
00205             kdDebug(38000) << "VGroup::loadOasis: e.tagName() = " << e.tagName() << endl;
00206             kdDebug(38000) << "VGroup::loadOasis: e.namespaceURI() = " << e.namespaceURI() << endl;
00207             kdDebug(38000) << "VGroup::loadOasis: e.localName() = " << e.localName() << endl;
00208 
00209             if( e.namespaceURI() != KoXmlNS::draw )
00210                 continue;
00211 
00212             context.styleStack().save();
00213 
00214             if( e.localName() == "path" || e.localName() == "custom-shape" )
00215             {
00216                 VPath* composite = new VPath( this );
00217                 composite->loadOasis( e, context );
00218                 append( composite );
00219             }
00220             else if( e.localName() == "circle" || e.localName() == "ellipse" )
00221             {
00222                 VEllipse* ellipse = new VEllipse( this );
00223                 ellipse->loadOasis( e, context );
00224                 append( ellipse );
00225             }
00226             else if( e.localName() == "rect" )
00227             {
00228                 VRectangle* rectangle = new VRectangle( this );
00229                 rectangle->loadOasis( e, context );
00230                 append( rectangle );
00231             }
00232             else if( e.localName() == "g" )
00233             {
00234                 VGroup* group = new VGroup( this );
00235                 group->loadOasis( e, context );
00236                 append( group );
00237             }
00238             else if( e.localName() == "polyline" || e.localName() == "line" )
00239             {
00240                 VPolyline* polyline = new VPolyline( this );
00241                 polyline->loadOasis( e, context );
00242                 append( polyline );
00243             }
00244             else if( e.localName() == "polygon" )
00245             {
00246                 VPolygon* polygon = new VPolygon( this );
00247                 polygon->loadOasis( e, context );
00248                 append( polygon );
00249             }
00250 
00251             context.styleStack().restore();
00252         }
00253     }
00254 
00255     return true;
00256 }
00257 
00258 void
00259 VGroup::load( const QDomElement& element )
00260 {
00261     m_objects.setAutoDelete( true );
00262     m_objects.clear();
00263     m_objects.setAutoDelete( false );
00264 
00265     VObject::load( element );
00266 
00267     QDomNodeList list = element.childNodes();
00268     for( uint i = 0; i < list.count(); ++i )
00269     {
00270         if( list.item( i ).isElement() )
00271         {
00272             QDomElement e = list.item( i ).toElement();
00273 
00274             if( e.tagName() == "COMPOSITE" || e.tagName() == "PATH" ) // TODO : remove COMPOSITE later
00275             {
00276                 VPath* composite = new VPath( this );
00277                 composite->load( e );
00278                 append( composite );
00279             }
00280             else if( e.tagName() == "ELLIPSE" )
00281             {
00282                 VEllipse* ellipse = new VEllipse( this );
00283                 ellipse->load( e );
00284                 append( ellipse );
00285             }
00286             else if( e.tagName() == "RECT" )
00287             {
00288                 VRectangle* rectangle = new VRectangle( this );
00289                 rectangle->load( e );
00290                 append( rectangle );
00291             }
00292             else if( e.tagName() == "POLYLINE" )
00293             {
00294                 VPolyline* polyline = new VPolyline( this );
00295                 polyline->load( e );
00296                 append( polyline );
00297             }
00298             else if( e.tagName() == "POLYGON" )
00299             {
00300                 VPolygon* polygon = new VPolygon( this );
00301                 polygon->load( e );
00302                 append( polygon );
00303             }
00304             else if( e.tagName() == "SINUS" )
00305             {
00306                 VSinus* sinus = new VSinus( this );
00307                 sinus->load( e );
00308                 append( sinus );
00309             }
00310             else if( e.tagName() == "SPIRAL" )
00311             {
00312                 VSpiral* spiral = new VSpiral( this );
00313                 spiral->load( e );
00314                 append( spiral );
00315             }
00316             else if( e.tagName() == "STAR" )
00317             {
00318                 VStar* star = new VStar( this );
00319                 star->load( e );
00320                 append( star );
00321             }
00322             else if( e.tagName() == "GROUP" )
00323             {
00324                 VGroup* group = new VGroup( this );
00325                 group->load( e );
00326                 append( group );
00327             }
00328             else if( e.tagName() == "CLIP" )
00329             {
00330                 VClipGroup* grp = new VClipGroup( this );
00331                 grp->load( e );
00332                 append( grp );
00333             }
00334             else if( e.tagName() == "IMAGE" )
00335             {
00336                 VImage* img = new VImage( this );
00337                 img->load( e );
00338                 append( img );
00339             }
00340             else if( e.tagName() == "TEXT" )
00341             {
00342 #ifdef HAVE_KARBONTEXT
00343                 VText *text = new VText( this );
00344                 text->load( e );
00345                 append( text );
00346 #endif
00347             }
00348         }
00349     }
00350 }
00351 
00352 void
00353 VGroup::accept( VVisitor& visitor )
00354 {
00355     visitor.visitVGroup( *this );
00356 }
00357 
00358 
00359 void
00360 VGroup::take( const VObject& object )
00361 {
00362     m_objects.removeRef( &object );
00363 
00364     invalidateBoundingBox();
00365 }
00366 
00367 void
00368 VGroup::append( VObject* object )
00369 {
00370     object->setParent( this );
00371 
00372     m_objects.append( object );
00373 
00374     invalidateBoundingBox();
00375 }
00376 
00377 void
00378 VGroup::insertInfrontOf( VObject* newObject, VObject* oldObject )
00379 {
00380     newObject->setParent( this );
00381 
00382     m_objects.insert( m_objects.find( oldObject ), newObject );
00383 
00384     invalidateBoundingBox();
00385 }
00386 
00387 void
00388 VGroup::clear()
00389 {
00390     m_objects.clear();
00391 
00392     invalidateBoundingBox();
00393 }
00394 
KDE Home | KDE Accessibility Home | Description of Access Keys