• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kig

  • sources
  • kde-4.12
  • kdeedu
  • kig
  • filters
drgeo-filter.cc
Go to the documentation of this file.
1 // Copyright (C) 2004 Pino Toscano <toscano.pino@tiscali.it>
2 // Copyright (C) 2004 Dominique Devriese <devriese@kde.org>
3 
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.
8 
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.
13 
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., 51 Franklin Street, Fifth Floor, Boston, MA
17 // 02110-1301, USA.
18 
19 #include "drgeo-filter.h"
20 
21 #include "filters-common.h"
22 
23 #include "../kig/kig_document.h"
24 #include "../kig/kig_part.h"
25 #include "../misc/common.h"
26 #include "../misc/coordinate.h"
27 #include "../objects/angle_type.h"
28 #include "../objects/arc_type.h"
29 #include "../objects/bogus_imp.h"
30 #include "../objects/circle_imp.h"
31 #include "../objects/circle_type.h"
32 #include "../objects/conic_imp.h"
33 #include "../objects/conic_types.h"
34 #include "../objects/curve_imp.h"
35 #include "../objects/intersection_types.h"
36 #include "../objects/line_imp.h"
37 #include "../objects/line_type.h"
38 #include "../objects/object_calcer.h"
39 #include "../objects/object_drawer.h"
40 #include "../objects/object_factory.h"
41 #include "../objects/object_holder.h"
42 #include "../objects/object_type.h"
43 #include "../objects/other_imp.h"
44 #include "../objects/other_type.h"
45 #include "../objects/point_imp.h"
46 #include "../objects/point_type.h"
47 #include "../objects/polygon_type.h"
48 #include "../objects/transform_types.h"
49 #include "../objects/vector_type.h"
50 
51 #include <math.h>
52 
53 #include <qfile.h>
54 #include <qnamespace.h>
55 #include <QDomDocument>
56 
57 #include <kinputdialog.h>
58 #include <klocale.h>
59 
60 #undef DRGEO_DEBUG
61 //#define DRGEO_DEBUG
62 
63 struct DrGeoHierarchyElement
64 {
65  QString id;
66  std::vector<QString> parents;
67 };
68 
69 KigFilterDrgeo::KigFilterDrgeo()
70 {
71 }
72 
73 KigFilterDrgeo::~KigFilterDrgeo()
74 {
75 }
76 
77 bool KigFilterDrgeo::supportMime( const QString& mime )
78 {
79  return mime == "application/x-drgeo";
80 }
81 
82 KigDocument* KigFilterDrgeo::load( const QString& file )
83 {
84  QFile f( file );
85  if ( ! f.open( QIODevice::ReadOnly ) )
86  {
87  fileNotFound( file );
88  return 0;
89  }
90 
91  QStringList figures;
92  QDomDocument doc( "drgenius" );
93  if ( !doc.setContent( &f ) )
94  KIG_FILTER_PARSE_ERROR;
95  QDomElement main = doc.documentElement();
96  int nmacros = 0;
97  // reading figures...
98  for ( QDomNode n = main.firstChild(); ! n.isNull(); n = n.nextSibling() )
99  {
100  QDomElement e = n.toElement();
101  if ( e.isNull() ) continue;
102  else if ( e.tagName() == "drgeo" )
103  figures.append( e.attribute( "name" ) );
104  else if ( e.tagName() == "macro" )
105  nmacros++;
106  }
107  if ( figures.isEmpty() ) {
108  if( nmacros > 0 )
109  warning( i18n( "The Dr. Geo file \"%1\" is a macro file so it contains no "
110  "figures.", file ) );
111  else
112  warning( i18n( "There are no figures in Dr. Geo file \"%1\".", file ) );
113  return 0;
114  }
115 
116  int nfig = figures.count();
117  // no figures, no party...
118  if ( nfig == 0 )
119  return 0;
120 
121  QString myfig = figures.at( 0 );
122 
123  if ( nfig > 1 )
124  {
125  // Dr. Geo file has more than 1 figure, let the user choose one...
126  bool ok = true;
127  myfig = KInputDialog::getItem(
128  i18n( "Dr. Geo Filter" ),
129  i18n( "The current Dr. Geo file contains more than one figure.\n"
130  "Please select which to import:" ),
131  figures, 0, false, &ok );
132  if ( !ok )
133  return 0;
134  }
135 
136 #ifdef DRGEO_DEBUG
137  kDebug() << "drgeo file " << file;
138 #endif
139 
140  for ( QDomNode n = main.firstChild(); ! n.isNull(); n = n.nextSibling() )
141  {
142  QDomElement e = n.toElement();
143  if ( e.isNull() ) continue;
144  else if ( e.tagName() == "drgeo" )
145  {
146  if ( e.attribute("name") == myfig )
147  {
148 #ifdef DRGEO_DEBUG
149  kDebug() << "- Figure: '" << e.attribute("name") << "'";
150 #endif
151  bool grid = !e.attribute( "grid" ).isEmpty() &&
152  ( e.attribute( "grid" ) != "False" );
153  return importFigure( e.firstChild(), file, grid );
154  }
155  }
156  }
157 
158  return 0;
159 }
160 
161 static int convertDrgeoIndex( const std::vector<DrGeoHierarchyElement>& es, const QString& myid )
162 {
163  for ( uint i = 0; i < es.size(); ++i )
164  if ( es[i].id == myid )
165  return i;
166  return -1;
167 }
168 
169 static const Coordinate convertDrgeoLineParam( const double param, const LineData& line )
170 {
171  const double n = ( param - 0.5 ) * M_PI;
172  const Coordinate c = line.dir() / line.dir().length();
173  const Coordinate p = line.a + tan( n ) * c;
174  return p;
175 }
176 
177 static const Coordinate convertDrgeoHalflineParam( const double param, const LineData& line )
178 {
179  const double n = param * M_PI * 0.5;
180  const Coordinate c = line.dir() / line.dir().length();
181  const Coordinate p = line.a + tan( n ) * c;
182  return p;
183 }
184 
185 KigDocument* KigFilterDrgeo::importFigure( const QDomNode& f, const QString& file, const bool grid )
186 {
187  KigDocument* ret = new KigDocument();
188 
189  using namespace std;
190  std::vector<DrGeoHierarchyElement> elems;
191  int withoutid = 0;
192 
193  // 1st: fetch relationships and build an appropriate structure
194  for (QDomNode a = f; ! a.isNull(); a = a.nextSibling() )
195  {
196  QDomElement domelem = a.toElement();
197  if ( domelem.isNull() ) continue;
198  else
199  {
200  DrGeoHierarchyElement elem;
201 #ifdef DRGEO_DEBUG
202  kDebug() << " * " << domelem.tagName() << "(" << domelem.attribute("type") << ")";
203 #endif
204  for ( QDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() )
205  {
206  QDomElement ce = c.toElement();
207  if ( ce.isNull() ) continue;
208  else if ( ce.tagName() == "parent" )
209  elem.parents.push_back( ce.attribute( "ref" ) );
210  }
211  QString curid = domelem.attribute( "id" );
212  elem.id = !curid.isNull() ? curid : QString::number( withoutid++ ) ;
213  elems.push_back( elem );
214  }
215  }
216 
217 #ifdef DRGEO_DEBUG
218  QString x;
219  kDebug() << "+++ elems";
220  for ( uint i = 0; i < elems.size(); ++i )
221  {
222  x = "";
223  for ( uint j = 0; j < elems[i].parents.size(); ++j )
224  {
225  x += elems[i].parents[j] + '_';
226  }
227  kDebug() << " --> " << i << " - " << elems[i].id << " - " << x;
228  }
229 #endif
230 
231  // 2nd: let's draw!
232  int curid = 0;
233  const ObjectFactory* fact = ObjectFactory::instance();
234  std::vector<ObjectHolder*> holders;
235  std::vector<ObjectHolder*> holders2;
236  ObjectTypeCalcer* oc = 0;
237  ObjectCalcer* oc2 = 0;
238  int nignored = 0;
239 
240  // there's no need to sort the objects because it seems that DrGeo objects
241  // appear in the right order... so let's go!
242  for (QDomNode a = f; ! a.isNull(); a = a.nextSibling() )
243  {
244 #ifdef DRGEO_DEBUG
245  kDebug() << "+++ id: " << curid;
246 #endif
247  const DrGeoHierarchyElement& el = elems[curid];
248  std::vector<ObjectCalcer*> parents;
249  for ( uint j = 0; j < el.parents.size(); ++j )
250  {
251  int parentid = convertDrgeoIndex( elems, el.parents[j] );
252  if ( parentid == -1 )
253  KIG_FILTER_PARSE_ERROR;
254  parents.push_back( holders[parentid-nignored]->calcer() );
255  };
256  QDomElement domelem = a.toElement();
257 
258 #ifdef DRGEO_DEBUG
259  if ( parents.size() > 0 )
260  for ( uint j = 0; j < parents.size(); ++j )
261  {
262  kDebug() << "+++++++++ parent[" << j << "]: " << parents[j] << " - "
263  << parents[j]->imp()->type()->internalName() << endl;
264  }
265  else
266  kDebug() << "+++++++++ parents: NO";
267  kDebug() << "+++++++++ " << domelem.tagName() << " - " << domelem.attribute("type");
268 #endif
269 
270  if ( domelem.isNull() ) continue;
271  else if ( domelem.tagName() == "point" )
272  {
273  QString xs;
274  QString ys;
275  QString values;
276  for ( QDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() )
277  {
278  QDomElement ce = c.toElement();
279  if ( ce.isNull() ) continue;
280  else if ( ce.tagName() == "x" )
281  xs = ce.text();
282  else if ( ce.tagName() == "y" )
283  ys = ce.text();
284  else if ( ce.tagName() == "value" )
285  values = ce.text();
286  }
287  if ( domelem.attribute( "type" ) == "Free" )
288  {
289  bool ok;
290  bool ok2;
291  double x = xs.toDouble( &ok );
292  double y = ys.toDouble( &ok2 );
293  if ( ! ( ok && ok2 ) )
294  KIG_FILTER_PARSE_ERROR;
295  oc = fact->fixedPointCalcer( Coordinate( x, y ) );
296  }
297  else if ( domelem.attribute( "type" ) == "Middle_2pts" )
298  oc = new ObjectTypeCalcer( MidPointType::instance(), parents );
299  else if ( domelem.attribute( "type" ) == "Middle_segment" )
300  {
301  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
302  if ( !parents[0]->imp()->inherits( SegmentImp::stype() ) )
303  KIG_FILTER_PARSE_ERROR;
304  ObjectPropertyCalcer* o1 = fact->propertyObjectCalcer( parents[0], "end-point-A" );
305  o1->calc( *ret );
306  ObjectPropertyCalcer* o2 = fact->propertyObjectCalcer( parents[0], "end-point-B" );
307  o2->calc( *ret );
308  std::vector<ObjectCalcer*> args;
309  args.push_back( o1 );
310  args.push_back( o2 );
311  oc = new ObjectTypeCalcer( MidPointType::instance(), args );
312  }
313  else if ( domelem.attribute( "type" ) == "On_curve" )
314  {
315  bool ok3;
316  double value = values.toDouble( &ok3 );
317  if ( ! ok3 )
318  KIG_FILTER_PARSE_ERROR;
319  if ( ( parents[0]->imp()->inherits( CircleImp::stype() ) ) ||
320  ( parents[0]->imp()->inherits( SegmentImp::stype() ) ) )
321  oc = fact->constrainedPointCalcer( parents[0], value );
322  else if ( parents[0]->imp()->inherits( LineImp::stype() ) )
323  {
324  const LineData l = static_cast<const LineImp*>( parents[0]->imp() )->data();
325  const Coordinate p = convertDrgeoLineParam( value, l );
326  oc = fact->constrainedPointCalcer( parents[0], p, *ret );
327  }
328  else if ( parents[0]->imp()->inherits( RayImp::stype() ) )
329  {
330  const LineData l = static_cast<const RayImp*>( parents[0]->imp() )->data();
331  const Coordinate p = convertDrgeoHalflineParam( value, l );
332  oc = fact->constrainedPointCalcer( parents[0], p, *ret );
333  }
334  else if ( parents[0]->imp()->inherits( ArcImp::stype() ) )
335  oc = fact->constrainedPointCalcer( parents[0], 1 - value );
336  else
337  {
338 // oc = fact->constrainedPointCalcer( parents[0], value );
339  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
340  "which Kig does not currently support.", domelem.tagName() ,
341  domelem.attribute( "type" ) ) );
342  return 0;
343  }
344  }
345  else if ( domelem.attribute( "type" ) == "Intersection" )
346  {
347  if ( ( parents[0]->imp()->inherits( AbstractLineImp::stype() ) ) &&
348  ( parents[1]->imp()->inherits( AbstractLineImp::stype() ) ) )
349  oc = new ObjectTypeCalcer( LineLineIntersectionType::instance(), parents );
350  else
351  {
352  bool ok;
353  int which = domelem.attribute( "extra" ).toInt( &ok );
354  if ( !ok ) KIG_FILTER_PARSE_ERROR;
355  if ( which == 1 ) which = -1;
356  else if ( which == 0 ) which = 1;
357  else KIG_FILTER_PARSE_ERROR;
358  std::vector<ObjectCalcer*> args = parents;
359  const ObjectType* type = 0;
360  args.push_back( new ObjectConstCalcer( new IntImp( which ) ) );
361  if ( ( parents[0]->imp()->inherits( CircleImp::stype() ) ) &&
362  ( parents[1]->imp()->inherits( CircleImp::stype() ) ) )
363  type = CircleCircleIntersectionType::instance();
364  else if ( ( parents[0]->imp()->inherits( CircleImp::stype() ) &&
365  parents[1]->imp()->inherits( AbstractLineImp::stype() ) ) ||
366  ( parents[1]->imp()->inherits( CircleImp::stype() ) &&
367  parents[0]->imp()->inherits( AbstractLineImp::stype() ) ) )
368  type = ConicLineIntersectionType::instance();
369  else if ( ( parents[0]->imp()->inherits( ArcImp::stype() ) &&
370  parents[1]->imp()->inherits( AbstractLineImp::stype() ) ) ||
371  ( parents[1]->imp()->inherits( ArcImp::stype() ) &&
372  parents[0]->imp()->inherits( AbstractLineImp::stype() ) ) )
373  type = ArcLineIntersectionType::instance();
374  else
375  {
376  notSupported( file, i18n( "This Dr. Geo file contains an intersection type, "
377  "which Kig does not currently support." ) );
378  return 0;
379  }
380  oc = new ObjectTypeCalcer( type, args );
381  }
382  }
383  else if ( domelem.attribute( "type" ) == "Coordinate" )
384  oc = new ObjectTypeCalcer( PointByCoordsType::instance(), parents );
385  else if ( domelem.attribute( "type" ) == "Reflexion" )
386  oc = new ObjectTypeCalcer( LineReflectionType::instance(), parents );
387  else if ( domelem.attribute( "type" ) == "Symmetry" )
388  oc = new ObjectTypeCalcer( PointReflectionType::instance(), parents );
389  else if ( domelem.attribute( "type" ) == "Translation" )
390  oc = new ObjectTypeCalcer( TranslatedType::instance(), parents );
391  else if ( domelem.attribute( "type" ) == "Rotation" )
392  oc = new ObjectTypeCalcer( RotationType::instance(), parents );
393  else if ( domelem.attribute( "type" ) == "Scale" )
394  oc = new ObjectTypeCalcer( ScalingOverCenterType::instance(), parents );
395  else
396  {
397  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
398  "which Kig does not currently support.", domelem.tagName() ,
399  domelem.attribute( "type" ) ) );
400  return 0;
401  }
402 #ifdef DRGEO_DEBUG
403  kDebug() << "+++++++++ oc:" << oc;
404 #endif
405  }
406  else if( ( domelem.tagName() == "line" ) ||
407  ( domelem.tagName() == "halfLine" ) ||
408  ( domelem.tagName() == "segment" ) ||
409  ( domelem.tagName() == "vector" ) ||
410  ( domelem.tagName() == "circle" ) ||
411  ( domelem.tagName() == "arcCircle" ) ||
412  ( domelem.tagName() == "polygon" ) )
413  {
414  const ObjectType* type = 0;
415  if ( domelem.attribute( "type" ) == "2pts" )
416  {
417  if( domelem.tagName() == "line" )
418  type = LineABType::instance();
419  else if( domelem.tagName() == "halfLine" )
420  type = RayABType::instance();
421  else if( domelem.tagName() == "segment" )
422  type = SegmentABType::instance();
423  else if( domelem.tagName() == "vector" )
424  type = VectorType::instance();
425  else if( domelem.tagName() == "circle" )
426  type = CircleBCPType::instance();
427  else
428  {
429  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
430  "which Kig does not currently support.", domelem.tagName() ,
431  domelem.attribute( "type" ) ) );
432  return 0;
433  }
434  oc = new ObjectTypeCalcer( type, parents );
435  }
436  else if( domelem.attribute( "type" ) == "3pts" )
437  {
438  if( domelem.tagName() == "arcCircle" )
439  type = ArcBTPType::instance();
440  else
441  {
442  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
443  "which Kig does not currently support.", domelem.tagName() ,
444  domelem.attribute( "type" ) ) );
445  return 0;
446  }
447  oc = new ObjectTypeCalcer( type, parents );
448  }
449  else if ( ( domelem.attribute( "type" ) == "segment" ) ||
450  ( domelem.attribute( "type" ) == "radius" ) )
451  {
452  if( domelem.tagName() == "circle" )
453  {
454  type = CircleBPRType::instance();
455  if ( domelem.attribute( "type" ) == "segment" )
456  {
457  ObjectPropertyCalcer* o = fact->propertyObjectCalcer( parents[1], "length" );
458  o->calc( *ret );
459  parents.pop_back();
460  parents.push_back( o );
461  }
462  }
463  else
464  {
465  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
466  "which Kig does not currently support.", domelem.tagName() ,
467  domelem.attribute( "type" ) ) );
468  return 0;
469  }
470  oc = new ObjectTypeCalcer( type, parents );
471  }
472  else if( domelem.attribute( "type" ) == "npts" )
473  {
474  if( domelem.tagName() == "polygon" )
475  {
476  if ( parents.size() < 3 ) KIG_FILTER_PARSE_ERROR;
477  type = PolygonBNPType::instance();
478  }
479  else
480  {
481  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
482  "which Kig does not currently support.", domelem.tagName() ,
483  domelem.attribute( "type" ) ) );
484  return 0;
485  }
486  oc = new ObjectTypeCalcer( type, parents );
487  }
488  else if ( domelem.attribute( "type" ) == "perpendicular" )
489  oc = new ObjectTypeCalcer( LinePerpendLPType::instance(), parents );
490  else if ( domelem.attribute( "type" ) == "parallel" )
491  oc = new ObjectTypeCalcer( LineParallelLPType::instance(), parents );
492  else if ( domelem.attribute( "type" ) == "Reflexion" )
493  oc = new ObjectTypeCalcer( LineReflectionType::instance(), parents );
494  else if ( domelem.attribute( "type" ) == "Symmetry" )
495  oc = new ObjectTypeCalcer( PointReflectionType::instance(), parents );
496  else if ( domelem.attribute( "type" ) == "Translation" )
497  oc = new ObjectTypeCalcer( TranslatedType::instance(), parents );
498  else if ( domelem.attribute( "type" ) == "Rotation" )
499  oc = new ObjectTypeCalcer( RotationType::instance(), parents );
500  else if ( domelem.attribute( "type" ) == "Scale" )
501  oc = new ObjectTypeCalcer( ScalingOverCenterType::instance(), parents );
502  else
503  {
504  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
505  "which Kig does not currently support.", domelem.tagName() ,
506  domelem.attribute( "type" ) ) );
507  return 0;
508  }
509 #ifdef DRGEO_DEBUG
510  kDebug() << "+++++++++ oc:" << oc;
511 #endif
512  }
513  else if( ( domelem.tagName() == "numeric" ) ||
514  ( domelem.tagName() == "equation" ) )
515  {
516  QString xs;
517  QString ys;
518  QString value;
519  for ( QDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() )
520  {
521  QDomElement ce = c.toElement();
522  if ( ce.isNull() ) continue;
523  else if ( ce.tagName() == "x" )
524  xs = ce.text();
525  else if ( ce.tagName() == "y" )
526  ys = ce.text();
527  else if ( ce.tagName() == "value" )
528  value = ce.text();
529  }
530  bool ok;
531  bool ok2;
532  double x = xs.toDouble( &ok );
533  double y = ys.toDouble( &ok2 );
534  if ( ! ( ok && ok2 ) )
535  KIG_FILTER_PARSE_ERROR;
536  Coordinate m( x, y );
537  // types of 'numeric'
538  if ( domelem.attribute( "type" ) == "value" )
539  {
540  bool ok3;
541  double dvalue = value.toDouble( &ok3 );
542  if ( !ok3 )
543  KIG_FILTER_PARSE_ERROR;
544  oc = fact->numericValueCalcer( dvalue, m, *ret );
545  }
546  else if ( domelem.attribute( "type" ) == "pt_abscissa" )
547  {
548  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
549  oc = filtersConstructTextObject( m, parents[0], "coordinate-x", *ret, false );
550  }
551  else if ( domelem.attribute( "type" ) == "pt_ordinate" )
552  {
553  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
554  oc = filtersConstructTextObject( m, parents[0], "coordinate-y", *ret, false );
555  }
556  else if ( domelem.attribute( "type" ) == "segment_length" )
557  {
558  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
559  oc = filtersConstructTextObject( m, parents[0], "length", *ret, false );
560  }
561  else if ( domelem.attribute( "type" ) == "circle_perimeter" )
562  {
563  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
564  oc = filtersConstructTextObject( m, parents[0], "circumference", *ret, false );
565  }
566  else if ( domelem.attribute( "type" ) == "arc_length" )
567  {
568  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
569  oc = filtersConstructTextObject( m, parents[0], "arc-length", *ret, false );
570  }
571  else if ( domelem.attribute( "type" ) == "distance_2pts" )
572  {
573  if ( parents.size() != 2 ) KIG_FILTER_PARSE_ERROR;
574  ObjectTypeCalcer* so = new ObjectTypeCalcer( SegmentABType::instance(), parents );
575  so->calc( *ret );
576  oc = filtersConstructTextObject( m, so, "length", *ret, false );
577  }
578  else if ( domelem.attribute( "type" ) == "vector_norm" )
579  {
580  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
581  oc = filtersConstructTextObject( m, parents[0], "length", *ret, false );
582  }
583  else if ( domelem.attribute( "type" ) == "vector_abscissa" )
584  {
585  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
586  oc = filtersConstructTextObject( m, parents[0], "length-x", *ret, false );
587  }
588  else if ( domelem.attribute( "type" ) == "vector_ordinate" )
589  {
590  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
591  oc = filtersConstructTextObject( m, parents[0], "length-y", *ret, false );
592  }
593  else if ( domelem.attribute( "type" ) == "slope" )
594  {
595  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
596  oc = filtersConstructTextObject( m, parents[0], "slope", *ret, false );
597  }
598  else if ( domelem.attribute( "type" ) == "distance_pt_line" )
599  {
600  if ( parents.size() != 2 ) KIG_FILTER_PARSE_ERROR;
601  std::vector<ObjectCalcer*> args;
602  args.push_back( parents[1] );
603  args.push_back( parents[0] );
604  ObjectTypeCalcer* po = new ObjectTypeCalcer( LinePerpendLPType::instance(), args );
605  po->calc( *ret );
606  args.clear();
607  args.push_back( parents[1] );
608  args.push_back( po );
609  ObjectTypeCalcer* io = new ObjectTypeCalcer( LineLineIntersectionType::instance(), args );
610  io->calc( *ret );
611  args.clear();
612  args.push_back( parents[0] );
613  args.push_back( io );
614  ObjectTypeCalcer* so = new ObjectTypeCalcer( SegmentABType::instance(), args );
615  so->calc( *ret );
616  oc = filtersConstructTextObject( m, so, "length", *ret, false );
617  }
618  // types of 'equation'
619  else if ( domelem.attribute( "type" ) == "line" )
620  {
621  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
622  oc = filtersConstructTextObject( m, parents[0], "equation", *ret, false );
623  }
624  else if ( domelem.attribute( "type" ) == "circle" )
625  {
626  if ( parents.size() != 1 ) KIG_FILTER_PARSE_ERROR;
627  oc = filtersConstructTextObject( m, parents[0], "simply-cartesian-equation", *ret, false );
628  }
629  else
630  {
631  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
632  "which Kig does not currently support.", domelem.tagName() ,
633  domelem.attribute( "type" ) ) );
634  return 0;
635  }
636 #ifdef DRGEO_DEBUG
637  kDebug() << "+++++++++ oc:" << oc;
638 #endif
639  }
640  else if ( domelem.tagName() == "angle" )
641  {
642  if ( domelem.attribute( "type" ) == "3pts" )
643  {
644  if ( parents.size() != 3 ) KIG_FILTER_PARSE_ERROR;
645  oc = new ObjectTypeCalcer( HalfAngleType::instance(), parents );
646  }
647  else
648  {
649  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
650  "which Kig does not currently support.", domelem.tagName() ,
651  domelem.attribute( "type" ) ) );
652  return 0;
653  }
654 #ifdef DRGEO_DEBUG
655  kDebug() << "+++++++++ oc:" << oc;
656 #endif
657  }
658  else if ( domelem.tagName() == "script" )
659  {
660  QString xs;
661  QString ys;
662  QString text;
663  for ( QDomNode c = domelem.firstChild(); ! c.isNull(); c = c.nextSibling() )
664  {
665  QDomElement ce = c.toElement();
666  if ( ce.isNull() ) continue;
667  else if ( ce.tagName() == "x" )
668  xs = ce.text();
669  else if ( ce.tagName() == "y" )
670  ys = ce.text();
671  else if ( ce.tagName() == "code" )
672  text = ce.text();
673  }
674  bool ok;
675  bool ok2;
676  double x = xs.toDouble( &ok );
677  double y = ys.toDouble( &ok2 );
678  if ( ! ( ok && ok2 ) )
679  KIG_FILTER_PARSE_ERROR;
680  // since Kig doesn't support Guile scripts, it will write script's text
681  // in a label, so the user can freely see the code and make whatever
682  // he/she wants
683  // possible idea: construct a new script object with the parents of Guile
684  // one and the Guile code inserted commented... depends on a better
685  // handling of arguments in scripts?
686  if ( domelem.attribute( "type" ) == "nitems" )
687  oc = fact->labelCalcer( text, Coordinate( x, y ), false, std::vector<ObjectCalcer*>(), *ret );
688  else
689  {
690  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
691  "which Kig does not currently support.", domelem.tagName() ,
692  domelem.attribute( "type" ) ) );
693  return 0;
694  }
695  }
696  else if ( domelem.tagName() == "locus" )
697  {
698  if ( domelem.attribute( "type" ) == "None" )
699  oc = fact->locusCalcer( parents[0], parents[1] );
700  else
701  {
702  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
703  "which Kig does not currently support.", domelem.tagName() ,
704  domelem.attribute( "type" ) ) );
705  return 0;
706  }
707 #ifdef DRGEO_DEBUG
708  kDebug() << "+++++++++ oc:" << oc;
709 #endif
710  }
711  else if ( ( domelem.tagName() == "boundingBox" ) ||
712  ( domelem.tagName() == "customUI" ) )
713  {
714  // ignoring these elements, since they are not useful to us...
715  nignored++;
716  }
717  else
718  {
719 #ifdef DRGEO_DEBUG
720  kDebug() << ">>>>>>>>> UNKNOWN OBJECT";
721 #endif
722  notSupported( file, i18n( "This Dr. Geo file contains a \"%1 %2\" object, "
723  "which Kig does not currently support.", domelem.tagName() ,
724  domelem.attribute( "type" ) ) );
725  return 0;
726  }
727  curid++;
728  if ( oc == 0 )
729  continue;
730 
731 // reading color
732  QColor co( domelem.attribute( "color" ) );
733  if ( ! co.isValid() )
734  {
735  if ( domelem.attribute( "color" ) == "Bordeaux" )
736  co.setRgb( 145, 0, 0 );
737  else
738  co = Qt::blue;
739  }
740 // reading width and style
741 // Dashed -> the little one
742 // Normal -> the medium
743 // Thick -> the biggest one
744  int w = -1;
745  Qt::PenStyle s = Qt::SolidLine;
746  if ( domelem.tagName() == "point" )
747  {
748  if ( domelem.attribute( "thickness" ) == "Normal" )
749  w = 7;
750  else if ( domelem.attribute( "thickness" ) == "Thick" )
751  w = 9;
752  }
753  else
754  {
755  if ( domelem.attribute( "thickness" ) == "Dashed" )
756  s = Qt::DotLine;
757  if ( domelem.attribute( "thickness" ) == "Thick" )
758  w = 2;
759  }
760  QString ps = domelem.attribute( "style" );
761  int pointstyle = ObjectDrawer::pointStyleFromString( ps );
762 // show this object?
763  bool show = ( ( domelem.attribute( "masked" ) != "True" ) &&
764  ( domelem.attribute( "masked" ) != "Alway" ) );
765 // costructing the ObjectDrawer*
766  ObjectDrawer* d = new ObjectDrawer( co, w, show, s, pointstyle );
767 // reading object name
768  QString strname = domelem.attribute( "name" );
769  ObjectConstCalcer* name = new ObjectConstCalcer( new StringImp( strname ) );
770 
771 // creating the ObjectHolder*
772  ObjectHolder* o = new ObjectHolder( oc, d, name );
773  holders.push_back( o );
774 // calc()
775 #ifdef DRGEO_DEBUG
776  kDebug() << ">>>>>>>>> calc";
777 #endif
778  holders[curid-1-nignored]->calc( *ret );
779 #ifdef DRGEO_DEBUG
780  kDebug() << "+++++++++ oc: " << oc << " - "
781  << oc->imp()->type()->internalName() << endl;
782 #endif
783 
784  if ( domelem.tagName() == "point" )
785  {
786  if ( !strname.isEmpty() )
787  {
788  std::vector<ObjectCalcer*> args2;
789  args2.push_back( o->nameCalcer() );
790  oc2 = fact->attachedLabelCalcer( QString::fromLatin1( "%1" ), oc,
791  static_cast<const PointImp*>( oc->imp() )->coordinate(),
792  false, args2, *ret );
793  co = Qt::black;
794  }
795  }
796  else if ( domelem.tagName() == "angle" )
797  {
798  oc2 = filtersConstructTextObject(
799  static_cast<const PointImp*>( holders[curid-1-nignored]->calcer()->parents()[1]->imp() )->coordinate(),
800  holders[curid-1-nignored]->calcer(), "angle-degrees", *ret, false );
801  }
802 
803  oc = 0;
804 
805  if ( oc2 != 0 )
806  {
807  oc2->calc( *ret );
808  ObjectDrawer* d2 = new ObjectDrawer( co );
809  ObjectHolder* o2 = new ObjectHolder( oc2, d2 );
810  holders2.push_back( o2 );
811  oc2 = 0;
812  }
813  }
814 
815  ret->addObjects( holders );
816  ret->addObjects( holders2 );
817  ret->setGrid( grid );
818  ret->setAxes( grid );
819  return ret;
820 }
821 
822 KigFilterDrgeo* KigFilterDrgeo::instance()
823 {
824  static KigFilterDrgeo f;
825  return &f;
826 }
ObjectFactory::instance
static const ObjectFactory * instance()
Definition: object_factory.cc:90
ArcLineIntersectionType::instance
static const ArcLineIntersectionType * instance()
Definition: intersection_types.cc:541
KigFilterDrgeo::~KigFilterDrgeo
~KigFilterDrgeo()
Definition: drgeo-filter.cc:73
ArcBTPType::instance
static const ArcBTPType * instance()
Definition: arc_type.cc:70
PointReflectionType::instance
static const PointReflectionType * instance()
Definition: transform_types.cc:87
StringImp
This ObjectImp is a BogusImp containing only a string value.
Definition: bogus_imp.h:167
RotationType::instance
static const RotationType * instance()
Definition: transform_types.cc:161
TranslatedType::instance
static const TranslatedType * instance()
Definition: transform_types.cc:52
LineData
Simple class representing a line.
Definition: misc/common.h:49
ObjectConstCalcer
This is an ObjectCalcer that keeps an ObjectImp, and never calculates a new one.
Definition: object_calcer.h:232
LineData::dir
const Coordinate dir() const
The direction of the line.
Definition: misc/common.h:72
LinePerpendLPType::instance
static LinePerpendLPType * instance()
Definition: line_type.cc:130
main
int main(int argc, char **argv)
Definition: main.cpp:97
RayImp
An ObjectImp representing a ray.
Definition: line_imp.h:136
CircleBPRType::instance
static const CircleBPRType * instance()
Definition: circle_type.cc:210
CircleCircleIntersectionType::instance
static const CircleCircleIntersectionType * instance()
Definition: intersection_types.cc:490
RayImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the RayImp type.
Definition: line_imp.cc:562
RayABType::instance
static const RayABType * instance()
Definition: line_type.cc:119
HalfAngleType::instance
static const HalfAngleType * instance()
Definition: angle_type.cc:178
KigDocument::addObjects
void addObjects(const std::vector< ObjectHolder * > &os)
Add the objects os to the document.
Definition: kig_document.cc:143
convertDrgeoLineParam
static const Coordinate convertDrgeoLineParam(const double param, const LineData &line)
Definition: drgeo-filter.cc:169
KigFilterDrgeo::instance
static KigFilterDrgeo * instance()
Definition: drgeo-filter.cc:822
ObjectTypeCalcer
This is an ObjectCalcer that uses one of the various ObjectType's to calculate its ObjectImp...
Definition: object_calcer.h:183
LineImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the LineImp type.
Definition: line_imp.cc:528
ObjectHolder::nameCalcer
const ObjectConstCalcer * nameCalcer() const
Definition: object_holder.cc:63
IntImp
This ObjectImp is a BogusImp containing only an int value.
Definition: bogus_imp.h:128
Coordinate
The Coordinate class is the basic class representing a 2D location by its x and y components...
Definition: coordinate.h:33
convertDrgeoHalflineParam
static const Coordinate convertDrgeoHalflineParam(const double param, const LineData &line)
Definition: drgeo-filter.cc:177
Coordinate::length
double length() const
Length.
Definition: coordinate.cpp:144
KigDocument::setGrid
void setGrid(bool showgrid)
set to show/hide the grid.
Definition: kig_document.cc:181
ObjectPropertyCalcer::calc
void calc(const KigDocument &doc)
Makes the ObjectCalcer recalculate its ObjectImp from its parents.
Definition: object_calcer.cc:183
LineLineIntersectionType::instance
static const LineLineIntersectionType * instance()
Definition: intersection_types.cc:374
KigFilterDrgeo
This is an import filter for the GNOME geometry program DrGeo.
Definition: drgeo-filter.h:31
ObjectHolder
An ObjectHolder represents an object as it is known to the document.
Definition: object_holder.h:40
LineParallelLPType::instance
static LineParallelLPType * instance()
Definition: line_type.cc:163
VectorType::instance
static const VectorType * instance()
Definition: vector_type.cc:43
ObjectCalcer
An ObjectCalcer is an object that represents an algorithm for calculating an ObjectImp from other Obj...
Definition: object_calcer.h:66
filtersConstructTextObject
ObjectTypeCalcer * filtersConstructTextObject(const Coordinate &c, ObjectCalcer *o, const QByteArray &arg, const KigDocument &doc, bool needframe)
constructs a text object with text "%1", location c, and variable parts given by the argument arg of ...
Definition: filters-common.cc:28
KigFilterDrgeo::load
KigDocument * load(const QString &file)
load file fromfile and build a KigDocument from it.
Definition: drgeo-filter.cc:82
KigFilter::notSupported
void notSupported(const QString &file, const QString &explanation) const
Definition: filter.cc:92
LineData::a
Coordinate a
One point on the line.
Definition: misc/common.h:64
SegmentImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the SegmentImp type.
Definition: line_imp.cc:545
ObjectPropertyCalcer
This is an ObjectCalcer that has a single parent, and gets a certain property from it in its calc() m...
Definition: object_calcer.h:276
ArcImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the ArcImp type.
Definition: other_imp.cc:629
CircleBCPType::instance
static const CircleBCPType * instance()
Definition: circle_type.cc:55
CircleImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the CircleImp type.
Definition: circle_imp.cc:342
ObjectType
The ObjectType class is a thing that represents the "behaviour" for a certain type.
Definition: object_type.h:32
ObjectDrawer::pointStyleFromString
static int pointStyleFromString(const QString &style)
Note that this returns a valid point style in every case, even if the given style string is unknown...
Definition: object_drawer.cc:169
ScalingOverCenterType::instance
static const ScalingOverCenterType * instance()
Definition: transform_types.cc:203
ObjectDrawer
A class holding some information about how a certain object is drawn on the window.
Definition: object_drawer.h:47
KigDocument::setAxes
void setAxes(bool showaxes)
set to show/hide the grid.
Definition: kig_document.cc:191
filters-common.h
drgeo-filter.h
convertDrgeoIndex
static int convertDrgeoIndex(const std::vector< DrGeoHierarchyElement > &es, const QString &myid)
Definition: drgeo-filter.cc:161
KigDocument
KigDocument is the class holding the real data in a Kig document.
Definition: kig_document.h:36
AbstractLineImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the AbstractLineImp type.
Definition: line_imp.cc:520
ConicLineIntersectionType::instance
static const ConicLineIntersectionType * instance()
Definition: intersection_types.cc:54
LineImp
An ObjectImp representing a line.
Definition: line_imp.h:184
PolygonBNPType::instance
static const PolygonBNPType * instance()
Definition: polygon_type.cc:151
MidPointType::instance
static const MidPointType * instance()
Definition: point_type.cc:282
ObjectTypeCalcer::calc
void calc(const KigDocument &doc)
Makes the ObjectCalcer recalculate its ObjectImp from its parents.
Definition: object_calcer.cc:32
KIG_FILTER_PARSE_ERROR
#define KIG_FILTER_PARSE_ERROR
Definition: filter.h:53
SegmentABType::instance
static const SegmentABType * instance()
Definition: line_type.cc:55
KigFilterDrgeo::supportMime
bool supportMime(const QString &mime)
can the filter handle the mimetype mime ?
Definition: drgeo-filter.cc:77
KigFilterDrgeo::KigFilterDrgeo
KigFilterDrgeo()
Definition: drgeo-filter.cc:69
KigFilter::warning
void warning(const QString &explanation) const
Definition: filter.cc:99
LineReflectionType::instance
static const LineReflectionType * instance()
Definition: transform_types.cc:122
KigFilter::fileNotFound
void fileNotFound(const QString &file) const
Definition: filter.cc:70
PointByCoordsType::instance
static const PointByCoordsType * instance()
Definition: point_type.cc:799
ObjectFactory
Definition: object_factory.h:23
uint
unsigned int uint
Definition: object_imp.h:87
LineABType::instance
static const LineABType * instance()
Definition: line_type.cc:87
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:35:39 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kig

Skip menu "kig"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal