// Copyright (C) 2004 Pino Toscano // Copyright (C) 2004 Dominique Devriese // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program 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 General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301, USA. #include "drgeo-filter.h" #include "drgeo-filter-chooser.h" #include "filters-common.h" #include "../kig/kig_document.h" #include "../kig/kig_part.h" #include "../misc/common.h" #include "../misc/coordinate.h" #include "../objects/angle_type.h" #include "../objects/arc_type.h" #include "../objects/bogus_imp.h" #include "../objects/circle_imp.h" #include "../objects/circle_type.h" #include "../objects/conic_imp.h" #include "../objects/conic_types.h" #include "../objects/curve_imp.h" #include "../objects/intersection_types.h" #include "../objects/line_imp.h" #include "../objects/line_type.h" #include "../objects/object_calcer.h" #include "../objects/object_drawer.h" #include "../objects/object_factory.h" #include "../objects/object_holder.h" #include "../objects/object_type.h" #include "../objects/other_imp.h" #include "../objects/other_type.h" #include "../objects/point_imp.h" #include "../objects/point_type.h" #include "../objects/polygon_type.h" #include "../objects/transform_types.h" #include "../objects/vector_type.h" #include #include #include #include #undef DRGEO_DEBUG //#define DRGEO_DEBUG struct DrGeoHierarchyElement { TQString id; std::vector parents; }; KigFilterDrgeo::KigFilterDrgeo() { } KigFilterDrgeo::~KigFilterDrgeo() { } bool KigFilterDrgeo::supportMime( const TQString& mime ) { return mime == "application/x-drgeo"; } KigDocument* KigFilterDrgeo::load( const TQString& file ) { TQFile f( file ); if ( ! f.open( IO_ReadOnly ) ) { fileNotFound( file ); return 0; } TQStringList figures; TQDomDocument doc( "drgenius" ); if ( !doc.setContent( &f ) ) KIG_FILTER_PARSE_ERROR; TQDomElement main = doc.documentElement(); int nmacros = 0; // reading figures... for ( TQDomNode n = main.firstChild(); ! n.isNull(); n = n.nextSibling() ) { TQDomElement e = n.toElement(); if ( e.isNull() ) continue; else if ( e.tagName() == "drgeo" ) figures.append( e.attribute( "name" ) ); else if ( e.tagName() == "macro" ) nmacros++; } if ( figures.isEmpty() ) { if( nmacros > 0 ) warning( i18n( "The Dr. Geo file \"%1\" is a macro file so it contains no " "figures." ).arg( file ) ); else warning( i18n( "There are no figures in Dr. Geo file \"%1\"." ).arg( file ) ); return 0; } int nfig = figures.count(); // no figures, no party... if ( nfig == 0 ) return 0; int myfig = 0; if ( nfig > 1 ) { // Dr. Geo file has more than 1 figure, let the user choose one... KigFilterDrgeoChooser* c = new KigFilterDrgeoChooser( figures ); myfig = c->exec(); delete c; } #ifdef DRGEO_DEBUG kdDebug() << "drgeo file " << file << endl; #endif int curfig = -1; for ( TQDomNode n = main.firstChild(); ! n.isNull(); n = n.nextSibling() ) { TQDomElement e = n.toElement(); if ( e.isNull() ) continue; else if ( e.tagName() == "drgeo" ) { curfig += 1; if ( curfig == myfig ) { #ifdef DRGEO_DEBUG kdDebug() << "- Figure: '" << e.attribute("name") << "'" << endl; #endif bool grid = !e.attribute( "grid" ).isEmpty() && ( e.attribute( "grid" ) != "False" ); return importFigure( e.firstChild(), file, grid ); } } } return 0; } int convertDrgeoIndex( const std::vector es, const TQString myid ) { for ( uint i = 0; i < es.size(); ++i ) if ( es[i].id == myid ) return i; return -1; } const Coordinate convertDrgeoLineParam( const double param, const LineData& line ) { const double n = ( param - 0.5 ) * M_PI; const Coordinate c = line.dir() / line.dir().length(); const Coordinate p = line.a + tan( n ) * c; return p; } const Coordinate convertDrgeoHalflineParam( const double param, const LineData& line ) { const double n = param * M_PI * 0.5; const Coordinate c = line.dir() / line.dir().length(); const Coordinate p = line.a + tan( n ) * c; return p; } KigDocument* KigFilterDrgeo::importFigure( TQDomNode f, const TQString& file, const bool grid ) { KigDocument* ret = new KigDocument(); using namespace std; std::vector elems; int withoutid = 0; // 1st: fetch relationships and build an appropriate structure for (TQDomNode a = f; ! a.isNull(); a = a.nextSibling() ) { TQDomElement domelem = a.toElement(); if ( domelem.isNull() ) continue; else { DrGeoHierarchyElement elem; #ifdef DRGEO_DEBUG kdDebug() << " * " << domelem.tagName() << "(" << domelem.attribute("type") << ")" << endl; #endif for ( TQDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() ) { TQDomElement ce = c.toElement(); if ( ce.isNull() ) continue; else if ( ce.tagName() == "parent" ) elem.parents.push_back( ce.attribute( "ref" ) ); } TQString curid = domelem.attribute( "id" ); elem.id = !curid.isNull() ? curid : TQString::number( withoutid++ ) ; elems.push_back( elem ); } } #ifdef DRGEO_DEBUG TQString x; kdDebug() << "+++ elems" << endl; for ( uint i = 0; i < elems.size(); ++i ) { x = ""; for ( uint j = 0; j < elems[i].parents.size(); ++j ) { x += elems[i].parents[j] + "_"; } kdDebug() << " --> " << i << " - " << elems[i].id << " - " << x << endl; } #endif // 2nd: let's draw! int curid = 0; const ObjectFactory* fact = ObjectFactory::instance(); std::vector holders; std::vector holders2; ObjectTypeCalcer* oc = 0; ObjectCalcer* oc2 = 0; int nignored = 0; // there's no need to sort the objects because it seems that DrGeo objects // appear in the right order... so let's go! for (TQDomNode a = f; ! a.isNull(); a = a.nextSibling() ) { #ifdef DRGEO_DEBUG kdDebug() << "+++ id: " << curid << endl; #endif const DrGeoHierarchyElement& el = elems[curid]; std::vector parents; for ( uint j = 0; j < el.parents.size(); ++j ) { int parentid = convertDrgeoIndex( elems, el.parents[j] ); if ( parentid == -1 ) KIG_FILTER_PARSE_ERROR; parents.push_back( holders[parentid-nignored]->calcer() ); }; TQDomElement domelem = a.toElement(); #ifdef DRGEO_DEBUG if ( parents.size() > 0 ) for ( uint j = 0; j < parents.size(); ++j ) { kdDebug() << "+++++++++ parent[" << j << "]: " << parents[j] << " - " << parents[j]->imp()->type()->internalName() << endl; } else kdDebug() << "+++++++++ parents: NO" << endl; kdDebug() << "+++++++++ " << domelem.tagName() << " - " << domelem.attribute("type") << endl; #endif if ( domelem.isNull() ) continue; else if ( domelem.tagName() == "point" ) { TQString xs; TQString ys; TQString values; for ( TQDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() ) { TQDomElement ce = c.toElement(); if ( ce.isNull() ) continue; else if ( ce.tagName() == "x" ) xs = ce.text(); else if ( ce.tagName() == "y" ) ys = ce.text(); else if ( ce.tagName() == "value" ) values = ce.text(); } if ( domelem.attribute( "type" ) == "Free" ) { bool ok; bool ok2; double x = xs.toDouble( &ok ); double y = ys.toDouble( &ok2 ); if ( ! ( ok && ok2 ) ) KIG_FILTER_PARSE_ERROR; oc = fact->fixedPointCalcer( Coordinate( x, y ) ); } else if ( domelem.attribute( "type" ) == "Middle_2pts" ) oc = new ObjectTypeCalcer( MidPointType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Middle_segment" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; if ( !parents[0]->imp()->inherits( SegmentImp::stype() ) ) KIG_FILTER_PARSE_ERROR; ObjectPropertyCalcer* o1 = fact->propertyObjectCalcer( parents[0], "end-point-A" ); o1->calc( *ret ); ObjectPropertyCalcer* o2 = fact->propertyObjectCalcer( parents[0], "end-point-B" ); o2->calc( *ret ); std::vector args; args.push_back( o1 ); args.push_back( o2 ); oc = new ObjectTypeCalcer( MidPointType::instance(), args ); } else if ( domelem.attribute( "type" ) == "On_curve" ) { bool ok3; double value = values.toDouble( &ok3 ); if ( ! ok3 ) KIG_FILTER_PARSE_ERROR; if ( ( parents[0]->imp()->inherits( CircleImp::stype() ) ) || ( parents[0]->imp()->inherits( SegmentImp::stype() ) ) ) oc = fact->constrainedPointCalcer( parents[0], value ); else if ( parents[0]->imp()->inherits( LineImp::stype() ) ) { const LineData l = static_cast( parents[0]->imp() )->data(); const Coordinate p = convertDrgeoLineParam( value, l ); oc = fact->constrainedPointCalcer( parents[0], p, *ret ); } else if ( parents[0]->imp()->inherits( RayImp::stype() ) ) { const LineData l = static_cast( parents[0]->imp() )->data(); const Coordinate p = convertDrgeoHalflineParam( value, l ); oc = fact->constrainedPointCalcer( parents[0], p, *ret ); } else if ( parents[0]->imp()->inherits( ArcImp::stype() ) ) oc = fact->constrainedPointCalcer( parents[0], 1 - value ); else { // oc = fact->constrainedPointCalcer( parents[0], value ); notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } } else if ( domelem.attribute( "type" ) == "Intersection" ) { if ( ( parents[0]->imp()->inherits( AbstractLineImp::stype() ) ) && ( parents[1]->imp()->inherits( AbstractLineImp::stype() ) ) ) oc = new ObjectTypeCalcer( LineLineIntersectionType::instance(), parents ); else { bool ok; int which = domelem.attribute( "extra" ).toInt( &ok ); if ( !ok ) KIG_FILTER_PARSE_ERROR; if ( which == 1 ) which = -1; else if ( which == 0 ) which = 1; else KIG_FILTER_PARSE_ERROR; std::vector args = parents; const ObjectType* type = 0; args.push_back( new ObjectConstCalcer( new IntImp( which ) ) ); if ( ( parents[0]->imp()->inherits( CircleImp::stype() ) ) && ( parents[1]->imp()->inherits( CircleImp::stype() ) ) ) type = CircleCircleIntersectionType::instance(); else if ( ( parents[0]->imp()->inherits( CircleImp::stype() ) && parents[1]->imp()->inherits( AbstractLineImp::stype() ) ) || ( parents[1]->imp()->inherits( CircleImp::stype() ) && parents[0]->imp()->inherits( AbstractLineImp::stype() ) ) ) type = ConicLineIntersectionType::instance(); else if ( ( parents[0]->imp()->inherits( ArcImp::stype() ) && parents[1]->imp()->inherits( AbstractLineImp::stype() ) ) || ( parents[1]->imp()->inherits( ArcImp::stype() ) && parents[0]->imp()->inherits( AbstractLineImp::stype() ) ) ) type = ArcLineIntersectionType::instance(); else { notSupported( file, i18n( "This Dr. Geo file contains an intersection type, " "which Kig does not currently support." ) ); return 0; } oc = new ObjectTypeCalcer( type, args ); } } else if ( domelem.attribute( "type" ) == "Reflexion" ) oc = new ObjectTypeCalcer( LineReflectionType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Symmetry" ) oc = new ObjectTypeCalcer( PointReflectionType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Translation" ) oc = new ObjectTypeCalcer( TranslatedType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Rotation" ) oc = new ObjectTypeCalcer( RotationType::instance(), parents ); else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } #ifdef DRGEO_DEBUG kdDebug() << "+++++++++ oc:" << oc << endl; #endif } else if( ( domelem.tagName() == "line" ) || ( domelem.tagName() == "halfLine" ) || ( domelem.tagName() == "segment" ) || ( domelem.tagName() == "vector" ) || ( domelem.tagName() == "circle" ) || ( domelem.tagName() == "arcCircle" ) || ( domelem.tagName() == "polygon" ) ) { const ObjectType* type = 0; if ( domelem.attribute( "type" ) == "2pts" ) { if( domelem.tagName() == "line" ) type = LineABType::instance(); else if( domelem.tagName() == "halfLine" ) type = RayABType::instance(); else if( domelem.tagName() == "segment" ) type = SegmentABType::instance(); else if( domelem.tagName() == "vector" ) type = VectorType::instance(); else if( domelem.tagName() == "circle" ) type = CircleBCPType::instance(); else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } oc = new ObjectTypeCalcer( type, parents ); } else if( domelem.attribute( "type" ) == "3pts" ) { if( domelem.tagName() == "arcCircle" ) type = ArcBTPType::instance(); else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } oc = new ObjectTypeCalcer( type, parents ); } else if( domelem.attribute( "type" ) == "segment" ) { if( domelem.tagName() == "circle" ) { type = CircleBPRType::instance(); ObjectPropertyCalcer* o = fact->propertyObjectCalcer( parents[1], "length" ); o->calc( *ret ); ObjectCalcer* a = parents[0]; parents.clear(); parents.push_back( a ); parents.push_back( o ); } else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } oc = new ObjectTypeCalcer( type, parents ); } else if( domelem.attribute( "type" ) == "npts" ) { if( domelem.tagName() == "polygon" ) { if ( parents.size() < 3 ) KIG_FILTER_PARSE_ERROR; type = PolygonBNPType::instance(); } else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } oc = new ObjectTypeCalcer( type, parents ); } else if ( domelem.attribute( "type" ) == "perpendicular" ) oc = new ObjectTypeCalcer( LinePerpendLPType::instance(), parents ); else if ( domelem.attribute( "type" ) == "parallel" ) oc = new ObjectTypeCalcer( LineParallelLPType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Reflexion" ) oc = new ObjectTypeCalcer( LineReflectionType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Symmetry" ) oc = new ObjectTypeCalcer( PointReflectionType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Translation" ) oc = new ObjectTypeCalcer( TranslatedType::instance(), parents ); else if ( domelem.attribute( "type" ) == "Rotation" ) oc = new ObjectTypeCalcer( RotationType::instance(), parents ); else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } #ifdef DRGEO_DEBUG kdDebug() << "+++++++++ oc:" << oc << endl; #endif } else if( ( domelem.tagName() == "numeric" ) || ( domelem.tagName() == "equation" ) ) { TQString xs; TQString ys; TQString value; for ( TQDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() ) { TQDomElement ce = c.toElement(); if ( ce.isNull() ) continue; else if ( ce.tagName() == "x" ) xs = ce.text(); else if ( ce.tagName() == "y" ) ys = ce.text(); else if ( ce.tagName() == "value" ) value = ce.text(); } bool ok; bool ok2; double x = xs.toDouble( &ok ); double y = ys.toDouble( &ok2 ); if ( ! ( ok && ok2 ) ) KIG_FILTER_PARSE_ERROR; Coordinate m( x, y ); // types of 'numeric' // ugly hack to show value numerics... if ( domelem.attribute( "type" ) == "value" ) { bool ok3; double dvalue = value.toDouble( &ok3 ); if ( ok3 ) value = TQString( "%1" ).arg( dvalue, 0, 'g', 3 ); oc = fact->labelCalcer( value, m, false, std::vector(), *ret ); } else if ( domelem.attribute( "type" ) == "pt_abscissa" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "coordinate-x", *ret, false ); } else if ( domelem.attribute( "type" ) == "pt_ordinate" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "coordinate-y", *ret, false ); } else if ( domelem.attribute( "type" ) == "segment_length" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "length", *ret, false ); } else if ( domelem.attribute( "type" ) == "circle_perimeter" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "circumference", *ret, false ); } else if ( domelem.attribute( "type" ) == "arc_length" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "arc-length", *ret, false ); } else if ( domelem.attribute( "type" ) == "distance_2pts" ) { if ( parents.size() != 2 ) KIG_FILTER_PARSE_ERROR; ObjectTypeCalcer* so = new ObjectTypeCalcer( SegmentABType::instance(), parents ); so->calc( *ret ); oc = filtersConstructTextObject( m, so, "length", *ret, false ); } else if ( domelem.attribute( "type" ) == "vector_norm" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "length", *ret, false ); } else if ( domelem.attribute( "type" ) == "vector_abscissa" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "length-x", *ret, false ); } else if ( domelem.attribute( "type" ) == "vector_ordinate" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "length-y", *ret, false ); } else if ( domelem.attribute( "type" ) == "slope" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "slope", *ret, false ); } else if ( domelem.attribute( "type" ) == "distance_pt_line" ) { if ( parents.size() != 2 ) KIG_FILTER_PARSE_ERROR; std::vector args; args.push_back( parents[1] ); args.push_back( parents[0] ); ObjectTypeCalcer* po = new ObjectTypeCalcer( LinePerpendLPType::instance(), args ); po->calc( *ret ); args.clear(); args.push_back( parents[1] ); args.push_back( po ); ObjectTypeCalcer* io = new ObjectTypeCalcer( LineLineIntersectionType::instance(), args ); io->calc( *ret ); args.clear(); args.push_back( parents[0] ); args.push_back( io ); ObjectTypeCalcer* so = new ObjectTypeCalcer( SegmentABType::instance(), args ); so->calc( *ret ); oc = filtersConstructTextObject( m, so, "length", *ret, false ); } // types of 'equation' else if ( domelem.attribute( "type" ) == "line" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "equation", *ret, false ); } else if ( domelem.attribute( "type" ) == "circle" ) { if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR; oc = filtersConstructTextObject( m, parents[0], "simply-cartesian-equation", *ret, false ); } else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } #ifdef DRGEO_DEBUG kdDebug() << "+++++++++ oc:" << oc << endl; #endif } else if ( domelem.tagName() == "angle" ) { if ( domelem.attribute( "type" ) == "3pts" ) { if ( parents.size() != 3 ) KIG_FILTER_PARSE_ERROR; oc = new ObjectTypeCalcer( HalfAngleType::instance(), parents ); } else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } #ifdef DRGEO_DEBUG kdDebug() << "+++++++++ oc:" << oc << endl; #endif } else if ( domelem.tagName() == "script" ) { TQString xs; TQString ys; TQString text; for ( TQDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() ) { TQDomElement ce = c.toElement(); if ( ce.isNull() ) continue; else if ( ce.tagName() == "x" ) xs = ce.text(); else if ( ce.tagName() == "y" ) ys = ce.text(); else if ( ce.tagName() == "code" ) text = ce.text(); } bool ok; bool ok2; double x = xs.toDouble( &ok ); double y = ys.toDouble( &ok2 ); if ( ! ( ok && ok2 ) ) KIG_FILTER_PARSE_ERROR; // since Kig doesn't support Guile scripts, it will write script's text // in a label, so the user can freely see the code and make whatever // he/she wants // possible idea: construct a new script object with the parents of Guile // one and the Guile code inserted commented... depends on a better // handling of arguments in scripts? if ( domelem.attribute( "type" ) == "nitems" ) oc = fact->labelCalcer( text, Coordinate( x, y ), false, std::vector(), *ret ); else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } } else if ( domelem.tagName() == "locus" ) { if ( domelem.attribute( "type" ) == "None" ) oc = fact->locusCalcer( parents[0], parents[1] ); else { notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } #ifdef DRGEO_DEBUG kdDebug() << "+++++++++ oc:" << oc << endl; #endif } else if ( ( domelem.tagName() == "boundingBox" ) || ( domelem.tagName() == "customUI" ) ) { // ignoring these elements, since they are not useful to us... nignored++; } else { #ifdef DRGEO_DEBUG kdDebug() << ">>>>>>>>> UNKNOWN OBJECT" << endl; #endif notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, " "which Kig does not currently support." ).arg( domelem.tagName() ).arg( domelem.attribute( "type" ) ) ); return 0; } curid++; if ( oc == 0 ) continue; // reading color TQColor co( domelem.attribute( "color" ) ); if ( ! co.isValid() ) if ( domelem.attribute( "color" ) == "Bordeaux" ) co.setRgb( 145, 0, 0 ); else co = TQt::blue; // reading width and style // Dashed -> the little one // Normal -> the medium // Thick -> the biggest one int w = -1; Qt::PenStyle s = Qt::SolidLine; if ( domelem.tagName() == "point" ) { if ( domelem.attribute( "thickness" ) == "Normal" ) w = 7; else if ( domelem.attribute( "thickness" ) == "Thick" ) w = 9; } else { if ( domelem.attribute( "thickness" ) == "Dashed" ) s = Qt::DotLine; if ( domelem.attribute( "thickness" ) == "Thick" ) w = 2; } TQString ps = domelem.attribute( "style" ); int pointstyle = ObjectDrawer::pointStyleFromString( ps ); // show this object? bool show = ( ( domelem.attribute( "masked" ) != "True" ) && ( domelem.attribute( "masked" ) != "Alway" ) ); // costructing the ObjectDrawer* ObjectDrawer* d = new ObjectDrawer( co, w, show, s, pointstyle ); // reading object name TQString strname = domelem.attribute( "name" ); ObjectConstCalcer* name = new ObjectConstCalcer( new StringImp( strname ) ); // creating the ObjectHolder* ObjectHolder* o = new ObjectHolder( oc, d, name ); holders.push_back( o ); // calc() #ifdef DRGEO_DEBUG kdDebug() << ">>>>>>>>> calc" << endl; #endif holders[curid-1-nignored]->calc( *ret ); if ( domelem.tagName() == "point" ) { if ( !strname.isEmpty() ) { std::vector args2; args2.push_back( o->nameCalcer() ); oc2 = fact->attachedLabelCalcer( TQString::fromLatin1( "%1" ), oc, static_cast( oc->imp() )->coordinate(), false, args2, *ret ); co = TQt::black; } } else if ( domelem.tagName() == "angle" ) { oc2 = filtersConstructTextObject( static_cast( holders[curid-1-nignored]->calcer()->parents()[1]->imp() )->coordinate(), holders[curid-1-nignored]->calcer(), "angle-degrees", *ret, false ); } oc = 0; if ( oc2 != 0 ) { oc2->calc( *ret ); ObjectDrawer* d2 = new ObjectDrawer( co ); ObjectHolder* o2 = new ObjectHolder( oc2, d2 ); holders2.push_back( o2 ); oc2 = 0; } } ret->addObjects( holders ); ret->addObjects( holders2 ); ret->setGrid( grid ); ret->setAxes( grid ); return ret; } KigFilterDrgeo* KigFilterDrgeo::instance() { static KigFilterDrgeo f; return &f; }