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     // do not save deleted objects
00181     if( state() == deleted )
00182         return;
00183 
00184     docWriter->startElement( "draw:g" );
00185 
00186     // save objects:
00187     VObjectListIterator itr = m_objects;
00188 
00189     for ( ; itr.current(); ++itr )
00190         itr.current()->saveOasis( store, docWriter, mainStyles, ++index );
00191 
00192     docWriter->endElement();
00193 }
00194 
00195 bool
00196 VGroup::loadOasis( const QDomElement &element, KoOasisLoadingContext &context )
00197 {
00198     m_objects.setAutoDelete( true );
00199     m_objects.clear();
00200     m_objects.setAutoDelete( false );
00201 
00202     QDomNodeList list = element.childNodes();
00203     for( uint i = 0; i < list.count(); ++i )
00204     {
00205         if( list.item( i ).isElement() )
00206         {
00207             QDomElement e = list.item( i ).toElement();
00208 
00209             kdDebug(38000) << "VGroup::loadOasis: e.tagName() = " << e.tagName() << endl;
00210             kdDebug(38000) << "VGroup::loadOasis: e.namespaceURI() = " << e.namespaceURI() << endl;
00211             kdDebug(38000) << "VGroup::loadOasis: e.localName() = " << e.localName() << endl;
00212 
00213             if( e.namespaceURI() != KoXmlNS::draw )
00214                 continue;
00215 
00216             context.styleStack().save();
00217 
00218             if( e.localName() == "path" || e.localName() == "custom-shape" )
00219             {
00220                 VPath* composite = new VPath( this );
00221                 composite->loadOasis( e, context );
00222                 append( composite );
00223             }
00224             else if( e.localName() == "circle" || e.localName() == "ellipse" )
00225             {
00226                 VEllipse* ellipse = new VEllipse( this );
00227                 ellipse->loadOasis( e, context );
00228                 append( ellipse );
00229             }
00230             else if( e.localName() == "rect" )
00231             {
00232                 VRectangle* rectangle = new VRectangle( this );
00233                 rectangle->loadOasis( e, context );
00234                 append( rectangle );
00235             }
00236             else if( e.localName() == "g" )
00237             {
00238                 VGroup* group = new VGroup( this );
00239                 group->loadOasis( e, context );
00240                 append( group );
00241             }
00242             else if( e.localName() == "polyline" || e.localName() == "line" )
00243             {
00244                 VPolyline* polyline = new VPolyline( this );
00245                 polyline->loadOasis( e, context );
00246                 append( polyline );
00247             }
00248             else if( e.localName() == "polygon" )
00249             {
00250                 VPolygon* polygon = new VPolygon( this );
00251                 polygon->loadOasis( e, context );
00252                 append( polygon );
00253             }
00254 
00255             context.styleStack().restore();
00256         }
00257     }
00258 
00259     return true;
00260 }
00261 
00262 void
00263 VGroup::load( const QDomElement& element )
00264 {
00265     m_objects.setAutoDelete( true );
00266     m_objects.clear();
00267     m_objects.setAutoDelete( false );
00268 
00269     VObject::load( element );
00270 
00271     QDomNodeList list = element.childNodes();
00272     for( uint i = 0; i < list.count(); ++i )
00273     {
00274         if( list.item( i ).isElement() )
00275         {
00276             QDomElement e = list.item( i ).toElement();
00277 
00278             if( e.tagName() == "COMPOSITE" || e.tagName() == "PATH" ) // TODO : remove COMPOSITE later
00279             {
00280                 VPath* composite = new VPath( this );
00281                 composite->load( e );
00282                 append( composite );
00283             }
00284             else if( e.tagName() == "ELLIPSE" )
00285             {
00286                 VEllipse* ellipse = new VEllipse( this );
00287                 ellipse->load( e );
00288                 append( ellipse );
00289             }
00290             else if( e.tagName() == "RECT" )
00291             {
00292                 VRectangle* rectangle = new VRectangle( this );
00293                 rectangle->load( e );
00294                 append( rectangle );
00295             }
00296             else if( e.tagName() == "POLYLINE" )
00297             {
00298                 VPolyline* polyline = new VPolyline( this );
00299                 polyline->load( e );
00300                 append( polyline );
00301             }
00302             else if( e.tagName() == "POLYGON" )
00303             {
00304                 VPolygon* polygon = new VPolygon( this );
00305                 polygon->load( e );
00306                 append( polygon );
00307             }
00308             else if( e.tagName() == "SINUS" )
00309             {
00310                 VSinus* sinus = new VSinus( this );
00311                 sinus->load( e );
00312                 append( sinus );
00313             }
00314             else if( e.tagName() == "SPIRAL" )
00315             {
00316                 VSpiral* spiral = new VSpiral( this );
00317                 spiral->load( e );
00318                 append( spiral );
00319             }
00320             else if( e.tagName() == "STAR" )
00321             {
00322                 VStar* star = new VStar( this );
00323                 star->load( e );
00324                 append( star );
00325             }
00326             else if( e.tagName() == "GROUP" )
00327             {
00328                 VGroup* group = new VGroup( this );
00329                 group->load( e );
00330                 append( group );
00331             }
00332             else if( e.tagName() == "CLIP" )
00333             {
00334                 VClipGroup* grp = new VClipGroup( this );
00335                 grp->load( e );
00336                 append( grp );
00337             }
00338             else if( e.tagName() == "IMAGE" )
00339             {
00340                 VImage* img = new VImage( this );
00341                 img->load( e );
00342                 append( img );
00343             }
00344             else if( e.tagName() == "TEXT" )
00345             {
00346 #ifdef HAVE_KARBONTEXT
00347                 VText *text = new VText( this );
00348                 text->load( e );
00349                 append( text );
00350 #endif
00351             }
00352         }
00353     }
00354 }
00355 
00356 void
00357 VGroup::accept( VVisitor& visitor )
00358 {
00359     visitor.visitVGroup( *this );
00360 }
00361 
00362 
00363 void
00364 VGroup::take( const VObject& object )
00365 {
00366     m_objects.removeRef( &object );
00367 
00368     invalidateBoundingBox();
00369 }
00370 
00371 void
00372 VGroup::append( VObject* object )
00373 {
00374     object->setParent( this );
00375 
00376     m_objects.append( object );
00377 
00378     invalidateBoundingBox();
00379 }
00380 
00381 void
00382 VGroup::insertInfrontOf( VObject* newObject, VObject* oldObject )
00383 {
00384     newObject->setParent( this );
00385 
00386     m_objects.insert( m_objects.find( oldObject ), newObject );
00387 
00388     invalidateBoundingBox();
00389 }
00390 
00391 void
00392 VGroup::clear()
00393 {
00394     m_objects.clear();
00395 
00396     invalidateBoundingBox();
00397 }
00398 
KDE Home | KDE Accessibility Home | Description of Access Keys