1 // Copyright (C) 2004 Pino Toscano <toscano.pino@tiscali.it>
2 // Copyright (C) 2004 Dominique Devriese <devriese@kde.org>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 #include "drgeo-filter.h"
21 #include "drgeo-filter-chooser.h"
22 #include "filters-common.h"
24 #include "../kig/kig_document.h"
25 #include "../kig/kig_part.h"
26 #include "../misc/common.h"
27 #include "../misc/coordinate.h"
28 #include "../objects/angle_type.h"
29 #include "../objects/arc_type.h"
30 #include "../objects/bogus_imp.h"
31 #include "../objects/circle_imp.h"
32 #include "../objects/circle_type.h"
33 #include "../objects/conic_imp.h"
34 #include "../objects/conic_types.h"
35 #include "../objects/curve_imp.h"
36 #include "../objects/intersection_types.h"
37 #include "../objects/line_imp.h"
38 #include "../objects/line_type.h"
39 #include "../objects/object_calcer.h"
40 #include "../objects/object_drawer.h"
41 #include "../objects/object_factory.h"
42 #include "../objects/object_holder.h"
43 #include "../objects/object_type.h"
44 #include "../objects/other_imp.h"
45 #include "../objects/other_type.h"
46 #include "../objects/point_imp.h"
47 #include "../objects/point_type.h"
48 #include "../objects/polygon_type.h"
49 #include "../objects/transform_types.h"
50 #include "../objects/vector_type.h"
55 #include <qnamespace.h>
62 struct DrGeoHierarchyElement
65 std::vector
<QString
> parents
;
68 KigFilterDrgeo::KigFilterDrgeo()
72 KigFilterDrgeo::~KigFilterDrgeo()
76 bool KigFilterDrgeo::supportMime( const QString
& mime
)
78 return mime
== "application/x-drgeo";
81 KigDocument
* KigFilterDrgeo::load( const QString
& file
)
84 if ( ! f
.open( IO_ReadOnly
) )
91 QDomDocument
doc( "drgenius" );
92 if ( !doc
.setContent( &f
) )
93 KIG_FILTER_PARSE_ERROR
;
94 QDomElement main
= doc
.documentElement();
97 for ( QDomNode n
= main
.firstChild(); ! n
.isNull(); n
= n
.nextSibling() )
99 QDomElement e
= n
.toElement();
100 if ( e
.isNull() ) continue;
101 else if ( e
.tagName() == "drgeo" )
102 figures
.append( e
.attribute( "name" ) );
103 else if ( e
.tagName() == "macro" )
106 if ( figures
.isEmpty() ) {
108 warning( i18n( "The Dr. Geo file \"%1\" is a macro file so it contains no "
109 "figures." ).arg( file
) );
111 warning( i18n( "There are no figures in Dr. Geo file \"%1\"." ).arg( file
) );
115 int nfig
= figures
.count();
116 // no figures, no party...
124 // Dr. Geo file has more than 1 figure, let the user choose one...
125 KigFilterDrgeoChooser
* c
= new KigFilterDrgeoChooser( figures
);
131 kdDebug() << "drgeo file " << file
<< endl
;
135 for ( QDomNode n
= main
.firstChild(); ! n
.isNull(); n
= n
.nextSibling() )
137 QDomElement e
= n
.toElement();
138 if ( e
.isNull() ) continue;
139 else if ( e
.tagName() == "drgeo" )
142 if ( curfig
== myfig
)
145 kdDebug() << "- Figure: '" << e
.attribute("name") << "'" << endl
;
147 bool grid
= !e
.attribute( "grid" ).isEmpty() &&
148 ( e
.attribute( "grid" ) != "False" );
149 return importFigure( e
.firstChild(), file
, grid
);
157 int convertDrgeoIndex( const std::vector
<DrGeoHierarchyElement
> es
, const QString myid
)
159 for ( uint i
= 0; i
< es
.size(); ++i
)
160 if ( es
[i
].id
== myid
)
165 const Coordinate
convertDrgeoLineParam( const double param
, const LineData
& line
)
167 const double n
= ( param
- 0.5 ) * M_PI
;
168 const Coordinate c
= line
.dir() / line
.dir().length();
169 const Coordinate p
= line
.a
+ tan( n
) * c
;
173 const Coordinate
convertDrgeoHalflineParam( const double param
, const LineData
& line
)
175 const double n
= param
* M_PI
* 0.5;
176 const Coordinate c
= line
.dir() / line
.dir().length();
177 const Coordinate p
= line
.a
+ tan( n
) * c
;
181 KigDocument
* KigFilterDrgeo::importFigure( QDomNode f
, const QString
& file
, const bool grid
)
183 KigDocument
* ret
= new KigDocument();
186 std::vector
<DrGeoHierarchyElement
> elems
;
189 // 1st: fetch relationships and build an appropriate structure
190 for (QDomNode a
= f
; ! a
.isNull(); a
= a
.nextSibling() )
192 QDomElement domelem
= a
.toElement();
193 if ( domelem
.isNull() ) continue;
196 DrGeoHierarchyElement elem
;
198 kdDebug() << " * " << domelem
.tagName() << "(" << domelem
.attribute("type") << ")" << endl
;
200 for ( QDomNode c
= domelem
.firstChild(); ! c
.isNull(); c
= c
.nextSibling() )
202 QDomElement ce
= c
.toElement();
203 if ( ce
.isNull() ) continue;
204 else if ( ce
.tagName() == "parent" )
205 elem
.parents
.push_back( ce
.attribute( "ref" ) );
207 QString curid
= domelem
.attribute( "id" );
208 elem
.id
= !curid
.isNull() ? curid
: QString::number( withoutid
++ ) ;
209 elems
.push_back( elem
);
215 kdDebug() << "+++ elems" << endl
;
216 for ( uint i
= 0; i
< elems
.size(); ++i
)
219 for ( uint j
= 0; j
< elems
[i
].parents
.size(); ++j
)
221 x
+= elems
[i
].parents
[j
] + "_";
223 kdDebug() << " --> " << i
<< " - " << elems
[i
].id
<< " - " << x
<< endl
;
229 const ObjectFactory
* fact
= ObjectFactory::instance();
230 std::vector
<ObjectHolder
*> holders
;
231 std::vector
<ObjectHolder
*> holders2
;
232 ObjectTypeCalcer
* oc
= 0;
233 ObjectCalcer
* oc2
= 0;
236 // there's no need to sort the objects because it seems that DrGeo objects
237 // appear in the right order... so let's go!
238 for (QDomNode a
= f
; ! a
.isNull(); a
= a
.nextSibling() )
241 kdDebug() << "+++ id: " << curid
<< endl
;
243 const DrGeoHierarchyElement
& el
= elems
[curid
];
244 std::vector
<ObjectCalcer
*> parents
;
245 for ( uint j
= 0; j
< el
.parents
.size(); ++j
)
247 int parentid
= convertDrgeoIndex( elems
, el
.parents
[j
] );
248 if ( parentid
== -1 )
249 KIG_FILTER_PARSE_ERROR
;
250 parents
.push_back( holders
[parentid
-nignored
]->calcer() );
252 QDomElement domelem
= a
.toElement();
255 if ( parents
.size() > 0 )
256 for ( uint j
= 0; j
< parents
.size(); ++j
)
258 kdDebug() << "+++++++++ parent[" << j
<< "]: " << parents
[j
] << " - "
259 << parents
[j
]->imp()->type()->internalName() << endl
;
262 kdDebug() << "+++++++++ parents: NO" << endl
;
263 kdDebug() << "+++++++++ " << domelem
.tagName() << " - " << domelem
.attribute("type") << endl
;
266 if ( domelem
.isNull() ) continue;
267 else if ( domelem
.tagName() == "point" )
272 for ( QDomNode c
= domelem
.firstChild(); ! c
.isNull(); c
= c
.nextSibling() )
274 QDomElement ce
= c
.toElement();
275 if ( ce
.isNull() ) continue;
276 else if ( ce
.tagName() == "x" )
278 else if ( ce
.tagName() == "y" )
280 else if ( ce
.tagName() == "value" )
283 if ( domelem
.attribute( "type" ) == "Free" )
287 double x
= xs
.toDouble( &ok
);
288 double y
= ys
.toDouble( &ok2
);
289 if ( ! ( ok
&& ok2
) )
290 KIG_FILTER_PARSE_ERROR
;
291 oc
= fact
->fixedPointCalcer( Coordinate( x
, y
) );
293 else if ( domelem
.attribute( "type" ) == "Middle_2pts" )
294 oc
= new ObjectTypeCalcer( MidPointType::instance(), parents
);
295 else if ( domelem
.attribute( "type" ) == "Middle_segment" )
297 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
298 if ( !parents
[0]->imp()->inherits( SegmentImp::stype() ) )
299 KIG_FILTER_PARSE_ERROR
;
300 ObjectPropertyCalcer
* o1
= fact
->propertyObjectCalcer( parents
[0], "end-point-A" );
302 ObjectPropertyCalcer
* o2
= fact
->propertyObjectCalcer( parents
[0], "end-point-B" );
304 std::vector
<ObjectCalcer
*> args
;
305 args
.push_back( o1
);
306 args
.push_back( o2
);
307 oc
= new ObjectTypeCalcer( MidPointType::instance(), args
);
309 else if ( domelem
.attribute( "type" ) == "On_curve" )
312 double value
= values
.toDouble( &ok3
);
314 KIG_FILTER_PARSE_ERROR
;
315 if ( ( parents
[0]->imp()->inherits( CircleImp::stype() ) ) ||
316 ( parents
[0]->imp()->inherits( SegmentImp::stype() ) ) )
317 oc
= fact
->constrainedPointCalcer( parents
[0], value
);
318 else if ( parents
[0]->imp()->inherits( LineImp::stype() ) )
320 const LineData l
= static_cast<const LineImp
*>( parents
[0]->imp() )->data();
321 const Coordinate p
= convertDrgeoLineParam( value
, l
);
322 oc
= fact
->constrainedPointCalcer( parents
[0], p
, *ret
);
324 else if ( parents
[0]->imp()->inherits( RayImp::stype() ) )
326 const LineData l
= static_cast<const RayImp
*>( parents
[0]->imp() )->data();
327 const Coordinate p
= convertDrgeoHalflineParam( value
, l
);
328 oc
= fact
->constrainedPointCalcer( parents
[0], p
, *ret
);
330 else if ( parents
[0]->imp()->inherits( ArcImp::stype() ) )
331 oc
= fact
->constrainedPointCalcer( parents
[0], 1 - value
);
334 // oc = fact->constrainedPointCalcer( parents[0], value );
335 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
336 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
337 domelem
.attribute( "type" ) ) );
341 else if ( domelem
.attribute( "type" ) == "Intersection" )
343 if ( ( parents
[0]->imp()->inherits( AbstractLineImp::stype() ) ) &&
344 ( parents
[1]->imp()->inherits( AbstractLineImp::stype() ) ) )
345 oc
= new ObjectTypeCalcer( LineLineIntersectionType::instance(), parents
);
349 int which
= domelem
.attribute( "extra" ).toInt( &ok
);
350 if ( !ok
) KIG_FILTER_PARSE_ERROR
;
351 if ( which
== 1 ) which
= -1;
352 else if ( which
== 0 ) which
= 1;
353 else KIG_FILTER_PARSE_ERROR
;
354 std::vector
<ObjectCalcer
*> args
= parents
;
355 const ObjectType
* type
= 0;
356 args
.push_back( new ObjectConstCalcer( new IntImp( which
) ) );
357 if ( ( parents
[0]->imp()->inherits( CircleImp::stype() ) ) &&
358 ( parents
[1]->imp()->inherits( CircleImp::stype() ) ) )
359 type
= CircleCircleIntersectionType::instance();
360 else if ( ( parents
[0]->imp()->inherits( CircleImp::stype() ) &&
361 parents
[1]->imp()->inherits( AbstractLineImp::stype() ) ) ||
362 ( parents
[1]->imp()->inherits( CircleImp::stype() ) &&
363 parents
[0]->imp()->inherits( AbstractLineImp::stype() ) ) )
364 type
= ConicLineIntersectionType::instance();
365 else if ( ( parents
[0]->imp()->inherits( ArcImp::stype() ) &&
366 parents
[1]->imp()->inherits( AbstractLineImp::stype() ) ) ||
367 ( parents
[1]->imp()->inherits( ArcImp::stype() ) &&
368 parents
[0]->imp()->inherits( AbstractLineImp::stype() ) ) )
369 type
= ArcLineIntersectionType::instance();
372 notSupported( file
, i18n( "This Dr. Geo file contains an intersection type, "
373 "which Kig does not currently support." ) );
376 oc
= new ObjectTypeCalcer( type
, args
);
379 else if ( domelem
.attribute( "type" ) == "Reflexion" )
380 oc
= new ObjectTypeCalcer( LineReflectionType::instance(), parents
);
381 else if ( domelem
.attribute( "type" ) == "Symmetry" )
382 oc
= new ObjectTypeCalcer( PointReflectionType::instance(), parents
);
383 else if ( domelem
.attribute( "type" ) == "Translation" )
384 oc
= new ObjectTypeCalcer( TranslatedType::instance(), parents
);
385 else if ( domelem
.attribute( "type" ) == "Rotation" )
386 oc
= new ObjectTypeCalcer( RotationType::instance(), parents
);
389 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
390 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
391 domelem
.attribute( "type" ) ) );
395 kdDebug() << "+++++++++ oc:" << oc
<< endl
;
398 else if( ( domelem
.tagName() == "line" ) ||
399 ( domelem
.tagName() == "halfLine" ) ||
400 ( domelem
.tagName() == "segment" ) ||
401 ( domelem
.tagName() == "vector" ) ||
402 ( domelem
.tagName() == "circle" ) ||
403 ( domelem
.tagName() == "arcCircle" ) ||
404 ( domelem
.tagName() == "polygon" ) )
406 const ObjectType
* type
= 0;
407 if ( domelem
.attribute( "type" ) == "2pts" )
409 if( domelem
.tagName() == "line" )
410 type
= LineABType::instance();
411 else if( domelem
.tagName() == "halfLine" )
412 type
= RayABType::instance();
413 else if( domelem
.tagName() == "segment" )
414 type
= SegmentABType::instance();
415 else if( domelem
.tagName() == "vector" )
416 type
= VectorType::instance();
417 else if( domelem
.tagName() == "circle" )
418 type
= CircleBCPType::instance();
421 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
422 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
423 domelem
.attribute( "type" ) ) );
426 oc
= new ObjectTypeCalcer( type
, parents
);
428 else if( domelem
.attribute( "type" ) == "3pts" )
430 if( domelem
.tagName() == "arcCircle" )
431 type
= ArcBTPType::instance();
434 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
435 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
436 domelem
.attribute( "type" ) ) );
439 oc
= new ObjectTypeCalcer( type
, parents
);
441 else if( domelem
.attribute( "type" ) == "segment" )
443 if( domelem
.tagName() == "circle" )
445 type
= CircleBPRType::instance();
446 ObjectPropertyCalcer
* o
= fact
->propertyObjectCalcer( parents
[1], "length" );
448 ObjectCalcer
* a
= parents
[0];
450 parents
.push_back( a
);
451 parents
.push_back( o
);
455 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
456 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
457 domelem
.attribute( "type" ) ) );
460 oc
= new ObjectTypeCalcer( type
, parents
);
462 else if( domelem
.attribute( "type" ) == "npts" )
464 if( domelem
.tagName() == "polygon" )
466 if ( parents
.size() < 3 ) KIG_FILTER_PARSE_ERROR
;
467 type
= PolygonBNPType::instance();
471 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
472 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
473 domelem
.attribute( "type" ) ) );
476 oc
= new ObjectTypeCalcer( type
, parents
);
478 else if ( domelem
.attribute( "type" ) == "perpendicular" )
479 oc
= new ObjectTypeCalcer( LinePerpendLPType::instance(), parents
);
480 else if ( domelem
.attribute( "type" ) == "parallel" )
481 oc
= new ObjectTypeCalcer( LineParallelLPType::instance(), parents
);
482 else if ( domelem
.attribute( "type" ) == "Reflexion" )
483 oc
= new ObjectTypeCalcer( LineReflectionType::instance(), parents
);
484 else if ( domelem
.attribute( "type" ) == "Symmetry" )
485 oc
= new ObjectTypeCalcer( PointReflectionType::instance(), parents
);
486 else if ( domelem
.attribute( "type" ) == "Translation" )
487 oc
= new ObjectTypeCalcer( TranslatedType::instance(), parents
);
488 else if ( domelem
.attribute( "type" ) == "Rotation" )
489 oc
= new ObjectTypeCalcer( RotationType::instance(), parents
);
492 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
493 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
494 domelem
.attribute( "type" ) ) );
498 kdDebug() << "+++++++++ oc:" << oc
<< endl
;
501 else if( ( domelem
.tagName() == "numeric" ) ||
502 ( domelem
.tagName() == "equation" ) )
507 for ( QDomNode c
= domelem
.firstChild(); ! c
.isNull(); c
= c
.nextSibling() )
509 QDomElement ce
= c
.toElement();
510 if ( ce
.isNull() ) continue;
511 else if ( ce
.tagName() == "x" )
513 else if ( ce
.tagName() == "y" )
515 else if ( ce
.tagName() == "value" )
520 double x
= xs
.toDouble( &ok
);
521 double y
= ys
.toDouble( &ok2
);
522 if ( ! ( ok
&& ok2
) )
523 KIG_FILTER_PARSE_ERROR
;
524 Coordinate
m( x
, y
);
525 // types of 'numeric'
526 // ugly hack to show value numerics...
527 if ( domelem
.attribute( "type" ) == "value" )
530 double dvalue
= value
.toDouble( &ok3
);
532 value
= QString( "%1" ).arg( dvalue
, 0, 'g', 3 );
533 oc
= fact
->labelCalcer( value
, m
, false, std::vector
<ObjectCalcer
*>(), *ret
);
535 else if ( domelem
.attribute( "type" ) == "pt_abscissa" )
537 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
538 oc
= filtersConstructTextObject( m
, parents
[0], "coordinate-x", *ret
, false );
540 else if ( domelem
.attribute( "type" ) == "pt_ordinate" )
542 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
543 oc
= filtersConstructTextObject( m
, parents
[0], "coordinate-y", *ret
, false );
545 else if ( domelem
.attribute( "type" ) == "segment_length" )
547 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
548 oc
= filtersConstructTextObject( m
, parents
[0], "length", *ret
, false );
550 else if ( domelem
.attribute( "type" ) == "circle_perimeter" )
552 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
553 oc
= filtersConstructTextObject( m
, parents
[0], "circumference", *ret
, false );
555 else if ( domelem
.attribute( "type" ) == "arc_length" )
557 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
558 oc
= filtersConstructTextObject( m
, parents
[0], "arc-length", *ret
, false );
560 else if ( domelem
.attribute( "type" ) == "distance_2pts" )
562 if ( parents
.size() != 2 ) KIG_FILTER_PARSE_ERROR
;
563 ObjectTypeCalcer
* so
= new ObjectTypeCalcer( SegmentABType::instance(), parents
);
565 oc
= filtersConstructTextObject( m
, so
, "length", *ret
, false );
567 else if ( domelem
.attribute( "type" ) == "vector_norm" )
569 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
570 oc
= filtersConstructTextObject( m
, parents
[0], "length", *ret
, false );
572 else if ( domelem
.attribute( "type" ) == "vector_abscissa" )
574 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
575 oc
= filtersConstructTextObject( m
, parents
[0], "length-x", *ret
, false );
577 else if ( domelem
.attribute( "type" ) == "vector_ordinate" )
579 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
580 oc
= filtersConstructTextObject( m
, parents
[0], "length-y", *ret
, false );
582 else if ( domelem
.attribute( "type" ) == "slope" )
584 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
585 oc
= filtersConstructTextObject( m
, parents
[0], "slope", *ret
, false );
587 else if ( domelem
.attribute( "type" ) == "distance_pt_line" )
589 if ( parents
.size() != 2 ) KIG_FILTER_PARSE_ERROR
;
590 std::vector
<ObjectCalcer
*> args
;
591 args
.push_back( parents
[1] );
592 args
.push_back( parents
[0] );
593 ObjectTypeCalcer
* po
= new ObjectTypeCalcer( LinePerpendLPType::instance(), args
);
596 args
.push_back( parents
[1] );
597 args
.push_back( po
);
598 ObjectTypeCalcer
* io
= new ObjectTypeCalcer( LineLineIntersectionType::instance(), args
);
601 args
.push_back( parents
[0] );
602 args
.push_back( io
);
603 ObjectTypeCalcer
* so
= new ObjectTypeCalcer( SegmentABType::instance(), args
);
605 oc
= filtersConstructTextObject( m
, so
, "length", *ret
, false );
607 // types of 'equation'
608 else if ( domelem
.attribute( "type" ) == "line" )
610 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
611 oc
= filtersConstructTextObject( m
, parents
[0], "equation", *ret
, false );
613 else if ( domelem
.attribute( "type" ) == "circle" )
615 if ( parents
.size() != 1 ) KIG_FILTER_PARSE_ERROR
;
616 oc
= filtersConstructTextObject( m
, parents
[0], "simply-cartesian-equation", *ret
, false );
620 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
621 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
622 domelem
.attribute( "type" ) ) );
626 kdDebug() << "+++++++++ oc:" << oc
<< endl
;
629 else if ( domelem
.tagName() == "angle" )
631 if ( domelem
.attribute( "type" ) == "3pts" )
633 if ( parents
.size() != 3 ) KIG_FILTER_PARSE_ERROR
;
634 oc
= new ObjectTypeCalcer( HalfAngleType::instance(), parents
);
638 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
639 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
640 domelem
.attribute( "type" ) ) );
644 kdDebug() << "+++++++++ oc:" << oc
<< endl
;
647 else if ( domelem
.tagName() == "script" )
652 for ( QDomNode c
= domelem
.firstChild(); ! c
.isNull(); c
= c
.nextSibling() )
654 QDomElement ce
= c
.toElement();
655 if ( ce
.isNull() ) continue;
656 else if ( ce
.tagName() == "x" )
658 else if ( ce
.tagName() == "y" )
660 else if ( ce
.tagName() == "code" )
665 double x
= xs
.toDouble( &ok
);
666 double y
= ys
.toDouble( &ok2
);
667 if ( ! ( ok
&& ok2
) )
668 KIG_FILTER_PARSE_ERROR
;
669 // since Kig doesn't support Guile scripts, it will write script's text
670 // in a label, so the user can freely see the code and make whatever
672 // possible idea: construct a new script object with the parents of Guile
673 // one and the Guile code inserted commented... depends on a better
674 // handling of arguments in scripts?
675 if ( domelem
.attribute( "type" ) == "nitems" )
676 oc
= fact
->labelCalcer( text
, Coordinate( x
, y
), false, std::vector
<ObjectCalcer
*>(), *ret
);
679 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
680 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
681 domelem
.attribute( "type" ) ) );
685 else if ( domelem
.tagName() == "locus" )
687 if ( domelem
.attribute( "type" ) == "None" )
688 oc
= fact
->locusCalcer( parents
[0], parents
[1] );
691 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
692 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
693 domelem
.attribute( "type" ) ) );
697 kdDebug() << "+++++++++ oc:" << oc
<< endl
;
700 else if ( ( domelem
.tagName() == "boundingBox" ) ||
701 ( domelem
.tagName() == "customUI" ) )
703 // ignoring these elements, since they are not useful to us...
709 kdDebug() << ">>>>>>>>> UNKNOWN OBJECT" << endl
;
711 notSupported( file
, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
712 "which Kig does not currently support." ).arg( domelem
.tagName() ).arg(
713 domelem
.attribute( "type" ) ) );
721 QColor
co( domelem
.attribute( "color" ) );
722 if ( ! co
.isValid() )
723 if ( domelem
.attribute( "color" ) == "Bordeaux" )
724 co
.setRgb( 145, 0, 0 );
727 // reading width and style
728 // Dashed -> the little one
729 // Normal -> the medium
730 // Thick -> the biggest one
732 Qt::PenStyle s
= Qt::SolidLine
;
733 if ( domelem
.tagName() == "point" )
735 if ( domelem
.attribute( "thickness" ) == "Normal" )
737 else if ( domelem
.attribute( "thickness" ) == "Thick" )
742 if ( domelem
.attribute( "thickness" ) == "Dashed" )
744 if ( domelem
.attribute( "thickness" ) == "Thick" )
747 QString ps
= domelem
.attribute( "style" );
748 int pointstyle
= ObjectDrawer::pointStyleFromString( ps
);
750 bool show
= ( ( domelem
.attribute( "masked" ) != "True" ) &&
751 ( domelem
.attribute( "masked" ) != "Alway" ) );
752 // costructing the ObjectDrawer*
753 ObjectDrawer
* d
= new ObjectDrawer( co
, w
, show
, s
, pointstyle
);
754 // reading object name
755 QString strname
= domelem
.attribute( "name" );
756 ObjectConstCalcer
* name
= new ObjectConstCalcer( new StringImp( strname
) );
758 // creating the ObjectHolder*
759 ObjectHolder
* o
= new ObjectHolder( oc
, d
, name
);
760 holders
.push_back( o
);
763 kdDebug() << ">>>>>>>>> calc" << endl
;
765 holders
[curid
-1-nignored
]->calc( *ret
);
767 if ( domelem
.tagName() == "point" )
769 if ( !strname
.isEmpty() )
771 std::vector
<ObjectCalcer
*> args2
;
772 args2
.push_back( o
->nameCalcer() );
773 oc2
= fact
->attachedLabelCalcer( QString::fromLatin1( "%1" ), oc
,
774 static_cast<const PointImp
*>( oc
->imp() )->coordinate(),
775 false, args2
, *ret
);
779 else if ( domelem
.tagName() == "angle" )
781 oc2
= filtersConstructTextObject(
782 static_cast<const PointImp
*>( holders
[curid
-1-nignored
]->calcer()->parents()[1]->imp() )->coordinate(),
783 holders
[curid
-1-nignored
]->calcer(), "angle-degrees", *ret
, false );
791 ObjectDrawer
* d2
= new ObjectDrawer( co
);
792 ObjectHolder
* o2
= new ObjectHolder( oc2
, d2
);
793 holders2
.push_back( o2
);
798 ret
->addObjects( holders
);
799 ret
->addObjects( holders2
);
800 ret
->setGrid( grid
);
801 ret
->setAxes( grid
);
805 KigFilterDrgeo
* KigFilterDrgeo::instance()
807 static KigFilterDrgeo f
;